Commit e0a7b70df059588150b7c9e6b9cd5b109262922c

Authored by Dan Croak
1 parent 21eb6ccf

adding mime types and xml simple gems

README.markdown
... ... @@ -20,7 +20,9 @@ This will create a Rails 2.3.2 app with Heroku-recommended code:
20 20 * jQuery for Javascript
21 21 * Clearance for authentication
22 22 * Cucumber, Shoulda, Factory Girl, & Mocha for testing
23   -* Evergreen for CSS framework
  23 +* Flutie for CSS framework
  24 +* Formtastic for form builders
  25 +* Inherited Resources for RESTful controllers
24 26 * Blitz for features, model, controller, & helper generators
25 27  
26 28 If you don't have all the necessary gems, they will be installed.
... ...
vendor/gems/mime-types-1.16/.specification 0 → 100644
... ... @@ -0,0 +1,133 @@
  1 +--- !ruby/object:Gem::Specification
  2 +name: mime-types
  3 +version: !ruby/object:Gem::Version
  4 + version: "1.16"
  5 +platform: ruby
  6 +authors:
  7 +- Austin Ziegler
  8 +autorequire:
  9 +bindir: bin
  10 +cert_chain:
  11 +- |
  12 + -----BEGIN CERTIFICATE-----
  13 + MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ8wDQYDVQQDDAZhdXN0
  14 + aW4xGTAXBgoJkiaJk/IsZAEZFglydWJ5Zm9yZ2UxEzARBgoJkiaJk/IsZAEZFgNv
  15 + cmcwHhcNMDcxMTMwMDE0OTAwWhcNMDgxMTI5MDE0OTAwWjBBMQ8wDQYDVQQDDAZh
  16 + dXN0aW4xGTAXBgoJkiaJk/IsZAEZFglydWJ5Zm9yZ2UxEzARBgoJkiaJk/IsZAEZ
  17 + FgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOSg1riVV22ord
  18 + q0t4YVx57GDPMqdjlnQ5M7D9iBnnW0c8pifegbb0dm+mC9hJSuPtcJS53+YPTy9F
  19 + wlZbjI2cN+P0QLUUTOlZus2sHq7Pr9jz2nJf8hCT7t5Vlopv1N/xlKtXqpcyEkhJ
  20 + JHTrxe1avGwuq8DIAIN01moQJ+hJlgrnR2eRJRazTGiXKBLGAFXDl/Agn78MHx6w
  21 + pzZ2APydo6Nuk7Ktq1MvCHzLzCACbOlYawFk3/9dbsmHhVjsi6YW+CpEJ2BnTy8X
  22 + JBXlyNTk1JxDmcs3RzNr+9AmDQh3u4LcmJnWxtLJo9e7UBxH/bwVORJyf8dAOmOm
  23 + HO6bFTLvAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
  24 + BBT9e1+pFfcV1LxVxILANqLtZzI/XTANBgkqhkiG9w0BAQUFAAOCAQEAhg42pvrL
  25 + uVlqAaHqV88KqgnW2ymCWm0ePohicFTcyiS5Yj5cN3OXLsPV2x12zqvLCFsfpA4u
  26 + D/85rngKFHITSW0h9e/CIT/pwQA6Uuqkbr0ypkoU6mlNIDS10PlK7aXXFTCP9X3f
  27 + IndAajiNRgKwb67nj+zpQwHa6dmooyRQIRRijrMKTgY6ebaCCrm7J3BLLTJAyxOW
  28 + +1nD0cuTkBEKIuSVK06E19Ml+xWt2bdtS9Wz/8jHivJ0SvUpbmhKVzh1rBslwm65
  29 + JpQgg3SsV23vF4qkCa2dt1FL+FeWJyCdj23DV3598X72RYiK3D6muWURck16jqeA
  30 + BRvUFuFHOwa/yA==
  31 + -----END CERTIFICATE-----
  32 +
  33 +date: 2009-03-02 00:00:00 -05:00
  34 +default_executable:
  35 +dependencies:
  36 +- !ruby/object:Gem::Dependency
  37 + name: archive-tar-minitar
  38 + type: :development
  39 + version_requirement:
  40 + version_requirements: !ruby/object:Gem::Requirement
  41 + requirements:
  42 + - - ~>
  43 + - !ruby/object:Gem::Version
  44 + version: "0.5"
  45 + version:
  46 +- !ruby/object:Gem::Dependency
  47 + name: nokogiri
  48 + type: :development
  49 + version_requirement:
  50 + version_requirements: !ruby/object:Gem::Requirement
  51 + requirements:
  52 + - - ~>
  53 + - !ruby/object:Gem::Version
  54 + version: "1.2"
  55 + version:
  56 +- !ruby/object:Gem::Dependency
  57 + name: rcov
  58 + type: :development
  59 + version_requirement:
  60 + version_requirements: !ruby/object:Gem::Requirement
  61 + requirements:
  62 + - - ~>
  63 + - !ruby/object:Gem::Version
  64 + version: "0.8"
  65 + version:
  66 +- !ruby/object:Gem::Dependency
  67 + name: hoe
  68 + type: :development
  69 + version_requirement:
  70 + version_requirements: !ruby/object:Gem::Requirement
  71 + requirements:
  72 + - - ">="
  73 + - !ruby/object:Gem::Version
  74 + version: 1.8.3
  75 + version:
  76 +description: MIME::Types for Ruby originally based on and synchronized with MIME::Types for Perl by Mark Overmeer, copyright 2001 - 2009. As of version 1.15, the data format for the MIME::Type list has changed and the synchronization will no longer happen.
  77 +email:
  78 +- austin@rubyforge.org
  79 +executables: []
  80 +
  81 +extensions: []
  82 +
  83 +extra_rdoc_files:
  84 +- History.txt
  85 +- Install.txt
  86 +- Licence.txt
  87 +- README.txt
  88 +files:
  89 +- History.txt
  90 +- Install.txt
  91 +- Licence.txt
  92 +- Manifest.txt
  93 +- README.txt
  94 +- Rakefile
  95 +- lib/mime/types.rb
  96 +- lib/mime/types.rb.data
  97 +- mime-types.gemspec
  98 +- setup.rb
  99 +- test/test_mime_type.rb
  100 +- test/test_mime_types.rb
  101 +has_rdoc: true
  102 +homepage: http://mime-types.rubyforge.org/
  103 +licenses: []
  104 +
  105 +post_install_message:
  106 +rdoc_options:
  107 +- --main
  108 +- README.txt
  109 +require_paths:
  110 +- bin
  111 +- lib
  112 +required_ruby_version: !ruby/object:Gem::Requirement
  113 + requirements:
  114 + - - ">="
  115 + - !ruby/object:Gem::Version
  116 + version: "0"
  117 + version:
  118 +required_rubygems_version: !ruby/object:Gem::Requirement
  119 + requirements:
  120 + - - ">="
  121 + - !ruby/object:Gem::Version
  122 + version: "0"
  123 + version:
  124 +requirements: []
  125 +
  126 +rubyforge_project: mime-types
  127 +rubygems_version: 1.3.4
  128 +signing_key:
  129 +specification_version: 2
  130 +summary: Manages a MIME Content-Type database that will return the Content-Type for a given filename.
  131 +test_files:
  132 +- test/test_mime_type.rb
  133 +- test/test_mime_types.rb
... ...
vendor/gems/mime-types-1.16/History.txt 0 → 100644
... ... @@ -0,0 +1,107 @@
  1 +== MIME::Types 1.16
  2 +* Made compatible with Ruby 1.8.6, 1.8.7, and 1.9.1.
  3 +* Switched to the 'hoe' gem system and added a lot of build-time tools.
  4 +* Updated the MIME types to the list based on the values in the Perl library
  5 + version 1.27. Also updated based on external source information and bug
  6 + reports.
  7 +* This is the last planned version of MIME::Types 1.x. Work will be
  8 + starting soon on MIME::Types 2.x with richer data querying mechanisms
  9 + and support for external data sources.
  10 +
  11 +== MIME::Types 1.15
  12 +* Removed lib/mime/type.rb to form a single MIME::Types database source. It
  13 + is unlikely that one will ever need MIME::Type without MIME::Types.
  14 +* Re-synchronized the MIME type list with the sources, focusing primarily on
  15 + the IANA list.
  16 +* Added more detailed source information for MIME::Type objects.
  17 +* Changed MIME::Types from a module to a class with a default instance. There
  18 + should be no difference in usage.
  19 +* Removed MIME::Types::DATA_VERSION; it is now an attribute on the
  20 + MIME::Types instance.
  21 +* NOTE: Synchronization with the Perl version of MIME::Types is no longer a
  22 + priority as of this release. The data format and information has changed.
  23 +* Removed MIME::Types.by_suffix and MIME::Types.by_mediatype.
  24 +
  25 +== MIME::Types 1.13.1
  26 +* Fixed a problem with the installer running tests. This now works.
  27 +* Improved the implementation of MIME::Type.signature?
  28 +* Moved code around to use the class << self idiom instead of always
  29 + prepending the module/class name.
  30 +* Added two new best-guess implementations of functions found in Perl's
  31 + MIME::Types implementation (1.13). Do not rely on these until the purpose
  32 + and implementation is stabilised.
  33 +* Updated the MIME list to reflect changes noted by
  34 + Ville Skyttä <ville.skytta@iki.fi>.
  35 +* Added a new constant to MIME::Types, DATA_VERSION. This will allow the Ruby
  36 + version number to be updated separately from the Perl version while keeping
  37 + the MIME Type list version in sync.
  38 +
  39 +== MIME::Types 1.13
  40 + ! WARNING: This version changes the API of MIME::Types !
  41 + ! WARNING: This version is compatible with Ruby 1.8 and higher ONLY !
  42 +* Removed dependency on InstallPackage; offering 1.13 as either .tar.gz or
  43 + .gem.
  44 +* Split into two files, mime/type.rb and mime/types.rb. This will make
  45 + maintaining the list of changes easier.
  46 +* Changed the MIME::Type construction API. Accepts only a single String
  47 + argument (but does no named type-checking) and yields self.
  48 +* Removed private methods #init_extensions, #init_encoding, and #init_system
  49 + and replaced with #extensions=, #encoding=, and #system=.
  50 +* Added #default_encoding to return 'quoted-printable' or 'base64' depending
  51 + on the media type of the MIME type.
  52 +* Added #raw_media_type and #raw_sub_type to provide the non-simplified
  53 + versions of the media type and subtype.
  54 +* Alternative constructors MIME::Type.from_array, MIME::Type.from_hash, and
  55 + MIME::Type.from_mime_type added to compensate for the removal of named type
  56 + checking in the original constructor.
  57 +* Added #to_str, #to_a, and #to_hash methods. The latter two will provide
  58 + output suitable for use in #from_array and #from_hash.
  59 +* Removed "binary" encoding and enforced the use of a valid encoding string.
  60 +* Added #system? returning true if the MIME::Type is an OS-specific
  61 + MIME::Type.
  62 +* Added #platform? returning true if the MIME::Type is an OS-specific
  63 + MIME::Type for the current RUBY_PLATFORM.
  64 +* Added #like? returning true if the simplified type matches the other value
  65 + provided. #<'application/x-excel'>.like?('application/excel') is true.
  66 +* Added #complete? returning true if the MIME::Type specifies an extension
  67 + list.
  68 +* Updated the MIME type list to reflect additions by Mark Overmeer for Perl's
  69 + MIME::Types 1.12 and the official IANA list as of 2004.04.06. A number of
  70 + formerly "registered" MIME types are now no longer registered (e.g.,
  71 + application/excel is now application/x-excel). This ensures that the
  72 + simplified type still works with applications, but does not report an
  73 + unregistered type as registered.
  74 +* Restored MIME type list to Mark Overmeer's format to facilitate easy
  75 + exchange between the two projects.
  76 +* Added additional unit tests from Mark Overmeer's 1.12 version.
  77 +
  78 +== MIME::Types 1.07
  79 +* Changed version numbering to match Perl MIME::Types 1.07.
  80 +* Re-synchronized with Mark Overmeer's list in Perl PMIME::Types 1.07.
  81 +* [NN Poster] updated the attributes for the PGP types.
  82 +
  83 +== MIME::Types 1.005
  84 +* Changed to Phil Thomson's InstallPackage.
  85 +* Added several types from Perl MIME::Types 1.005.
  86 +* Cleaned up data format; some data formats will show up with proper data now.
  87 +
  88 +== MIME::Types 1.004
  89 +* Updated to match Perl MIME::Types 1.004, links credited to Dan Puro. Adds
  90 + new reference list to http://www.indiana.edu/cgi-bin-local/mimetypes
  91 +* Removed InvalidType and replaced with TypeError.
  92 +* Changed instances of #type to #class.
  93 +* Cleaned up how simplified versions are created.
  94 +
  95 +== MIME::Types 1.003
  96 +* Initial release based on Perl MIME::Types 1.003.
  97 +
  98 +== Copyright
  99 + MIME::Types
  100 + A Ruby implementation of a MIME Types information library. Based in spirit
  101 + on the Perl MIME::Types information library by Mark Overmeer.
  102 + http://rubyforge.org/projects/mime-types/
  103 +
  104 + Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  105 + Artistic licence. See Licence.txt for more information.
  106 +
  107 + Copyright 2003 - 2009 Austin Ziegler
... ...
vendor/gems/mime-types-1.16/Install.txt 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +Installing this package is as simple as:
  2 +
  3 + % ruby setup.rb
  4 +
  5 +Alternatively, you can use the Gem version of MIME::Types available as
  6 +mime-types-1.16.gem from the usual sources.
  7 +
  8 +== Copyright
  9 + MIME::Types
  10 + A Ruby implementation of a MIME Types information library. Based in spirit
  11 + on the Perl MIME::Types information library by Mark Overmeer.
  12 + http://rubyforge.org/projects/mime-types/
  13 +
  14 + Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  15 + Artistic licence. See Licence.txt for more information.
  16 +
  17 + Copyright 2003 - 2009 Austin Ziegler
... ...
vendor/gems/mime-types-1.16/Licence.txt 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 += MIME::Types for Ruby
  2 +Homepage:: http://rubyforge.org/projects/mime-types/
  3 +Copyright:: Copyright (c) 2003 - 2006 Austin Ziegler.
  4 +Summary:: Ruby's licence, Perl Aristic Licence,
  5 + GNU GPL version 2 (or later)
  6 +
  7 +The text of the Ruby licence can be found at:
  8 +http://www.ruby-lang.org/en/LICENSE.txt
  9 +
  10 +The text of the Perl Artistic Licence can be found at:
  11 +http://www.perl.com/pub/a/language/misc/Artistic.html
  12 +
  13 +The text of the GNU GPL can be found at: http://www.gnu.org/copyleft/gpl.html
  14 +
  15 +If you do not accept one of these licences, you may not use this software.
... ...
vendor/gems/mime-types-1.16/Manifest.txt 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +History.txt
  2 +Install.txt
  3 +Licence.txt
  4 +Manifest.txt
  5 +README.txt
  6 +Rakefile
  7 +lib/mime/types.rb
  8 +lib/mime/types.rb.data
  9 +mime-types.gemspec
  10 +setup.rb
  11 +test/test_mime_type.rb
  12 +test/test_mime_types.rb
... ...
vendor/gems/mime-types-1.16/README.txt 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 += README: Mime::Types for Ruby
  2 +This library allows for the identification of a file's likely MIME content
  3 +type. This is release 1.16. The identification of MIME content type is based
  4 +on a file's filename extensions.
  5 +
  6 +MIME::Types for Ruby originally based on and synchronized with MIME::Types
  7 +for Perl by Mark Overmeer, copyright 2001 - 2009. As of version 1.15, the
  8 +data format for the MIME::Type list has changed and the synchronization will
  9 +no longer happen.
  10 +
  11 +Homepage:: http://mime-types.rubyforge.org/
  12 +Copyright:: 2002 - 2009, Austin Ziegler
  13 + Based in part on prior work copyright Mark Overmeer
  14 +
  15 +== Licensing
  16 +MIME::Types is available under three disjunctive licences, as detailed in the
  17 +Licence.txt file.
  18 +
  19 +== Copyright
  20 + MIME::Types
  21 + A Ruby implementation of a MIME Types information library. Based in spirit
  22 + on the Perl MIME::Types information library by Mark Overmeer.
  23 + http://rubyforge.org/projects/mime-types/
  24 +
  25 + Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  26 + Artistic licence. See Licence.txt for more information.
  27 +
  28 + Copyright 2003 - 2009 Austin Ziegler
... ...
vendor/gems/mime-types-1.16/Rakefile 0 → 100644
... ... @@ -0,0 +1,316 @@
  1 +#! /usr/bin/env rake
  2 +#--
  3 +# MIME::Types
  4 +# A Ruby implementation of a MIME Types information library. Based in spirit
  5 +# on the Perl MIME::Types information library by Mark Overmeer.
  6 +# http://rubyforge.org/projects/mime-types/
  7 +#
  8 +# Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  9 +# Artistic licence. See Licence.txt for more information.
  10 +#
  11 +# Copyright 2003 - 2009 Austin Ziegler
  12 +#++
  13 +
  14 +require 'rubygems'
  15 +require 'hoe'
  16 +
  17 +$LOAD_PATH.unshift('lib')
  18 +
  19 +require 'mime/types'
  20 +
  21 +PKG_NAME = 'mime-types'
  22 +PKG_VERSION = MIME::Types::VERSION
  23 +PKG_DIST = "#{PKG_NAME}-#{PKG_VERSION}"
  24 +PKG_TAR = "pkg/#{PKG_DIST}.tar.gz"
  25 +MANIFEST = File.read("Manifest.txt").split
  26 +
  27 +hoe = Hoe.new PKG_NAME, PKG_VERSION do |p|
  28 + p.rubyforge_name = PKG_NAME
  29 + # This is a lie because I will continue to use Archive::Tar::Minitar.
  30 + p.need_tar = false
  31 + # need_zip - Should package create a zipfile? [default: false]
  32 +
  33 + p.author = [ "Austin Ziegler" ]
  34 + p.email = %W(austin@rubyforge.org)
  35 + p.url = "http://mime-types.rubyforge.org/"
  36 + p.summary = %q{Manages a MIME Content-Type database that will return the Content-Type for a given filename.}
  37 + p.changes = p.paragraphs_of("History.txt", 0..0).join("\n\n")
  38 + p.description = p.paragraphs_of("README.txt", 1..1).join("\n\n")
  39 +
  40 + p.extra_dev_deps << %w(archive-tar-minitar ~>0.5)
  41 + p.extra_dev_deps << %w(nokogiri ~>1.2)
  42 + p.extra_dev_deps << %w(rcov ~>0.8)
  43 +
  44 + p.clean_globs << "coverage"
  45 +
  46 + p.spec_extras[:extra_rdoc_files] = MANIFEST.grep(/txt$/) - ["Manifest.txt"]
  47 +end
  48 +
  49 +begin
  50 + require 'rcov/rcovtask'
  51 + Rcov::RcovTask.new do |t|
  52 + t.libs << 'test'
  53 + t.test_files = hoe.test_files
  54 + t.verbose = true
  55 + end
  56 +rescue LoadError
  57 + puts "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
  58 +end
  59 +
  60 +=begin
  61 + require 'cucumber/rake/task'
  62 + Cucumber::Rake::Task.new(:features)
  63 +rescue LoadError
  64 + puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
  65 +=end
  66 +
  67 +desc "Build a MIME::Types .tar.gz distribution."
  68 +task :tar => [ PKG_TAR ]
  69 +file PKG_TAR => [ :test ] do |t|
  70 + require 'archive/tar/minitar'
  71 + require 'zlib'
  72 + files = MANIFEST.map { |f|
  73 + fn = File.join(PKG_DIST, f)
  74 + tm = File.stat(f).mtime
  75 +
  76 + if File.directory?(f)
  77 + { :name => fn, :mode => 0755, :dir => true, :mtime => tm }
  78 + else
  79 + mode = if f =~ %r{^bin}
  80 + 0755
  81 + else
  82 + 0644
  83 + end
  84 + data = File.read(f)
  85 + { :name => fn, :mode => mode, :data => data, :size => data.size,
  86 + :mtime => tm }
  87 + end
  88 + }
  89 +
  90 + begin
  91 + unless File.directory?(File.dirname(t.name))
  92 + require 'fileutils'
  93 + FileUtils.mkdir_p File.dirname(t.name)
  94 + end
  95 + tf = File.open(t.name, 'wb')
  96 + gz = Zlib::GzipWriter.new(tf)
  97 + tw = Archive::Tar::Minitar::Writer.new(gz)
  98 +
  99 + files.each do |entry|
  100 + if entry[:dir]
  101 + tw.mkdir(entry[:name], entry)
  102 + else
  103 + tw.add_file_simple(entry[:name], entry) { |os|
  104 + os.write(entry[:data])
  105 + }
  106 + end
  107 + end
  108 + ensure
  109 + tw.close if tw
  110 + gz.close if gz
  111 + end
  112 +end
  113 +task :package => [ PKG_TAR ]
  114 +
  115 +desc "Build the manifest file from the current set of files."
  116 +task :build_manifest do |t|
  117 + require 'find'
  118 +
  119 + hoerc = File.join(File.dirname(__FILE__), ".hoerc")
  120 + hoerc = File.open(hoerc, "rb") { |f| f.read }
  121 + hoerc = YAML::load(hoerc)
  122 +
  123 + paths = []
  124 + Find.find(".") do |path|
  125 + next if File.directory?(path) || path =~ hoerc["exclude"]
  126 + paths << path.sub(%r{^\./}, '')
  127 + end
  128 +
  129 + paths = paths.sort.join("\n")
  130 +
  131 + File.open("Manifest.txt", "w") do |f|
  132 + f.puts paths
  133 + end
  134 +
  135 + puts paths
  136 +end
  137 +
  138 +desc "Download the current MIME type registrations from IANA."
  139 +task :iana, :save, :destination do |t, args|
  140 + save_type = args.save || :text
  141 + save_type = save_type.to_sym
  142 +
  143 + case save_type
  144 + when :text, :both, :html
  145 + nil
  146 + else
  147 + raise "Unknown save type provided. Must be one of text, both, or html."
  148 + end
  149 +
  150 + destination = args.destination || "type-lists"
  151 +
  152 + require 'open-uri'
  153 + require 'nokogiri'
  154 + require 'cgi'
  155 +
  156 + class IANAParser
  157 + include Comparable
  158 +
  159 + INDEX = %q(http://www.iana.org/assignments/media-types/)
  160 + CONTACT_PEOPLE = %r{http://www.iana.org/assignments/contact-people.html?#(.*)}
  161 + RFC_EDITOR = %r{http://www.rfc-editor.org/rfc/rfc(\d+).txt}
  162 + IETF_RFC = %r{http://www.ietf.org/rfc/rfc(\d+).txt}
  163 + IETF_RFC_TOOLS = %r{http://tools.ietf.org/html/rfc(\d+)}
  164 +
  165 + class << self
  166 + def load_index
  167 + @types ||= {}
  168 +
  169 + Nokogiri::HTML(open(INDEX) { |f| f.read }).xpath('//p/a').each do |tag|
  170 + href_match = %r{^/assignments/media-types/(.+)/$}.match(tag['href'])
  171 + next if href_match.nil?
  172 + type = href_match.captures[0]
  173 + @types[tag.content] = IANAParser.new(tag.content, type)
  174 + end
  175 + end
  176 +
  177 + attr_reader :types
  178 + end
  179 +
  180 + def initialize(name, type)
  181 + @name = name
  182 + @type = type
  183 + @url = File.join(INDEX, @type)
  184 + end
  185 +
  186 + attr_reader :name
  187 + attr_reader :type
  188 + attr_reader :url
  189 + attr_reader :html
  190 +
  191 + def download(name = nil)
  192 + @html = Nokogiri::HTML(open(name || @url) { |f| f.read })
  193 + end
  194 +
  195 + def save_html
  196 + File.open("#@name.html", "wb") { |w| w.write @html }
  197 + end
  198 +
  199 + def <=>(o)
  200 + self.name <=> o.name
  201 + end
  202 +
  203 + def parse
  204 + nodes = html.xpath("//table//table//tr")
  205 +
  206 + # How many <td> children does the first node have?
  207 + node_count = nodes.first.children.select { |node| node.elem? }.size
  208 +
  209 + @mime_types = nodes.map do |node|
  210 + next if node == nodes.first
  211 + elems = node.children.select { |n| n.elem? }
  212 + next if elems.size.zero?
  213 + raise "size mismatch #{elems.size} != #{node_count}" if node_count != elems.size
  214 +
  215 + case elems.size
  216 + when 3
  217 + subtype_index = 1
  218 + refnode_index = 2
  219 + when 4
  220 + subtype_index = 1
  221 + refnode_index = 3
  222 + else
  223 + raise "Unknown element size."
  224 + end
  225 +
  226 + subtype = elems[subtype_index].content.chomp.strip
  227 + refnodes = elems[refnode_index].children.select { |n| n.elem? }.map { |ref|
  228 + case ref['href']
  229 + when CONTACT_PEOPLE
  230 + tag = CGI::unescape($1).chomp.strip
  231 + if tag == ref.content
  232 + "[#{ref.content}]"
  233 + else
  234 + "[#{ref.content}=#{tag}]"
  235 + end
  236 + when RFC_EDITOR, IETF_RFC, IETF_RFC_TOOLS
  237 + "RFC#$1"
  238 + when %r{(https?://.*)}
  239 + "{#{ref.content}=#$1}"
  240 + else
  241 + ref
  242 + end
  243 + }
  244 + refs = refnodes.join(',')
  245 +
  246 + "#@type/#{subtype} 'IANA,#{refs}"
  247 + end.compact
  248 +
  249 + @mime_types
  250 + end
  251 +
  252 + def save_text
  253 + File.open("#@name.txt", "wb") { |w| w.write @mime_types.join("\n") }
  254 + end
  255 + end
  256 +
  257 + puts "Downloading index of MIME types from #{IANAParser::INDEX}."
  258 + IANAParser.load_index
  259 +
  260 + require 'fileutils'
  261 + FileUtils.mkdir_p destination
  262 + Dir.chdir destination do
  263 + IANAParser.types.values.sort.each do |parser|
  264 + next if parser.name == "example" or parser.name == "mime"
  265 + puts "Downloading #{parser.name} from #{parser.url}"
  266 + parser.download
  267 +
  268 + if :html == save_type || :both == save_type
  269 + puts "Saving #{parser.name}.html"
  270 + parser.save_html
  271 + end
  272 +
  273 + puts "Parsing #{parser.name} HTML"
  274 + parser.parse
  275 +
  276 + if :text == save_type || :both == save_type
  277 + puts "Saving #{parser.name}.txt"
  278 + parser.save_text
  279 + end
  280 + end
  281 + end
  282 +end
  283 +
  284 +desc "Shows known MIME type sources."
  285 +task :mime_type_sources do
  286 + puts <<-EOS
  287 +http://www.ltsw.se/knbase/internet/mime.htp
  288 +http://www.webmaster-toolkit.com/mime-types.shtml
  289 +http://plugindoc.mozdev.org/winmime.php
  290 +http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
  291 +http://www.feedforall.com/mime-types.htm
  292 +http://www.iana.org/assignments/media-types/
  293 + EOS
  294 +end
  295 +
  296 +desc "Validate the RubyGem spec for GitHub."
  297 +task :github_validate_spec do |t|
  298 + require 'yaml'
  299 +
  300 + require 'rubygems/specification'
  301 + data = File.read("#{PKG_NAME}.gemspec")
  302 + spec = nil
  303 +
  304 + if data !~ %r{!ruby/object:Gem::Specification}
  305 + code = "$SAFE = 3\n#{data}"
  306 + p code.split($/)[44]
  307 + Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
  308 + else
  309 + spec = YAML.load(data)
  310 + end
  311 +
  312 + spec.validate
  313 +
  314 + puts spec
  315 + puts "OK"
  316 +end
... ...
vendor/gems/mime-types-1.16/lib/mime/types.rb 0 → 100644
... ... @@ -0,0 +1,751 @@
  1 +# vim: ft=ruby encoding=utf-8
  2 +#--
  3 +# MIME::Types
  4 +# A Ruby implementation of a MIME Types information library. Based in spirit
  5 +# on the Perl MIME::Types information library by Mark Overmeer.
  6 +# http://rubyforge.org/projects/mime-types/
  7 +#
  8 +# Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  9 +# Artistic licence. See Licence.txt for more information.
  10 +#
  11 +# Copyright 2003 - 2009 Austin Ziegler
  12 +#++
  13 +
  14 +# The namespace for MIME applications, tools, and libraries.
  15 +module MIME
  16 + # Reflects a MIME Content-Type which is in invalid format (e.g., it isn't
  17 + # in the form of type/subtype).
  18 + class InvalidContentType < RuntimeError; end
  19 +
  20 + # The definition of one MIME content-type.
  21 + #
  22 + # == Usage
  23 + # require 'mime/types'
  24 + #
  25 + # plaintext = MIME::Types['text/plain']
  26 + # print plaintext.media_type # => 'text'
  27 + # print plaintext.sub_type # => 'plain'
  28 + #
  29 + # puts plaintext.extensions.join(" ") # => 'asc txt c cc h hh cpp'
  30 + #
  31 + # puts plaintext.encoding # => 8bit
  32 + # puts plaintext.binary? # => false
  33 + # puts plaintext.ascii? # => true
  34 + # puts plaintext == 'text/plain' # => true
  35 + # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
  36 + #
  37 + class Type
  38 + VERSION = '1.16'
  39 +
  40 + include Comparable
  41 +
  42 + MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}o
  43 + UNREG_RE = %r{[Xx]-}o
  44 + ENCODING_RE = %r{(?:base64|7bit|8bit|quoted\-printable)}o
  45 + PLATFORM_RE = %r|#{RUBY_PLATFORM}|o
  46 +
  47 + SIGNATURES = %w(application/pgp-keys application/pgp
  48 + application/pgp-signature application/pkcs10
  49 + application/pkcs7-mime application/pkcs7-signature
  50 + text/vcard)
  51 +
  52 + IANA_URL = "http://www.iana.org/assignments/media-types/%s/%s"
  53 + RFC_URL = "http://rfc-editor.org/rfc/rfc%s.txt"
  54 + DRAFT_URL = "http://datatracker.ietf.org/public/idindex.cgi?command=id_details&filename=%s"
  55 + LTSW_URL = "http://www.ltsw.se/knbase/internet/%s.htp"
  56 + CONTACT_URL = "http://www.iana.org/assignments/contact-people.htm#%s"
  57 +
  58 + # Returns +true+ if the simplified type matches the current
  59 + def like?(other)
  60 + if other.respond_to?(:simplified)
  61 + @simplified == other.simplified
  62 + else
  63 + @simplified == Type.simplified(other)
  64 + end
  65 + end
  66 +
  67 + # Compares the MIME::Type against the exact content type or the
  68 + # simplified type (the simplified type will be used if comparing against
  69 + # something that can be treated as a String with #to_s). In comparisons,
  70 + # this is done against the lowercase version of the MIME::Type.
  71 + def <=>(other)
  72 + if other.respond_to?(:content_type)
  73 + @content_type.downcase <=> other.content_type.downcase
  74 + elsif other.respond_to?(:to_s)
  75 + @simplified <=> Type.simplified(other.to_s)
  76 + else
  77 + @content_type.downcase <=> other.downcase
  78 + end
  79 + end
  80 +
  81 + # Compares the MIME::Type based on how reliable it is before doing a
  82 + # normal <=> comparison. Used by MIME::Types#[] to sort types. The
  83 + # comparisons involved are:
  84 + #
  85 + # 1. self.simplified <=> other.simplified (ensures that we
  86 + # don't try to compare different types)
  87 + # 2. IANA-registered definitions > other definitions.
  88 + # 3. Generic definitions > platform definitions.
  89 + # 3. Complete definitions > incomplete definitions.
  90 + # 4. Current definitions > obsolete definitions.
  91 + # 5. Obselete with use-instead references > obsolete without.
  92 + # 6. Obsolete use-instead definitions are compared.
  93 + def priority_compare(other)
  94 + pc = simplified <=> other.simplified
  95 +
  96 + if pc.zero? and registered? != other.registered?
  97 + pc = registered? ? -1 : 1
  98 + end
  99 +
  100 + if pc.zero? and platform? != other.platform?
  101 + pc = platform? ? 1 : -1
  102 + end
  103 +
  104 + if pc.zero? and complete? != other.complete?
  105 + pc = complete? ? -1 : 1
  106 + end
  107 +
  108 + if pc.zero? and obsolete? != other.obsolete?
  109 + pc = obsolete? ? 1 : -1
  110 + end
  111 +
  112 + if pc.zero? and obsolete? and (use_instead != other.use_instead)
  113 + pc = if use_instead.nil?
  114 + -1
  115 + elsif other.use_instead.nil?
  116 + 1
  117 + else
  118 + use_instead <=> other.use_instead
  119 + end
  120 + end
  121 +
  122 + pc
  123 + end
  124 +
  125 + # Returns +true+ if the other object is a MIME::Type and the content
  126 + # types match.
  127 + def eql?(other)
  128 + other.kind_of?(MIME::Type) and self == other
  129 + end
  130 +
  131 + # Returns the whole MIME content-type string.
  132 + #
  133 + # text/plain => text/plain
  134 + # x-chemical/x-pdb => x-chemical/x-pdb
  135 + attr_reader :content_type
  136 + # Returns the media type of the simplified MIME type.
  137 + #
  138 + # text/plain => text
  139 + # x-chemical/x-pdb => chemical
  140 + attr_reader :media_type
  141 + # Returns the media type of the unmodified MIME type.
  142 + #
  143 + # text/plain => text
  144 + # x-chemical/x-pdb => x-chemical
  145 + attr_reader :raw_media_type
  146 + # Returns the sub-type of the simplified MIME type.
  147 + #
  148 + # text/plain => plain
  149 + # x-chemical/x-pdb => pdb
  150 + attr_reader :sub_type
  151 + # Returns the media type of the unmodified MIME type.
  152 + #
  153 + # text/plain => plain
  154 + # x-chemical/x-pdb => x-pdb
  155 + attr_reader :raw_sub_type
  156 + # The MIME types main- and sub-label can both start with <tt>x-</tt>,
  157 + # which indicates that it is a non-registered name. Of course, after
  158 + # registration this flag can disappear, adds to the confusing
  159 + # proliferation of MIME types. The simplified string has the <tt>x-</tt>
  160 + # removed and are translated to lowercase.
  161 + #
  162 + # text/plain => text/plain
  163 + # x-chemical/x-pdb => chemical/pdb
  164 + attr_reader :simplified
  165 + # The list of extensions which are known to be used for this MIME::Type.
  166 + # Non-array values will be coerced into an array with #to_a. Array
  167 + # values will be flattened and +nil+ values removed.
  168 + attr_accessor :extensions
  169 + remove_method :extensions= ;
  170 + def extensions=(ext) #:nodoc:
  171 + @extensions = [ext].flatten.compact
  172 + end
  173 +
  174 + # The encoding (7bit, 8bit, quoted-printable, or base64) required to
  175 + # transport the data of this content type safely across a network, which
  176 + # roughly corresponds to Content-Transfer-Encoding. A value of +nil+ or
  177 + # <tt>:default</tt> will reset the #encoding to the #default_encoding
  178 + # for the MIME::Type. Raises ArgumentError if the encoding provided is
  179 + # invalid.
  180 + #
  181 + # If the encoding is not provided on construction, this will be either
  182 + # 'quoted-printable' (for text/* media types) and 'base64' for eveything
  183 + # else.
  184 + attr_accessor :encoding
  185 + remove_method :encoding= ;
  186 + def encoding=(enc) #:nodoc:
  187 + if enc.nil? or enc == :default
  188 + @encoding = self.default_encoding
  189 + elsif enc =~ ENCODING_RE
  190 + @encoding = enc
  191 + else
  192 + raise ArgumentError, "The encoding must be nil, :default, base64, 7bit, 8bit, or quoted-printable."
  193 + end
  194 + end
  195 +
  196 + # The regexp for the operating system that this MIME::Type is specific
  197 + # to.
  198 + attr_accessor :system
  199 + remove_method :system= ;
  200 + def system=(os) #:nodoc:
  201 + if os.nil? or os.kind_of?(Regexp)
  202 + @system = os
  203 + else
  204 + @system = %r|#{os}|
  205 + end
  206 + end
  207 + # Returns the default encoding for the MIME::Type based on the media
  208 + # type.
  209 + attr_reader :default_encoding
  210 + remove_method :default_encoding
  211 + def default_encoding
  212 + (@media_type == 'text') ? 'quoted-printable' : 'base64'
  213 + end
  214 +
  215 + # Returns the media type or types that should be used instead of this
  216 + # media type, if it is obsolete. If there is no replacement media type,
  217 + # or it is not obsolete, +nil+ will be returned.
  218 + attr_reader :use_instead
  219 + remove_method :use_instead
  220 + def use_instead
  221 + return nil unless @obsolete
  222 + @use_instead
  223 + end
  224 +
  225 + # Returns +true+ if the media type is obsolete.
  226 + def obsolete?
  227 + @obsolete ? true : false
  228 + end
  229 + # Sets the obsolescence indicator for this media type.
  230 + attr_writer :obsolete
  231 +
  232 + # The documentation for this MIME::Type. Documentation about media
  233 + # types will be found on a media type definition as a comment.
  234 + # Documentation will be found through #docs.
  235 + attr_accessor :docs
  236 + remove_method :docs= ;
  237 + def docs=(d)
  238 + if d
  239 + a = d.scan(%r{use-instead:#{MEDIA_TYPE_RE}})
  240 +
  241 + if a.empty?
  242 + @use_instead = nil
  243 + else
  244 + @use_instead = a.map { |el| "#{el[0]}/#{el[1]}" }
  245 + end
  246 + end
  247 + @docs = d
  248 + end
  249 +
  250 + # The encoded URL list for this MIME::Type. See #urls for more
  251 + # information.
  252 + attr_accessor :url
  253 + # The decoded URL list for this MIME::Type.
  254 + # The special URL value IANA will be translated into:
  255 + # http://www.iana.org/assignments/media-types/<mediatype>/<subtype>
  256 + #
  257 + # The special URL value RFC### will be translated into:
  258 + # http://www.rfc-editor.org/rfc/rfc###.txt
  259 + #
  260 + # The special URL value DRAFT:name will be translated into:
  261 + # https://datatracker.ietf.org/public/idindex.cgi?
  262 + # command=id_detail&filename=<name>
  263 + #
  264 + # The special URL value LTSW will be translated into:
  265 + # http://www.ltsw.se/knbase/internet/<mediatype>.htp
  266 + #
  267 + # The special URL value [token] will be translated into:
  268 + # http://www.iana.org/assignments/contact-people.htm#<token>
  269 + #
  270 + # These values will be accessible through #urls, which always returns an
  271 + # array.
  272 + def urls
  273 + @url.map do |el|
  274 + case el
  275 + when %r{^IANA$}
  276 + IANA_URL % [ @media_type, @sub_type ]
  277 + when %r{^RFC(\d+)$}
  278 + RFC_URL % $1
  279 + when %r{^DRAFT:(.+)$}
  280 + DRAFT_URL % $1
  281 + when %r{^LTSW$}
  282 + LTSW_URL % @media_type
  283 + when %r<^\{([^=]+)=([^\]]+)\}>
  284 + [$1, $2]
  285 + when %r{^\[([^=]+)=([^\]]+)\]}
  286 + [$1, CONTACT_URL % $2]
  287 + when %r{^\[([^\]]+)\]}
  288 + CONTACT_URL % $1
  289 + else
  290 + el
  291 + end
  292 + end
  293 + end
  294 +
  295 + class << self
  296 + # The MIME types main- and sub-label can both start with <tt>x-</tt>,
  297 + # which indicates that it is a non-registered name. Of course, after
  298 + # registration this flag can disappear, adds to the confusing
  299 + # proliferation of MIME types. The simplified string has the
  300 + # <tt>x-</tt> removed and are translated to lowercase.
  301 + def simplified(content_type)
  302 + matchdata = MEDIA_TYPE_RE.match(content_type)
  303 +
  304 + if matchdata.nil?
  305 + simplified = nil
  306 + else
  307 + media_type = matchdata.captures[0].downcase.gsub(UNREG_RE, '')
  308 + subtype = matchdata.captures[1].downcase.gsub(UNREG_RE, '')
  309 + simplified = "#{media_type}/#{subtype}"
  310 + end
  311 + simplified
  312 + end
  313 +
  314 + # Creates a MIME::Type from an array in the form of:
  315 + # [type-name, [extensions], encoding, system]
  316 + #
  317 + # +extensions+, +encoding+, and +system+ are optional.
  318 + #
  319 + # MIME::Type.from_array("application/x-ruby", ['rb'], '8bit')
  320 + # MIME::Type.from_array(["application/x-ruby", ['rb'], '8bit'])
  321 + #
  322 + # These are equivalent to:
  323 + #
  324 + # MIME::Type.new('application/x-ruby') do |t|
  325 + # t.extensions = %w(rb)
  326 + # t.encoding = '8bit'
  327 + # end
  328 + def from_array(*args) #:yields MIME::Type.new:
  329 + # Dereferences the array one level, if necessary.
  330 + args = args[0] if args[0].kind_of?(Array)
  331 +
  332 + if args.size.between?(1, 8)
  333 + m = MIME::Type.new(args[0]) do |t|
  334 + t.extensions = args[1] if args.size > 1
  335 + t.encoding = args[2] if args.size > 2
  336 + t.system = args[3] if args.size > 3
  337 + t.obsolete = args[4] if args.size > 4
  338 + t.docs = args[5] if args.size > 5
  339 + t.url = args[6] if args.size > 6
  340 + t.registered = args[7] if args.size > 7
  341 + end
  342 + yield m if block_given?
  343 + else
  344 + raise ArgumentError, "Array provided must contain between one and eight elements."
  345 + end
  346 + m
  347 + end
  348 +
  349 + # Creates a MIME::Type from a hash. Keys are case-insensitive,
  350 + # dashes may be replaced with underscores, and the internal Symbol
  351 + # of the lowercase-underscore version can be used as well. That is,
  352 + # Content-Type can be provided as content-type, Content_Type,
  353 + # content_type, or :content_type.
  354 + #
  355 + # Known keys are <tt>Content-Type</tt>,
  356 + # <tt>Content-Transfer-Encoding</tt>, <tt>Extensions</tt>, and
  357 + # <tt>System</tt>.
  358 + #
  359 + # MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
  360 + # 'Content-Transfer-Encoding' => '8bit',
  361 + # 'System' => 'linux',
  362 + # 'Extensions' => ['yaml', 'yml'])
  363 + #
  364 + # This is equivalent to:
  365 + #
  366 + # MIME::Type.new('text/x-yaml') do |t|
  367 + # t.encoding = '8bit'
  368 + # t.system = 'linux'
  369 + # t.extensions = ['yaml', 'yml']
  370 + # end
  371 + def from_hash(hash) #:yields MIME::Type.new:
  372 + type = {}
  373 + hash.each_pair do |k, v|
  374 + type[k.to_s.tr('A-Z', 'a-z').gsub(/-/, '_').to_sym] = v
  375 + end
  376 +
  377 + m = MIME::Type.new(type[:content_type]) do |t|
  378 + t.extensions = type[:extensions]
  379 + t.encoding = type[:content_transfer_encoding]
  380 + t.system = type[:system]
  381 + t.obsolete = type[:obsolete]
  382 + t.docs = type[:docs]
  383 + t.url = type[:url]
  384 + t.registered = type[:registered]
  385 + end
  386 +
  387 + yield m if block_given?
  388 + m
  389 + end
  390 +
  391 + # Essentially a copy constructor.
  392 + #
  393 + # MIME::Type.from_mime_type(plaintext)
  394 + #
  395 + # is equivalent to:
  396 + #
  397 + # MIME::Type.new(plaintext.content_type.dup) do |t|
  398 + # t.extensions = plaintext.extensions.dup
  399 + # t.system = plaintext.system.dup
  400 + # t.encoding = plaintext.encoding.dup
  401 + # end
  402 + def from_mime_type(mime_type) #:yields the new MIME::Type:
  403 + m = MIME::Type.new(mime_type.content_type.dup) do |t|
  404 + t.extensions = mime_type.extensions.map { |e| e.dup }
  405 + t.url = mime_type.url && mime_type.url.map { |e| e.dup }
  406 +
  407 + mime_type.system && t.system = mime_type.system.dup
  408 + mime_type.encoding && t.encoding = mime_type.encoding.dup
  409 +
  410 + t.obsolete = mime_type.obsolete?
  411 + t.registered = mime_type.registered?
  412 +
  413 + mime_type.docs && t.docs = mime_type.docs.dup
  414 +
  415 + end
  416 +
  417 + yield m if block_given?
  418 + end
  419 + end
  420 +
  421 + # Builds a MIME::Type object from the provided MIME Content Type value
  422 + # (e.g., 'text/plain' or 'applicaton/x-eruby'). The constructed object
  423 + # is yielded to an optional block for additional configuration, such as
  424 + # associating extensions and encoding information.
  425 + def initialize(content_type) #:yields self:
  426 + matchdata = MEDIA_TYPE_RE.match(content_type)
  427 +
  428 + if matchdata.nil?
  429 + raise InvalidContentType, "Invalid Content-Type provided ('#{content_type}')"
  430 + end
  431 +
  432 + @content_type = content_type
  433 + @raw_media_type = matchdata.captures[0]
  434 + @raw_sub_type = matchdata.captures[1]
  435 +
  436 + @simplified = MIME::Type.simplified(@content_type)
  437 + matchdata = MEDIA_TYPE_RE.match(@simplified)
  438 + @media_type = matchdata.captures[0]
  439 + @sub_type = matchdata.captures[1]
  440 +
  441 + self.extensions = nil
  442 + self.encoding = :default
  443 + self.system = nil
  444 + self.registered = true
  445 + self.url = nil
  446 + self.obsolete = nil
  447 + self.docs = nil
  448 +
  449 + yield self if block_given?
  450 + end
  451 +
  452 + # MIME content-types which are not regestered by IANA nor defined in
  453 + # RFCs are required to start with <tt>x-</tt>. This counts as well for
  454 + # a new media type as well as a new sub-type of an existing media
  455 + # type. If either the media-type or the content-type begins with
  456 + # <tt>x-</tt>, this method will return +false+.
  457 + def registered?
  458 + if (@raw_media_type =~ UNREG_RE) || (@raw_sub_type =~ UNREG_RE)
  459 + false
  460 + else
  461 + @registered
  462 + end
  463 + end
  464 + attr_writer :registered #:nodoc:
  465 +
  466 + # MIME types can be specified to be sent across a network in particular
  467 + # formats. This method returns +true+ when the MIME type encoding is set
  468 + # to <tt>base64</tt>.
  469 + def binary?
  470 + @encoding == 'base64'
  471 + end
  472 +
  473 + # MIME types can be specified to be sent across a network in particular
  474 + # formats. This method returns +false+ when the MIME type encoding is
  475 + # set to <tt>base64</tt>.
  476 + def ascii?
  477 + not binary?
  478 + end
  479 +
  480 + # Returns +true+ when the simplified MIME type is in the list of known
  481 + # digital signatures.
  482 + def signature?
  483 + SIGNATURES.include?(@simplified.downcase)
  484 + end
  485 +
  486 + # Returns +true+ if the MIME::Type is specific to an operating system.
  487 + def system?
  488 + not @system.nil?
  489 + end
  490 +
  491 + # Returns +true+ if the MIME::Type is specific to the current operating
  492 + # system as represented by RUBY_PLATFORM.
  493 + def platform?
  494 + system? and (RUBY_PLATFORM =~ @system)
  495 + end
  496 +
  497 + # Returns +true+ if the MIME::Type specifies an extension list,
  498 + # indicating that it is a complete MIME::Type.
  499 + def complete?
  500 + not @extensions.empty?
  501 + end
  502 +
  503 + # Returns the MIME type as a string.
  504 + def to_s
  505 + @content_type
  506 + end
  507 +
  508 + # Returns the MIME type as a string for implicit conversions.
  509 + def to_str
  510 + @content_type
  511 + end
  512 +
  513 + # Returns the MIME type as an array suitable for use with
  514 + # MIME::Type.from_array.
  515 + def to_a
  516 + [ @content_type, @extensions, @encoding, @system, @obsolete, @docs,
  517 + @url, registered? ]
  518 + end
  519 +
  520 + # Returns the MIME type as an array suitable for use with
  521 + # MIME::Type.from_hash.
  522 + def to_hash
  523 + { 'Content-Type' => @content_type,
  524 + 'Content-Transfer-Encoding' => @encoding,
  525 + 'Extensions' => @extensions,
  526 + 'System' => @system,
  527 + 'Obsolete' => @obsolete,
  528 + 'Docs' => @docs,
  529 + 'URL' => @url,
  530 + 'Registered' => registered?,
  531 + }
  532 + end
  533 + end
  534 +
  535 + # = MIME::Types
  536 + # MIME types are used in MIME-compliant communications, as in e-mail or
  537 + # HTTP traffic, to indicate the type of content which is transmitted.
  538 + # MIME::Types provides the ability for detailed information about MIME
  539 + # entities (provided as a set of MIME::Type objects) to be determined and
  540 + # used programmatically. There are many types defined by RFCs and vendors,
  541 + # so the list is long but not complete; don't hesitate to ask to add
  542 + # additional information. This library follows the IANA collection of MIME
  543 + # types (see below for reference).
  544 + #
  545 + # == Description
  546 + # MIME types are used in MIME entities, as in email or HTTP traffic. It is
  547 + # useful at times to have information available about MIME types (or,
  548 + # inversely, about files). A MIME::Type stores the known information about
  549 + # one MIME type.
  550 + #
  551 + # == Usage
  552 + # require 'mime/types'
  553 + #
  554 + # plaintext = MIME::Types['text/plain']
  555 + # print plaintext.media_type # => 'text'
  556 + # print plaintext.sub_type # => 'plain'
  557 + #
  558 + # puts plaintext.extensions.join(" ") # => 'asc txt c cc h hh cpp'
  559 + #
  560 + # puts plaintext.encoding # => 8bit
  561 + # puts plaintext.binary? # => false
  562 + # puts plaintext.ascii? # => true
  563 + # puts plaintext.obsolete? # => false
  564 + # puts plaintext.registered? # => true
  565 + # puts plaintext == 'text/plain' # => true
  566 + # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
  567 + #
  568 + # This module is built to conform to the MIME types of RFCs 2045 and 2231.
  569 + # It follows the official IANA registry at
  570 + # http://www.iana.org/assignments/media-types/ and
  571 + # ftp://ftp.iana.org/assignments/media-types with some unofficial types
  572 + # added from the the collection at
  573 + # http://www.ltsw.se/knbase/internet/mime.htp
  574 + #
  575 + # This is originally based on Perl MIME::Types by Mark Overmeer.
  576 + #
  577 + # = Author
  578 + # Copyright:: Copyright (c) 2002 - 2009 by Austin Ziegler
  579 + # <austin@rubyforge.org>
  580 + # Version:: 1.16
  581 + # Based On:: Perl
  582 + # MIME::Types[http://search.cpan.org/author/MARKOV/MIME-Types-1.27/MIME/Types.pm],
  583 + # Copyright (c) 2001 - 2009 by Mark Overmeer
  584 + # <mimetypes@overmeer.net>.
  585 + # Licence:: Ruby's, Perl Artistic, or GPL version 2 (or later)
  586 + # See Also:: http://www.iana.org/assignments/media-types/
  587 + # http://www.ltsw.se/knbase/internet/mime.htp
  588 + #
  589 + class Types
  590 + # The released version of Ruby MIME::Types
  591 + VERSION = '1.16'
  592 +
  593 + # The data version.
  594 + attr_reader :data_version
  595 +
  596 + def initialize(data_version = nil)
  597 + @type_variants = Hash.new { |h, k| h[k] = [] }
  598 + @extension_index = Hash.new { |h, k| h[k] = [] }
  599 + end
  600 +
  601 + def add_type_variant(mime_type) #:nodoc:
  602 + @type_variants[mime_type.simplified] << mime_type
  603 + end
  604 +
  605 + def index_extensions(mime_type) #:nodoc:
  606 + mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
  607 + end
  608 +
  609 + @__types__ = self.new(VERSION)
  610 +
  611 + # Returns a list of MIME::Type objects, which may be empty. The optional
  612 + # flag parameters are :complete (finds only complete MIME::Type objects)
  613 + # and :platform (finds only MIME::Types for the current platform). It is
  614 + # possible for multiple matches to be returned for either type (in the
  615 + # example below, 'text/plain' returns two values -- one for the general
  616 + # case, and one for VMS systems.
  617 + #
  618 + # puts "\nMIME::Types['text/plain']"
  619 + # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
  620 + #
  621 + # puts "\nMIME::Types[/^image/, :complete => true]"
  622 + # MIME::Types[/^image/, :complete => true].each do |t|
  623 + # puts t.to_a.join(", ")
  624 + # end
  625 + #
  626 + # If multiple type definitions are returned, returns them sorted as
  627 + # follows:
  628 + # 1. Complete definitions sort before incomplete ones;
  629 + # 2. IANA-registered definitions sort before LTSW-recorded
  630 + # definitions.
  631 + # 3. Generic definitions sort before platform-specific ones;
  632 + # 4. Current definitions sort before obsolete ones;
  633 + # 5. Obsolete definitions with use-instead clauses sort before those
  634 + # without;
  635 + # 6. Obsolete definitions use-instead clauses are compared.
  636 + # 7. Sort on name.
  637 + def [](type_id, flags = {})
  638 + if type_id.kind_of?(Regexp)
  639 + matches = []
  640 + @type_variants.each_key do |k|
  641 + matches << @type_variants[k] if k =~ type_id
  642 + end
  643 + matches.flatten!
  644 + elsif type_id.kind_of?(MIME::Type)
  645 + matches = [type_id]
  646 + else
  647 + matches = @type_variants[MIME::Type.simplified(type_id)]
  648 + end
  649 +
  650 + matches.delete_if { |e| not e.complete? } if flags[:complete]
  651 + matches.delete_if { |e| not e.platform? } if flags[:platform]
  652 +
  653 + matches.sort { |a, b| a.priority_compare(b) }
  654 + end
  655 +
  656 + # Return the list of MIME::Types which belongs to the file based on its
  657 + # filename extension. If +platform+ is +true+, then only file types that
  658 + # are specific to the current platform will be returned.
  659 + #
  660 + # puts "MIME::Types.type_for('citydesk.xml')
  661 + # => "#{MIME::Types.type_for('citydesk.xml')}"
  662 + # puts "MIME::Types.type_for('citydesk.gif')
  663 + # => "#{MIME::Types.type_for('citydesk.gif')}"
  664 + def type_for(filename, platform = false)
  665 + ext = filename.chomp.downcase.gsub(/.*\./o, '')
  666 + list = @extension_index[ext]
  667 + list.delete_if { |e| not e.platform? } if platform
  668 + list
  669 + end
  670 +
  671 + # A synonym for MIME::Types.type_for
  672 + def of(filename, platform = false)
  673 + type_for(filename, platform)
  674 + end
  675 +
  676 + # Add one or more MIME::Type objects to the set of known types. Each
  677 + # type should be experimental (e.g., 'application/x-ruby'). If the type
  678 + # is already known, a warning will be displayed.
  679 + #
  680 + # <b>Please inform the maintainer of this module when registered types
  681 + # are missing.</b>
  682 + def add(*types)
  683 + types.each do |mime_type|
  684 + if @type_variants.include?(mime_type.simplified)
  685 + if @type_variants[mime_type.simplified].include?(mime_type)
  686 + warn "Type #{mime_type} already registered as a variant of #{mime_type.simplified}."
  687 + end
  688 + end
  689 + add_type_variant(mime_type)
  690 + index_extensions(mime_type)
  691 + end
  692 + end
  693 +
  694 + class << self
  695 + def add_type_variant(mime_type) #:nodoc:
  696 + @__types__.add_type_variant(mime_type)
  697 + end
  698 +
  699 + def index_extensions(mime_type) #:nodoc:
  700 + @__types__.index_extensions(mime_type)
  701 + end
  702 +
  703 + # Returns a list of MIME::Type objects, which may be empty. The
  704 + # optional flag parameters are :complete (finds only complete
  705 + # MIME::Type objects) and :platform (finds only MIME::Types for the
  706 + # current platform). It is possible for multiple matches to be
  707 + # returned for either type (in the example below, 'text/plain' returns
  708 + # two values -- one for the general case, and one for VMS systems.
  709 + #
  710 + # puts "\nMIME::Types['text/plain']"
  711 + # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
  712 + #
  713 + # puts "\nMIME::Types[/^image/, :complete => true]"
  714 + # MIME::Types[/^image/, :complete => true].each do |t|
  715 + # puts t.to_a.join(", ")
  716 + # end
  717 + def [](type_id, flags = {})
  718 + @__types__[type_id, flags]
  719 + end
  720 +
  721 + # Return the list of MIME::Types which belongs to the file based on
  722 + # its filename extension. If +platform+ is +true+, then only file
  723 + # types that are specific to the current platform will be returned.
  724 + #
  725 + # puts "MIME::Types.type_for('citydesk.xml')
  726 + # => "#{MIME::Types.type_for('citydesk.xml')}"
  727 + # puts "MIME::Types.type_for('citydesk.gif')
  728 + # => "#{MIME::Types.type_for('citydesk.gif')}"
  729 + def type_for(filename, platform = false)
  730 + @__types__.type_for(filename, platform)
  731 + end
  732 +
  733 + # A synonym for MIME::Types.type_for
  734 + def of(filename, platform = false)
  735 + @__types__.type_for(filename, platform)
  736 + end
  737 +
  738 + # Add one or more MIME::Type objects to the set of known types. Each
  739 + # type should be experimental (e.g., 'application/x-ruby'). If the
  740 + # type is already known, a warning will be displayed.
  741 + #
  742 + # <b>Please inform the maintainer of this module when registered types
  743 + # are missing.</b>
  744 + def add(*types)
  745 + @__types__.add(*types)
  746 + end
  747 + end
  748 + end
  749 +end
  750 +
  751 +load File.join(File.dirname(__FILE__), 'types.rb.data')
... ...
vendor/gems/mime-types-1.16/lib/mime/types.rb.data 0 → 100644
... ... @@ -0,0 +1,1324 @@
  1 +# vim: ft=ruby encoding=utf-8
  2 +#--
  3 +# MIME::Types
  4 +# A Ruby implementation of a MIME Types information library. Based in spirit
  5 +# on the Perl MIME::Types information library by Mark Overmeer.
  6 +# http://rubyforge.org/projects/mime-types/
  7 +#
  8 +# Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  9 +# Artistic licence. See Licence.txt for more information.
  10 +#
  11 +# Copyright 2003 - 2009 Austin Ziegler
  12 +#++
  13 +
  14 +# Build the type list from the string below.
  15 +#
  16 +# [*][!][os:]mt/st[<ws>@ext][<ws>:enc][<ws>'url-list][<ws>=docs]
  17 +#
  18 +# == *
  19 +# An unofficial MIME type. This should be used if and only if the MIME type
  20 +# is not properly specified (that is, not under either x-type or
  21 +# vnd.name.type).
  22 +#
  23 +# == !
  24 +# An obsolete MIME type. May be used with an unofficial MIME type.
  25 +#
  26 +# == os:
  27 +# Platform-specific MIME type definition.
  28 +#
  29 +# == mt
  30 +# The media type.
  31 +#
  32 +# == st
  33 +# The media subtype.
  34 +#
  35 +# == <ws>@ext
  36 +# The list of comma-separated extensions.
  37 +#
  38 +# == <ws>:enc
  39 +# The encoding.
  40 +#
  41 +# == <ws>'url-list
  42 +# The list of comma-separated URLs.
  43 +#
  44 +# == <ws>=docs
  45 +# The documentation string.
  46 +#
  47 +# That is, everything except the media type and the subtype is optional. The
  48 +# more information that's available, though, the richer the values that can
  49 +# be provided.
  50 +
  51 +data_mime_type_first_line = __LINE__ + 2
  52 +data_mime_type = <<MIME_TYPES
  53 + # application/*
  54 +application/activemessage 'IANA,[Shapiro]
  55 +application/andrew-inset 'IANA,[Borenstein]
  56 +application/applefile :base64 'IANA,[Faltstrom]
  57 +application/atom+xml @atom :8bit 'IANA,RFC4287,RFC5023
  58 +application/atomcat+xml :8bit 'IANA,RFC5023
  59 +application/atomicmail 'IANA,[Borenstein]
  60 +application/atomsvc+xml :8bit 'IANA,RFC5023
  61 +application/auth-policy+xml :8bit 'IANA,RFC4745
  62 +application/batch-SMTP 'IANA,RFC2442
  63 +application/beep+xml 'IANA,RFC3080
  64 +application/cals-1840 'IANA,RFC1895
  65 +application/ccxml+xml 'IANA,RFC4267
  66 +application/cea-2018+xml 'IANA,[Zimmermann]
  67 +application/cellml+xml 'IANA,RFC4708
  68 +application/cnrp+xml 'IANA,RFC3367
  69 +application/commonground 'IANA,[Glazer]
  70 +application/conference-info+xml 'IANA,RFC4575
  71 +application/cpl+xml 'IANA,RFC3880
  72 +application/csta+xml 'IANA,[Ecma International Helpdesk]
  73 +application/CSTAdata+xml 'IANA,[Ecma International Helpdesk]
  74 +application/cybercash 'IANA,[Eastlake]
  75 +application/davmount+xml 'IANA,RFC4709
  76 +application/dca-rft 'IANA,[Campbell]
  77 +application/dec-dx 'IANA,[Campbell]
  78 +application/dialog-info+xml 'IANA,RFC4235
  79 +application/dicom 'IANA,RFC3240
  80 +application/dns 'IANA,RFC4027
  81 +application/dvcs 'IANA,RFC3029
  82 +application/ecmascript 'IANA,RFC4329
  83 +application/EDI-Consent 'IANA,RFC1767
  84 +application/EDI-X12 'IANA,RFC1767
  85 +application/EDIFACT 'IANA,RFC1767
  86 +application/emma+xml 'IANA,[W3C]
  87 +application/epp+xml 'IANA,RFC3730
  88 +application/eshop 'IANA,[Katz]
  89 +application/fastinfoset 'IANA,[ITU-T ASN.1 Rapporteur]
  90 +application/fastsoap 'IANA,[ITU-T ASN.1 Rapporteur]
  91 +application/fits 'IANA,RFC4047
  92 +application/font-tdpfr @pfr 'IANA,RFC3073
  93 +application/H224 'IANA,RFC4573
  94 +application/http 'IANA,RFC2616
  95 +application/hyperstudio @stk 'IANA,[Domino]
  96 +application/ibe-key-request+xml 'IANA,RFC5408
  97 +application/ibe-pkg-reply+xml 'IANA,RFC5408
  98 +application/ibe-pp-data 'IANA,RFC5408
  99 +application/iges 'IANA,[Parks]
  100 +application/im-iscomposing+xml 'IANA,RFC3994
  101 +application/index 'IANA,RFC2652
  102 +application/index.cmd 'IANA,RFC2652
  103 +application/index.obj 'IANA,RFC2652
  104 +application/index.response 'IANA,RFC2652
  105 +application/index.vnd 'IANA,RFC2652
  106 +application/iotp 'IANA,RFC2935
  107 +application/ipp 'IANA,RFC2910
  108 +application/isup 'IANA,RFC3204
  109 +application/javascript @js :8bit 'IANA,RFC4329
  110 +application/json @json :8bit 'IANA,RFC4627
  111 +application/kpml-request+xml 'IANA,RFC4730
  112 +application/kpml-response+xml 'IANA,RFC4730
  113 +application/lost+xml 'IANA,RFC5222
  114 +application/mac-binhex40 @hqx :8bit 'IANA,[Faltstrom]
  115 +application/macwriteii 'IANA,[Lindner]
  116 +application/marc 'IANA,RFC2220
  117 +application/mathematica 'IANA,[Wolfram]
  118 +application/mbms-associated-procedure-description+xml 'IANA,[3GPP]
  119 +application/mbms-deregister+xml 'IANA,[3GPP]
  120 +application/mbms-envelope+xml 'IANA,[3GPP]
  121 +application/mbms-msk+xml 'IANA,[3GPP]
  122 +application/mbms-msk-response+xml 'IANA,[3GPP]
  123 +application/mbms-protection-description+xml 'IANA,[3GPP]
  124 +application/mbms-reception-report+xml 'IANA,[3GPP]
  125 +application/mbms-register+xml 'IANA,[3GPP]
  126 +application/mbms-register-response+xml 'IANA,[3GPP]
  127 +application/mbms-user-service-description+xml 'IANA,[3GPP]
  128 +application/mbox 'IANA,RFC4155
  129 +application/media_control+xml 'IANA,RFC5168
  130 +application/mediaservercontrol+xml 'IANA,RFC5022
  131 +application/mikey 'IANA,RFC3830
  132 +application/moss-keys 'IANA,RFC1848
  133 +application/moss-signature 'IANA,RFC1848
  134 +application/mosskey-data 'IANA,RFC1848
  135 +application/mosskey-request 'IANA,RFC1848
  136 +application/mp4 'IANA,RFC4337
  137 +application/mpeg4-generic 'IANA,RFC3640
  138 +application/mpeg4-iod 'IANA,RFC4337
  139 +application/mpeg4-iod-xmt 'IANA,RFC4337
  140 +application/msword @doc,dot,wrd :base64 'IANA,[Lindner]
  141 +application/mxf 'IANA,RFC4539
  142 +application/nasdata 'IANA,RFC4707
  143 +application/news-transmission 'IANA,RFC1036,[Spencer]
  144 +application/nss 'IANA,[Hammer]
  145 +application/ocsp-request 'IANA,RFC2560
  146 +application/ocsp-response 'IANA,RFC2560
  147 +application/octet-stream @bin,dms,lha,lzh,exe,class,ani,pgp,so,dll,dmg,dylib :base64 'IANA,RFC2045,RFC2046
  148 +application/oda @oda 'IANA,RFC2045,RFC2046
  149 +application/oebps-package+xml 'IANA,RFC4839
  150 +application/ogg @ogx 'IANA,RFC5334
  151 +application/parityfec 'IANA,RFC5109
  152 +application/patch-ops-error+xml 'IANA,RFC5261
  153 +application/pdf @pdf :base64 'IANA,RFC3778
  154 +application/pgp-encrypted :7bit 'IANA,RFC3156
  155 +application/pgp-keys :7bit 'IANA,RFC3156
  156 +application/pgp-signature @sig :base64 'IANA,RFC3156
  157 +application/pidf+xml 'IANA,RFC3863
  158 +application/pidf-diff+xml 'IANA,RFC5262
  159 +application/pkcs10 @p10 'IANA,RFC2311
  160 +application/pkcs7-mime @p7m,p7c 'IANA,RFC2311
  161 +application/pkcs7-signature @p7s 'IANA,RFC2311
  162 +application/pkix-cert @cer 'IANA,RFC2585
  163 +application/pkix-crl @crl 'IANA,RFC2585
  164 +application/pkix-pkipath @pkipath 'IANA,RFC4366
  165 +application/pkixcmp @pki 'IANA,RFC2510
  166 +application/pls+xml 'IANA,RFC4267
  167 +application/poc-settings+xml 'IANA,RFC4354
  168 +application/postscript @ai,eps,ps :8bit 'IANA,RFC2045,RFC2046
  169 +application/prs.alvestrand.titrax-sheet 'IANA,[Alvestrand]
  170 +application/prs.cww @cw,cww 'IANA,[Rungchavalnont]
  171 +application/prs.nprend @rnd,rct 'IANA,[Doggett]
  172 +application/prs.plucker 'IANA,[Janssen]
  173 +application/qsig 'IANA,RFC3204
  174 +application/rdf+xml @rdf :8bit 'IANA,RFC3870
  175 +application/reginfo+xml 'IANA,RFC3680
  176 +application/relax-ng-compact-syntax 'IANA,{ISO/IEC 1957-2:2003/FDAM-1=http://www.jtc1sc34.org/repository/0661.pdf}
  177 +application/remote-printing 'IANA,RFC1486,[Rose]
  178 +application/resource-lists+xml 'IANA,RFC4826
  179 +application/resource-lists-diff+xml 'IANA,RFC5362
  180 +application/riscos 'IANA,[Smith]
  181 +application/rlmi+xml 'IANA,RFC4662
  182 +application/rls-services+xml 'IANA,RFC4826
  183 +application/rtf @rtf 'IANA,[Lindner]
  184 +application/rtx 'IANA,RFC4588
  185 +application/samlassertion+xml 'IANA,[OASIS Security Services Technical Committee (SSTC)]
  186 +application/samlmetadata+xml 'IANA,[OASIS Security Services Technical Committee (SSTC)]
  187 +application/sbml+xml 'IANA,RFC3823
  188 +application/scvp-cv-request 'IANA,RFC5055
  189 +application/scvp-cv-response 'IANA,RFC5055
  190 +application/scvp-vp-request 'IANA,RFC5055
  191 +application/scvp-vp-response 'IANA,RFC5055
  192 +application/sdp 'IANA,RFC4566
  193 +application/set-payment 'IANA,[Korver]
  194 +application/set-payment-initiation 'IANA,[Korver]
  195 +application/set-registration 'IANA,[Korver]
  196 +application/set-registration-initiation 'IANA,[Korver]
  197 +application/sgml @sgml 'IANA,RFC1874
  198 +application/sgml-open-catalog @soc 'IANA,[Grosso]
  199 +application/shf+xml 'IANA,RFC4194
  200 +application/sieve @siv 'IANA,RFC5228
  201 +application/simple-filter+xml 'IANA,RFC4661
  202 +application/simple-message-summary 'IANA,RFC3842
  203 +application/simpleSymbolContainer 'IANA,[3GPP]
  204 +application/slate 'IANA,[Crowley]
  205 +application/smil+xml @smi,smil :8bit 'IANA,RFC4536
  206 +application/soap+fastinfoset 'IANA,[ITU-T ASN.1 Rapporteur]
  207 +application/soap+xml 'IANA,RFC3902
  208 +application/sparql-query 'IANA,[W3C]
  209 +application/sparql-results+xml 'IANA,[W3C]
  210 +application/spirits-event+xml 'IANA,RFC3910
  211 +application/srgs 'IANA,RFC4267
  212 +application/srgs+xml 'IANA,RFC4267
  213 +application/ssml+xml 'IANA,RFC4267
  214 +application/timestamp-query 'IANA,RFC3161
  215 +application/timestamp-reply 'IANA,RFC3161
  216 +application/tve-trigger 'IANA,[Welsh]
  217 +application/ulpfec 'IANA,RFC5109
  218 +application/vemmi 'IANA,RFC2122
  219 +application/vnd.3gpp.bsf+xml 'IANA,[Meredith]
  220 +application/vnd.3gpp.pic-bw-large @plb 'IANA,[Meredith]
  221 +application/vnd.3gpp.pic-bw-small @psb 'IANA,[Meredith]
  222 +application/vnd.3gpp.pic-bw-var @pvb 'IANA,[Meredith]
  223 +application/vnd.3gpp.sms @sms 'IANA,[Meredith]
  224 +application/vnd.3gpp2.bcmcsinfo+xml 'IANA,[Dryden]
  225 +application/vnd.3gpp2.sms 'IANA,[Mahendran]
  226 +application/vnd.3gpp2.tcap 'IANA,[Mahendran]
  227 +application/vnd.3M.Post-it-Notes 'IANA,[O'Brien]
  228 +application/vnd.accpac.simply.aso 'IANA,[Leow]
  229 +application/vnd.accpac.simply.imp 'IANA,[Leow]
  230 +application/vnd.acucobol 'IANA,[Lubin]
  231 +application/vnd.acucorp @atc,acutc :7bit 'IANA,[Lubin]
  232 +application/vnd.adobe.xdp+xml 'IANA,[Brinkman]
  233 +application/vnd.adobe.xfdf @xfdf 'IANA,[Perelman]
  234 +application/vnd.aether.imp 'IANA,[Moskowitz]
  235 +application/vnd.airzip.filesecure.azf 'IANA,[Mould],[Clueit]
  236 +application/vnd.airzip.filesecure.azs 'IANA,[Mould],[Clueit]
  237 +application/vnd.americandynamics.acc 'IANA,[Sands]
  238 +application/vnd.amiga.ami @ami 'IANA,[Blumberg]
  239 +application/vnd.anser-web-certificate-issue-initiation 'IANA,[Mori]
  240 +application/vnd.antix.game-component 'IANA,[Shelton]
  241 +application/vnd.apple.installer+xml 'IANA,[Bierman]
  242 +application/vnd.arastra.swi 'IANA,[Fenner]
  243 +application/vnd.audiograph 'IANA,[Slusanschi]
  244 +application/vnd.autopackage 'IANA,[Hearn]
  245 +application/vnd.avistar+xml 'IANA,[Vysotsky]
  246 +application/vnd.blueice.multipass @mpm 'IANA,[Holmstrom]
  247 +application/vnd.bluetooth.ep.oob 'IANA,[Foley]
  248 +application/vnd.bmi 'IANA,[Gotoh]
  249 +application/vnd.businessobjects 'IANA,[Imoucha]
  250 +application/vnd.cab-jscript 'IANA,[Falkenberg]
  251 +application/vnd.canon-cpdl 'IANA,[Muto]
  252 +application/vnd.canon-lips 'IANA,[Muto]
  253 +application/vnd.cendio.thinlinc.clientconf 'IANA,[Åstrand=Astrand]
  254 +application/vnd.chemdraw+xml 'IANA,[Howes]
  255 +application/vnd.chipnuts.karaoke-mmd 'IANA,[Xiong]
  256 +application/vnd.cinderella @cdy 'IANA,[Kortenkamp]
  257 +application/vnd.cirpack.isdn-ext 'IANA,[Mayeux]
  258 +application/vnd.claymore 'IANA,[Simpson]
  259 +application/vnd.clonk.c4group 'IANA,[Brammer]
  260 +application/vnd.commerce-battelle 'IANA,[Applebaum]
  261 +application/vnd.commonspace 'IANA,[Chandhok]
  262 +application/vnd.contact.cmsg 'IANA,[Patz]
  263 +application/vnd.cosmocaller @cmc 'IANA,[Dellutri]
  264 +application/vnd.crick.clicker 'IANA,[Burt]
  265 +application/vnd.crick.clicker.keyboard 'IANA,[Burt]
  266 +application/vnd.crick.clicker.palette 'IANA,[Burt]
  267 +application/vnd.crick.clicker.template 'IANA,[Burt]
  268 +application/vnd.crick.clicker.wordbank 'IANA,[Burt]
  269 +application/vnd.criticaltools.wbs+xml @wbs 'IANA,[Spiller]
  270 +application/vnd.ctc-posml 'IANA,[Kohlhepp]
  271 +application/vnd.ctct.ws+xml 'IANA,[Ancona]
  272 +application/vnd.cups-pdf 'IANA,[Sweet]
  273 +application/vnd.cups-postscript 'IANA,[Sweet]
  274 +application/vnd.cups-ppd 'IANA,[Sweet]
  275 +application/vnd.cups-raster 'IANA,[Sweet]
  276 +application/vnd.cups-raw 'IANA,[Sweet]
  277 +application/vnd.curl @curl 'IANA,[Byrnes]
  278 +application/vnd.cybank 'IANA,[Helmee]
  279 +application/vnd.data-vision.rdz @rdz 'IANA,[Fields]
  280 +application/vnd.denovo.fcselayout-link 'IANA,[Dixon]
  281 +application/vnd.dir-bi.plate-dl-nosuffix 'IANA,[Yamanaka]
  282 +application/vnd.dna 'IANA,[Searcy]
  283 +application/vnd.dpgraph 'IANA,[Parker]
  284 +application/vnd.dreamfactory @dfac 'IANA,[Appleton]
  285 +application/vnd.dvb.esgcontainer 'IANA,[Heuer]
  286 +application/vnd.dvb.ipdcesgaccess 'IANA,[Heuer]
  287 +application/vnd.dvb.iptv.alfec-base 'IANA,[Henry]
  288 +application/vnd.dvb.iptv.alfec-enhancement 'IANA,[Henry]
  289 +application/vnd.dvb.notif-container+xml 'IANA,[Yue]
  290 +application/vnd.dvb.notif-generic+xml 'IANA,[Yue]
  291 +application/vnd.dvb.notif-ia-msglist+xml 'IANA,[Yue]
  292 +application/vnd.dvb.notif-ia-registration-request+xml 'IANA,[Yue]
  293 +application/vnd.dvb.notif-ia-registration-response+xml 'IANA,[Yue]
  294 +application/vnd.dxr 'IANA,[Duffy]
  295 +application/vnd.ecdis-update 'IANA,[Buettgenbach]
  296 +application/vnd.ecowin.chart 'IANA,[Olsson]
  297 +application/vnd.ecowin.filerequest 'IANA,[Olsson]
  298 +application/vnd.ecowin.fileupdate 'IANA,[Olsson]
  299 +application/vnd.ecowin.series 'IANA,[Olsson]
  300 +application/vnd.ecowin.seriesrequest 'IANA,[Olsson]
  301 +application/vnd.ecowin.seriesupdate 'IANA,[Olsson]
  302 +application/vnd.emclient.accessrequest+xml 'IANA,[Navara]
  303 +application/vnd.enliven 'IANA,[Santinelli]
  304 +application/vnd.epson.esf 'IANA,[Hoshina]
  305 +application/vnd.epson.msf 'IANA,[Hoshina]
  306 +application/vnd.epson.quickanime 'IANA,[Gu]
  307 +application/vnd.epson.salt 'IANA,[Nagatomo]
  308 +application/vnd.epson.ssf 'IANA,[Hoshina]
  309 +application/vnd.ericsson.quickcall 'IANA,[Tidwell]
  310 +application/vnd.eszigno3+xml 'IANA,[Tóth=Toth]
  311 +application/vnd.eudora.data 'IANA,[Resnick]
  312 +application/vnd.ezpix-album 'IANA,[Electronic Zombie, Corp.=ElectronicZombieCorp]
  313 +application/vnd.ezpix-package 'IANA,[Electronic Zombie, Corp.=ElectronicZombieCorp]
  314 +application/vnd.f-secure.mobile 'IANA,[Sarivaara]
  315 +application/vnd.fdf 'IANA,[Zilles]
  316 +application/vnd.fdsn.mseed 'IANA,[Ratzesberger]
  317 +application/vnd.ffsns 'IANA,[Holstage]
  318 +application/vnd.fints 'IANA,[Hammann]
  319 +application/vnd.FloGraphIt 'IANA,[Floersch]
  320 +application/vnd.fluxtime.clip 'IANA,[Winter]
  321 +application/vnd.font-fontforge-sfd 'IANA,[Williams]
  322 +application/vnd.framemaker @frm,maker,frame,fm,fb,book,fbdoc 'IANA,[Wexler]
  323 +application/vnd.frogans.fnc 'IANA,[Tamas]
  324 +application/vnd.frogans.ltf 'IANA,[Tamas]
  325 +application/vnd.fsc.weblaunch @fsc :7bit 'IANA,[D.Smith]
  326 +application/vnd.fujitsu.oasys 'IANA,[Togashi]
  327 +application/vnd.fujitsu.oasys2 'IANA,[Togashi]
  328 +application/vnd.fujitsu.oasys3 'IANA,[Okudaira]
  329 +application/vnd.fujitsu.oasysgp 'IANA,[Sugimoto]
  330 +application/vnd.fujitsu.oasysprs 'IANA,[Ogita]
  331 +application/vnd.fujixerox.ART-EX 'IANA,[Tanabe]
  332 +application/vnd.fujixerox.ART4 'IANA,[Tanabe]
  333 +application/vnd.fujixerox.ddd 'IANA,[Onda]
  334 +application/vnd.fujixerox.docuworks 'IANA,[Taguchi]
  335 +application/vnd.fujixerox.docuworks.binder 'IANA,[Matsumoto]
  336 +application/vnd.fujixerox.HBPL 'IANA,[Tanabe]
  337 +application/vnd.fut-misnet 'IANA,[Pruulmann]
  338 +application/vnd.fuzzysheet 'IANA,[Birtwistle]
  339 +application/vnd.genomatix.tuxedo @txd 'IANA,[Frey]
  340 +application/vnd.geogebra.file 'IANA,[GeoGebra],[Kreis]
  341 +application/vnd.gmx 'IANA,[Sciberras]
  342 +application/vnd.google-earth.kml+xml @kml :8bit 'IANA,[Ashbridge]
  343 +application/vnd.google-earth.kmz @kmz :8bit 'IANA,[Ashbridge]
  344 +application/vnd.grafeq 'IANA,[Tupper]
  345 +application/vnd.gridmp 'IANA,[Lawson]
  346 +application/vnd.groove-account 'IANA,[Joseph]
  347 +application/vnd.groove-help 'IANA,[Joseph]
  348 +application/vnd.groove-identity-message 'IANA,[Joseph]
  349 +application/vnd.groove-injector 'IANA,[Joseph]
  350 +application/vnd.groove-tool-message 'IANA,[Joseph]
  351 +application/vnd.groove-tool-template 'IANA,[Joseph]
  352 +application/vnd.groove-vcard 'IANA,[Joseph]
  353 +application/vnd.HandHeld-Entertainment+xml 'IANA,[Hamilton]
  354 +application/vnd.hbci @hbci,hbc,kom,upa,pkd,bpd 'IANA,[Hammann]
  355 +application/vnd.hcl-bireports 'IANA,[Serres]
  356 +application/vnd.hhe.lesson-player @les 'IANA,[Jones]
  357 +application/vnd.hp-HPGL @plt,hpgl 'IANA,[Pentecost]
  358 +application/vnd.hp-hpid 'IANA,[Gupta]
  359 +application/vnd.hp-hps 'IANA,[Aubrey]
  360 +application/vnd.hp-jlyt 'IANA,[Gaash]
  361 +application/vnd.hp-PCL 'IANA,[Pentecost]
  362 +application/vnd.hp-PCLXL 'IANA,[Pentecost]
  363 +application/vnd.httphone 'IANA,[Lefevre]
  364 +application/vnd.hydrostatix.sof-data 'IANA,[Gillam]
  365 +application/vnd.hzn-3d-crossword 'IANA,[Minnis]
  366 +application/vnd.ibm.afplinedata 'IANA,[Buis]
  367 +application/vnd.ibm.electronic-media @emm 'IANA,[Tantlinger]
  368 +application/vnd.ibm.MiniPay 'IANA,[Herzberg]
  369 +application/vnd.ibm.modcap 'IANA,[Hohensee]
  370 +application/vnd.ibm.rights-management @irm 'IANA,[Tantlinger]
  371 +application/vnd.ibm.secure-container @sc 'IANA,[Tantlinger]
  372 +application/vnd.iccprofile 'IANA,[Green]
  373 +application/vnd.igloader 'IANA,[Fisher]
  374 +application/vnd.immervision-ivp 'IANA,[Villegas]
  375 +application/vnd.immervision-ivu 'IANA,[Villegas]
  376 +application/vnd.informedcontrol.rms+xml 'IANA,[Wahl]
  377 +application/vnd.informix-visionary 'IANA,[Gales]
  378 +application/vnd.intercon.formnet 'IANA,[Gurak]
  379 +application/vnd.intertrust.digibox 'IANA,[Tomasello]
  380 +application/vnd.intertrust.nncp 'IANA,[Tomasello]
  381 +application/vnd.intu.qbo 'IANA,[Scratchley]
  382 +application/vnd.intu.qfx 'IANA,[Scratchley]
  383 +application/vnd.iptc.g2.conceptitem+xml 'IANA,[Steidl]
  384 +application/vnd.iptc.g2.knowledgeitem+xml 'IANA,[Steidl]
  385 +application/vnd.iptc.g2.newsitem+xml 'IANA,[Steidl]
  386 +application/vnd.iptc.g2.packageitem+xml 'IANA,[Steidl]
  387 +application/vnd.ipunplugged.rcprofile @rcprofile 'IANA,[Ersson]
  388 +application/vnd.irepository.package+xml @irp 'IANA,[Knowles]
  389 +application/vnd.is-xpr 'IANA,[Natarajan]
  390 +application/vnd.jam 'IANA,[B.Kumar]
  391 +application/vnd.japannet-directory-service 'IANA,[Fujii]
  392 +application/vnd.japannet-jpnstore-wakeup 'IANA,[Yoshitake]
  393 +application/vnd.japannet-payment-wakeup 'IANA,[Fujii]
  394 +application/vnd.japannet-registration 'IANA,[Yoshitake]
  395 +application/vnd.japannet-registration-wakeup 'IANA,[Fujii]
  396 +application/vnd.japannet-setstore-wakeup 'IANA,[Yoshitake]
  397 +application/vnd.japannet-verification 'IANA,[Yoshitake]
  398 +application/vnd.japannet-verification-wakeup 'IANA,[Fujii]
  399 +application/vnd.jcp.javame.midlet-rms 'IANA,[Gorshenev]
  400 +application/vnd.jisp @jisp 'IANA,[Deckers]
  401 +application/vnd.joost.joda-archive 'IANA,[Joost]
  402 +application/vnd.kahootz 'IANA,[Macdonald]
  403 +application/vnd.kde.karbon @karbon 'IANA,[Faure]
  404 +application/vnd.kde.kchart @chrt 'IANA,[Faure]
  405 +application/vnd.kde.kformula @kfo 'IANA,[Faure]
  406 +application/vnd.kde.kivio @flw 'IANA,[Faure]
  407 +application/vnd.kde.kontour @kon 'IANA,[Faure]
  408 +application/vnd.kde.kpresenter @kpr,kpt 'IANA,[Faure]
  409 +application/vnd.kde.kspread @ksp 'IANA,[Faure]
  410 +application/vnd.kde.kword @kwd,kwt 'IANA,[Faure]
  411 +application/vnd.kenameaapp @htke 'IANA,[DiGiorgio-Haag]
  412 +application/vnd.kidspiration @kia 'IANA,[Bennett]
  413 +application/vnd.Kinar @kne,knp,sdf 'IANA,[Thakkar]
  414 +application/vnd.koan 'IANA,[Cole]
  415 +application/vnd.kodak-descriptor 'IANA,[Donahue]
  416 +application/vnd.liberty-request+xml 'IANA,[McDowell]
  417 +application/vnd.llamagraphics.life-balance.desktop @lbd 'IANA,[White]
  418 +application/vnd.llamagraphics.life-balance.exchange+xml @lbe 'IANA,[White]
  419 +application/vnd.lotus-1-2-3 @wks,123 'IANA,[Wattenberger]
  420 +application/vnd.lotus-approach 'IANA,[Wattenberger]
  421 +application/vnd.lotus-freelance 'IANA,[Wattenberger]
  422 +application/vnd.lotus-notes 'IANA,[Laramie]
  423 +application/vnd.lotus-organizer 'IANA,[Wattenberger]
  424 +application/vnd.lotus-screencam 'IANA,[Wattenberger]
  425 +application/vnd.lotus-wordpro 'IANA,[Wattenberger]
  426 +application/vnd.macports.portpkg 'IANA,[Berry]
  427 +application/vnd.marlin.drm.actiontoken+xml 'IANA,[Ellison]
  428 +application/vnd.marlin.drm.conftoken+xml 'IANA,[Ellison]
  429 +application/vnd.marlin.drm.license+xml 'IANA,[Ellison]
  430 +application/vnd.marlin.drm.mdcf 'IANA,[Ellison]
  431 +application/vnd.mcd @mcd 'IANA,[Gotoh]
  432 +application/vnd.medcalcdata 'IANA,[Schoonjans]
  433 +application/vnd.mediastation.cdkey 'IANA,[Flurry]
  434 +application/vnd.meridian-slingshot 'IANA,[Wedel]
  435 +application/vnd.MFER 'IANA,[Hirai]
  436 +application/vnd.mfmp @mfm 'IANA,[Ikeda]
  437 +application/vnd.micrografx.flo @flo 'IANA,[Prevo]
  438 +application/vnd.micrografx.igx @igx 'IANA,[Prevo]
  439 +application/vnd.mif @mif 'IANA,[Wexler]
  440 +application/vnd.minisoft-hp3000-save 'IANA,[Bartram]
  441 +application/vnd.mitsubishi.misty-guard.trustweb 'IANA,[Tanaka]
  442 +application/vnd.Mobius.DAF 'IANA,[Kabayama]
  443 +application/vnd.Mobius.DIS 'IANA,[Kabayama]
  444 +application/vnd.Mobius.MBK 'IANA,[Devasia]
  445 +application/vnd.Mobius.MQY 'IANA,[Devasia]
  446 +application/vnd.Mobius.MSL 'IANA,[Kabayama]
  447 +application/vnd.Mobius.PLC 'IANA,[Kabayama]
  448 +application/vnd.Mobius.TXF 'IANA,[Kabayama]
  449 +application/vnd.mophun.application @mpn 'IANA,[Wennerstrom]
  450 +application/vnd.mophun.certificate @mpc 'IANA,[Wennerstrom]
  451 +application/vnd.motorola.flexsuite 'IANA,[Patton]
  452 +application/vnd.motorola.flexsuite.adsi 'IANA,[Patton]
  453 +application/vnd.motorola.flexsuite.fis 'IANA,[Patton]
  454 +application/vnd.motorola.flexsuite.gotap 'IANA,[Patton]
  455 +application/vnd.motorola.flexsuite.kmr 'IANA,[Patton]
  456 +application/vnd.motorola.flexsuite.ttc 'IANA,[Patton]
  457 +application/vnd.motorola.flexsuite.wem 'IANA,[Patton]
  458 +application/vnd.motorola.iprm 'IANA,[Shamsaasef]
  459 +application/vnd.mozilla.xul+xml @xul 'IANA,[McDaniel]
  460 +application/vnd.ms-artgalry @cil 'IANA,[Slawson]
  461 +application/vnd.ms-asf @asf 'IANA,[Fleischman]
  462 +application/vnd.ms-cab-compressed @cab 'IANA,[Scarborough]
  463 +application/vnd.ms-excel @xls,xlt :base64 'IANA,[Gill]
  464 +application/vnd.ms-fontobject 'IANA,[Scarborough]
  465 +application/vnd.ms-ims 'IANA,[Ledoux]
  466 +application/vnd.ms-lrm @lrm 'IANA,[Ledoux]
  467 +application/vnd.ms-playready.initiator+xml 'IANA,[Schneider]
  468 +application/vnd.ms-powerpoint @ppt,pps,pot :base64 'IANA,[Gill]
  469 +application/vnd.ms-project @mpp :base64 'IANA,[Gill]
  470 +application/vnd.ms-tnef :base64 'IANA,[Gill]
  471 +application/vnd.ms-wmdrm.lic-chlg-req 'IANA,[Lau]
  472 +application/vnd.ms-wmdrm.lic-resp 'IANA,[Lau]
  473 +application/vnd.ms-wmdrm.meter-chlg-req 'IANA,[Lau]
  474 +application/vnd.ms-wmdrm.meter-resp 'IANA,[Lau]
  475 +application/vnd.ms-works :base64 'IANA,[Gill]
  476 +application/vnd.ms-wpl @wpl :base64 'IANA,[Plastina]
  477 +application/vnd.ms-xpsdocument @xps :8bit 'IANA,[McGatha]
  478 +application/vnd.mseq @mseq 'IANA,[Le Bodic]
  479 +application/vnd.msign 'IANA,[Borcherding]
  480 +application/vnd.multiad.creator 'IANA,[Mills]
  481 +application/vnd.multiad.creator.cif 'IANA,[Mills]
  482 +application/vnd.music-niff 'IANA,[Butler]
  483 +application/vnd.musician 'IANA,[Adams]
  484 +application/vnd.muvee.style 'IANA,[Anantharamu]
  485 +application/vnd.ncd.control 'IANA,[Tarkkala]
  486 +application/vnd.ncd.reference 'IANA,[Tarkkala]
  487 +application/vnd.nervana @ent,entity,req,request,bkm,kcm 'IANA,[Judkins]
  488 +application/vnd.netfpx 'IANA,[Mutz]
  489 +application/vnd.neurolanguage.nlu 'IANA,[DuFeu]
  490 +application/vnd.noblenet-directory 'IANA,[Solomon]
  491 +application/vnd.noblenet-sealer 'IANA,[Solomon]
  492 +application/vnd.noblenet-web 'IANA,[Solomon]
  493 +application/vnd.nokia.catalogs 'IANA,[Nokia]
  494 +application/vnd.nokia.conml+wbxml 'IANA,[Nokia]
  495 +application/vnd.nokia.conml+xml 'IANA,[Nokia]
  496 +application/vnd.nokia.iptv.config+xml 'IANA,[Nokia]
  497 +application/vnd.nokia.iSDS-radio-presets 'IANA,[Nokia]
  498 +application/vnd.nokia.landmark+wbxml 'IANA,[Nokia]
  499 +application/vnd.nokia.landmark+xml 'IANA,[Nokia]
  500 +application/vnd.nokia.landmarkcollection+xml 'IANA,[Nokia]
  501 +application/vnd.nokia.n-gage.ac+xml 'IANA,[Nokia]
  502 +application/vnd.nokia.n-gage.data 'IANA,[Nokia]
  503 +application/vnd.nokia.n-gage.symbian.install 'IANA,[Nokia]
  504 +application/vnd.nokia.ncd+xml 'IANA,[Nokia]
  505 +application/vnd.nokia.pcd+wbxml 'IANA,[Nokia]
  506 +application/vnd.nokia.pcd+xml 'IANA,[Nokia]
  507 +application/vnd.nokia.radio-preset @rpst 'IANA,[Nokia]
  508 +application/vnd.nokia.radio-presets @rpss 'IANA,[Nokia]
  509 +application/vnd.novadigm.EDM 'IANA,[Swenson]
  510 +application/vnd.novadigm.EDX 'IANA,[Swenson]
  511 +application/vnd.novadigm.EXT 'IANA,[Swenson]
  512 +application/vnd.oasis.opendocument.chart @odc 'IANA,[Oppermann]
  513 +application/vnd.oasis.opendocument.chart-template @odc 'IANA,[Oppermann]
  514 +application/vnd.oasis.opendocument.database @odb 'IANA,[Schubert],[Oasis OpenDocument TC=OASIS OpenDocumentTC]
  515 +application/vnd.oasis.opendocument.formula @odf 'IANA,[Oppermann]
  516 +application/vnd.oasis.opendocument.formula-template @odf 'IANA,[Oppermann]
  517 +application/vnd.oasis.opendocument.graphics @odg 'IANA,[Oppermann]
  518 +application/vnd.oasis.opendocument.graphics-template @otg 'IANA,[Oppermann]
  519 +application/vnd.oasis.opendocument.image @odi 'IANA,[Oppermann]
  520 +application/vnd.oasis.opendocument.image-template @odi 'IANA,[Oppermann]
  521 +application/vnd.oasis.opendocument.presentation @odp 'IANA,[Oppermann]
  522 +application/vnd.oasis.opendocument.presentation-template @otp 'IANA,[Oppermann]
  523 +application/vnd.oasis.opendocument.spreadsheet @ods 'IANA,[Oppermann]
  524 +application/vnd.oasis.opendocument.spreadsheet-template @ots 'IANA,[Oppermann]
  525 +application/vnd.oasis.opendocument.text @odt 'IANA,[Oppermann]
  526 +application/vnd.oasis.opendocument.text-master @odm 'IANA,[Oppermann]
  527 +application/vnd.oasis.opendocument.text-template @ott 'IANA,[Oppermann]
  528 +application/vnd.oasis.opendocument.text-web @oth 'IANA,[Oppermann]
  529 +application/vnd.obn 'IANA,[Hessling]
  530 +application/vnd.olpc-sugar 'IANA,[Palmieri]
  531 +application/vnd.oma-scws-config 'IANA,[Mahalal]
  532 +application/vnd.oma-scws-http-request 'IANA,[Mahalal]
  533 +application/vnd.oma-scws-http-response 'IANA,[Mahalal]
  534 +application/vnd.oma.bcast.associated-procedure-parameter+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  535 +application/vnd.oma.bcast.drm-trigger+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  536 +application/vnd.oma.bcast.imd+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  537 +application/vnd.oma.bcast.ltkm 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  538 +application/vnd.oma.bcast.notification+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  539 +application/vnd.oma.bcast.provisioningtrigger 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  540 +application/vnd.oma.bcast.sgboot 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  541 +application/vnd.oma.bcast.sgdd+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  542 +application/vnd.oma.bcast.sgdu 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  543 +application/vnd.oma.bcast.simple-symbol-container 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  544 +application/vnd.oma.bcast.smartcard-trigger+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  545 +application/vnd.oma.bcast.sprov+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  546 +application/vnd.oma.bcast.stkm 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  547 +application/vnd.oma.dcd 'IANA,[Primo],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  548 +application/vnd.oma.dcdc 'IANA,[Primo],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  549 +application/vnd.oma.dd2+xml 'IANA,[Sato],[Open Mobile Alliance's BAC DLDRM Working Group]
  550 +application/vnd.oma.drm.risd+xml 'IANA,[Rauschenbach],[OMNA - Open Mobile Naming Authority=OMNA-OpenMobileNamingAuthority]
  551 +application/vnd.oma.group-usage-list+xml 'IANA,[Kelley],[OMA Presence and Availability (PAG) Working Group]
  552 +application/vnd.oma.poc.detailed-progress-report+xml 'IANA,[OMA Push to Talk over Cellular (POC) Working Group]
  553 +application/vnd.oma.poc.final-report+xml 'IANA,[OMA Push to Talk over Cellular (POC) Working Group]
  554 +application/vnd.oma.poc.groups+xml 'IANA,[Kelley],[OMA Push to Talk over Cellular (POC) Working Group]
  555 +application/vnd.oma.poc.invocation-descriptor+xml 'IANA,[OMA Push to Talk over Cellular (POC) Working Group]
  556 +application/vnd.oma.poc.optimized-progress-report+xml 'IANA,[OMA Push to Talk over Cellular (POC) Working Group]
  557 +application/vnd.oma.xcap-directory+xml 'IANA,[Kelley],[OMA Presence and Availability (PAG) Working Group]
  558 +application/vnd.omads-email+xml 'IANA,[OMA Data Synchronization Working Group]
  559 +application/vnd.omads-file+xml 'IANA,[OMA Data Synchronization Working Group]
  560 +application/vnd.omads-folder+xml 'IANA,[OMA Data Synchronization Working Group]
  561 +application/vnd.omaloc-supl-init 'IANA,[Grange]
  562 +application/vnd.openofficeorg.extension 'IANA,[Lingner]
  563 +application/vnd.osa.netdeploy 'IANA,[Klos]
  564 +application/vnd.osgi.bundle 'IANA,[Kriens]
  565 +application/vnd.osgi.dp 'IANA,[Kriens]
  566 +application/vnd.otps.ct-kip+xml 'IANA,[Nyström=Nystrom]
  567 +application/vnd.palm @prc,pdb,pqa,oprc :base64 'IANA,[Peacock]
  568 +application/vnd.paos.xml 'IANA,[Kemp]
  569 +application/vnd.pg.format 'IANA,[Gandert]
  570 +application/vnd.pg.osasli 'IANA,[Gandert]
  571 +application/vnd.piaccess.application-licence 'IANA,[Maneos]
  572 +application/vnd.picsel @efif 'IANA,[Naccarato]
  573 +application/vnd.poc.group-advertisement+xml 'IANA,[Kelley],[OMA Push to Talk over Cellular (POC) Working Group]
  574 +application/vnd.pocketlearn 'IANA,[Pando]
  575 +application/vnd.powerbuilder6 'IANA,[Guy]
  576 +application/vnd.powerbuilder6-s 'IANA,[Guy]
  577 +application/vnd.powerbuilder7 'IANA,[Shilts]
  578 +application/vnd.powerbuilder7-s 'IANA,[Shilts]
  579 +application/vnd.powerbuilder75 'IANA,[Shilts]
  580 +application/vnd.powerbuilder75-s 'IANA,[Shilts]
  581 +application/vnd.preminet 'IANA,[Tenhunen]
  582 +application/vnd.previewsystems.box 'IANA,[Smolgovsky]
  583 +application/vnd.proteus.magazine 'IANA,[Hoch]
  584 +application/vnd.publishare-delta-tree 'IANA,[Ben-Kiki]
  585 +application/vnd.pvi.ptid1 @pti,ptid 'IANA,[Lamb]
  586 +application/vnd.pwg-multiplexed 'IANA,RFC3391
  587 +application/vnd.pwg-xhtml-print+xml 'IANA,[Wright]
  588 +application/vnd.qualcomm.brew-app-res 'IANA,[Forrester]
  589 +application/vnd.Quark.QuarkXPress @qxd,qxt,qwd,qwt,qxl,qxb :8bit 'IANA,[Scheidler]
  590 +application/vnd.rapid 'IANA,[Szekely]
  591 +application/vnd.recordare.musicxml 'IANA,[Good]
  592 +application/vnd.recordare.musicxml+xml 'IANA,[Good]
  593 +application/vnd.RenLearn.rlprint 'IANA,[Wick]
  594 +application/vnd.route66.link66+xml 'IANA,[Kikstra]
  595 +application/vnd.ruckus.download 'IANA,[Harris]
  596 +application/vnd.s3sms 'IANA,[Tarkkala]
  597 +application/vnd.sbm.cid 'IANA,[Kusakari]
  598 +application/vnd.sbm.mid2 'IANA,[Murai]
  599 +application/vnd.scribus 'IANA,[Bradney]
  600 +application/vnd.sealed.3df 'IANA,[Kwan]
  601 +application/vnd.sealed.csf 'IANA,[Kwan]
  602 +application/vnd.sealed.doc @sdoc,sdo,s1w 'IANA,[Petersen]
  603 +application/vnd.sealed.eml @seml,sem 'IANA,[Petersen]
  604 +application/vnd.sealed.mht @smht,smh 'IANA,[Petersen]
  605 +application/vnd.sealed.net 'IANA,[Lambert]
  606 +application/vnd.sealed.ppt @sppt,spp,s1p 'IANA,[Petersen]
  607 +application/vnd.sealed.tiff 'IANA,[Kwan],[Lambert]
  608 +application/vnd.sealed.xls @sxls,sxl,s1e 'IANA,[Petersen]
  609 +application/vnd.sealedmedia.softseal.html @stml,stm,s1h 'IANA,[Petersen]
  610 +application/vnd.sealedmedia.softseal.pdf @spdf,spd,s1a 'IANA,[Petersen]
  611 +application/vnd.seemail @see 'IANA,[Webb]
  612 +application/vnd.sema 'IANA,[Hansson]
  613 +application/vnd.semd 'IANA,[Hansson]
  614 +application/vnd.semf 'IANA,[Hansson]
  615 +application/vnd.shana.informed.formdata 'IANA,[Selzler]
  616 +application/vnd.shana.informed.formtemplate 'IANA,[Selzler]
  617 +application/vnd.shana.informed.interchange 'IANA,[Selzler]
  618 +application/vnd.shana.informed.package 'IANA,[Selzler]
  619 +application/vnd.SimTech-MindMapper 'IANA,[Koh]
  620 +application/vnd.smaf @mmf 'IANA,[Takahashi]
  621 +application/vnd.smart.teacher 'IANA,[Boyle]
  622 +application/vnd.software602.filler.form+xml 'IANA,[Hytka],[Vondrous]
  623 +application/vnd.software602.filler.form-xml-zip 'IANA,[Hytka],[Vondrous]
  624 +application/vnd.solent.sdkm+xml 'IANA,[Gauntlett]
  625 +application/vnd.spotfire.dxp 'IANA,[Jernberg]
  626 +application/vnd.spotfire.sfs 'IANA,[Jernberg]
  627 +application/vnd.sss-cod 'IANA,[Dani]
  628 +application/vnd.sss-dtf 'IANA,[Bruno]
  629 +application/vnd.sss-ntf 'IANA,[Bruno]
  630 +application/vnd.street-stream 'IANA,[Levitt]
  631 +application/vnd.sun.wadl+xml 'IANA,[Hadley]
  632 +application/vnd.sus-calendar @sus,susp 'IANA,[Niedfeldt]
  633 +application/vnd.svd 'IANA,[Becker]
  634 +application/vnd.swiftview-ics 'IANA,[Widener]
  635 +application/vnd.syncml+xml 'IANA,[OMA Data Synchronization Working Group]
  636 +application/vnd.syncml.dm+wbxml 'IANA,[OMA-DM Work Group]
  637 +application/vnd.syncml.dm+xml 'IANA,[Rao],[OMA-DM Work Group]
  638 +application/vnd.syncml.ds.notification 'IANA,[OMA Data Synchronization Working Group]
  639 +application/vnd.tao.intent-module-archive 'IANA,[Shelton]
  640 +application/vnd.tmobile-livetv 'IANA,[Helin]
  641 +application/vnd.trid.tpt 'IANA,[Cusack]
  642 +application/vnd.triscape.mxs 'IANA,[Simonoff]
  643 +application/vnd.trueapp 'IANA,[Hepler]
  644 +application/vnd.truedoc 'IANA,[Chase]
  645 +application/vnd.ufdl 'IANA,[Manning]
  646 +application/vnd.uiq.theme 'IANA,[Ocock]
  647 +application/vnd.umajin 'IANA,[Riden]
  648 +application/vnd.unity 'IANA,[Unity3d]
  649 +application/vnd.uoml+xml 'IANA,[Gerdes]
  650 +application/vnd.uplanet.alert 'IANA,[Martin]
  651 +application/vnd.uplanet.alert-wbxml 'IANA,[Martin]
  652 +application/vnd.uplanet.bearer-choice 'IANA,[Martin]
  653 +application/vnd.uplanet.bearer-choice-wbxml 'IANA,[Martin]
  654 +application/vnd.uplanet.cacheop 'IANA,[Martin]
  655 +application/vnd.uplanet.cacheop-wbxml 'IANA,[Martin]
  656 +application/vnd.uplanet.channel 'IANA,[Martin]
  657 +application/vnd.uplanet.channel-wbxml 'IANA,[Martin]
  658 +application/vnd.uplanet.list 'IANA,[Martin]
  659 +application/vnd.uplanet.list-wbxml 'IANA,[Martin]
  660 +application/vnd.uplanet.listcmd 'IANA,[Martin]
  661 +application/vnd.uplanet.listcmd-wbxml 'IANA,[Martin]
  662 +application/vnd.uplanet.signal 'IANA,[Martin]
  663 +application/vnd.vcx 'IANA,[T.Sugimoto]
  664 +application/vnd.vd-study 'IANA,[Rogge]
  665 +application/vnd.vectorworks 'IANA,[Ferguson],[Sarkar]
  666 +application/vnd.vidsoft.vidconference @vsc :8bit 'IANA,[Hess]
  667 +application/vnd.visio @vsd,vst,vsw,vss 'IANA,[Sandal]
  668 +application/vnd.visionary @vis 'IANA,[Aravindakumar]
  669 +application/vnd.vividence.scriptfile 'IANA,[Risher]
  670 +application/vnd.vsf 'IANA,[Rowe]
  671 +application/vnd.wap.sic @sic 'IANA,[WAP-Forum]
  672 +application/vnd.wap.slc @slc 'IANA,[WAP-Forum]
  673 +application/vnd.wap.wbxml @wbxml 'IANA,[Stark]
  674 +application/vnd.wap.wmlc @wmlc 'IANA,[Stark]
  675 +application/vnd.wap.wmlscriptc @wmlsc 'IANA,[Stark]
  676 +application/vnd.webturbo @wtb 'IANA,[Rehem]
  677 +application/vnd.wfa.wsc 'IANA,[Wi-Fi Alliance]
  678 +application/vnd.wmc 'IANA,[Kjørnes=Kjornes]
  679 +application/vnd.wmf.bootstrap 'IANA,[Nguyenphu],[Iyer]
  680 +application/vnd.wordperfect @wpd 'IANA,[Scarborough]
  681 +application/vnd.wqd @wqd 'IANA,[Bostrom]
  682 +application/vnd.wrq-hp3000-labelled 'IANA,[Bartram]
  683 +application/vnd.wt.stf 'IANA,[Wohler]
  684 +application/vnd.wv.csp+wbxml @wv 'IANA,[Salmi]
  685 +application/vnd.wv.csp+xml :8bit 'IANA,[Ingimundarson]
  686 +application/vnd.wv.ssp+xml :8bit 'IANA,[Ingimundarson]
  687 +application/vnd.xara 'IANA,[Matthewman]
  688 +application/vnd.xfdl 'IANA,[Manning]
  689 +application/vnd.xfdl.webform 'IANA,[Mansell]
  690 +application/vnd.xmi+xml 'IANA,[Waskiewicz]
  691 +application/vnd.xmpie.cpkg 'IANA,[Sherwin]
  692 +application/vnd.xmpie.dpkg 'IANA,[Sherwin]
  693 +application/vnd.xmpie.plan 'IANA,[Sherwin]
  694 +application/vnd.xmpie.ppkg 'IANA,[Sherwin]
  695 +application/vnd.xmpie.xlim 'IANA,[Sherwin]
  696 +application/vnd.yamaha.hv-dic @hvd 'IANA,[Yamamoto]
  697 +application/vnd.yamaha.hv-script @hvs 'IANA,[Yamamoto]
  698 +application/vnd.yamaha.hv-voice @hvp 'IANA,[Yamamoto]
  699 +application/vnd.yamaha.smaf-audio @saf 'IANA,[Shinoda]
  700 +application/vnd.yamaha.smaf-phrase @spf 'IANA,[Shinoda]
  701 +application/vnd.yellowriver-custom-menu 'IANA,[Yellow]
  702 +application/vnd.zul 'IANA,[Grothmann]
  703 +application/vnd.zzazz.deck+xml 'IANA,[Hewett]
  704 +application/voicexml+xml 'IANA,RFC4267
  705 +application/watcherinfo+xml @wif 'IANA,RFC3858
  706 +application/whoispp-query 'IANA,RFC2957
  707 +application/whoispp-response 'IANA,RFC2958
  708 +application/wita 'IANA,[Campbell]
  709 +application/wordperfect5.1 @wp5,wp 'IANA,[Lindner]
  710 +application/wsdl+xml 'IANA,[W3C]
  711 +application/wspolicy+xml 'IANA,[W3C]
  712 +application/x400-bp 'IANA,RFC1494
  713 +application/xcap-att+xml 'IANA,RFC4825
  714 +application/xcap-caps+xml 'IANA,RFC4825
  715 +application/xcap-el+xml 'IANA,RFC4825
  716 +application/xcap-error+xml 'IANA,RFC4825
  717 +application/xcap-ns+xml 'IANA,RFC4825
  718 +application/xenc+xml 'IANA,[Reagle],[XENC Working Group]
  719 +application/xhtml+xml @xhtml :8bit 'IANA,RFC3236
  720 +application/xml @xml,xsl :8bit 'IANA,RFC3023
  721 +application/xml-dtd @dtd :8bit 'IANA,RFC3023
  722 +application/xml-external-parsed-entity 'IANA,RFC3023
  723 +application/xmpp+xml 'IANA,RFC3923
  724 +application/xop+xml 'IANA,[Nottingham]
  725 +application/xv+xml 'IANA,RFC4374
  726 +application/zip @zip :base64 'IANA,[Lindner]
  727 +
  728 +*mac:application/x-mac @bin :base64
  729 +*mac:application/x-macbase64 @bin :base64
  730 +
  731 +!application/smil @smi,smil :8bit 'IANA,RFC4536 =use-instead:application/smil+xml
  732 +!application/xhtml-voice+xml 'IANA,{RFC-mccobb-xplusv-media-type-04.txt=https://datatracker.ietf.org/public/idindex.cgi?command=id_detail&filename=draft-mccobb-xplusv-media-type}
  733 +*!application/VMSBACKUP @bck :base64 =use-instead:application/x-VMSBACKUP
  734 +*!application/access @mdf,mda,mdb,mde =use-instead:application/x-msaccess
  735 +*!application/bleeper @bleep :base64 =use-instead:application/x-bleeper
  736 +*!application/cals1840 'LTSW =use-instead:application/cals-1840
  737 +*!application/futuresplash @spl =use-instead:application/x-futuresplash
  738 +*!application/ghostview =use-instead:application/x-ghostview
  739 +*!application/hep @hep =use-instead:application/x-hep
  740 +*!application/imagemap @imagemap,imap :8bit =use-instead:application/x-imagemap
  741 +*!application/lotus-123 @wks =use-instead:application/vnd.lotus-1-2-3
  742 +*!application/mac-compactpro @cpt =use-instead:application/x-mac-compactpro
  743 +*!application/mathcad @mcd :base64 =use-instead:application/vnd.mcd
  744 +*!application/mathematica-old =use-instead:application/x-mathematica-old
  745 +*!application/news-message-id 'IANA,RFC1036,[Spencer]
  746 +*!application/quicktimeplayer @qtl =use-instead:application/x-quicktimeplayer
  747 +*!application/remote_printing 'LTSW =use-instead:application/remote-printing
  748 +*!application/toolbook @tbk =use-instead:application/x-toolbook
  749 +*!application/vnd.ms-excel.sheet.binary.macroEnabled.12 @xlsb
  750 +*!application/vnd.ms-excel.sheet.macroEnabled.12 @xlsm
  751 +*!application/vnd.ms-word.document.macroEnabled.12 @docm
  752 +*!application/vnd.ms-word.template.macroEnabled.12 @dotm
  753 +*!application/wordperfect @wp =use-instead:application/vnd.wordperfect
  754 +*!application/wordperfect6.1 @wp6 =use-instead:application/x-wordperfect6.1
  755 +*!application/wordperfectd @wpd =use-instead:application/vnd.wordperfect
  756 +*!application/x-123 @wk =use-instead:application/vnd.lotus-1-2-3
  757 +*!application/x-access @mdf,mda,mdb,mde =use-instead:application/x-msaccess
  758 +*!application/x-compress @z,Z :base64 =use-instead:application/x-compressed
  759 +*!application/x-javascript @js :8bit =use-instead:application/javascript
  760 +*!application/x-lotus-123 @wks =use-instead:application/vnd.lotus-1-2-3
  761 +*!application/x-mathcad @mcd :base64 =use-instead:application/vnd.mcd
  762 +*!application/x-msword @doc,dot,wrd :base64 =use-instead:application/msword
  763 +*!application/x-rtf @rtf :base64 'LTSW =use-instead:application/rtf
  764 +*!application/x-troff 'LTSW =use-instead:text/troff
  765 +*!application/x-u-star 'LTSW =use-instead:application/x-ustar
  766 +*!application/x-word @doc,dot :base64 =use-instead:application/msword
  767 +*!application/x-wordperfect @wp =use-instead:application/vnd.wordperfect
  768 +*!application/x-wordperfectd @wpd =use-instead:application/vnd.wordperfect
  769 +*!application/x400.bp 'LTSW =use-instead:application/x400-bp
  770 +*application/SLA 'LTSW
  771 +*application/STEP 'LTSW
  772 +*application/acad 'LTSW
  773 +*application/appledouble :base64
  774 +*application/clariscad 'LTSW
  775 +*application/drafting 'LTSW
  776 +*application/dxf 'LTSW
  777 +*application/excel @xls,xlt 'LTSW
  778 +*application/fractals 'LTSW
  779 +*application/i-deas 'LTSW
  780 +*application/macbinary 'LTSW
  781 +*application/netcdf @nc,cdf 'LTSW
  782 +*application/powerpoint @ppt,pps,pot :base64 'LTSW
  783 +*application/pro_eng 'LTSW
  784 +*application/set 'LTSW
  785 +*application/solids 'LTSW
  786 +*application/vda 'LTSW
  787 +*application/vnd.openxmlformats-officedocument.presentationml.presentation @pptx
  788 +*application/vnd.openxmlformats-officedocument.presentationml.slideshow @ppsx
  789 +*application/vnd.openxmlformats-officedocument.spreadsheetml.sheet @xlsx :quoted-printable
  790 +*application/vnd.openxmlformats-officedocument.wordprocessingml.document @docx
  791 +*application/vnd.openxmlformats-officedocument.wordprocessingml.template @dotx
  792 +*application/vnd.stardivision.calc @sdc
  793 +*application/vnd.stardivision.chart @sds
  794 +*application/vnd.stardivision.draw @sda
  795 +*application/vnd.stardivision.impress @sdd
  796 +*application/vnd.stardivision.math @sdf
  797 +*application/vnd.stardivision.writer @sdw
  798 +*application/vnd.stardivision.writer-global @sgl
  799 +*application/vnd.street-stream 'IANA,[Levitt]
  800 +*application/vnd.sun.wadl+xml 'IANA,[Hadley]
  801 +*application/vnd.sun.xml.calc @sxc
  802 +*application/vnd.sun.xml.calc.template @stc
  803 +*application/vnd.sun.xml.draw @sxd
  804 +*application/vnd.sun.xml.draw.template @std
  805 +*application/vnd.sun.xml.impress @sxi
  806 +*application/vnd.sun.xml.impress.template @sti
  807 +*application/vnd.sun.xml.math @sxm
  808 +*application/vnd.sun.xml.writer @sxw
  809 +*application/vnd.sun.xml.writer.global @sxg
  810 +*application/vnd.sun.xml.writer.template @stw
  811 +*application/word @doc,dot 'LTSW
  812 +*application/x-SLA
  813 +*application/x-STEP
  814 +*application/x-VMSBACKUP @bck :base64
  815 +*application/x-Wingz @wz
  816 +*application/x-bcpio @bcpio 'LTSW
  817 +*application/x-bleeper @bleep :base64
  818 +*application/x-bzip2 @bz2
  819 +*application/x-cdlink @vcd
  820 +*application/x-chess-pgn @pgn
  821 +*application/x-clariscad
  822 +*application/x-compressed @z,Z :base64 'LTSW
  823 +*application/x-cpio @cpio :base64 'LTSW
  824 +*application/x-csh @csh :8bit 'LTSW
  825 +*application/x-cu-seeme @csm,cu
  826 +*application/x-debian-package @deb
  827 +*application/x-director @dcr,@dir,@dxr
  828 +*application/x-drafting
  829 +*application/x-dvi @dvi :base64 'LTSW
  830 +*application/x-dxf
  831 +*application/x-excel
  832 +*application/x-fractals
  833 +*application/x-futuresplash @spl
  834 +*application/x-ghostview
  835 +*application/x-gtar @gtar,tgz,tbz2,tbz :base64 'LTSW
  836 +*application/x-gzip @gz :base64 'LTSW
  837 +*application/x-hdf @hdf 'LTSW
  838 +*application/x-hep @hep
  839 +*application/x-html+ruby @rhtml :8bit
  840 +*application/x-httpd-php @phtml,pht,php :8bit
  841 +*application/x-ica @ica
  842 +*application/x-ideas
  843 +*application/x-imagemap @imagemap,imap :8bit
  844 +*application/x-java-archive @jar 'LTSW
  845 +*application/x-java-jnlp-file @jnlp 'LTSW
  846 +*application/x-java-serialized-object @ser 'LTSW
  847 +*application/x-java-vm @class 'LTSW
  848 +*application/x-koan @skp,skd,skt,skm
  849 +*application/x-latex @ltx,latex :8bit 'LTSW
  850 +*application/x-mac-compactpro @cpt
  851 +*application/x-macbinary
  852 +*application/x-maker @frm,maker,frame,fm,fb,book,fbdoc =use-instead:application/vnd.framemaker
  853 +*application/x-mathematica-old
  854 +*application/x-mif @mif 'LTSW
  855 +*application/x-msaccess @mda,mdb,mde,mdf
  856 +*application/x-msdos-program @cmd,bat :8bit
  857 +*application/x-msdos-program @com,exe :base64
  858 +*application/x-msdownload @exe,com :base64
  859 +*application/x-netcdf @nc,cdf
  860 +*application/x-ns-proxy-autoconfig @pac
  861 +*application/x-pagemaker @pm,pm5,pt5
  862 +*application/x-perl @pl,pm :8bit
  863 +*application/x-pgp
  864 +*application/x-python @py :8bit
  865 +*application/x-quicktimeplayer @qtl
  866 +*application/x-rar-compressed @rar :base64
  867 +*application/x-remote_printing
  868 +*application/x-ruby @rb,rbw :8bit
  869 +*application/x-set
  870 +*application/x-sh @sh :8bit 'LTSW
  871 +*application/x-shar @shar :8bit 'LTSW
  872 +*application/x-shockwave-flash @swf
  873 +*application/x-solids
  874 +*application/x-spss @sav,sbs,sps,spo,spp
  875 +*application/x-stuffit @sit :base64 'LTSW
  876 +*application/x-sv4cpio @sv4cpio :base64 'LTSW
  877 +*application/x-sv4crc @sv4crc :base64 'LTSW
  878 +*application/x-tar @tar :base64 'LTSW
  879 +*application/x-tcl @tcl :8bit 'LTSW
  880 +*application/x-tex @tex :8bit
  881 +*application/x-texinfo @texinfo,texi :8bit
  882 +*application/x-toolbook @tbk
  883 +*application/x-troff @t,tr,roff :8bit
  884 +*application/x-troff-man @man :8bit 'LTSW
  885 +*application/x-troff-me @me 'LTSW
  886 +*application/x-troff-ms @ms 'LTSW
  887 +*application/x-ustar @ustar :base64 'LTSW
  888 +*application/x-wais-source @src 'LTSW
  889 +*application/x-wordperfect6.1 @wp6
  890 +*application/x-x509-ca-cert @crt :base64
  891 +*application/xslt+xml @xslt :8bit
  892 +
  893 + # audio/*
  894 +audio/32kadpcm 'IANA,RFC2421,RFC2422
  895 +audio/3gpp @3gpp 'IANA,RFC4281,RFC3839
  896 +audio/3gpp2 'IANA,RFC4393,RFC4281
  897 +audio/ac3 'IANA,RFC4184
  898 +audio/AMR @amr :base64 'RFC4867
  899 +audio/AMR-WB @awb :base64 'RFC4867
  900 +audio/amr-wb+ 'IANA,RFC4352
  901 +audio/asc 'IANA,RFC4695
  902 +audio/basic @au,snd :base64 'IANA,RFC2045,RFC2046
  903 +audio/BV16 'IANA,RFC4298
  904 +audio/BV32 'IANA,RFC4298
  905 +audio/clearmode 'IANA,RFC4040
  906 +audio/CN 'IANA,RFC3389
  907 +audio/DAT12 'IANA,RFC3190
  908 +audio/dls 'IANA,RFC4613
  909 +audio/dsr-es201108 'IANA,RFC3557
  910 +audio/dsr-es202050 'IANA,RFC4060
  911 +audio/dsr-es202211 'IANA,RFC4060
  912 +audio/dsr-es202212 'IANA,RFC4060
  913 +audio/DVI4 'IANA,RFC4856
  914 +audio/eac3 'IANA,RFC4598
  915 +audio/EVRC @evc 'IANA,RFC4788
  916 +audio/EVRC-QCP 'IANA,RFC3625
  917 +audio/EVRC0 'IANA,RFC4788
  918 +audio/EVRC1 'IANA,RFC4788
  919 +audio/EVRCB 'IANA,RFC5188
  920 +audio/EVRCB0 'IANA,RFC5188
  921 +audio/EVRCB1 'IANA,RFC4788
  922 +audio/EVRCWB 'IANA,RFC5188
  923 +audio/EVRCWB0 'IANA,RFC5188
  924 +audio/EVRCWB1 'IANA,RFC5188
  925 +audio/G719 'IANA,RFC5404
  926 +audio/G722 'IANA,RFC4856
  927 +audio/G7221 'IANA,RFC3047
  928 +audio/G723 'IANA,RFC4856
  929 +audio/G726-16 'IANA,RFC4856
  930 +audio/G726-24 'IANA,RFC4856
  931 +audio/G726-32 'IANA,RFC4856
  932 +audio/G726-40 'IANA,RFC4856
  933 +audio/G728 'IANA,RFC4856
  934 +audio/G729 'IANA,RFC4856
  935 +audio/G7291 'IANA,RFC4749,RFC5459
  936 +audio/G729D 'IANA,RFC4856
  937 +audio/G729E 'IANA,RFC4856
  938 +audio/GSM 'IANA,RFC4856
  939 +audio/GSM-EFR 'IANA,RFC4856
  940 +audio/iLBC 'IANA,RFC3952
  941 +audio/L16 @l16 'IANA,RFC4856
  942 +audio/L20 'IANA,RFC3190
  943 +audio/L24 'IANA,RFC3190
  944 +audio/L8 'IANA,RFC4856
  945 +audio/LPC 'IANA,RFC4856
  946 +audio/mobile-xmf 'IANA,RFC4723
  947 +audio/mp4 'IANA,RFC4337
  948 +audio/MP4A-LATM 'IANA,RFC3016
  949 +audio/MPA 'IANA,RFC3555
  950 +audio/mpa-robust 'IANA,RFC5219
  951 +audio/mpeg @mpga,mp2,mp3 :base64 'IANA,RFC3003
  952 +audio/mpeg4-generic 'IANA,RFC3640
  953 +audio/ogg 'IANA,RFC5334
  954 +audio/parityfec 'IANA,RFC5109
  955 +audio/PCMA 'IANA,RFC4856
  956 +audio/PCMA-WB 'IANA,RFC5391
  957 +audio/PCMU 'IANA,RFC4856
  958 +audio/PCMU-WB 'IANA,RFC5391
  959 +audio/prs.sid 'IANA,[Walleij]
  960 +audio/QCELP 'IANA,RFC3555,RFC3625
  961 +audio/RED 'IANA,RFC3555
  962 +audio/rtp-enc-aescm128 'IANA,[3GPP]
  963 +audio/rtp-midi 'IANA,RFC4695
  964 +audio/rtx 'IANA,RFC4588
  965 +audio/SMV @smv 'IANA,RFC3558
  966 +audio/SMV-QCP 'IANA,RFC3625
  967 +audio/SMV0 'IANA,RFC3558
  968 +audio/sp-midi 'IANA,[Kosonen],[T. White=T.White]
  969 +audio/t140c 'IANA,RFC4351
  970 +audio/t38 'IANA,RFC4612
  971 +audio/telephone-event 'IANA,RFC4733
  972 +audio/tone 'IANA,RFC4733
  973 +audio/ulpfec 'IANA,RFC5109
  974 +audio/VDVI 'IANA,RFC4856
  975 +audio/VMR-WB 'IANA,RFC4348,RFC4424
  976 +audio/vnd.3gpp.iufp 'IANA,[Belling]
  977 +audio/vnd.4SB 'IANA,[De Jaham]
  978 +audio/vnd.audiokoz 'IANA,[DeBarros]
  979 +audio/vnd.CELP 'IANA,[De Jaham]
  980 +audio/vnd.cisco.nse 'IANA,[Kumar]
  981 +audio/vnd.cmles.radio-events 'IANA,[Goulet]
  982 +audio/vnd.cns.anp1 'IANA,[McLaughlin]
  983 +audio/vnd.cns.inf1 'IANA,[McLaughlin]
  984 +audio/vnd.digital-winds @eol :7bit 'IANA,[Strazds]
  985 +audio/vnd.dlna.adts 'IANA,[Heredia]
  986 +audio/vnd.dolby.mlp 'IANA,[Ward]
  987 +audio/vnd.dolby.mps 'IANA,[Hattersley]
  988 +audio/vnd.dts 'IANA,[Zou]
  989 +audio/vnd.dts.hd 'IANA,[Zou]
  990 +audio/vnd.everad.plj @plj 'IANA,[Cicelsky]
  991 +audio/vnd.hns.audio 'IANA,[Swaminathan]
  992 +audio/vnd.lucent.voice @lvp 'IANA,[Vaudreuil]
  993 +audio/vnd.ms-playready.media.pya 'IANA,[DiAcetis]
  994 +audio/vnd.nokia.mobile-xmf @mxmf 'IANA,[Nokia Corporation=Nokia]
  995 +audio/vnd.nortel.vbk @vbk 'IANA,[Parsons]
  996 +audio/vnd.nuera.ecelp4800 @ecelp4800 'IANA,[Fox]
  997 +audio/vnd.nuera.ecelp7470 @ecelp7470 'IANA,[Fox]
  998 +audio/vnd.nuera.ecelp9600 @ecelp9600 'IANA,[Fox]
  999 +audio/vnd.octel.sbc 'IANA,[Vaudreuil]
  1000 +audio/vnd.rhetorex.32kadpcm 'IANA,[Vaudreuil]
  1001 +audio/vnd.sealedmedia.softseal.mpeg @smp3,smp,s1m 'IANA,[Petersen]
  1002 +audio/vnd.vmx.cvsd 'IANA,[Vaudreuil]
  1003 +audio/vorbis 'IANA,RFC5215
  1004 +audio/vorbis-config 'IANA,RFC5215
  1005 +
  1006 +audio/x-aiff @aif,aifc,aiff :base64
  1007 +audio/x-midi @mid,midi,kar :base64
  1008 +audio/x-pn-realaudio @rm,ram :base64
  1009 +audio/x-pn-realaudio-plugin @rpm
  1010 +audio/x-realaudio @ra :base64
  1011 +audio/x-wav @wav :base64
  1012 +
  1013 +!audio/vnd.qcelp @qcp 'IANA,RFC3625 =use-instead:audio/QCELP
  1014 +
  1015 + # image/*
  1016 +image/cgm 'IANA,[Francis]
  1017 +image/fits 'IANA,RFC4047
  1018 +image/g3fax 'IANA,RFC1494
  1019 +image/gif @gif :base64 'IANA,RFC2045,RFC2046
  1020 +image/ief @ief :base64 'IANA,RFC1314
  1021 +image/jp2 @jp2,jpg2 :base64 'IANA,RFC3745
  1022 +image/jpeg @jpeg,jpg,jpe :base64 'IANA,RFC2045,RFC2046
  1023 +image/jpm @jpm,jpgm :base64 'IANA,RFC3745
  1024 +image/jpx @jpx,jpf :base64 'IANA,RFC3745
  1025 +image/naplps 'IANA,[Ferber]
  1026 +image/png @png :base64 'IANA,[Randers-Pehrson]
  1027 +image/prs.btif 'IANA,[Simon]
  1028 +image/prs.pti 'IANA,[Laun]
  1029 +image/t38 'IANA,RFC3362
  1030 +image/tiff @tiff,tif :base64 'IANA,RFC2302
  1031 +image/tiff-fx 'IANA,RFC3950
  1032 +image/vnd.adobe.photoshop 'IANA,[Scarborough]
  1033 +image/vnd.cns.inf2 'IANA,[McLaughlin]
  1034 +image/vnd.djvu @djvu,djv 'IANA,[Bottou]
  1035 +image/vnd.dwg @dwg 'IANA,[Moline]
  1036 +image/vnd.dxf 'IANA,[Moline]
  1037 +image/vnd.fastbidsheet 'IANA,[Becker]
  1038 +image/vnd.fpx 'IANA,[Spencer]
  1039 +image/vnd.fst 'IANA,[Fuldseth]
  1040 +image/vnd.fujixerox.edmics-mmr 'IANA,[Onda]
  1041 +image/vnd.fujixerox.edmics-rlc 'IANA,[Onda]
  1042 +image/vnd.globalgraphics.pgb @pgb 'IANA,[Bailey]
  1043 +image/vnd.microsoft.icon @ico 'IANA,[Butcher]
  1044 +image/vnd.mix 'IANA,[Reddy]
  1045 +image/vnd.ms-modi @mdi 'IANA,[Vaughan]
  1046 +image/vnd.net-fpx 'IANA,[Spencer]
  1047 +image/vnd.sealed.png @spng,spn,s1n 'IANA,[Petersen]
  1048 +image/vnd.sealedmedia.softseal.gif @sgif,sgi,s1g 'IANA,[Petersen]
  1049 +image/vnd.sealedmedia.softseal.jpg @sjpg,sjp,s1j 'IANA,[Petersen]
  1050 +image/vnd.svf 'IANA,[Moline]
  1051 +image/vnd.wap.wbmp @wbmp 'IANA,[Stark]
  1052 +image/vnd.xiff 'IANA,[S.Martin]
  1053 +
  1054 +*!image/bmp @bmp =use-instead:image/x-bmp
  1055 +*!image/cmu-raster =use-instead:image/x-cmu-raster
  1056 +*!image/targa @tga =use-instead:image/x-targa
  1057 +*!image/vnd.dgn @dgn =use-instead:image/x-vnd.dgn
  1058 +*!image/vnd.net.fpx =use-instead:image/vnd.net-fpx
  1059 +*image/pjpeg :base64 =Fixes a bug with IE6 and progressive JPEGs
  1060 +*image/svg+xml @svg :8bit
  1061 +*image/x-bmp @bmp
  1062 +*image/x-cmu-raster @ras
  1063 +*image/x-paintshoppro @psp,pspimage :base64
  1064 +*image/x-pict
  1065 +*image/x-portable-anymap @pnm :base64
  1066 +*image/x-portable-bitmap @pbm :base64
  1067 +*image/x-portable-graymap @pgm :base64
  1068 +*image/x-portable-pixmap @ppm :base64
  1069 +*image/x-rgb @rgb :base64
  1070 +*image/x-targa @tga
  1071 +*image/x-vnd.dgn @dgn
  1072 +*image/x-win-bmp
  1073 +*image/x-xbitmap @xbm :7bit
  1074 +*image/x-xbm @xbm :7bit
  1075 +*image/x-xpixmap @xpm :8bit
  1076 +*image/x-xwindowdump @xwd :base64
  1077 +
  1078 + # message/*
  1079 +message/CPIM 'IANA,RFC3862
  1080 +message/delivery-status 'IANA,RFC1894
  1081 +message/disposition-notification 'IANA,RFC2298
  1082 +message/external-body :8bit 'IANA,RFC2045,RFC2046
  1083 +message/global 'IANA,RFC5335
  1084 +message/global-delivery-status 'IANA,RFC5337
  1085 +message/global-disposition-notification 'IANA,RFC5337
  1086 +message/global-headers 'IANA,RFC5337
  1087 +message/http 'IANA,RFC2616
  1088 +message/imdn+xml 'IANA,RFC5438
  1089 +message/news :8bit 'IANA,RFC1036,[H.Spencer]
  1090 +message/partial :8bit 'IANA,RFC2045,RFC2046
  1091 +message/rfc822 @eml :8bit 'IANA,RFC2045,RFC2046
  1092 +message/s-http 'IANA,RFC2660
  1093 +message/sip 'IANA,RFC3261
  1094 +message/sipfrag 'IANA,RFC3420
  1095 +message/tracking-status 'IANA,RFC3886
  1096 +message/vnd.si.simp 'IANA,[Parks Young=ParksYoung]
  1097 +
  1098 + # model/*
  1099 +model/iges @igs,iges 'IANA,[Parks]
  1100 +model/mesh @msh,mesh,silo 'IANA,RFC2077
  1101 +model/vnd.dwf 'IANA,[Pratt]
  1102 +model/vnd.flatland.3dml 'IANA,[Powers]
  1103 +model/vnd.gdl 'IANA,[Babits]
  1104 +model/vnd.gs-gdl 'IANA,[Babits]
  1105 +model/vnd.gtw 'IANA,[Ozaki]
  1106 +model/vnd.moml+xml 'IANA,[Brooks]
  1107 +model/vnd.mts 'IANA,[Rabinovitch]
  1108 +model/vnd.parasolid.transmit.binary @x_b,xmt_bin 'IANA,[Parasolid]
  1109 +model/vnd.parasolid.transmit.text @x_t,xmt_txt :quoted-printable 'IANA,[Parasolid]
  1110 +model/vnd.vtu 'IANA,[Rabinovitch]
  1111 +model/vrml @wrl,vrml 'IANA,RFC2077
  1112 +
  1113 + # multipart/*
  1114 +multipart/alternative :8bit 'IANA,RFC2045,RFC2046
  1115 +multipart/appledouble :8bit 'IANA,[Faltstrom]
  1116 +multipart/byteranges 'IANA,RFC2068
  1117 +multipart/digest :8bit 'IANA,RFC2045,RFC2046
  1118 +multipart/encrypted 'IANA,RFC1847
  1119 +multipart/form-data 'IANA,RFC2388
  1120 +multipart/header-set 'IANA,[Crocker]
  1121 +multipart/mixed :8bit 'IANA,RFC2045,RFC2046
  1122 +multipart/parallel :8bit 'IANA,RFC2045,RFC2046
  1123 +multipart/related 'IANA,RFC2387
  1124 +multipart/report 'IANA,RFC3462
  1125 +multipart/signed 'IANA,RFC1847
  1126 +multipart/voice-message 'IANA,RFC2421,RFC2423
  1127 +*multipart/x-gzip
  1128 +*multipart/x-mixed-replace
  1129 +*multipart/x-tar
  1130 +*multipart/x-ustar
  1131 +*multipart/x-www-form-urlencoded
  1132 +*multipart/x-zip
  1133 +*!multipart/x-parallel =use-instead:multipart/parallel
  1134 +
  1135 + # text/*
  1136 +text/calendar 'IANA,RFC2445
  1137 +text/css @css :8bit 'IANA,RFC2318
  1138 +text/csv @csv :8bit 'IANA,RFC4180
  1139 +text/directory 'IANA,RFC2425
  1140 +text/dns 'IANA,RFC4027
  1141 +text/enriched 'IANA,RFC1896
  1142 +text/html @html,htm,htmlx,shtml,htx :8bit 'IANA,RFC2854
  1143 +text/parityfec 'IANA,RFC5109
  1144 +text/plain @txt,asc,c,cc,h,hh,cpp,hpp,dat,hlp 'IANA,RFC2046,RFC3676,RFC5147
  1145 +text/prs.fallenstein.rst @rst 'IANA,[Fallenstein]
  1146 +text/prs.lines.tag 'IANA,[Lines]
  1147 +text/RED 'IANA,RFC4102
  1148 +text/rfc822-headers 'IANA,RFC3462
  1149 +text/richtext @rtx :8bit 'IANA,RFC2045,RFC2046
  1150 +text/rtf @rtf :8bit 'IANA,[Lindner]
  1151 +text/rtp-enc-aescm128 'IANA,[3GPP]
  1152 +text/rtx 'IANA,RFC4588
  1153 +text/sgml @sgml,sgm 'IANA,RFC1874
  1154 +text/t140 'IANA,RFC4103
  1155 +text/tab-separated-values @tsv 'IANA,[Lindner]
  1156 +text/troff @t,tr,roff,troff :8bit 'IANA,RFC4263
  1157 +text/ulpfec 'IANA,RFC5109
  1158 +text/uri-list 'IANA,RFC2483
  1159 +text/vnd.abc 'IANA,[Allen]
  1160 +text/vnd.curl 'IANA,[Byrnes]
  1161 +text/vnd.DMClientScript 'IANA,[Bradley]
  1162 +text/vnd.esmertec.theme-descriptor 'IANA,[Eilemann]
  1163 +text/vnd.fly 'IANA,[Gurney]
  1164 +text/vnd.fmi.flexstor 'IANA,[Hurtta]
  1165 +text/vnd.graphviz 'IANA,[Ellson]
  1166 +text/vnd.in3d.3dml 'IANA,[Powers]
  1167 +text/vnd.in3d.spot 'IANA,[Powers]
  1168 +text/vnd.IPTC.NewsML 'IANA,[IPTC]
  1169 +text/vnd.IPTC.NITF 'IANA,[IPTC]
  1170 +text/vnd.latex-z 'IANA,[Lubos]
  1171 +text/vnd.motorola.reflex 'IANA,[Patton]
  1172 +text/vnd.ms-mediapackage 'IANA,[Nelson]
  1173 +text/vnd.net2phone.commcenter.command @ccc 'IANA,[Xie]
  1174 +text/vnd.si.uricatalogue 'IANA,[Parks Young=ParksYoung]
  1175 +text/vnd.sun.j2me.app-descriptor @jad :8bit 'IANA,[G.Adams]
  1176 +text/vnd.trolltech.linguist 'IANA,[D.Lambert]
  1177 +text/vnd.wap.si @si 'IANA,[WAP-Forum]
  1178 +text/vnd.wap.sl @sl 'IANA,[WAP-Forum]
  1179 +text/vnd.wap.wml @wml 'IANA,[Stark]
  1180 +text/vnd.wap.wmlscript @wmls 'IANA,[Stark]
  1181 +text/xml @xml,dtd :8bit 'IANA,RFC3023
  1182 +text/xml-external-parsed-entity 'IANA,RFC3023
  1183 +
  1184 +vms:text/plain @doc :8bit
  1185 +
  1186 +!text/ecmascript 'IANA,RFC4329
  1187 +!text/javascript 'IANA,RFC4329
  1188 +*!text/comma-separated-values @csv :8bit =use-instead:text/csv
  1189 +*!text/vnd.flatland.3dml =use-instead:model/vnd.flatland.3dml
  1190 +*!text/x-rtf @rtf :8bit =use-instead:text/rtf
  1191 +*!text/x-vnd.flatland.3dml =use-instead:model/vnd.flatland.3dml
  1192 +*text/x-component @htc :8bit
  1193 +*text/x-setext @etx
  1194 +*text/x-vcalendar @vcs :8bit
  1195 +*text/x-vcard @vcf :8bit
  1196 +*text/x-yaml @yaml,yml :8bit
  1197 +
  1198 + # Registered: video/*
  1199 +video/3gpp @3gp,3gpp 'IANA,RFC3839,RFC4281
  1200 +video/3gpp-tt 'IANA,RFC4396
  1201 +video/3gpp2 'IANA,RFC4393,RFC4281
  1202 +video/BMPEG 'IANA,RFC3555
  1203 +video/BT656 'IANA,RFC3555
  1204 +video/CelB 'IANA,RFC3555
  1205 +video/DV 'IANA,RFC3189
  1206 +video/H261 'IANA,RFC4587
  1207 +video/H263 'IANA,RFC3555
  1208 +video/H263-1998 'IANA,RFC4629
  1209 +video/H263-2000 'IANA,RFC4629
  1210 +video/H264 'IANA,RFC3984
  1211 +video/JPEG 'IANA,RFC3555
  1212 +video/jpeg2000 'IANA,RFC5371,RFC5372
  1213 +video/MJ2 @mj2,mjp2 'IANA,RFC3745
  1214 +video/MP1S 'IANA,RFC3555
  1215 +video/MP2P 'IANA,RFC3555
  1216 +video/MP2T 'IANA,RFC3555
  1217 +video/mp4 'IANA,RFC4337
  1218 +video/MP4V-ES 'IANA,RFC3016
  1219 +video/mpeg @mp2,mpe,mp3g,mpg :base64 'IANA,RFC2045,RFC2046
  1220 +video/mpeg4-generic 'IANA,RFC3640
  1221 +video/MPV 'IANA,RFC3555
  1222 +video/nv 'IANA,RFC4856
  1223 +video/ogg @ogv 'IANA,RFC5334
  1224 +video/parityfec 'IANA,RFC5109
  1225 +video/pointer 'IANA,RFC2862
  1226 +video/quicktime @qt,mov :base64 'IANA,[Lindner]
  1227 +video/raw 'IANA,RFC4175
  1228 +video/rtp-enc-aescm128 'IANA,[3GPP]
  1229 +video/rtx 'IANA,RFC4588
  1230 +video/SMPTE292M 'IANA,RFC3497
  1231 +video/ulpfec 'IANA,RFC5109
  1232 +video/vc1 'IANA,RFC4425
  1233 +video/vnd.CCTV 'IANA,[Rottmann]
  1234 +video/vnd.fvt 'IANA,[Fuldseth]
  1235 +video/vnd.hns.video 'IANA,[Swaminathan]
  1236 +video/vnd.iptvforum.1dparityfec-1010 'IANA,[Nakamura]
  1237 +video/vnd.iptvforum.1dparityfec-2005 'IANA,[Nakamura]
  1238 +video/vnd.iptvforum.2dparityfec-1010 'IANA,[Nakamura]
  1239 +video/vnd.iptvforum.2dparityfec-2005 'IANA,[Nakamura]
  1240 +video/vnd.iptvforum.ttsavc 'IANA,[Nakamura]
  1241 +video/vnd.iptvforum.ttsmpeg2 'IANA,[Nakamura]
  1242 +video/vnd.motorola.video 'IANA,[McGinty]
  1243 +video/vnd.motorola.videop 'IANA,[McGinty]
  1244 +video/vnd.mpegurl @mxu,m4u :8bit 'IANA,[Recktenwald]
  1245 +video/vnd.ms-playready.media.pyv 'IANA,[DiAcetis]
  1246 +video/vnd.nokia.interleaved-multimedia @nim 'IANA,[Kangaslampi]
  1247 +video/vnd.objectvideo @mp4 'IANA,[Clark]
  1248 +video/vnd.sealed.mpeg1 @s11 'IANA,[Petersen]
  1249 +video/vnd.sealed.mpeg4 @smpg,s14 'IANA,[Petersen]
  1250 +video/vnd.sealed.swf @sswf,ssw 'IANA,[Petersen]
  1251 +video/vnd.sealedmedia.softseal.mov @smov,smo,s1q 'IANA,[Petersen]
  1252 +video/vnd.vivo @viv,vivo 'IANA,[Wolfe]
  1253 +
  1254 +*!video/dl @dl :base64 =use-instead:video/x-dl
  1255 +*!video/gl @gl :base64 =use-instead:video/x-gl
  1256 +*!video/vnd.dlna.mpeg-tts 'IANA,[Heredia]
  1257 +*video/x-dl @dl :base64
  1258 +*video/x-fli @fli :base64
  1259 +*video/x-flv @flv :base64
  1260 +*video/x-gl @gl :base64
  1261 +*video/x-ms-asf @asf,asx
  1262 +*video/x-ms-wmv @wmv
  1263 +*video/x-msvideo @avi :base64
  1264 +*video/x-sgi-movie @movie :base64
  1265 +
  1266 + # Unregistered: other/*
  1267 +*!chemical/x-pdb @pdb =use-instead:x-chemical/x-pdb
  1268 +*!chemical/x-xyz @xyz =use-instead:x-chemical/x-xyz
  1269 +*!drawing/dwf @dwf =use-instead:x-drawing/dwf
  1270 +x-chemical/x-pdb @pdb
  1271 +x-chemical/x-xyz @xyz
  1272 +x-conference/x-cooltalk @ice
  1273 +x-drawing/dwf @dwf
  1274 +x-world/x-vrml @wrl,vrml
  1275 +MIME_TYPES
  1276 +
  1277 +_re = %r{
  1278 + ^
  1279 + ([*])? # 0: Unregistered?
  1280 + (!)? # 1: Obsolete?
  1281 + (?:(\w+):)? # 2: Platform marker
  1282 + #{MIME::Type::MEDIA_TYPE_RE} # 3,4: Media type
  1283 + (?:\s@([^\s]+))? # 5: Extensions
  1284 + (?:\s:(#{MIME::Type::ENCODING_RE}))? # 6: Encoding
  1285 + (?:\s'(.+))? # 7: URL list
  1286 + (?:\s=(.+))? # 8: Documentation
  1287 + $
  1288 +}x
  1289 +
  1290 +data_mime_type.split($/).each_with_index do |i, x|
  1291 + item = i.chomp.strip.gsub(%r{#.*}o, '')
  1292 + next if item.empty?
  1293 +
  1294 + begin
  1295 + m = _re.match(item).captures
  1296 + rescue Exception => ex
  1297 + puts <<-"ERROR"
  1298 +#{__FILE__}:#{x + data_mime_type_first_line}: Parsing error in MIME type definitions.
  1299 +=> "#{item}"
  1300 + ERROR
  1301 + raise
  1302 + end
  1303 +
  1304 + unregistered, obsolete, platform, mediatype, subtype, extensions,
  1305 + encoding, urls, docs = *m
  1306 +
  1307 + extensions &&= extensions.split(/,/)
  1308 + urls &&= urls.split(/,/)
  1309 +
  1310 + mime_type = MIME::Type.new("#{mediatype}/#{subtype}") do |t|
  1311 + t.extensions = extensions
  1312 + t.encoding = encoding
  1313 + t.system = platform
  1314 + t.obsolete = obsolete
  1315 + t.registered = false if unregistered
  1316 + t.docs = docs
  1317 + t.url = urls
  1318 + end
  1319 +
  1320 + MIME::Types.add_type_variant(mime_type)
  1321 + MIME::Types.index_extensions(mime_type)
  1322 +end
  1323 +
  1324 +_re = data_mime_type = data_mime_type_first_line = nil
... ...
vendor/gems/mime-types-1.16/mime-types.gemspec 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +# -*- encoding: utf-8 -*-
  2 +
  3 +Gem::Specification.new do |s|
  4 + s.name = %q{mime-types}
  5 + s.version = "1.16"
  6 +
  7 + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
  8 + s.authors = ["Austin Ziegler"]
  9 + s.cert_chain = ["/Users/austin/.gem/gem-public_cert.pem"]
  10 + s.date = %q{2009-03-01}
  11 + s.description = %q{MIME::Types for Ruby originally based on and synchronized with MIME::Types for Perl by Mark Overmeer, copyright 2001 - 2009. As of version 1.15, the data format for the MIME::Type list has changed and the synchronization will no longer happen.}
  12 + s.email = ["austin@rubyforge.org"]
  13 + s.extra_rdoc_files = ["History.txt", "Install.txt", "Licence.txt", "README.txt"]
  14 + s.files = ["History.txt", "Install.txt", "Licence.txt", "Manifest.txt", "README.txt", "Rakefile", "lib/mime/types.rb", "lib/mime/types.rb.data", "setup.rb", "test/test_mime_type.rb", "test/test_mime_types.rb"]
  15 + s.has_rdoc = true
  16 + s.homepage = %q{http://mime-types.rubyforge.org/}
  17 + s.rdoc_options = ["--main", "README.txt"]
  18 + s.require_paths = ["lib"]
  19 + s.rubyforge_project = %q{mime-types}
  20 + s.rubygems_version = %q{1.3.1}
  21 + s.signing_key = %q{/Users/austin/.gem/gem-private_key.pem}
  22 + s.summary = %q{Manages a MIME Content-Type database that will return the Content-Type for a given filename.}
  23 + s.test_files = ["test/test_mime_type.rb", "test/test_mime_types.rb"]
  24 +
  25 + if s.respond_to? :specification_version then
  26 + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
  27 + s.specification_version = 2
  28 +
  29 + if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
  30 + s.add_development_dependency(%q<archive-tar-minitar>, ["~> 0.5.1"])
  31 + s.add_development_dependency(%q<nokogiri>, ["~> 1.2.1"])
  32 + s.add_development_dependency(%q<hoe>, [">= 1.8.3"])
  33 + else
  34 + s.add_dependency(%q<archive-tar-minitar>, ["~> 0.5.1"])
  35 + s.add_dependency(%q<nokogiri>, ["~> 1.2.1"])
  36 + s.add_dependency(%q<hoe>, [">= 1.8.3"])
  37 + end
  38 + else
  39 + s.add_dependency(%q<archive-tar-minitar>, ["~> 0.5.1"])
  40 + s.add_dependency(%q<nokogiri>, ["~> 1.2.1"])
  41 + s.add_dependency(%q<hoe>, [">= 1.8.3"])
  42 + end
  43 +end
... ...
vendor/gems/mime-types-1.16/setup.rb 0 → 100644
... ... @@ -0,0 +1,1585 @@
  1 +#
  2 +# setup.rb
  3 +#
  4 +# Copyright (c) 2000-2005 Minero Aoki
  5 +#
  6 +# This program is free software.
  7 +# You can distribute/modify this program under the terms of
  8 +# the GNU LGPL, Lesser General Public License version 2.1.
  9 +#
  10 +
  11 +unless Enumerable.method_defined?(:map) # Ruby 1.4.6
  12 + module Enumerable
  13 + alias map collect
  14 + end
  15 +end
  16 +
  17 +unless File.respond_to?(:read) # Ruby 1.6
  18 + def File.read(fname)
  19 + open(fname) {|f|
  20 + return f.read
  21 + }
  22 + end
  23 +end
  24 +
  25 +unless Errno.const_defined?(:ENOTEMPTY) # Windows?
  26 + module Errno
  27 + class ENOTEMPTY
  28 + # We do not raise this exception, implementation is not needed.
  29 + end
  30 + end
  31 +end
  32 +
  33 +def File.binread(fname)
  34 + open(fname, 'rb') {|f|
  35 + return f.read
  36 + }
  37 +end
  38 +
  39 +# for corrupted Windows' stat(2)
  40 +def File.dir?(path)
  41 + File.directory?((path[-1,1] == '/') ? path : path + '/')
  42 +end
  43 +
  44 +
  45 +class ConfigTable
  46 +
  47 + include Enumerable
  48 +
  49 + def initialize(rbconfig)
  50 + @rbconfig = rbconfig
  51 + @items = []
  52 + @table = {}
  53 + # options
  54 + @install_prefix = nil
  55 + @config_opt = nil
  56 + @verbose = true
  57 + @no_harm = false
  58 + end
  59 +
  60 + attr_accessor :install_prefix
  61 + attr_accessor :config_opt
  62 +
  63 + attr_writer :verbose
  64 +
  65 + def verbose?
  66 + @verbose
  67 + end
  68 +
  69 + attr_writer :no_harm
  70 +
  71 + def no_harm?
  72 + @no_harm
  73 + end
  74 +
  75 + def [](key)
  76 + lookup(key).resolve(self)
  77 + end
  78 +
  79 + def []=(key, val)
  80 + lookup(key).set val
  81 + end
  82 +
  83 + def names
  84 + @items.map {|i| i.name }
  85 + end
  86 +
  87 + def each(&block)
  88 + @items.each(&block)
  89 + end
  90 +
  91 + def key?(name)
  92 + @table.key?(name)
  93 + end
  94 +
  95 + def lookup(name)
  96 + @table[name] or setup_rb_error "no such config item: #{name}"
  97 + end
  98 +
  99 + def add(item)
  100 + @items.push item
  101 + @table[item.name] = item
  102 + end
  103 +
  104 + def remove(name)
  105 + item = lookup(name)
  106 + @items.delete_if {|i| i.name == name }
  107 + @table.delete_if {|name, i| i.name == name }
  108 + item
  109 + end
  110 +
  111 + def load_script(path, inst = nil)
  112 + if File.file?(path)
  113 + MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
  114 + end
  115 + end
  116 +
  117 + def savefile
  118 + '.config'
  119 + end
  120 +
  121 + def load_savefile
  122 + begin
  123 + File.foreach(savefile()) do |line|
  124 + k, v = *line.split(/=/, 2)
  125 + self[k] = v.strip
  126 + end
  127 + rescue Errno::ENOENT
  128 + setup_rb_error $!.message + "\n#{File.basename($0)} config first"
  129 + end
  130 + end
  131 +
  132 + def save
  133 + @items.each {|i| i.value }
  134 + File.open(savefile(), 'w') {|f|
  135 + @items.each do |i|
  136 + f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
  137 + end
  138 + }
  139 + end
  140 +
  141 + def load_standard_entries
  142 + standard_entries(@rbconfig).each do |ent|
  143 + add ent
  144 + end
  145 + end
  146 +
  147 + def standard_entries(rbconfig)
  148 + c = rbconfig
  149 +
  150 + rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
  151 +
  152 + major = c['MAJOR'].to_i
  153 + minor = c['MINOR'].to_i
  154 + teeny = c['TEENY'].to_i
  155 + version = "#{major}.#{minor}"
  156 +
  157 + # ruby ver. >= 1.4.4?
  158 + newpath_p = ((major >= 2) or
  159 + ((major == 1) and
  160 + ((minor >= 5) or
  161 + ((minor == 4) and (teeny >= 4)))))
  162 +
  163 + if c['rubylibdir']
  164 + # V > 1.6.3
  165 + libruby = "#{c['prefix']}/lib/ruby"
  166 + librubyver = c['rubylibdir']
  167 + librubyverarch = c['archdir']
  168 + siteruby = c['sitedir']
  169 + siterubyver = c['sitelibdir']
  170 + siterubyverarch = c['sitearchdir']
  171 + elsif newpath_p
  172 + # 1.4.4 <= V <= 1.6.3
  173 + libruby = "#{c['prefix']}/lib/ruby"
  174 + librubyver = "#{c['prefix']}/lib/ruby/#{version}"
  175 + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
  176 + siteruby = c['sitedir']
  177 + siterubyver = "$siteruby/#{version}"
  178 + siterubyverarch = "$siterubyver/#{c['arch']}"
  179 + else
  180 + # V < 1.4.4
  181 + libruby = "#{c['prefix']}/lib/ruby"
  182 + librubyver = "#{c['prefix']}/lib/ruby/#{version}"
  183 + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
  184 + siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
  185 + siterubyver = siteruby
  186 + siterubyverarch = "$siterubyver/#{c['arch']}"
  187 + end
  188 + parameterize = lambda {|path|
  189 + path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
  190 + }
  191 +
  192 + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
  193 + makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
  194 + else
  195 + makeprog = 'make'
  196 + end
  197 +
  198 + [
  199 + ExecItem.new('installdirs', 'std/site/home',
  200 + 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
  201 + {|val, table|
  202 + case val
  203 + when 'std'
  204 + table['rbdir'] = '$librubyver'
  205 + table['sodir'] = '$librubyverarch'
  206 + when 'site'
  207 + table['rbdir'] = '$siterubyver'
  208 + table['sodir'] = '$siterubyverarch'
  209 + when 'home'
  210 + setup_rb_error '$HOME was not set' unless ENV['HOME']
  211 + table['prefix'] = ENV['HOME']
  212 + table['rbdir'] = '$libdir/ruby'
  213 + table['sodir'] = '$libdir/ruby'
  214 + end
  215 + },
  216 + PathItem.new('prefix', 'path', c['prefix'],
  217 + 'path prefix of target environment'),
  218 + PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
  219 + 'the directory for commands'),
  220 + PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
  221 + 'the directory for libraries'),
  222 + PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
  223 + 'the directory for shared data'),
  224 + PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
  225 + 'the directory for man pages'),
  226 + PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
  227 + 'the directory for system configuration files'),
  228 + PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
  229 + 'the directory for local state data'),
  230 + PathItem.new('libruby', 'path', libruby,
  231 + 'the directory for ruby libraries'),
  232 + PathItem.new('librubyver', 'path', librubyver,
  233 + 'the directory for standard ruby libraries'),
  234 + PathItem.new('librubyverarch', 'path', librubyverarch,
  235 + 'the directory for standard ruby extensions'),
  236 + PathItem.new('siteruby', 'path', siteruby,
  237 + 'the directory for version-independent aux ruby libraries'),
  238 + PathItem.new('siterubyver', 'path', siterubyver,
  239 + 'the directory for aux ruby libraries'),
  240 + PathItem.new('siterubyverarch', 'path', siterubyverarch,
  241 + 'the directory for aux ruby binaries'),
  242 + PathItem.new('rbdir', 'path', '$siterubyver',
  243 + 'the directory for ruby scripts'),
  244 + PathItem.new('sodir', 'path', '$siterubyverarch',
  245 + 'the directory for ruby extentions'),
  246 + PathItem.new('rubypath', 'path', rubypath,
  247 + 'the path to set to #! line'),
  248 + ProgramItem.new('rubyprog', 'name', rubypath,
  249 + 'the ruby program using for installation'),
  250 + ProgramItem.new('makeprog', 'name', makeprog,
  251 + 'the make program to compile ruby extentions'),
  252 + SelectItem.new('shebang', 'all/ruby/never', 'ruby',
  253 + 'shebang line (#!) editing mode'),
  254 + BoolItem.new('without-ext', 'yes/no', 'no',
  255 + 'does not compile/install ruby extentions')
  256 + ]
  257 + end
  258 + private :standard_entries
  259 +
  260 + def load_multipackage_entries
  261 + multipackage_entries().each do |ent|
  262 + add ent
  263 + end
  264 + end
  265 +
  266 + def multipackage_entries
  267 + [
  268 + PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
  269 + 'package names that you want to install'),
  270 + PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
  271 + 'package names that you do not want to install')
  272 + ]
  273 + end
  274 + private :multipackage_entries
  275 +
  276 + ALIASES = {
  277 + 'std-ruby' => 'librubyver',
  278 + 'stdruby' => 'librubyver',
  279 + 'rubylibdir' => 'librubyver',
  280 + 'archdir' => 'librubyverarch',
  281 + 'site-ruby-common' => 'siteruby', # For backward compatibility
  282 + 'site-ruby' => 'siterubyver', # For backward compatibility
  283 + 'bin-dir' => 'bindir',
  284 + 'bin-dir' => 'bindir',
  285 + 'rb-dir' => 'rbdir',
  286 + 'so-dir' => 'sodir',
  287 + 'data-dir' => 'datadir',
  288 + 'ruby-path' => 'rubypath',
  289 + 'ruby-prog' => 'rubyprog',
  290 + 'ruby' => 'rubyprog',
  291 + 'make-prog' => 'makeprog',
  292 + 'make' => 'makeprog'
  293 + }
  294 +
  295 + def fixup
  296 + ALIASES.each do |ali, name|
  297 + @table[ali] = @table[name]
  298 + end
  299 + @items.freeze
  300 + @table.freeze
  301 + @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
  302 + end
  303 +
  304 + def parse_opt(opt)
  305 + m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
  306 + m.to_a[1,2]
  307 + end
  308 +
  309 + def dllext
  310 + @rbconfig['DLEXT']
  311 + end
  312 +
  313 + def value_config?(name)
  314 + lookup(name).value?
  315 + end
  316 +
  317 + class Item
  318 + def initialize(name, template, default, desc)
  319 + @name = name.freeze
  320 + @template = template
  321 + @value = default
  322 + @default = default
  323 + @description = desc
  324 + end
  325 +
  326 + attr_reader :name
  327 + attr_reader :description
  328 +
  329 + attr_accessor :default
  330 + alias help_default default
  331 +
  332 + def help_opt
  333 + "--#{@name}=#{@template}"
  334 + end
  335 +
  336 + def value?
  337 + true
  338 + end
  339 +
  340 + def value
  341 + @value
  342 + end
  343 +
  344 + def resolve(table)
  345 + @value.gsub(%r<\$([^/]+)>) { table[$1] }
  346 + end
  347 +
  348 + def set(val)
  349 + @value = check(val)
  350 + end
  351 +
  352 + private
  353 +
  354 + def check(val)
  355 + setup_rb_error "config: --#{name} requires argument" unless val
  356 + val
  357 + end
  358 + end
  359 +
  360 + class BoolItem < Item
  361 + def config_type
  362 + 'bool'
  363 + end
  364 +
  365 + def help_opt
  366 + "--#{@name}"
  367 + end
  368 +
  369 + private
  370 +
  371 + def check(val)
  372 + return 'yes' unless val
  373 + case val
  374 + when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
  375 + when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
  376 + else
  377 + setup_rb_error "config: --#{@name} accepts only yes/no for argument"
  378 + end
  379 + end
  380 + end
  381 +
  382 + class PathItem < Item
  383 + def config_type
  384 + 'path'
  385 + end
  386 +
  387 + private
  388 +
  389 + def check(path)
  390 + setup_rb_error "config: --#{@name} requires argument" unless path
  391 + path[0,1] == '$' ? path : File.expand_path(path)
  392 + end
  393 + end
  394 +
  395 + class ProgramItem < Item
  396 + def config_type
  397 + 'program'
  398 + end
  399 + end
  400 +
  401 + class SelectItem < Item
  402 + def initialize(name, selection, default, desc)
  403 + super
  404 + @ok = selection.split('/')
  405 + end
  406 +
  407 + def config_type
  408 + 'select'
  409 + end
  410 +
  411 + private
  412 +
  413 + def check(val)
  414 + unless @ok.include?(val.strip)
  415 + setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
  416 + end
  417 + val.strip
  418 + end
  419 + end
  420 +
  421 + class ExecItem < Item
  422 + def initialize(name, selection, desc, &block)
  423 + super name, selection, nil, desc
  424 + @ok = selection.split('/')
  425 + @action = block
  426 + end
  427 +
  428 + def config_type
  429 + 'exec'
  430 + end
  431 +
  432 + def value?
  433 + false
  434 + end
  435 +
  436 + def resolve(table)
  437 + setup_rb_error "$#{name()} wrongly used as option value"
  438 + end
  439 +
  440 + undef set
  441 +
  442 + def evaluate(val, table)
  443 + v = val.strip.downcase
  444 + unless @ok.include?(v)
  445 + setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
  446 + end
  447 + @action.call v, table
  448 + end
  449 + end
  450 +
  451 + class PackageSelectionItem < Item
  452 + def initialize(name, template, default, help_default, desc)
  453 + super name, template, default, desc
  454 + @help_default = help_default
  455 + end
  456 +
  457 + attr_reader :help_default
  458 +
  459 + def config_type
  460 + 'package'
  461 + end
  462 +
  463 + private
  464 +
  465 + def check(val)
  466 + unless File.dir?("packages/#{val}")
  467 + setup_rb_error "config: no such package: #{val}"
  468 + end
  469 + val
  470 + end
  471 + end
  472 +
  473 + class MetaConfigEnvironment
  474 + def initialize(config, installer)
  475 + @config = config
  476 + @installer = installer
  477 + end
  478 +
  479 + def config_names
  480 + @config.names
  481 + end
  482 +
  483 + def config?(name)
  484 + @config.key?(name)
  485 + end
  486 +
  487 + def bool_config?(name)
  488 + @config.lookup(name).config_type == 'bool'
  489 + end
  490 +
  491 + def path_config?(name)
  492 + @config.lookup(name).config_type == 'path'
  493 + end
  494 +
  495 + def value_config?(name)
  496 + @config.lookup(name).config_type != 'exec'
  497 + end
  498 +
  499 + def add_config(item)
  500 + @config.add item
  501 + end
  502 +
  503 + def add_bool_config(name, default, desc)
  504 + @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
  505 + end
  506 +
  507 + def add_path_config(name, default, desc)
  508 + @config.add PathItem.new(name, 'path', default, desc)
  509 + end
  510 +
  511 + def set_config_default(name, default)
  512 + @config.lookup(name).default = default
  513 + end
  514 +
  515 + def remove_config(name)
  516 + @config.remove(name)
  517 + end
  518 +
  519 + # For only multipackage
  520 + def packages
  521 + raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
  522 + @installer.packages
  523 + end
  524 +
  525 + # For only multipackage
  526 + def declare_packages(list)
  527 + raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
  528 + @installer.packages = list
  529 + end
  530 + end
  531 +
  532 +end # class ConfigTable
  533 +
  534 +
  535 +# This module requires: #verbose?, #no_harm?
  536 +module FileOperations
  537 +
  538 + def mkdir_p(dirname, prefix = nil)
  539 + dirname = prefix + File.expand_path(dirname) if prefix
  540 + $stderr.puts "mkdir -p #{dirname}" if verbose?
  541 + return if no_harm?
  542 +
  543 + # Does not check '/', it's too abnormal.
  544 + dirs = File.expand_path(dirname).split(%r<(?=/)>)
  545 + if /\A[a-z]:\z/i =~ dirs[0]
  546 + disk = dirs.shift
  547 + dirs[0] = disk + dirs[0]
  548 + end
  549 + dirs.each_index do |idx|
  550 + path = dirs[0..idx].join('')
  551 + Dir.mkdir path unless File.dir?(path)
  552 + end
  553 + end
  554 +
  555 + def rm_f(path)
  556 + $stderr.puts "rm -f #{path}" if verbose?
  557 + return if no_harm?
  558 + force_remove_file path
  559 + end
  560 +
  561 + def rm_rf(path)
  562 + $stderr.puts "rm -rf #{path}" if verbose?
  563 + return if no_harm?
  564 + remove_tree path
  565 + end
  566 +
  567 + def remove_tree(path)
  568 + if File.symlink?(path)
  569 + remove_file path
  570 + elsif File.dir?(path)
  571 + remove_tree0 path
  572 + else
  573 + force_remove_file path
  574 + end
  575 + end
  576 +
  577 + def remove_tree0(path)
  578 + Dir.foreach(path) do |ent|
  579 + next if ent == '.'
  580 + next if ent == '..'
  581 + entpath = "#{path}/#{ent}"
  582 + if File.symlink?(entpath)
  583 + remove_file entpath
  584 + elsif File.dir?(entpath)
  585 + remove_tree0 entpath
  586 + else
  587 + force_remove_file entpath
  588 + end
  589 + end
  590 + begin
  591 + Dir.rmdir path
  592 + rescue Errno::ENOTEMPTY
  593 + # directory may not be empty
  594 + end
  595 + end
  596 +
  597 + def move_file(src, dest)
  598 + force_remove_file dest
  599 + begin
  600 + File.rename src, dest
  601 + rescue
  602 + File.open(dest, 'wb') {|f|
  603 + f.write File.binread(src)
  604 + }
  605 + File.chmod File.stat(src).mode, dest
  606 + File.unlink src
  607 + end
  608 + end
  609 +
  610 + def force_remove_file(path)
  611 + begin
  612 + remove_file path
  613 + rescue
  614 + end
  615 + end
  616 +
  617 + def remove_file(path)
  618 + File.chmod 0777, path
  619 + File.unlink path
  620 + end
  621 +
  622 + def install(from, dest, mode, prefix = nil)
  623 + $stderr.puts "install #{from} #{dest}" if verbose?
  624 + return if no_harm?
  625 +
  626 + realdest = prefix ? prefix + File.expand_path(dest) : dest
  627 + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
  628 + str = File.binread(from)
  629 + if diff?(str, realdest)
  630 + verbose_off {
  631 + rm_f realdest if File.exist?(realdest)
  632 + }
  633 + File.open(realdest, 'wb') {|f|
  634 + f.write str
  635 + }
  636 + File.chmod mode, realdest
  637 +
  638 + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
  639 + if prefix
  640 + f.puts realdest.sub(prefix, '')
  641 + else
  642 + f.puts realdest
  643 + end
  644 + }
  645 + end
  646 + end
  647 +
  648 + def diff?(new_content, path)
  649 + return true unless File.exist?(path)
  650 + new_content != File.binread(path)
  651 + end
  652 +
  653 + def command(*args)
  654 + $stderr.puts args.join(' ') if verbose?
  655 + system(*args) or raise RuntimeError,
  656 + "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
  657 + end
  658 +
  659 + def ruby(*args)
  660 + command config('rubyprog'), *args
  661 + end
  662 +
  663 + def make(task = nil)
  664 + command(*[config('makeprog'), task].compact)
  665 + end
  666 +
  667 + def extdir?(dir)
  668 + File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
  669 + end
  670 +
  671 + def files_of(dir)
  672 + Dir.open(dir) {|d|
  673 + return d.select {|ent| File.file?("#{dir}/#{ent}") }
  674 + }
  675 + end
  676 +
  677 + DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
  678 +
  679 + def directories_of(dir)
  680 + Dir.open(dir) {|d|
  681 + return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
  682 + }
  683 + end
  684 +
  685 +end
  686 +
  687 +
  688 +# This module requires: #srcdir_root, #objdir_root, #relpath
  689 +module HookScriptAPI
  690 +
  691 + def get_config(key)
  692 + @config[key]
  693 + end
  694 +
  695 + alias config get_config
  696 +
  697 + # obsolete: use metaconfig to change configuration
  698 + def set_config(key, val)
  699 + @config[key] = val
  700 + end
  701 +
  702 + #
  703 + # srcdir/objdir (works only in the package directory)
  704 + #
  705 +
  706 + def curr_srcdir
  707 + "#{srcdir_root()}/#{relpath()}"
  708 + end
  709 +
  710 + def curr_objdir
  711 + "#{objdir_root()}/#{relpath()}"
  712 + end
  713 +
  714 + def srcfile(path)
  715 + "#{curr_srcdir()}/#{path}"
  716 + end
  717 +
  718 + def srcexist?(path)
  719 + File.exist?(srcfile(path))
  720 + end
  721 +
  722 + def srcdirectory?(path)
  723 + File.dir?(srcfile(path))
  724 + end
  725 +
  726 + def srcfile?(path)
  727 + File.file?(srcfile(path))
  728 + end
  729 +
  730 + def srcentries(path = '.')
  731 + Dir.open("#{curr_srcdir()}/#{path}") {|d|
  732 + return d.to_a - %w(. ..)
  733 + }
  734 + end
  735 +
  736 + def srcfiles(path = '.')
  737 + srcentries(path).select {|fname|
  738 + File.file?(File.join(curr_srcdir(), path, fname))
  739 + }
  740 + end
  741 +
  742 + def srcdirectories(path = '.')
  743 + srcentries(path).select {|fname|
  744 + File.dir?(File.join(curr_srcdir(), path, fname))
  745 + }
  746 + end
  747 +
  748 +end
  749 +
  750 +
  751 +class ToplevelInstaller
  752 +
  753 + Version = '3.4.1'
  754 + Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
  755 +
  756 + TASKS = [
  757 + [ 'all', 'do config, setup, then install' ],
  758 + [ 'config', 'saves your configurations' ],
  759 + [ 'show', 'shows current configuration' ],
  760 + [ 'setup', 'compiles ruby extentions and others' ],
  761 + [ 'install', 'installs files' ],
  762 + [ 'test', 'run all tests in test/' ],
  763 + [ 'clean', "does `make clean' for each extention" ],
  764 + [ 'distclean',"does `make distclean' for each extention" ]
  765 + ]
  766 +
  767 + def ToplevelInstaller.invoke
  768 + config = ConfigTable.new(load_rbconfig())
  769 + config.load_standard_entries
  770 + config.load_multipackage_entries if multipackage?
  771 + config.fixup
  772 + klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
  773 + klass.new(File.dirname($0), config).invoke
  774 + end
  775 +
  776 + def ToplevelInstaller.multipackage?
  777 + File.dir?(File.dirname($0) + '/packages')
  778 + end
  779 +
  780 + def ToplevelInstaller.load_rbconfig
  781 + if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
  782 + ARGV.delete(arg)
  783 + load File.expand_path(arg.split(/=/, 2)[1])
  784 + $".push 'rbconfig.rb'
  785 + else
  786 + require 'rbconfig'
  787 + end
  788 + ::Config::CONFIG
  789 + end
  790 +
  791 + def initialize(ardir_root, config)
  792 + @ardir = File.expand_path(ardir_root)
  793 + @config = config
  794 + # cache
  795 + @valid_task_re = nil
  796 + end
  797 +
  798 + def config(key)
  799 + @config[key]
  800 + end
  801 +
  802 + def inspect
  803 + "#<#{self.class} #{__id__()}>"
  804 + end
  805 +
  806 + def invoke
  807 + run_metaconfigs
  808 + case task = parsearg_global()
  809 + when nil, 'all'
  810 + parsearg_config
  811 + init_installers
  812 + exec_config
  813 + exec_setup
  814 + exec_install
  815 + else
  816 + case task
  817 + when 'config', 'test'
  818 + ;
  819 + when 'clean', 'distclean'
  820 + @config.load_savefile if File.exist?(@config.savefile)
  821 + else
  822 + @config.load_savefile
  823 + end
  824 + __send__ "parsearg_#{task}"
  825 + init_installers
  826 + __send__ "exec_#{task}"
  827 + end
  828 + end
  829 +
  830 + def run_metaconfigs
  831 + @config.load_script "#{@ardir}/metaconfig"
  832 + end
  833 +
  834 + def init_installers
  835 + @installer = Installer.new(@config, @ardir, File.expand_path('.'))
  836 + end
  837 +
  838 + #
  839 + # Hook Script API bases
  840 + #
  841 +
  842 + def srcdir_root
  843 + @ardir
  844 + end
  845 +
  846 + def objdir_root
  847 + '.'
  848 + end
  849 +
  850 + def relpath
  851 + '.'
  852 + end
  853 +
  854 + #
  855 + # Option Parsing
  856 + #
  857 +
  858 + def parsearg_global
  859 + while arg = ARGV.shift
  860 + case arg
  861 + when /\A\w+\z/
  862 + setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
  863 + return arg
  864 + when '-q', '--quiet'
  865 + @config.verbose = false
  866 + when '--verbose'
  867 + @config.verbose = true
  868 + when '--help'
  869 + print_usage $stdout
  870 + exit 0
  871 + when '--version'
  872 + puts "#{File.basename($0)} version #{Version}"
  873 + exit 0
  874 + when '--copyright'
  875 + puts Copyright
  876 + exit 0
  877 + else
  878 + setup_rb_error "unknown global option '#{arg}'"
  879 + end
  880 + end
  881 + nil
  882 + end
  883 +
  884 + def valid_task?(t)
  885 + valid_task_re() =~ t
  886 + end
  887 +
  888 + def valid_task_re
  889 + @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
  890 + end
  891 +
  892 + def parsearg_no_options
  893 + unless ARGV.empty?
  894 + task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
  895 + setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
  896 + end
  897 + end
  898 +
  899 + alias parsearg_show parsearg_no_options
  900 + alias parsearg_setup parsearg_no_options
  901 + alias parsearg_test parsearg_no_options
  902 + alias parsearg_clean parsearg_no_options
  903 + alias parsearg_distclean parsearg_no_options
  904 +
  905 + def parsearg_config
  906 + evalopt = []
  907 + set = []
  908 + @config.config_opt = []
  909 + while i = ARGV.shift
  910 + if /\A--?\z/ =~ i
  911 + @config.config_opt = ARGV.dup
  912 + break
  913 + end
  914 + name, value = *@config.parse_opt(i)
  915 + if @config.value_config?(name)
  916 + @config[name] = value
  917 + else
  918 + evalopt.push [name, value]
  919 + end
  920 + set.push name
  921 + end
  922 + evalopt.each do |name, value|
  923 + @config.lookup(name).evaluate value, @config
  924 + end
  925 + # Check if configuration is valid
  926 + set.each do |n|
  927 + @config[n] if @config.value_config?(n)
  928 + end
  929 + end
  930 +
  931 + def parsearg_install
  932 + @config.no_harm = false
  933 + @config.install_prefix = ''
  934 + while a = ARGV.shift
  935 + case a
  936 + when '--no-harm'
  937 + @config.no_harm = true
  938 + when /\A--prefix=/
  939 + path = a.split(/=/, 2)[1]
  940 + path = File.expand_path(path) unless path[0,1] == '/'
  941 + @config.install_prefix = path
  942 + else
  943 + setup_rb_error "install: unknown option #{a}"
  944 + end
  945 + end
  946 + end
  947 +
  948 + def print_usage(out)
  949 + out.puts 'Typical Installation Procedure:'
  950 + out.puts " $ ruby #{File.basename $0} config"
  951 + out.puts " $ ruby #{File.basename $0} setup"
  952 + out.puts " # ruby #{File.basename $0} install (may require root privilege)"
  953 + out.puts
  954 + out.puts 'Detailed Usage:'
  955 + out.puts " ruby #{File.basename $0} <global option>"
  956 + out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
  957 +
  958 + fmt = " %-24s %s\n"
  959 + out.puts
  960 + out.puts 'Global options:'
  961 + out.printf fmt, '-q,--quiet', 'suppress message outputs'
  962 + out.printf fmt, ' --verbose', 'output messages verbosely'
  963 + out.printf fmt, ' --help', 'print this message'
  964 + out.printf fmt, ' --version', 'print version and quit'
  965 + out.printf fmt, ' --copyright', 'print copyright and quit'
  966 + out.puts
  967 + out.puts 'Tasks:'
  968 + TASKS.each do |name, desc|
  969 + out.printf fmt, name, desc
  970 + end
  971 +
  972 + fmt = " %-24s %s [%s]\n"
  973 + out.puts
  974 + out.puts 'Options for CONFIG or ALL:'
  975 + @config.each do |item|
  976 + out.printf fmt, item.help_opt, item.description, item.help_default
  977 + end
  978 + out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
  979 + out.puts
  980 + out.puts 'Options for INSTALL:'
  981 + out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
  982 + out.printf fmt, '--prefix=path', 'install path prefix', ''
  983 + out.puts
  984 + end
  985 +
  986 + #
  987 + # Task Handlers
  988 + #
  989 +
  990 + def exec_config
  991 + @installer.exec_config
  992 + @config.save # must be final
  993 + end
  994 +
  995 + def exec_setup
  996 + @installer.exec_setup
  997 + end
  998 +
  999 + def exec_install
  1000 + @installer.exec_install
  1001 + end
  1002 +
  1003 + def exec_test
  1004 + @installer.exec_test
  1005 + end
  1006 +
  1007 + def exec_show
  1008 + @config.each do |i|
  1009 + printf "%-20s %s\n", i.name, i.value if i.value?
  1010 + end
  1011 + end
  1012 +
  1013 + def exec_clean
  1014 + @installer.exec_clean
  1015 + end
  1016 +
  1017 + def exec_distclean
  1018 + @installer.exec_distclean
  1019 + end
  1020 +
  1021 +end # class ToplevelInstaller
  1022 +
  1023 +
  1024 +class ToplevelInstallerMulti < ToplevelInstaller
  1025 +
  1026 + include FileOperations
  1027 +
  1028 + def initialize(ardir_root, config)
  1029 + super
  1030 + @packages = directories_of("#{@ardir}/packages")
  1031 + raise 'no package exists' if @packages.empty?
  1032 + @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
  1033 + end
  1034 +
  1035 + def run_metaconfigs
  1036 + @config.load_script "#{@ardir}/metaconfig", self
  1037 + @packages.each do |name|
  1038 + @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
  1039 + end
  1040 + end
  1041 +
  1042 + attr_reader :packages
  1043 +
  1044 + def packages=(list)
  1045 + raise 'package list is empty' if list.empty?
  1046 + list.each do |name|
  1047 + raise "directory packages/#{name} does not exist"\
  1048 + unless File.dir?("#{@ardir}/packages/#{name}")
  1049 + end
  1050 + @packages = list
  1051 + end
  1052 +
  1053 + def init_installers
  1054 + @installers = {}
  1055 + @packages.each do |pack|
  1056 + @installers[pack] = Installer.new(@config,
  1057 + "#{@ardir}/packages/#{pack}",
  1058 + "packages/#{pack}")
  1059 + end
  1060 + with = extract_selection(config('with'))
  1061 + without = extract_selection(config('without'))
  1062 + @selected = @installers.keys.select {|name|
  1063 + (with.empty? or with.include?(name)) \
  1064 + and not without.include?(name)
  1065 + }
  1066 + end
  1067 +
  1068 + def extract_selection(list)
  1069 + a = list.split(/,/)
  1070 + a.each do |name|
  1071 + setup_rb_error "no such package: #{name}" unless @installers.key?(name)
  1072 + end
  1073 + a
  1074 + end
  1075 +
  1076 + def print_usage(f)
  1077 + super
  1078 + f.puts 'Inluded packages:'
  1079 + f.puts ' ' + @packages.sort.join(' ')
  1080 + f.puts
  1081 + end
  1082 +
  1083 + #
  1084 + # Task Handlers
  1085 + #
  1086 +
  1087 + def exec_config
  1088 + run_hook 'pre-config'
  1089 + each_selected_installers {|inst| inst.exec_config }
  1090 + run_hook 'post-config'
  1091 + @config.save # must be final
  1092 + end
  1093 +
  1094 + def exec_setup
  1095 + run_hook 'pre-setup'
  1096 + each_selected_installers {|inst| inst.exec_setup }
  1097 + run_hook 'post-setup'
  1098 + end
  1099 +
  1100 + def exec_install
  1101 + run_hook 'pre-install'
  1102 + each_selected_installers {|inst| inst.exec_install }
  1103 + run_hook 'post-install'
  1104 + end
  1105 +
  1106 + def exec_test
  1107 + run_hook 'pre-test'
  1108 + each_selected_installers {|inst| inst.exec_test }
  1109 + run_hook 'post-test'
  1110 + end
  1111 +
  1112 + def exec_clean
  1113 + rm_f @config.savefile
  1114 + run_hook 'pre-clean'
  1115 + each_selected_installers {|inst| inst.exec_clean }
  1116 + run_hook 'post-clean'
  1117 + end
  1118 +
  1119 + def exec_distclean
  1120 + rm_f @config.savefile
  1121 + run_hook 'pre-distclean'
  1122 + each_selected_installers {|inst| inst.exec_distclean }
  1123 + run_hook 'post-distclean'
  1124 + end
  1125 +
  1126 + #
  1127 + # lib
  1128 + #
  1129 +
  1130 + def each_selected_installers
  1131 + Dir.mkdir 'packages' unless File.dir?('packages')
  1132 + @selected.each do |pack|
  1133 + $stderr.puts "Processing the package `#{pack}' ..." if verbose?
  1134 + Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
  1135 + Dir.chdir "packages/#{pack}"
  1136 + yield @installers[pack]
  1137 + Dir.chdir '../..'
  1138 + end
  1139 + end
  1140 +
  1141 + def run_hook(id)
  1142 + @root_installer.run_hook id
  1143 + end
  1144 +
  1145 + # module FileOperations requires this
  1146 + def verbose?
  1147 + @config.verbose?
  1148 + end
  1149 +
  1150 + # module FileOperations requires this
  1151 + def no_harm?
  1152 + @config.no_harm?
  1153 + end
  1154 +
  1155 +end # class ToplevelInstallerMulti
  1156 +
  1157 +
  1158 +class Installer
  1159 +
  1160 + FILETYPES = %w( bin lib ext data conf man )
  1161 +
  1162 + include FileOperations
  1163 + include HookScriptAPI
  1164 +
  1165 + def initialize(config, srcroot, objroot)
  1166 + @config = config
  1167 + @srcdir = File.expand_path(srcroot)
  1168 + @objdir = File.expand_path(objroot)
  1169 + @currdir = '.'
  1170 + end
  1171 +
  1172 + def inspect
  1173 + "#<#{self.class} #{File.basename(@srcdir)}>"
  1174 + end
  1175 +
  1176 + def noop(rel)
  1177 + end
  1178 +
  1179 + #
  1180 + # Hook Script API base methods
  1181 + #
  1182 +
  1183 + def srcdir_root
  1184 + @srcdir
  1185 + end
  1186 +
  1187 + def objdir_root
  1188 + @objdir
  1189 + end
  1190 +
  1191 + def relpath
  1192 + @currdir
  1193 + end
  1194 +
  1195 + #
  1196 + # Config Access
  1197 + #
  1198 +
  1199 + # module FileOperations requires this
  1200 + def verbose?
  1201 + @config.verbose?
  1202 + end
  1203 +
  1204 + # module FileOperations requires this
  1205 + def no_harm?
  1206 + @config.no_harm?
  1207 + end
  1208 +
  1209 + def verbose_off
  1210 + begin
  1211 + save, @config.verbose = @config.verbose?, false
  1212 + yield
  1213 + ensure
  1214 + @config.verbose = save
  1215 + end
  1216 + end
  1217 +
  1218 + #
  1219 + # TASK config
  1220 + #
  1221 +
  1222 + def exec_config
  1223 + exec_task_traverse 'config'
  1224 + end
  1225 +
  1226 + alias config_dir_bin noop
  1227 + alias config_dir_lib noop
  1228 +
  1229 + def config_dir_ext(rel)
  1230 + extconf if extdir?(curr_srcdir())
  1231 + end
  1232 +
  1233 + alias config_dir_data noop
  1234 + alias config_dir_conf noop
  1235 + alias config_dir_man noop
  1236 +
  1237 + def extconf
  1238 + ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
  1239 + end
  1240 +
  1241 + #
  1242 + # TASK setup
  1243 + #
  1244 +
  1245 + def exec_setup
  1246 + exec_task_traverse 'setup'
  1247 + end
  1248 +
  1249 + def setup_dir_bin(rel)
  1250 + files_of(curr_srcdir()).each do |fname|
  1251 + update_shebang_line "#{curr_srcdir()}/#{fname}"
  1252 + end
  1253 + end
  1254 +
  1255 + alias setup_dir_lib noop
  1256 +
  1257 + def setup_dir_ext(rel)
  1258 + make if extdir?(curr_srcdir())
  1259 + end
  1260 +
  1261 + alias setup_dir_data noop
  1262 + alias setup_dir_conf noop
  1263 + alias setup_dir_man noop
  1264 +
  1265 + def update_shebang_line(path)
  1266 + return if no_harm?
  1267 + return if config('shebang') == 'never'
  1268 + old = Shebang.load(path)
  1269 + if old
  1270 + $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
  1271 + new = new_shebang(old)
  1272 + return if new.to_s == old.to_s
  1273 + else
  1274 + return unless config('shebang') == 'all'
  1275 + new = Shebang.new(config('rubypath'))
  1276 + end
  1277 + $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
  1278 + open_atomic_writer(path) {|output|
  1279 + File.open(path, 'rb') {|f|
  1280 + f.gets if old # discard
  1281 + output.puts new.to_s
  1282 + output.print f.read
  1283 + }
  1284 + }
  1285 + end
  1286 +
  1287 + def new_shebang(old)
  1288 + if /\Aruby/ =~ File.basename(old.cmd)
  1289 + Shebang.new(config('rubypath'), old.args)
  1290 + elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
  1291 + Shebang.new(config('rubypath'), old.args[1..-1])
  1292 + else
  1293 + return old unless config('shebang') == 'all'
  1294 + Shebang.new(config('rubypath'))
  1295 + end
  1296 + end
  1297 +
  1298 + def open_atomic_writer(path, &block)
  1299 + tmpfile = File.basename(path) + '.tmp'
  1300 + begin
  1301 + File.open(tmpfile, 'wb', &block)
  1302 + File.rename tmpfile, File.basename(path)
  1303 + ensure
  1304 + File.unlink tmpfile if File.exist?(tmpfile)
  1305 + end
  1306 + end
  1307 +
  1308 + class Shebang
  1309 + def Shebang.load(path)
  1310 + line = nil
  1311 + File.open(path) {|f|
  1312 + line = f.gets
  1313 + }
  1314 + return nil unless /\A#!/ =~ line
  1315 + parse(line)
  1316 + end
  1317 +
  1318 + def Shebang.parse(line)
  1319 + cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
  1320 + new(cmd, args)
  1321 + end
  1322 +
  1323 + def initialize(cmd, args = [])
  1324 + @cmd = cmd
  1325 + @args = args
  1326 + end
  1327 +
  1328 + attr_reader :cmd
  1329 + attr_reader :args
  1330 +
  1331 + def to_s
  1332 + "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
  1333 + end
  1334 + end
  1335 +
  1336 + #
  1337 + # TASK install
  1338 + #
  1339 +
  1340 + def exec_install
  1341 + rm_f 'InstalledFiles'
  1342 + exec_task_traverse 'install'
  1343 + end
  1344 +
  1345 + def install_dir_bin(rel)
  1346 + install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
  1347 + end
  1348 +
  1349 + def install_dir_lib(rel)
  1350 + install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
  1351 + end
  1352 +
  1353 + def install_dir_ext(rel)
  1354 + return unless extdir?(curr_srcdir())
  1355 + install_files rubyextentions('.'),
  1356 + "#{config('sodir')}/#{File.dirname(rel)}",
  1357 + 0555
  1358 + end
  1359 +
  1360 + def install_dir_data(rel)
  1361 + install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
  1362 + end
  1363 +
  1364 + def install_dir_conf(rel)
  1365 + # FIXME: should not remove current config files
  1366 + # (rename previous file to .old/.org)
  1367 + install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
  1368 + end
  1369 +
  1370 + def install_dir_man(rel)
  1371 + install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
  1372 + end
  1373 +
  1374 + def install_files(list, dest, mode)
  1375 + mkdir_p dest, @config.install_prefix
  1376 + list.each do |fname|
  1377 + install fname, dest, mode, @config.install_prefix
  1378 + end
  1379 + end
  1380 +
  1381 + def libfiles
  1382 + glob_reject(%w(*.y *.output), targetfiles())
  1383 + end
  1384 +
  1385 + def rubyextentions(dir)
  1386 + ents = glob_select("*.#{@config.dllext}", targetfiles())
  1387 + if ents.empty?
  1388 + setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
  1389 + end
  1390 + ents
  1391 + end
  1392 +
  1393 + def targetfiles
  1394 + mapdir(existfiles() - hookfiles())
  1395 + end
  1396 +
  1397 + def mapdir(ents)
  1398 + ents.map {|ent|
  1399 + if File.exist?(ent)
  1400 + then ent # objdir
  1401 + else "#{curr_srcdir()}/#{ent}" # srcdir
  1402 + end
  1403 + }
  1404 + end
  1405 +
  1406 + # picked up many entries from cvs-1.11.1/src/ignore.c
  1407 + JUNK_FILES = %w(
  1408 + core RCSLOG tags TAGS .make.state
  1409 + .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
  1410 + *~ *.old *.bak *.BAK *.orig *.rej _$* *$
  1411 +
  1412 + *.org *.in .*
  1413 + )
  1414 +
  1415 + def existfiles
  1416 + glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
  1417 + end
  1418 +
  1419 + def hookfiles
  1420 + %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
  1421 + %w( config setup install clean ).map {|t| sprintf(fmt, t) }
  1422 + }.flatten
  1423 + end
  1424 +
  1425 + def glob_select(pat, ents)
  1426 + re = globs2re([pat])
  1427 + ents.select {|ent| re =~ ent }
  1428 + end
  1429 +
  1430 + def glob_reject(pats, ents)
  1431 + re = globs2re(pats)
  1432 + ents.reject {|ent| re =~ ent }
  1433 + end
  1434 +
  1435 + GLOB2REGEX = {
  1436 + '.' => '\.',
  1437 + '$' => '\$',
  1438 + '#' => '\#',
  1439 + '*' => '.*'
  1440 + }
  1441 +
  1442 + def globs2re(pats)
  1443 + /\A(?:#{
  1444 + pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
  1445 + })\z/
  1446 + end
  1447 +
  1448 + #
  1449 + # TASK test
  1450 + #
  1451 +
  1452 + TESTDIR = 'test'
  1453 +
  1454 + def exec_test
  1455 + unless File.directory?('test')
  1456 + $stderr.puts 'no test in this package' if verbose?
  1457 + return
  1458 + end
  1459 + $stderr.puts 'Running tests...' if verbose?
  1460 + begin
  1461 + require 'test/unit'
  1462 + rescue LoadError
  1463 + setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
  1464 + end
  1465 + runner = Test::Unit::AutoRunner.new(true)
  1466 + runner.to_run << TESTDIR
  1467 + runner.run
  1468 + end
  1469 +
  1470 + #
  1471 + # TASK clean
  1472 + #
  1473 +
  1474 + def exec_clean
  1475 + exec_task_traverse 'clean'
  1476 + rm_f @config.savefile
  1477 + rm_f 'InstalledFiles'
  1478 + end
  1479 +
  1480 + alias clean_dir_bin noop
  1481 + alias clean_dir_lib noop
  1482 + alias clean_dir_data noop
  1483 + alias clean_dir_conf noop
  1484 + alias clean_dir_man noop
  1485 +
  1486 + def clean_dir_ext(rel)
  1487 + return unless extdir?(curr_srcdir())
  1488 + make 'clean' if File.file?('Makefile')
  1489 + end
  1490 +
  1491 + #
  1492 + # TASK distclean
  1493 + #
  1494 +
  1495 + def exec_distclean
  1496 + exec_task_traverse 'distclean'
  1497 + rm_f @config.savefile
  1498 + rm_f 'InstalledFiles'
  1499 + end
  1500 +
  1501 + alias distclean_dir_bin noop
  1502 + alias distclean_dir_lib noop
  1503 +
  1504 + def distclean_dir_ext(rel)
  1505 + return unless extdir?(curr_srcdir())
  1506 + make 'distclean' if File.file?('Makefile')
  1507 + end
  1508 +
  1509 + alias distclean_dir_data noop
  1510 + alias distclean_dir_conf noop
  1511 + alias distclean_dir_man noop
  1512 +
  1513 + #
  1514 + # Traversing
  1515 + #
  1516 +
  1517 + def exec_task_traverse(task)
  1518 + run_hook "pre-#{task}"
  1519 + FILETYPES.each do |type|
  1520 + if type == 'ext' and config('without-ext') == 'yes'
  1521 + $stderr.puts 'skipping ext/* by user option' if verbose?
  1522 + next
  1523 + end
  1524 + traverse task, type, "#{task}_dir_#{type}"
  1525 + end
  1526 + run_hook "post-#{task}"
  1527 + end
  1528 +
  1529 + def traverse(task, rel, mid)
  1530 + dive_into(rel) {
  1531 + run_hook "pre-#{task}"
  1532 + __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
  1533 + directories_of(curr_srcdir()).each do |d|
  1534 + traverse task, "#{rel}/#{d}", mid
  1535 + end
  1536 + run_hook "post-#{task}"
  1537 + }
  1538 + end
  1539 +
  1540 + def dive_into(rel)
  1541 + return unless File.dir?("#{@srcdir}/#{rel}")
  1542 +
  1543 + dir = File.basename(rel)
  1544 + Dir.mkdir dir unless File.dir?(dir)
  1545 + prevdir = Dir.pwd
  1546 + Dir.chdir dir
  1547 + $stderr.puts '---> ' + rel if verbose?
  1548 + @currdir = rel
  1549 + yield
  1550 + Dir.chdir prevdir
  1551 + $stderr.puts '<--- ' + rel if verbose?
  1552 + @currdir = File.dirname(rel)
  1553 + end
  1554 +
  1555 + def run_hook(id)
  1556 + path = [ "#{curr_srcdir()}/#{id}",
  1557 + "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
  1558 + return unless path
  1559 + begin
  1560 + instance_eval File.read(path), path, 1
  1561 + rescue
  1562 + raise if $DEBUG
  1563 + setup_rb_error "hook #{path} failed:\n" + $!.message
  1564 + end
  1565 + end
  1566 +
  1567 +end # class Installer
  1568 +
  1569 +
  1570 +class SetupError < StandardError; end
  1571 +
  1572 +def setup_rb_error(msg)
  1573 + raise SetupError, msg
  1574 +end
  1575 +
  1576 +if $0 == __FILE__
  1577 + begin
  1578 + ToplevelInstaller.invoke
  1579 + rescue SetupError
  1580 + raise if $DEBUG
  1581 + $stderr.puts $!.message
  1582 + $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
  1583 + exit 1
  1584 + end
  1585 +end
... ...
vendor/gems/mime-types-1.16/test/test_mime_type.rb 0 → 100644
... ... @@ -0,0 +1,356 @@
  1 +#! /usr/bin/env ruby
  2 +#--
  3 +# MIME::Types
  4 +# A Ruby implementation of a MIME Types information library. Based in spirit
  5 +# on the Perl MIME::Types information library by Mark Overmeer.
  6 +# http://rubyforge.org/projects/mime-types/
  7 +#
  8 +# Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  9 +# Artistic licence. See Licence.txt for more information.
  10 +#
  11 +# Copyright 2003 - 2009 Austin Ziegler
  12 +#++
  13 +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
  14 +
  15 +require 'mime/types'
  16 +require 'test/unit' unless defined? $ZENTEST and $ZENTEST
  17 +
  18 +module TestMIME
  19 + class TestType < Test::Unit::TestCase #:nodoc:
  20 + def setup
  21 + @zip = MIME::Type.new('x-appl/x-zip') { |t| t.extensions = ['zip', 'zp'] }
  22 + end
  23 +
  24 + def test_class_from_array
  25 + assert_nothing_raised do
  26 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit', 'linux')
  27 + end
  28 + assert_instance_of(MIME::Type, @yaml)
  29 + assert_equal('text/yaml', @yaml.simplified)
  30 + end
  31 +
  32 + def test_class_from_hash
  33 + assert_nothing_raised do
  34 + @yaml = MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
  35 + 'Content-Transfer-Encoding' => '8bit',
  36 + 'System' => 'linux',
  37 + 'Extensions' => %w(yaml yml))
  38 + end
  39 + assert_instance_of(MIME::Type, @yaml)
  40 + assert_equal('text/yaml', @yaml.simplified)
  41 + end
  42 +
  43 + def test_class_from_mime_type
  44 + assert_nothing_raised do
  45 + @zip2 = MIME::Type.from_mime_type(@zip)
  46 + end
  47 + assert_instance_of(MIME::Type, @zip)
  48 + assert_equal('appl/zip', @zip.simplified)
  49 + assert_not_equal(@zip.object_id, @zip2.object_id)
  50 + end
  51 +
  52 + def test_class_simplified
  53 + assert_equal(MIME::Type.simplified('text/plain'), 'text/plain')
  54 + assert_equal(MIME::Type.simplified('image/jpeg'), 'image/jpeg')
  55 + assert_equal(MIME::Type.simplified('application/x-msword'), 'application/msword')
  56 + assert_equal(MIME::Type.simplified('text/vCard'), 'text/vcard')
  57 + assert_equal(MIME::Type.simplified('application/pkcs7-mime'), 'application/pkcs7-mime')
  58 + assert_equal(@zip.simplified, 'appl/zip')
  59 + assert_equal(MIME::Type.simplified('x-xyz/abc'), 'xyz/abc')
  60 + end
  61 +
  62 + def test_CMP # '<=>'
  63 + assert(MIME::Type.new('text/plain') == MIME::Type.new('text/plain'))
  64 + assert(MIME::Type.new('text/plain') != MIME::Type.new('image/jpeg'))
  65 + assert(MIME::Type.new('text/plain') == 'text/plain')
  66 + assert(MIME::Type.new('text/plain') != 'image/jpeg')
  67 + assert(MIME::Type.new('text/plain') > MIME::Type.new('text/html'))
  68 + assert(MIME::Type.new('text/plain') > 'text/html')
  69 + assert(MIME::Type.new('text/html') < MIME::Type.new('text/plain'))
  70 + assert(MIME::Type.new('text/html') < 'text/plain')
  71 + assert('text/html' == MIME::Type.new('text/html'))
  72 + assert('text/html' < MIME::Type.new('text/plain'))
  73 + assert('text/plain' > MIME::Type.new('text/html'))
  74 + end
  75 +
  76 + def test_ascii_eh
  77 + assert(MIME::Type.new('text/plain').ascii?)
  78 + assert(!MIME::Type.new('image/jpeg').ascii?)
  79 + assert(!MIME::Type.new('application/x-msword').ascii?)
  80 + assert(MIME::Type.new('text/vCard').ascii?)
  81 + assert(!MIME::Type.new('application/pkcs7-mime').ascii?)
  82 + assert(!@zip.ascii?)
  83 + end
  84 +
  85 + def test_binary_eh
  86 + assert(!MIME::Type.new('text/plain').binary?)
  87 + assert(MIME::Type.new('image/jpeg').binary?)
  88 + assert(MIME::Type.new('application/x-msword').binary?)
  89 + assert(!MIME::Type.new('text/vCard').binary?)
  90 + assert(MIME::Type.new('application/pkcs7-mime').binary?)
  91 + assert(@zip.binary?)
  92 + end
  93 +
  94 + def test_complete_eh
  95 + assert_nothing_raised do
  96 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  97 + 'linux')
  98 + end
  99 + assert(@yaml.complete?)
  100 + assert_nothing_raised { @yaml.extensions = nil }
  101 + assert(!@yaml.complete?)
  102 + end
  103 +
  104 + def test_content_type
  105 + assert_equal(MIME::Type.new('text/plain').content_type, 'text/plain')
  106 + assert_equal(MIME::Type.new('image/jpeg').content_type, 'image/jpeg')
  107 + assert_equal(MIME::Type.new('application/x-msword').content_type, 'application/x-msword')
  108 + assert_equal(MIME::Type.new('text/vCard').content_type, 'text/vCard')
  109 + assert_equal(MIME::Type.new('application/pkcs7-mime').content_type, 'application/pkcs7-mime')
  110 + assert_equal(@zip.content_type, 'x-appl/x-zip');
  111 + end
  112 +
  113 + def test_encoding
  114 + assert_equal(MIME::Type.new('text/plain').encoding, 'quoted-printable')
  115 + assert_equal(MIME::Type.new('image/jpeg').encoding, 'base64')
  116 + assert_equal(MIME::Type.new('application/x-msword').encoding, 'base64')
  117 + assert_equal(MIME::Type.new('text/vCard').encoding, 'quoted-printable')
  118 + assert_equal(MIME::Type.new('application/pkcs7-mime').encoding, 'base64')
  119 + assert_nothing_raised do
  120 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  121 + 'linux')
  122 + end
  123 + assert_equal(@yaml.encoding, '8bit')
  124 + assert_nothing_raised { @yaml.encoding = 'base64' }
  125 + assert_equal(@yaml.encoding, 'base64')
  126 + assert_nothing_raised { @yaml.encoding = :default }
  127 + assert_equal(@yaml.encoding, 'quoted-printable')
  128 + assert_raises(ArgumentError) { @yaml.encoding = 'binary' }
  129 + assert_equal(@zip.encoding, 'base64')
  130 + end
  131 +
  132 + def _test_default_encoding
  133 + raise NotImplementedError, 'Need to write test_default_encoding'
  134 + end
  135 +
  136 + def _test_docs
  137 + raise NotImplementedError, 'Need to write test_docs'
  138 + end
  139 +
  140 + def _test_docs_equals
  141 + raise NotImplementedError, 'Need to write test_docs_equals'
  142 + end
  143 +
  144 + def test_eql?
  145 + assert(MIME::Type.new('text/plain').eql?(MIME::Type.new('text/plain')))
  146 + assert(!MIME::Type.new('text/plain').eql?(MIME::Type.new('image/jpeg')))
  147 + assert(!MIME::Type.new('text/plain').eql?('text/plain'))
  148 + assert(!MIME::Type.new('text/plain').eql?('image/jpeg'))
  149 + end
  150 +
  151 + def _test_encoding
  152 + raise NotImplementedError, 'Need to write test_encoding'
  153 + end
  154 +
  155 + def _test_encoding_equals
  156 + raise NotImplementedError, 'Need to write test_encoding_equals'
  157 + end
  158 +
  159 + def test_extensions
  160 + assert_nothing_raised do
  161 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  162 + 'linux')
  163 + end
  164 + assert_equal(@yaml.extensions, %w(yaml yml))
  165 + assert_nothing_raised { @yaml.extensions = 'yaml' }
  166 + assert_equal(@yaml.extensions, ['yaml'])
  167 + assert_equal(@zip.extensions.size, 2)
  168 + assert_equal(@zip.extensions, ['zip', 'zp'])
  169 + end
  170 +
  171 + def _test_extensions_equals
  172 + raise NotImplementedError, 'Need to write test_extensions_equals'
  173 + end
  174 +
  175 + def test_like_eh
  176 + assert(MIME::Type.new('text/plain').like?(MIME::Type.new('text/plain')))
  177 + assert(MIME::Type.new('text/plain').like?(MIME::Type.new('text/x-plain')))
  178 + assert(!MIME::Type.new('text/plain').like?(MIME::Type.new('image/jpeg')))
  179 + assert(MIME::Type.new('text/plain').like?('text/plain'))
  180 + assert(MIME::Type.new('text/plain').like?('text/x-plain'))
  181 + assert(!MIME::Type.new('text/plain').like?('image/jpeg'))
  182 + end
  183 +
  184 + def test_media_type
  185 + assert_equal(MIME::Type.new('text/plain').media_type, 'text')
  186 + assert_equal(MIME::Type.new('image/jpeg').media_type, 'image')
  187 + assert_equal(MIME::Type.new('application/x-msword').media_type, 'application')
  188 + assert_equal(MIME::Type.new('text/vCard').media_type, 'text')
  189 + assert_equal(MIME::Type.new('application/pkcs7-mime').media_type, 'application')
  190 + assert_equal(MIME::Type.new('x-chemical/x-pdb').media_type, 'chemical')
  191 + assert_equal(@zip.media_type, 'appl')
  192 + end
  193 +
  194 + def _test_obsolete_eh
  195 + raise NotImplementedError, 'Need to write test_obsolete_eh'
  196 + end
  197 +
  198 + def _test_obsolete_equals
  199 + raise NotImplementedError, 'Need to write test_obsolete_equals'
  200 + end
  201 +
  202 + def test_platform_eh
  203 + assert_nothing_raised do
  204 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  205 + 'oddbox')
  206 + end
  207 + assert(!@yaml.platform?)
  208 + assert_nothing_raised { @yaml.system = nil }
  209 + assert(!@yaml.platform?)
  210 + assert_nothing_raised { @yaml.system = /#{RUBY_PLATFORM}/ }
  211 + assert(@yaml.platform?)
  212 + end
  213 +
  214 + def test_raw_media_type
  215 + assert_equal(MIME::Type.new('text/plain').raw_media_type, 'text')
  216 + assert_equal(MIME::Type.new('image/jpeg').raw_media_type, 'image')
  217 + assert_equal(MIME::Type.new('application/x-msword').raw_media_type, 'application')
  218 + assert_equal(MIME::Type.new('text/vCard').raw_media_type, 'text')
  219 + assert_equal(MIME::Type.new('application/pkcs7-mime').raw_media_type, 'application')
  220 +
  221 + assert_equal(MIME::Type.new('x-chemical/x-pdb').raw_media_type, 'x-chemical')
  222 + assert_equal(@zip.raw_media_type, 'x-appl')
  223 + end
  224 +
  225 + def test_raw_sub_type
  226 + assert_equal(MIME::Type.new('text/plain').raw_sub_type, 'plain')
  227 + assert_equal(MIME::Type.new('image/jpeg').raw_sub_type, 'jpeg')
  228 + assert_equal(MIME::Type.new('application/x-msword').raw_sub_type, 'x-msword')
  229 + assert_equal(MIME::Type.new('text/vCard').raw_sub_type, 'vCard')
  230 + assert_equal(MIME::Type.new('application/pkcs7-mime').raw_sub_type, 'pkcs7-mime')
  231 + assert_equal(@zip.raw_sub_type, 'x-zip')
  232 + end
  233 +
  234 + def test_registered_eh
  235 + assert(MIME::Type.new('text/plain').registered?)
  236 + assert(MIME::Type.new('image/jpeg').registered?)
  237 + assert(!MIME::Type.new('application/x-msword').registered?)
  238 + assert(MIME::Type.new('text/vCard').registered?)
  239 + assert(MIME::Type.new('application/pkcs7-mime').registered?)
  240 + assert(!@zip.registered?)
  241 + end
  242 +
  243 + def _test_registered_equals
  244 + raise NotImplementedError, 'Need to write test_registered_equals'
  245 + end
  246 +
  247 + def test_signature_eh
  248 + assert(!MIME::Type.new('text/plain').signature?)
  249 + assert(!MIME::Type.new('image/jpeg').signature?)
  250 + assert(!MIME::Type.new('application/x-msword').signature?)
  251 + assert(MIME::Type.new('text/vCard').signature?)
  252 + assert(MIME::Type.new('application/pkcs7-mime').signature?)
  253 + end
  254 +
  255 + def test_simplified
  256 + assert_equal(MIME::Type.new('text/plain').simplified, 'text/plain')
  257 + assert_equal(MIME::Type.new('image/jpeg').simplified, 'image/jpeg')
  258 + assert_equal(MIME::Type.new('application/x-msword').simplified, 'application/msword')
  259 + assert_equal(MIME::Type.new('text/vCard').simplified, 'text/vcard')
  260 + assert_equal(MIME::Type.new('application/pkcs7-mime').simplified, 'application/pkcs7-mime')
  261 + assert_equal(MIME::Type.new('x-chemical/x-pdb').simplified, 'chemical/pdb')
  262 + end
  263 +
  264 + def test_sub_type
  265 + assert_equal(MIME::Type.new('text/plain').sub_type, 'plain')
  266 + assert_equal(MIME::Type.new('image/jpeg').sub_type, 'jpeg')
  267 + assert_equal(MIME::Type.new('application/x-msword').sub_type, 'msword')
  268 + assert_equal(MIME::Type.new('text/vCard').sub_type, 'vcard')
  269 + assert_equal(MIME::Type.new('application/pkcs7-mime').sub_type, 'pkcs7-mime')
  270 + assert_equal(@zip.sub_type, 'zip')
  271 + end
  272 +
  273 + def test_system_equals
  274 + assert_nothing_raised do
  275 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  276 + 'linux')
  277 + end
  278 + assert_equal(@yaml.system, %r{linux})
  279 + assert_nothing_raised { @yaml.system = /win32/ }
  280 + assert_equal(@yaml.system, %r{win32})
  281 + assert_nothing_raised { @yaml.system = nil }
  282 + assert_nil(@yaml.system)
  283 + end
  284 +
  285 + def test_system_eh
  286 + assert_nothing_raised do
  287 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  288 + 'linux')
  289 + end
  290 + assert(@yaml.system?)
  291 + assert_nothing_raised { @yaml.system = nil }
  292 + assert(!@yaml.system?)
  293 + end
  294 +
  295 + def test_to_a
  296 + assert_nothing_raised do
  297 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  298 + 'linux')
  299 + end
  300 + assert_equal(@yaml.to_a, ['text/x-yaml', %w(yaml yml), '8bit',
  301 + /linux/, nil, nil, nil, false])
  302 + end
  303 +
  304 + def test_to_hash
  305 + assert_nothing_raised do
  306 + @yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
  307 + 'linux')
  308 + end
  309 + assert_equal(@yaml.to_hash,
  310 + { 'Content-Type' => 'text/x-yaml',
  311 + 'Content-Transfer-Encoding' => '8bit',
  312 + 'Extensions' => %w(yaml yml),
  313 + 'System' => /linux/,
  314 + 'Registered' => false,
  315 + 'URL' => nil,
  316 + 'Obsolete' => nil,
  317 + 'Docs' => nil })
  318 + end
  319 +
  320 + def test_to_s
  321 + assert_equal("#{MIME::Type.new('text/plain')}", 'text/plain')
  322 + end
  323 +
  324 + def test_class_constructors
  325 + assert_not_nil(@zip)
  326 + yaml = MIME::Type.new('text/x-yaml') do |y|
  327 + y.extensions = %w(yaml yml)
  328 + y.encoding = '8bit'
  329 + y.system = 'linux'
  330 + end
  331 + assert_instance_of(MIME::Type, yaml)
  332 + assert_raises(MIME::InvalidContentType) { MIME::Type.new('apps') }
  333 + assert_raises(MIME::InvalidContentType) { MIME::Type.new(nil) }
  334 + end
  335 +
  336 + def _test_to_str
  337 + raise NotImplementedError, 'Need to write test_to_str'
  338 + end
  339 +
  340 + def _test_url
  341 + raise NotImplementedError, 'Need to write test_url'
  342 + end
  343 +
  344 + def _test_url_equals
  345 + raise NotImplementedError, 'Need to write test_url_equals'
  346 + end
  347 +
  348 + def _test_urls
  349 + raise NotImplementedError, 'Need to write test_urls'
  350 + end
  351 +
  352 + def __test_use_instead
  353 + raise NotImplementedError, 'Need to write test_use_instead'
  354 + end
  355 + end
  356 +end
... ...
vendor/gems/mime-types-1.16/test/test_mime_types.rb 0 → 100644
... ... @@ -0,0 +1,122 @@
  1 +#! /usr/bin/env ruby
  2 +#--
  3 +# MIME::Types
  4 +# A Ruby implementation of a MIME Types information library. Based in spirit
  5 +# on the Perl MIME::Types information library by Mark Overmeer.
  6 +# http://rubyforge.org/projects/mime-types/
  7 +#
  8 +# Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
  9 +# Artistic licence. See Licence.txt for more information.
  10 +#
  11 +# Copyright 2003 - 2009 Austin Ziegler
  12 +#++
  13 +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
  14 +
  15 +require 'mime/types'
  16 +require 'test/unit' unless defined? $ZENTEST and $ZENTEST
  17 +
  18 +module TestMIME
  19 + class TestTypes < Test::Unit::TestCase #:nodoc:
  20 + def test_class_index_1
  21 + text_plain = MIME::Type.new('text/plain') do |t|
  22 + t.encoding = '8bit'
  23 + t.extensions = %w(asc txt c cc h hh cpp hpp dat hlp)
  24 + end
  25 + text_plain_vms = MIME::Type.new('text/plain') do |t|
  26 + t.encoding = '8bit'
  27 + t.extensions = %w(doc)
  28 + t.system = 'vms'
  29 + end
  30 +
  31 + assert_equal(MIME::Types['text/plain'], [text_plain, text_plain_vms])
  32 + end
  33 +
  34 + def test_class_index_2
  35 + tst_bmp = MIME::Types["image/x-bmp"] +
  36 + MIME::Types["image/vnd.wap.wbmp"] + MIME::Types["image/x-win-bmp"]
  37 +
  38 + assert_equal(tst_bmp.sort, MIME::Types[/bmp$/].sort)
  39 +
  40 + assert_nothing_raised {
  41 + MIME::Types['image/bmp'][0].system = RUBY_PLATFORM
  42 + }
  43 +
  44 + assert_equal([MIME::Type.from_array('image/x-bmp', ['bmp'])],
  45 + MIME::Types[/bmp$/, { :platform => true }])
  46 + end
  47 +
  48 + def test_class_index_3
  49 + assert(MIME::Types['text/vnd.fly', { :complete => true }].empty?)
  50 + assert(!MIME::Types['text/plain', { :complete => true} ].empty?)
  51 + end
  52 +
  53 + def _test_class_index_extensions
  54 + raise NotImplementedError, 'Need to write test_class_index_extensions'
  55 + end
  56 +
  57 + def _test_class_add
  58 + assert_nothing_raised do
  59 + @eruby = MIME::Type.new("application/x-eruby") do |t|
  60 + t.extensions = "rhtml"
  61 + t.encoding = "8bit"
  62 + end
  63 +
  64 + MIME::Types.add(@eruby)
  65 + end
  66 +
  67 + assert_equal(MIME::Types['application/x-eruby'], [@eruby])
  68 + end
  69 +
  70 + def _test_class_add_type_variant
  71 + raise NotImplementedError, 'Need to write test_class_add_type_variant'
  72 + end
  73 +
  74 + def test_class_type_for
  75 + assert_equal(MIME::Types.type_for('xml').sort, [ MIME::Types['text/xml'], MIME::Types['application/xml'] ].sort)
  76 + assert_equal(MIME::Types.type_for('gif'), MIME::Types['image/gif'])
  77 + assert_nothing_raised do
  78 + MIME::Types['image/gif'][0].system = RUBY_PLATFORM
  79 + end
  80 + assert_equal(MIME::Types.type_for('gif', true), MIME::Types['image/gif'])
  81 + assert(MIME::Types.type_for('zzz').empty?)
  82 + end
  83 +
  84 + def test_class_of
  85 + assert_equal(MIME::Types.of('xml').sort, [ MIME::Types['text/xml'], MIME::Types['application/xml'] ].sort)
  86 + assert_equal(MIME::Types.of('gif'), MIME::Types['image/gif'])
  87 + assert_nothing_raised do
  88 + MIME::Types['image/gif'][0].system = RUBY_PLATFORM
  89 + end
  90 + assert_equal(MIME::Types.of('gif', true), MIME::Types['image/gif'])
  91 + assert(MIME::Types.of('zzz').empty?)
  92 + end
  93 +
  94 + def _test_add
  95 + raise NotImplementedError, 'Need to write test_add'
  96 + end
  97 +
  98 + def _test_add_type_variant
  99 + raise NotImplementedError, 'Need to write test_add_type_variant'
  100 + end
  101 +
  102 + def _test_data_version
  103 + raise NotImplementedError, 'Need to write test_data_version'
  104 + end
  105 +
  106 + def _test_index
  107 + raise NotImplementedError, 'Need to write test_index'
  108 + end
  109 +
  110 + def _test_index_extensions
  111 + raise NotImplementedError, 'Need to write test_index_extensions'
  112 + end
  113 +
  114 + def _test_of
  115 + raise NotImplementedError, 'Need to write test_of'
  116 + end
  117 +
  118 + def _test_type_for
  119 + raise NotImplementedError, 'Need to write test_type_for'
  120 + end
  121 + end
  122 +end
... ...
vendor/gems/xml-simple-1.0.12/.specification 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +--- !ruby/object:Gem::Specification
  2 +name: xml-simple
  3 +version: !ruby/object:Gem::Version
  4 + version: 1.0.12
  5 +platform: ruby
  6 +authors:
  7 +- Maik Schmidt
  8 +autorequire:
  9 +bindir: bin
  10 +cert_chain: []
  11 +
  12 +date: 2009-02-26 00:00:00 -05:00
  13 +default_executable:
  14 +dependencies: []
  15 +
  16 +description:
  17 +email: contact@maik-schmidt.de
  18 +executables: []
  19 +
  20 +extensions: []
  21 +
  22 +extra_rdoc_files: []
  23 +
  24 +files:
  25 +- lib/xmlsimple.rb
  26 +has_rdoc: true
  27 +homepage: http://xml-simple.rubyforge.org
  28 +licenses: []
  29 +
  30 +post_install_message:
  31 +rdoc_options: []
  32 +
  33 +require_paths:
  34 +- bin
  35 +- lib
  36 +required_ruby_version: !ruby/object:Gem::Requirement
  37 + requirements:
  38 + - - ">="
  39 + - !ruby/object:Gem::Version
  40 + version: "0"
  41 + version:
  42 +required_rubygems_version: !ruby/object:Gem::Requirement
  43 + requirements:
  44 + - - ">="
  45 + - !ruby/object:Gem::Version
  46 + version: "0"
  47 + version:
  48 +requirements: []
  49 +
  50 +rubyforge_project: xml-simple
  51 +rubygems_version: 1.3.4
  52 +signing_key:
  53 +specification_version: 2
  54 +summary: A simple API for XML processing.
  55 +test_files: []
  56 +
... ...
vendor/gems/xml-simple-1.0.12/lib/xmlsimple.rb 0 → 100755
... ... @@ -0,0 +1,1028 @@
  1 +# = XmlSimple
  2 +#
  3 +# Author:: Maik Schmidt <contact@maik-schmidt.de>
  4 +# Copyright:: Copyright (c) 2003-2009 Maik Schmidt
  5 +# License:: Distributes under the same terms as Ruby.
  6 +#
  7 +require 'rexml/document'
  8 +require 'stringio'
  9 +
  10 +# Easy API to maintain XML (especially configuration files).
  11 +class XmlSimple
  12 + include REXML
  13 +
  14 + @@VERSION = '1.0.12'
  15 +
  16 + # A simple cache for XML documents that were already transformed
  17 + # by xml_in.
  18 + class Cache
  19 + # Creates and initializes a new Cache object.
  20 + def initialize
  21 + @mem_share_cache = {}
  22 + @mem_copy_cache = {}
  23 + end
  24 +
  25 + # Saves a data structure into a file.
  26 + #
  27 + # data::
  28 + # Data structure to be saved.
  29 + # filename::
  30 + # Name of the file belonging to the data structure.
  31 + def save_storable(data, filename)
  32 + cache_file = get_cache_filename(filename)
  33 + File.open(cache_file, "w+") { |f| Marshal.dump(data, f) }
  34 + end
  35 +
  36 + # Restores a data structure from a file. If restoring the data
  37 + # structure failed for any reason, nil will be returned.
  38 + #
  39 + # filename::
  40 + # Name of the file belonging to the data structure.
  41 + def restore_storable(filename)
  42 + cache_file = get_cache_filename(filename)
  43 + return nil unless File::exist?(cache_file)
  44 + return nil unless File::mtime(cache_file).to_i > File::mtime(filename).to_i
  45 + data = nil
  46 + File.open(cache_file) { |f| data = Marshal.load(f) }
  47 + data
  48 + end
  49 +
  50 + # Saves a data structure in a shared memory cache.
  51 + #
  52 + # data::
  53 + # Data structure to be saved.
  54 + # filename::
  55 + # Name of the file belonging to the data structure.
  56 + def save_mem_share(data, filename)
  57 + @mem_share_cache[filename] = [Time::now.to_i, data]
  58 + end
  59 +
  60 + # Restores a data structure from a shared memory cache. You
  61 + # should consider these elements as "read only". If restoring
  62 + # the data structure failed for any reason, nil will be
  63 + # returned.
  64 + #
  65 + # filename::
  66 + # Name of the file belonging to the data structure.
  67 + def restore_mem_share(filename)
  68 + get_from_memory_cache(filename, @mem_share_cache)
  69 + end
  70 +
  71 + # Copies a data structure to a memory cache.
  72 + #
  73 + # data::
  74 + # Data structure to be copied.
  75 + # filename::
  76 + # Name of the file belonging to the data structure.
  77 + def save_mem_copy(data, filename)
  78 + @mem_share_cache[filename] = [Time::now.to_i, Marshal.dump(data)]
  79 + end
  80 +
  81 + # Restores a data structure from a memory cache. If restoring
  82 + # the data structure failed for any reason, nil will be
  83 + # returned.
  84 + #
  85 + # filename::
  86 + # Name of the file belonging to the data structure.
  87 + def restore_mem_copy(filename)
  88 + data = get_from_memory_cache(filename, @mem_share_cache)
  89 + data = Marshal.load(data) unless data.nil?
  90 + data
  91 + end
  92 +
  93 + private
  94 +
  95 + # Returns the "cache filename" belonging to a filename, i.e.
  96 + # the extension '.xml' in the original filename will be replaced
  97 + # by '.stor'. If filename does not have this extension, '.stor'
  98 + # will be appended.
  99 + #
  100 + # filename::
  101 + # Filename to get "cache filename" for.
  102 + def get_cache_filename(filename)
  103 + filename.sub(/(\.xml)?$/, '.stor')
  104 + end
  105 +
  106 + # Returns a cache entry from a memory cache belonging to a
  107 + # certain filename. If no entry could be found for any reason,
  108 + # nil will be returned.
  109 + #
  110 + # filename::
  111 + # Name of the file the cache entry belongs to.
  112 + # cache::
  113 + # Memory cache to get entry from.
  114 + def get_from_memory_cache(filename, cache)
  115 + return nil unless cache[filename]
  116 + return nil unless cache[filename][0] > File::mtime(filename).to_i
  117 + return cache[filename][1]
  118 + end
  119 + end
  120 +
  121 + # Create a "global" cache.
  122 + @@cache = Cache.new
  123 +
  124 + # Creates and intializes a new XmlSimple object.
  125 + #
  126 + # defaults::
  127 + # Default values for options.
  128 + def initialize(defaults = nil)
  129 + unless defaults.nil? || defaults.instance_of?(Hash)
  130 + raise ArgumentError, "Options have to be a Hash."
  131 + end
  132 + @default_options = normalize_option_names(defaults, (KNOWN_OPTIONS['in'] + KNOWN_OPTIONS['out']).uniq)
  133 + @options = Hash.new
  134 + @_var_values = nil
  135 + end
  136 +
  137 + # Converts an XML document in the same way as the Perl module XML::Simple.
  138 + #
  139 + # string::
  140 + # XML source. Could be one of the following:
  141 + #
  142 + # - nil: Tries to load and parse '<scriptname>.xml'.
  143 + # - filename: Tries to load and parse filename.
  144 + # - IO object: Reads from object until EOF is detected and parses result.
  145 + # - XML string: Parses string.
  146 + #
  147 + # options::
  148 + # Options to be used.
  149 + def xml_in(string = nil, options = nil)
  150 + handle_options('in', options)
  151 +
  152 + # If no XML string or filename was supplied look for scriptname.xml.
  153 + if string.nil?
  154 + string = File::basename($0).dup
  155 + string.sub!(/\.[^.]+$/, '')
  156 + string += '.xml'
  157 +
  158 + directory = File::dirname($0)
  159 + @options['searchpath'].unshift(directory) unless directory.nil?
  160 + end
  161 +
  162 + if string.instance_of?(String)
  163 + if string =~ /<.*?>/m
  164 + @doc = parse(string)
  165 + elsif string == '-'
  166 + @doc = parse($stdin.read)
  167 + else
  168 + filename = find_xml_file(string, @options['searchpath'])
  169 +
  170 + if @options.has_key?('cache')
  171 + @options['cache'].each { |scheme|
  172 + case(scheme)
  173 + when 'storable'
  174 + content = @@cache.restore_storable(filename)
  175 + when 'mem_share'
  176 + content = @@cache.restore_mem_share(filename)
  177 + when 'mem_copy'
  178 + content = @@cache.restore_mem_copy(filename)
  179 + else
  180 + raise ArgumentError, "Unsupported caching scheme: <#{scheme}>."
  181 + end
  182 + return content if content
  183 + }
  184 + end
  185 +
  186 + @doc = load_xml_file(filename)
  187 + end
  188 + elsif string.kind_of?(IO) || string.kind_of?(StringIO) || string.kind_of?(Zlib::GzipReader)
  189 + @doc = parse(string.read)
  190 + else
  191 + raise ArgumentError, "Could not parse object of type: <#{string.type}>."
  192 + end
  193 +
  194 + result = collapse(@doc.root)
  195 + result = @options['keeproot'] ? merge({}, @doc.root.name, result) : result
  196 + put_into_cache(result, filename)
  197 + result
  198 + end
  199 +
  200 + # This is the functional version of the instance method xml_in.
  201 + def XmlSimple.xml_in(string = nil, options = nil)
  202 + xml_simple = XmlSimple.new
  203 + xml_simple.xml_in(string, options)
  204 + end
  205 +
  206 + # Converts a data structure into an XML document.
  207 + #
  208 + # ref::
  209 + # Reference to data structure to be converted into XML.
  210 + # options::
  211 + # Options to be used.
  212 + def xml_out(ref, options = nil)
  213 + handle_options('out', options)
  214 + if ref.instance_of?(Array)
  215 + ref = { @options['anonymoustag'] => ref }
  216 + end
  217 +
  218 + if @options['keeproot']
  219 + keys = ref.keys
  220 + if keys.size == 1
  221 + ref = ref[keys[0]]
  222 + @options['rootname'] = keys[0]
  223 + end
  224 + elsif @options['rootname'] == ''
  225 + if ref.instance_of?(Hash)
  226 + refsave = ref
  227 + ref = {}
  228 + refsave.each { |key, value|
  229 + if !scalar(value)
  230 + ref[key] = value
  231 + else
  232 + ref[key] = [ value.to_s ]
  233 + end
  234 + }
  235 + end
  236 + end
  237 +
  238 + @ancestors = []
  239 + xml = value_to_xml(ref, @options['rootname'], '')
  240 + @ancestors = nil
  241 +
  242 + if @options['xmldeclaration']
  243 + xml = @options['xmldeclaration'] + "\n" + xml
  244 + end
  245 +
  246 + if @options.has_key?('outputfile')
  247 + if @options['outputfile'].kind_of?(IO)
  248 + return @options['outputfile'].write(xml)
  249 + else
  250 + File.open(@options['outputfile'], "w") { |file| file.write(xml) }
  251 + end
  252 + end
  253 + xml
  254 + end
  255 +
  256 + # This is the functional version of the instance method xml_out.
  257 + def XmlSimple.xml_out(hash, options = nil)
  258 + xml_simple = XmlSimple.new
  259 + xml_simple.xml_out(hash, options)
  260 + end
  261 +
  262 + private
  263 +
  264 + # Declare options that are valid for xml_in and xml_out.
  265 + KNOWN_OPTIONS = {
  266 + 'in' => %w(
  267 + keyattr keeproot forcecontent contentkey noattr
  268 + searchpath forcearray suppressempty anonymoustag
  269 + cache grouptags normalisespace normalizespace
  270 + variables varattr keytosymbol attrprefix
  271 + ),
  272 + 'out' => %w(
  273 + keyattr keeproot contentkey noattr rootname
  274 + xmldeclaration outputfile noescape suppressempty
  275 + anonymoustag indent grouptags noindent attrprefix
  276 + )
  277 + }
  278 +
  279 + # Define some reasonable defaults.
  280 + DEF_KEY_ATTRIBUTES = []
  281 + DEF_ROOT_NAME = 'opt'
  282 + DEF_CONTENT_KEY = 'content'
  283 + DEF_XML_DECLARATION = "<?xml version='1.0' standalone='yes'?>"
  284 + DEF_ANONYMOUS_TAG = 'anon'
  285 + DEF_FORCE_ARRAY = true
  286 + DEF_INDENTATION = ' '
  287 + DEF_KEY_TO_SYMBOL = false
  288 +
  289 + # Normalizes option names in a hash, i.e., turns all
  290 + # characters to lower case and removes all underscores.
  291 + # Additionally, this method checks, if an unknown option
  292 + # was used and raises an according exception.
  293 + #
  294 + # options::
  295 + # Hash to be normalized.
  296 + # known_options::
  297 + # List of known options.
  298 + def normalize_option_names(options, known_options)
  299 + return nil if options.nil?
  300 + result = Hash.new
  301 + options.each { |key, value|
  302 + lkey = key.downcase
  303 + lkey.gsub!(/_/, '')
  304 + if !known_options.member?(lkey)
  305 + raise ArgumentError, "Unrecognised option: #{lkey}."
  306 + end
  307 + result[lkey] = value
  308 + }
  309 + result
  310 + end
  311 +
  312 + # Merges a set of options with the default options.
  313 + #
  314 + # direction::
  315 + # 'in': If options should be handled for xml_in.
  316 + # 'out': If options should be handled for xml_out.
  317 + # options::
  318 + # Options to be merged with the default options.
  319 + def handle_options(direction, options)
  320 + @options = options || Hash.new
  321 +
  322 + raise ArgumentError, "Options must be a Hash!" unless @options.instance_of?(Hash)
  323 +
  324 + unless KNOWN_OPTIONS.has_key?(direction)
  325 + raise ArgumentError, "Unknown direction: <#{direction}>."
  326 + end
  327 +
  328 + known_options = KNOWN_OPTIONS[direction]
  329 + @options = normalize_option_names(@options, known_options)
  330 +
  331 + unless @default_options.nil?
  332 + known_options.each { |option|
  333 + unless @options.has_key?(option)
  334 + if @default_options.has_key?(option)
  335 + @options[option] = @default_options[option]
  336 + end
  337 + end
  338 + }
  339 + end
  340 +
  341 + unless @options.has_key?('noattr')
  342 + @options['noattr'] = false
  343 + end
  344 +
  345 + if @options.has_key?('rootname')
  346 + @options['rootname'] = '' if @options['rootname'].nil?
  347 + else
  348 + @options['rootname'] = DEF_ROOT_NAME
  349 + end
  350 +
  351 + if @options.has_key?('xmldeclaration') && @options['xmldeclaration'] == true
  352 + @options['xmldeclaration'] = DEF_XML_DECLARATION
  353 + end
  354 +
  355 + @options['keytosymbol'] = DEF_KEY_TO_SYMBOL unless @options.has_key?('keytosymbol')
  356 +
  357 + if @options.has_key?('contentkey')
  358 + if @options['contentkey'] =~ /^-(.*)$/
  359 + @options['contentkey'] = $1
  360 + @options['collapseagain'] = true
  361 + end
  362 + else
  363 + @options['contentkey'] = DEF_CONTENT_KEY
  364 + end
  365 +
  366 + unless @options.has_key?('normalisespace')
  367 + @options['normalisespace'] = @options['normalizespace']
  368 + end
  369 + @options['normalisespace'] = 0 if @options['normalisespace'].nil?
  370 +
  371 + if @options.has_key?('searchpath')
  372 + unless @options['searchpath'].instance_of?(Array)
  373 + @options['searchpath'] = [ @options['searchpath'] ]
  374 + end
  375 + else
  376 + @options['searchpath'] = []
  377 + end
  378 +
  379 + if @options.has_key?('cache') && scalar(@options['cache'])
  380 + @options['cache'] = [ @options['cache'] ]
  381 + end
  382 +
  383 + @options['anonymoustag'] = DEF_ANONYMOUS_TAG unless @options.has_key?('anonymoustag')
  384 +
  385 + if !@options.has_key?('indent') || @options['indent'].nil?
  386 + @options['indent'] = DEF_INDENTATION
  387 + end
  388 +
  389 + @options['indent'] = '' if @options.has_key?('noindent')
  390 +
  391 + # Special cleanup for 'keyattr' which could be an array or
  392 + # a hash or left to default to array.
  393 + if @options.has_key?('keyattr')
  394 + if !scalar(@options['keyattr'])
  395 + # Convert keyattr => { elem => '+attr' }
  396 + # to keyattr => { elem => ['attr', '+'] }
  397 + if @options['keyattr'].instance_of?(Hash)
  398 + @options['keyattr'].each { |key, value|
  399 + if value =~ /^([-+])?(.*)$/
  400 + @options['keyattr'][key] = [$2, $1 ? $1 : '']
  401 + end
  402 + }
  403 + elsif !@options['keyattr'].instance_of?(Array)
  404 + raise ArgumentError, "'keyattr' must be String, Hash, or Array!"
  405 + end
  406 + else
  407 + @options['keyattr'] = [ @options['keyattr'] ]
  408 + end
  409 + else
  410 + @options['keyattr'] = DEF_KEY_ATTRIBUTES
  411 + end
  412 +
  413 + if @options.has_key?('forcearray')
  414 + if @options['forcearray'].instance_of?(Regexp)
  415 + @options['forcearray'] = [ @options['forcearray'] ]
  416 + end
  417 +
  418 + if @options['forcearray'].instance_of?(Array)
  419 + force_list = @options['forcearray']
  420 + unless force_list.empty?
  421 + @options['forcearray'] = {}
  422 + force_list.each { |tag|
  423 + if tag.instance_of?(Regexp)
  424 + unless @options['forcearray']['_regex'].instance_of?(Array)
  425 + @options['forcearray']['_regex'] = []
  426 + end
  427 + @options['forcearray']['_regex'] << tag
  428 + else
  429 + @options['forcearray'][tag] = true
  430 + end
  431 + }
  432 + else
  433 + @options['forcearray'] = false
  434 + end
  435 + else
  436 + @options['forcearray'] = @options['forcearray'] ? true : false
  437 + end
  438 + else
  439 + @options['forcearray'] = DEF_FORCE_ARRAY
  440 + end
  441 +
  442 + if @options.has_key?('grouptags') && !@options['grouptags'].instance_of?(Hash)
  443 + raise ArgumentError, "Illegal value for 'GroupTags' option - expected a Hash."
  444 + end
  445 +
  446 + if @options.has_key?('variables') && !@options['variables'].instance_of?(Hash)
  447 + raise ArgumentError, "Illegal value for 'Variables' option - expected a Hash."
  448 + end
  449 +
  450 + if @options.has_key?('variables')
  451 + @_var_values = @options['variables']
  452 + elsif @options.has_key?('varattr')
  453 + @_var_values = {}
  454 + end
  455 + end
  456 +
  457 + # Actually converts an XML document element into a data structure.
  458 + #
  459 + # element::
  460 + # The document element to be collapsed.
  461 + def collapse(element)
  462 + result = @options['noattr'] ? {} : get_attributes(element)
  463 +
  464 + if @options['normalisespace'] == 2
  465 + result.each { |k, v| result[k] = normalise_space(v) }
  466 + end
  467 +
  468 + if element.has_elements?
  469 + element.each_element { |child|
  470 + value = collapse(child)
  471 + if empty(value) && (element.attributes.empty? || @options['noattr'])
  472 + next if @options.has_key?('suppressempty') && @options['suppressempty'] == true
  473 + end
  474 + result = merge(result, child.name, value)
  475 + }
  476 + if has_mixed_content?(element)
  477 + # normalisespace?
  478 + content = element.texts.map { |x| x.to_s }
  479 + content = content[0] if content.size == 1
  480 + result[@options['contentkey']] = content
  481 + end
  482 + elsif element.has_text? # i.e. it has only text.
  483 + return collapse_text_node(result, element)
  484 + end
  485 +
  486 + # Turn Arrays into Hashes if key fields present.
  487 + count = fold_arrays(result)
  488 +
  489 + # Disintermediate grouped tags.
  490 + if @options.has_key?('grouptags')
  491 + result.each { |key, value|
  492 + next unless (value.instance_of?(Hash) && (value.size == 1))
  493 + child_key, child_value = value.to_a[0]
  494 + if @options['grouptags'][key] == child_key
  495 + result[key] = child_value
  496 + end
  497 + }
  498 + end
  499 +
  500 + # Fold Hashes containing a single anonymous Array up into just the Array.
  501 + if count == 1
  502 + anonymoustag = @options['anonymoustag']
  503 + if result.has_key?(anonymoustag) && result[anonymoustag].instance_of?(Array)
  504 + return result[anonymoustag]
  505 + end
  506 + end
  507 +
  508 + if result.empty? && @options.has_key?('suppressempty')
  509 + return @options['suppressempty'] == '' ? '' : nil
  510 + end
  511 +
  512 + result
  513 + end
  514 +
  515 + # Collapses a text node and merges it with an existing Hash, if
  516 + # possible.
  517 + # Thanks to Curtis Schofield for reporting a subtle bug.
  518 + #
  519 + # hash::
  520 + # Hash to merge text node value with, if possible.
  521 + # element::
  522 + # Text node to be collapsed.
  523 + def collapse_text_node(hash, element)
  524 + value = node_to_text(element)
  525 + if empty(value) && !element.has_attributes?
  526 + return {}
  527 + end
  528 +
  529 + if element.has_attributes? && !@options['noattr']
  530 + return merge(hash, @options['contentkey'], value)
  531 + else
  532 + if @options['forcecontent']
  533 + return merge(hash, @options['contentkey'], value)
  534 + else
  535 + return value
  536 + end
  537 + end
  538 + end
  539 +
  540 + # Folds all arrays in a Hash.
  541 + #
  542 + # hash::
  543 + # Hash to be folded.
  544 + def fold_arrays(hash)
  545 + fold_amount = 0
  546 + keyattr = @options['keyattr']
  547 + if (keyattr.instance_of?(Array) || keyattr.instance_of?(Hash))
  548 + hash.each { |key, value|
  549 + if value.instance_of?(Array)
  550 + if keyattr.instance_of?(Array)
  551 + hash[key] = fold_array(value)
  552 + else
  553 + hash[key] = fold_array_by_name(key, value)
  554 + end
  555 + fold_amount += 1
  556 + end
  557 + }
  558 + end
  559 + fold_amount
  560 + end
  561 +
  562 + # Folds an Array to a Hash, if possible. Folding happens
  563 + # according to the content of keyattr, which has to be
  564 + # an array.
  565 + #
  566 + # array::
  567 + # Array to be folded.
  568 + def fold_array(array)
  569 + hash = Hash.new
  570 + array.each { |x|
  571 + return array unless x.instance_of?(Hash)
  572 + key_matched = false
  573 + @options['keyattr'].each { |key|
  574 + if x.has_key?(key)
  575 + key_matched = true
  576 + value = x[key]
  577 + return array if value.instance_of?(Hash) || value.instance_of?(Array)
  578 + value = normalise_space(value) if @options['normalisespace'] == 1
  579 + x.delete(key)
  580 + hash[value] = x
  581 + break
  582 + end
  583 + }
  584 + return array unless key_matched
  585 + }
  586 + hash = collapse_content(hash) if @options['collapseagain']
  587 + hash
  588 + end
  589 +
  590 + # Folds an Array to a Hash, if possible. Folding happens
  591 + # according to the content of keyattr, which has to be
  592 + # a Hash.
  593 + #
  594 + # name::
  595 + # Name of the attribute to be folded upon.
  596 + # array::
  597 + # Array to be folded.
  598 + def fold_array_by_name(name, array)
  599 + return array unless @options['keyattr'].has_key?(name)
  600 + key, flag = @options['keyattr'][name]
  601 +
  602 + hash = Hash.new
  603 + array.each { |x|
  604 + if x.instance_of?(Hash) && x.has_key?(key)
  605 + value = x[key]
  606 + return array if value.instance_of?(Hash) || value.instance_of?(Array)
  607 + value = normalise_space(value) if @options['normalisespace'] == 1
  608 + hash[value] = x
  609 + hash[value]["-#{key}"] = hash[value][key] if flag == '-'
  610 + hash[value].delete(key) unless flag == '+'
  611 + else
  612 + $stderr.puts("Warning: <#{name}> element has no '#{key}' attribute.")
  613 + return array
  614 + end
  615 + }
  616 + hash = collapse_content(hash) if @options['collapseagain']
  617 + hash
  618 + end
  619 +
  620 + # Tries to collapse a Hash even more ;-)
  621 + #
  622 + # hash::
  623 + # Hash to be collapsed again.
  624 + def collapse_content(hash)
  625 + content_key = @options['contentkey']
  626 + hash.each_value { |value|
  627 + return hash unless value.instance_of?(Hash) && value.size == 1 && value.has_key?(content_key)
  628 + hash.each_key { |key| hash[key] = hash[key][content_key] }
  629 + }
  630 + hash
  631 + end
  632 +
  633 + # Adds a new key/value pair to an existing Hash. If the key to be added
  634 + # does already exist and the existing value associated with key is not
  635 + # an Array, it will be converted into an Array. Then the new value is
  636 + # appended to that Array.
  637 + #
  638 + # hash::
  639 + # Hash to add key/value pair to.
  640 + # key::
  641 + # Key to be added.
  642 + # value::
  643 + # Value to be associated with key.
  644 + def merge(hash, key, value)
  645 + if value.instance_of?(String)
  646 + value = normalise_space(value) if @options['normalisespace'] == 2
  647 +
  648 + # do variable substitutions
  649 + unless @_var_values.nil? || @_var_values.empty?
  650 + value.gsub!(/\$\{(\w+)\}/) { |x| get_var($1) }
  651 + end
  652 +
  653 + # look for variable definitions
  654 + if @options.has_key?('varattr')
  655 + varattr = @options['varattr']
  656 + if hash.has_key?(varattr)
  657 + set_var(hash[varattr], value)
  658 + end
  659 + end
  660 + end
  661 +
  662 + #patch for converting keys to symbols
  663 + if @options.has_key?('keytosymbol')
  664 + if @options['keytosymbol'] == true
  665 + key = key.to_s.downcase.to_sym
  666 + end
  667 + end
  668 +
  669 + if hash.has_key?(key)
  670 + if hash[key].instance_of?(Array)
  671 + hash[key] << value
  672 + else
  673 + hash[key] = [ hash[key], value ]
  674 + end
  675 + elsif value.instance_of?(Array) # Handle anonymous arrays.
  676 + hash[key] = [ value ]
  677 + else
  678 + if force_array?(key)
  679 + hash[key] = [ value ]
  680 + else
  681 + hash[key] = value
  682 + end
  683 + end
  684 + hash
  685 + end
  686 +
  687 + # Checks, if the 'forcearray' option has to be used for
  688 + # a certain key.
  689 + def force_array?(key)
  690 + return false if key == @options['contentkey']
  691 + return true if @options['forcearray'] == true
  692 + forcearray = @options['forcearray']
  693 + if forcearray.instance_of?(Hash)
  694 + return true if forcearray.has_key?(key)
  695 + return false unless forcearray.has_key?('_regex')
  696 + forcearray['_regex'].each { |x| return true if key =~ x }
  697 + end
  698 + return false
  699 + end
  700 +
  701 + # Converts the attributes array of a document node into a Hash.
  702 + # Returns an empty Hash, if node has no attributes.
  703 + #
  704 + # node::
  705 + # Document node to extract attributes from.
  706 + def get_attributes(node)
  707 + attributes = {}
  708 + if @options['attrprefix']
  709 + node.attributes.each { |n,v| attributes["@" + n] = v }
  710 + else
  711 + node.attributes.each { |n,v| attributes[n] = v }
  712 + end
  713 + attributes
  714 + end
  715 +
  716 + # Determines, if a document element has mixed content.
  717 + #
  718 + # element::
  719 + # Document element to be checked.
  720 + def has_mixed_content?(element)
  721 + if element.has_text? && element.has_elements?
  722 + return true if element.texts.join('') !~ /^\s*$/s
  723 + end
  724 + false
  725 + end
  726 +
  727 + # Called when a variable definition is encountered in the XML.
  728 + # A variable definition looks like
  729 + # <element attrname="name">value</element>
  730 + # where attrname matches the varattr setting.
  731 + def set_var(name, value)
  732 + @_var_values[name] = value
  733 + end
  734 +
  735 + # Called during variable substitution to get the value for the
  736 + # named variable.
  737 + def get_var(name)
  738 + if @_var_values.has_key?(name)
  739 + return @_var_values[name]
  740 + else
  741 + return "${#{name}}"
  742 + end
  743 + end
  744 +
  745 + # Recurses through a data structure building up and returning an
  746 + # XML representation of that structure as a string.
  747 + #
  748 + # ref::
  749 + # Reference to the data structure to be encoded.
  750 + # name::
  751 + # The XML tag name to be used for this item.
  752 + # indent::
  753 + # A string of spaces for use as the current indent level.
  754 + def value_to_xml(ref, name, indent)
  755 + named = !name.nil? && name != ''
  756 + nl = @options.has_key?('noindent') ? '' : "\n"
  757 +
  758 + if !scalar(ref)
  759 + if @ancestors.member?(ref)
  760 + raise ArgumentError, "Circular data structures not supported!"
  761 + end
  762 + @ancestors << ref
  763 + else
  764 + if named
  765 + return [indent, '<', name, '>', @options['noescape'] ? ref.to_s : escape_value(ref.to_s), '</', name, '>', nl].join('')
  766 + else
  767 + return ref.to_s + nl
  768 + end
  769 + end
  770 +
  771 + # Unfold hash to array if possible.
  772 + if ref.instance_of?(Hash) && !ref.empty? && !@options['keyattr'].empty? && indent != ''
  773 + ref = hash_to_array(name, ref)
  774 + end
  775 +
  776 + result = []
  777 + if ref.instance_of?(Hash)
  778 + # Reintermediate grouped values if applicable.
  779 + if @options.has_key?('grouptags')
  780 + ref.each { |key, value|
  781 + if @options['grouptags'].has_key?(key)
  782 + ref[key] = { @options['grouptags'][key] => value }
  783 + end
  784 + }
  785 + end
  786 +
  787 + nested = []
  788 + text_content = nil
  789 + if named
  790 + result << indent << '<' << name
  791 + end
  792 +
  793 + if !ref.empty?
  794 + ref.each { |key, value|
  795 + next if !key.nil? && key[0, 1] == '-'
  796 + if value.nil?
  797 + unless @options.has_key?('suppressempty') && @options['suppressempty'].nil?
  798 + raise ArgumentError, "Use of uninitialized value!"
  799 + end
  800 + value = {}
  801 + end
  802 +
  803 + # Check for the '@' attribute prefix to allow separation of attributes and elements
  804 + if @options['noattr'] ||
  805 + (@options['attrprefix'] && !(key =~ /^@(.*)/)) ||
  806 + !scalar(value)
  807 + nested << value_to_xml(value, key, indent + @options['indent'])
  808 + else
  809 + value = value.to_s
  810 + value = escape_value(value) unless @options['noescape']
  811 + if key == @options['contentkey']
  812 + text_content = value
  813 + else
  814 + result << ' ' << ($1||key) << '="' << value << '"'
  815 + end
  816 + end
  817 + }
  818 + else
  819 + text_content = ''
  820 + end
  821 +
  822 + if !nested.empty? || !text_content.nil?
  823 + if named
  824 + result << '>'
  825 + if !text_content.nil?
  826 + result << text_content
  827 + nested[0].sub!(/^\s+/, '') if !nested.empty?
  828 + else
  829 + result << nl
  830 + end
  831 + if !nested.empty?
  832 + result << nested << indent
  833 + end
  834 + result << '</' << name << '>' << nl
  835 + else
  836 + result << nested
  837 + end
  838 + else
  839 + result << ' />' << nl
  840 + end
  841 + elsif ref.instance_of?(Array)
  842 + ref.each { |value|
  843 + if scalar(value)
  844 + result << indent << '<' << name << '>'
  845 + result << (@options['noescape'] ? value.to_s : escape_value(value.to_s))
  846 + result << '</' << name << '>' << nl
  847 + elsif value.instance_of?(Hash)
  848 + result << value_to_xml(value, name, indent)
  849 + else
  850 + result << indent << '<' << name << '>' << nl
  851 + result << value_to_xml(value, @options['anonymoustag'], indent + @options['indent'])
  852 + result << indent << '</' << name << '>' << nl
  853 + end
  854 + }
  855 + else
  856 + # Probably, this is obsolete.
  857 + raise ArgumentError, "Can't encode a value of type: #{ref.type}."
  858 + end
  859 + @ancestors.pop if !scalar(ref)
  860 + result.join('')
  861 + end
  862 +
  863 + # Checks, if a certain value is a "scalar" value. Whatever
  864 + # that will be in Ruby ... ;-)
  865 + #
  866 + # value::
  867 + # Value to be checked.
  868 + def scalar(value)
  869 + return false if value.instance_of?(Hash) || value.instance_of?(Array)
  870 + return true
  871 + end
  872 +
  873 + # Attempts to unfold a hash of hashes into an array of hashes. Returns
  874 + # a reference to th array on success or the original hash, if unfolding
  875 + # is not possible.
  876 + #
  877 + # parent::
  878 + #
  879 + # hashref::
  880 + # Reference to the hash to be unfolded.
  881 + def hash_to_array(parent, hashref)
  882 + arrayref = []
  883 + hashref.each { |key, value|
  884 + return hashref unless value.instance_of?(Hash)
  885 +
  886 + if @options['keyattr'].instance_of?(Hash)
  887 + return hashref unless @options['keyattr'].has_key?(parent)
  888 + arrayref << { @options['keyattr'][parent][0] => key }.update(value)
  889 + else
  890 + arrayref << { @options['keyattr'][0] => key }.update(value)
  891 + end
  892 + }
  893 + arrayref
  894 + end
  895 +
  896 + # Replaces XML markup characters by their external entities.
  897 + #
  898 + # data::
  899 + # The string to be escaped.
  900 + def escape_value(data)
  901 + Text::normalize(data)
  902 + end
  903 +
  904 + # Removes leading and trailing whitespace and sequences of
  905 + # whitespaces from a string.
  906 + #
  907 + # text::
  908 + # String to be normalised.
  909 + def normalise_space(text)
  910 + text.strip.gsub(/\s\s+/, ' ')
  911 + end
  912 +
  913 + # Checks, if an object is nil, an empty String or an empty Hash.
  914 + # Thanks to Norbert Gawor for a bugfix.
  915 + #
  916 + # value::
  917 + # Value to be checked for emptyness.
  918 + def empty(value)
  919 + case value
  920 + when Hash
  921 + return value.empty?
  922 + when String
  923 + return value !~ /\S/m
  924 + else
  925 + return value.nil?
  926 + end
  927 + end
  928 +
  929 + # Converts a document node into a String.
  930 + # If the node could not be converted into a String
  931 + # for any reason, default will be returned.
  932 + #
  933 + # node::
  934 + # Document node to be converted.
  935 + # default::
  936 + # Value to be returned, if node could not be converted.
  937 + def node_to_text(node, default = nil)
  938 + if node.instance_of?(REXML::Element)
  939 + node.texts.map { |t| t.value }.join('')
  940 + elsif node.instance_of?(REXML::Attribute)
  941 + node.value.nil? ? default : node.value.strip
  942 + elsif node.instance_of?(REXML::Text)
  943 + node.value.strip
  944 + else
  945 + default
  946 + end
  947 + end
  948 +
  949 + # Parses an XML string and returns the according document.
  950 + #
  951 + # xml_string::
  952 + # XML string to be parsed.
  953 + #
  954 + # The following exception may be raised:
  955 + #
  956 + # REXML::ParseException::
  957 + # If the specified file is not wellformed.
  958 + def parse(xml_string)
  959 + Document.new(xml_string)
  960 + end
  961 +
  962 + # Searches in a list of paths for a certain file. Returns
  963 + # the full path to the file, if it could be found. Otherwise,
  964 + # an exception will be raised.
  965 + #
  966 + # filename::
  967 + # Name of the file to search for.
  968 + # searchpath::
  969 + # List of paths to search in.
  970 + def find_xml_file(file, searchpath)
  971 + filename = File::basename(file)
  972 +
  973 + if filename != file
  974 + return file if File::file?(file)
  975 + else
  976 + searchpath.each { |path|
  977 + full_path = File::join(path, filename)
  978 + return full_path if File::file?(full_path)
  979 + }
  980 + end
  981 +
  982 + if searchpath.empty?
  983 + return file if File::file?(file)
  984 + raise ArgumentError, "File does not exist: #{file}."
  985 + end
  986 + raise ArgumentError, "Could not find <#{filename}> in <#{searchpath.join(':')}>"
  987 + end
  988 +
  989 + # Loads and parses an XML configuration file.
  990 + #
  991 + # filename::
  992 + # Name of the configuration file to be loaded.
  993 + #
  994 + # The following exceptions may be raised:
  995 + #
  996 + # Errno::ENOENT::
  997 + # If the specified file does not exist.
  998 + # REXML::ParseException::
  999 + # If the specified file is not wellformed.
  1000 + def load_xml_file(filename)
  1001 + parse(IO::read(filename))
  1002 + end
  1003 +
  1004 + # Caches the data belonging to a certain file.
  1005 + #
  1006 + # data::
  1007 + # Data to be cached.
  1008 + # filename::
  1009 + # Name of file the data was read from.
  1010 + def put_into_cache(data, filename)
  1011 + if @options.has_key?('cache')
  1012 + @options['cache'].each { |scheme|
  1013 + case(scheme)
  1014 + when 'storable'
  1015 + @@cache.save_storable(data, filename)
  1016 + when 'mem_share'
  1017 + @@cache.save_mem_share(data, filename)
  1018 + when 'mem_copy'
  1019 + @@cache.save_mem_copy(data, filename)
  1020 + else
  1021 + raise ArgumentError, "Unsupported caching scheme: <#{scheme}>."
  1022 + end
  1023 + }
  1024 + end
  1025 + end
  1026 +end
  1027 +
  1028 +# vim:sw=2
... ...