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,7 +20,9 @@ This will create a Rails 2.3.2 app with Heroku-recommended code:
20 * jQuery for Javascript 20 * jQuery for Javascript
21 * Clearance for authentication 21 * Clearance for authentication
22 * Cucumber, Shoulda, Factory Girl, & Mocha for testing 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 * Blitz for features, model, controller, & helper generators 26 * Blitz for features, model, controller, & helper generators
25 27
26 If you don't have all the necessary gems, they will be installed. 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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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