Index: mojo/public/dart/third_party/mime/lib/src/mime_type.dart |
diff --git a/mojo/public/dart/third_party/mime/lib/src/mime_type.dart b/mojo/public/dart/third_party/mime/lib/src/mime_type.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..744eead8768604d4b95b23677e3156b52c5d9969 |
--- /dev/null |
+++ b/mojo/public/dart/third_party/mime/lib/src/mime_type.dart |
@@ -0,0 +1,128 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library mime.mime_type; |
+ |
+import 'default_extension_map.dart'; |
+import 'magic_number.dart'; |
+ |
+final MimeTypeResolver _globalResolver = new MimeTypeResolver(); |
+ |
+/** |
+ * The maximum number of bytes needed, to match all default magic-numbers. |
+ */ |
+int get defaultMagicNumbersMaxLength => _globalResolver.magicNumbersMaxLength; |
+ |
+/** |
+ * Extract the extension from [path] and use that for MIME-type lookup, using |
+ * the default extension map. |
+ * |
+ * If no matching MIME-type was found, `null` is returned. |
+ * |
+ * If [headerBytes] is present, a match for known magic-numbers will be |
+ * performed first. This allows the correct mime-type to be found, even though |
+ * a file have been saved using the wrong file-name extension. If less than |
+ * [defaultMagicNumbersMaxLength] bytes was provided, some magic-numbers won't |
+ * be matched against. |
+ */ |
+String lookupMimeType(String path, {List<int> headerBytes}) => |
+ _globalResolver.lookup(path, headerBytes: headerBytes); |
+ |
+/** |
+ * MIME-type resolver class, used to customize the lookup of mime-types. |
+ */ |
+class MimeTypeResolver { |
+ final Map<String, String> _extensionMap = {}; |
+ final List<MagicNumber> _magicNumbers = []; |
+ final bool _useDefault; |
+ int _magicNumbersMaxLength; |
+ |
+ /** |
+ * Create a new empty [MimeTypeResolver]. |
+ */ |
+ MimeTypeResolver.empty() : _useDefault = false, _magicNumbersMaxLength = 0; |
+ |
+ /** |
+ * Create a new [MimeTypeResolver] containing the default scope. |
+ */ |
+ MimeTypeResolver() : |
+ _useDefault = true, |
+ _magicNumbersMaxLength = DEFAULT_MAGIC_NUMBERS_MAX_LENGTH; |
+ |
+ /** |
+ * Get the maximum number of bytes required to match all magic numbers, when |
+ * performing [lookup] with headerBytes present. |
+ */ |
+ int get magicNumbersMaxLength => _magicNumbersMaxLength; |
+ |
+ /** |
+ * Extract the extension from [path] and use that for MIME-type lookup. |
+ * |
+ * If no matching MIME-type was found, `null` is returned. |
+ * |
+ * If [headerBytes] is present, a match for known magic-numbers will be |
+ * performed first. This allows the correct mime-type to be found, even though |
+ * a file have been saved using the wrong file-name extension. If less than |
+ * [magicNumbersMaxLength] bytes was provided, some magic-numbers won't |
+ * be matched against. |
+ */ |
+ String lookup(String path, {List<int> headerBytes}) { |
+ String result; |
+ if (headerBytes != null) { |
+ result = _matchMagic(headerBytes, _magicNumbers); |
+ if (result != null) return result; |
+ if (_useDefault) { |
+ result = _matchMagic(headerBytes, DEFAULT_MAGIC_NUMBERS); |
+ if (result != null) return result; |
+ } |
+ } |
+ var ext = _ext(path); |
+ result = _extensionMap[ext]; |
+ if (result != null) return result; |
+ if (_useDefault) { |
+ result = defaultExtensionMap[ext]; |
+ if (result != null) return result; |
+ } |
+ return null; |
+ } |
+ |
+ /** |
+ * Add a new MIME-type mapping to the [MimeTypeResolver]. If the [extension] |
+ * is already present in the [MimeTypeResolver], it'll be overwritten. |
+ */ |
+ void addExtension(String extension, String mimeType) { |
+ _extensionMap[extension] = mimeType; |
+ } |
+ |
+ /** |
+ * Add a new magic-number mapping to the [MimeTypeResolver]. |
+ * |
+ * If [mask] is present,the [mask] is used to only perform matching on |
+ * selective bits. The [mask] must have the same length as [bytes]. |
+ */ |
+ void addMagicNumber(List<int> bytes, String mimeType, {List<int> mask}) { |
+ if (mask != null && bytes.length != mask.length) { |
+ throw new ArgumentError('Bytes and mask are of different lengths'); |
+ } |
+ if (bytes.length > _magicNumbersMaxLength) { |
+ _magicNumbersMaxLength = bytes.length; |
+ } |
+ _magicNumbers.add(new MagicNumber(mimeType, bytes, mask: mask)); |
+ } |
+ |
+ static String _matchMagic(List<int> headerBytes, |
+ List<MagicNumber> magicNumbers) { |
+ for (var mn in magicNumbers) { |
+ if (mn.matches(headerBytes)) return mn.mimeType; |
+ } |
+ return null; |
+ } |
+ |
+ static String _ext(String path) { |
+ int index = path.lastIndexOf('.'); |
+ if (index < 0 || index + 1 >= path.length) return path; |
+ return path.substring(index + 1).toLowerCase(); |
+ } |
+} |
+ |