Chromium Code Reviews| Index: net/base/mime_util.cc |
| =================================================================== |
| --- net/base/mime_util.cc (revision 58709) |
| +++ net/base/mime_util.cc (working copy) |
| @@ -11,11 +11,185 @@ |
| #include "base/hash_tables.h" |
| #include "base/logging.h" |
| #include "base/singleton.h" |
| +#include "base/string_split.h" |
| #include "base/string_util.h" |
| #include "base/utf_string_conversions.h" |
| using std::string; |
| +namespace { |
|
darin (slow to review)
2010/09/08 05:18:32
it would have been OK to put the anonymous namespa
|
| + |
| +struct MimeInfo { |
| + const char* mime_type; |
| + const char* extensions; // comma separated list |
| +}; |
| + |
| +static const MimeInfo kPrimaryMappings[] = { |
| + { "text/html", "html,htm" }, |
| + { "text/css", "css" }, |
| + { "text/xml", "xml" }, |
| + { "image/gif", "gif" }, |
| + { "image/jpeg", "jpeg,jpg" }, |
| + { "image/png", "png" }, |
| + { "video/mp4", "mp4,m4v" }, |
| + { "audio/x-m4a", "m4a" }, |
| + { "audio/mp3", "mp3" }, |
| + { "video/ogg", "ogv,ogm" }, |
| + { "audio/ogg", "ogg,oga" }, |
| + { "video/webm", "webm" }, |
| + { "audio/webm", "webm" }, |
| + { "application/xhtml+xml", "xhtml,xht" }, |
| + { "application/x-chrome-extension", "crx" } |
| +}; |
| + |
| +static const MimeInfo kSecondaryMappings[] = { |
| + { "application/octet-stream", "exe,com,bin" }, |
| + { "application/gzip", "gz" }, |
| + { "application/pdf", "pdf" }, |
| + { "application/postscript", "ps,eps,ai" }, |
| + { "application/x-javascript", "js" }, |
| + { "image/bmp", "bmp" }, |
| + { "image/x-icon", "ico" }, |
| + { "image/jpeg", "jfif,pjpeg,pjp" }, |
| + { "image/tiff", "tiff,tif" }, |
| + { "image/x-xbitmap", "xbm" }, |
| + { "image/svg+xml", "svg,svgz" }, |
| + { "message/rfc822", "eml" }, |
| + { "text/plain", "txt,text" }, |
| + { "text/html", "shtml,ehtml" }, |
| + { "application/rss+xml", "rss" }, |
| + { "application/rdf+xml", "rdf" }, |
| + { "text/xml", "xsl,xbl" }, |
| + { "application/vnd.mozilla.xul+xml", "xul" }, |
| + { "application/x-shockwave-flash", "swf,swl" } |
| +}; |
| + |
| +// From http://www.w3schools.com/media/media_mimeref.asp and |
| +// http://plugindoc.mozdev.org/winmime.php |
| +static const char* kStandardImageTypes[] = { |
| + "image/bmp", |
| + "image/cis-cod", |
| + "image/gif", |
| + "image/ief", |
| + "image/jpeg", |
| + "image/pict", |
| + "image/pipeg", |
| + "image/png", |
| + "image/svg+xml", |
| + "image/tiff", |
| + "image/x-cmu-raster", |
| + "image/x-cmx", |
| + "image/x-icon", |
| + "image/x-portable-anymap", |
| + "image/x-portable-bitmap", |
| + "image/x-portable-graymap", |
| + "image/x-portable-pixmap", |
| + "image/x-rgb", |
| + "image/x-xbitmap", |
| + "image/x-xpixmap", |
| + "image/x-xwindowdump" |
| +}; |
| +static const char* kStandardAudioTypes[] = { |
| + "audio/aac", |
| + "audio/aiff", |
| + "audio/amr", |
| + "audio/basic", |
| + "audio/midi", |
| + "audio/mp3", |
| + "audio/mp4", |
| + "audio/mpeg", |
| + "audio/mpeg3", |
| + "audio/ogg", |
| + "audio/wav", |
| + "audio/webm", |
| + "audio/vorbis", |
| + "audio/x-m4a", |
| + "audio/x-ms-wma", |
| + "audio/vnd.rn-realaudio", |
| + "audio/vnd.wave" |
| +}; |
| +static const char* kStandardVideoTypes[] = { |
| + "video/avi", |
| + "video/divx", |
| + "video/flc", |
| + "video/mp4", |
| + "video/mpeg", |
| + "video/ogg", |
| + "video/quicktime", |
| + "video/sd-video", |
| + "video/webm", |
| + "video/x-dv", |
| + "video/x-m4v", |
| + "video/x-mpeg", |
| + "video/x-ms-asf", |
| + "video/x-ms-wmv" |
| +}; |
| + |
| +void GetExtensionsFromHardCodedMappings( |
| + const MimeInfo* mappings, |
| + size_t mappings_len, |
| + const std::string& leading_mime_type, |
| + base::hash_set<FilePath::StringType>* extensions) { |
| + FilePath::StringType extension; |
| + for (size_t i = 0; i < mappings_len; ++i) { |
| + if (StartsWithASCII(mappings[i].mime_type, leading_mime_type, false)) { |
| + std::vector<string> this_extensions; |
| + base::SplitStringUsingSubstr(mappings[i].extensions, |
| + ",", |
| + &this_extensions); |
| + for (size_t j = 0; j < this_extensions.size(); ++j) { |
| +#if defined(OS_WIN) |
| + FilePath::StringType extension(UTF8ToWide(this_extensions[j])); |
| +#else |
| + FilePath::StringType extension(this_extensions[j]); |
| +#endif |
| + extensions->insert(extension); |
| + } |
| + } |
| + } |
| +} |
| + |
| +void GetExtensionsHelper( |
| + const char** standard_types, |
| + size_t standard_types_len, |
| + const std::string& leading_mime_type, |
| + base::hash_set<FilePath::StringType>* extensions) { |
| + FilePath::StringType extension; |
| + for (size_t i = 0; i < standard_types_len; ++i) { |
| + if (net::GetPreferredExtensionForMimeType(standard_types[i], &extension)) |
| + extensions->insert(extension); |
| + } |
| + |
| + // Also look up the extensions from hard-coded mappings in case that some |
| + // supported extensions are not registered in the system registry, like ogg. |
| + GetExtensionsFromHardCodedMappings(kPrimaryMappings, |
| + arraysize(kPrimaryMappings), |
| + leading_mime_type, |
| + extensions); |
| + |
| + GetExtensionsFromHardCodedMappings(kSecondaryMappings, |
| + arraysize(kSecondaryMappings), |
| + leading_mime_type, |
| + extensions); |
| +} |
| + |
| +// Notes: |
| +// 1) The elements in the source set will be appended to the target vector. |
| +// 2) The source set will be destroyed after this function returns. |
| +template<class T> |
| +void HashSetToVector(base::hash_set<T>* source, std::vector<T>* target) { |
| + size_t old_target_size = target->size(); |
| + target->resize(old_target_size + source->size()); |
| + size_t i = 0; |
| + for (base::hash_set<T>::iterator iter(source->begin()); |
| + iter != source->end(); ++iter, ++i) { |
| + target->at(old_target_size + i).swap(*iter); |
| + } |
| + source->clear(); |
| +} |
| + |
| +} |
| + |
| namespace net { |
| // Singleton utility class for mime types. |
| @@ -70,51 +244,6 @@ |
| StrictMappings strict_format_map_; |
| }; // class MimeUtil |
| -struct MimeInfo { |
| - const char* mime_type; |
| - const char* extensions; // comma separated list |
| -}; |
| - |
| -static const MimeInfo primary_mappings[] = { |
| - { "text/html", "html,htm" }, |
| - { "text/css", "css" }, |
| - { "text/xml", "xml" }, |
| - { "image/gif", "gif" }, |
| - { "image/jpeg", "jpeg,jpg" }, |
| - { "image/png", "png" }, |
| - { "video/mp4", "mp4,m4v" }, |
| - { "audio/x-m4a", "m4a" }, |
| - { "audio/mp3", "mp3" }, |
| - { "video/ogg", "ogv,ogm" }, |
| - { "audio/ogg", "ogg,oga" }, |
| - { "video/webm", "webm" }, |
| - { "audio/webm", "webm" }, |
| - { "application/xhtml+xml", "xhtml,xht" }, |
| - { "application/x-chrome-extension", "crx" } |
| -}; |
| - |
| -static const MimeInfo secondary_mappings[] = { |
| - { "application/octet-stream", "exe,com,bin" }, |
| - { "application/gzip", "gz" }, |
| - { "application/pdf", "pdf" }, |
| - { "application/postscript", "ps,eps,ai" }, |
| - { "application/x-javascript", "js" }, |
| - { "image/bmp", "bmp" }, |
| - { "image/x-icon", "ico" }, |
| - { "image/jpeg", "jfif,pjpeg,pjp" }, |
| - { "image/tiff", "tiff,tif" }, |
| - { "image/x-xbitmap", "xbm" }, |
| - { "image/svg+xml", "svg,svgz" }, |
| - { "message/rfc822", "eml" }, |
| - { "text/plain", "txt,text" }, |
| - { "text/html", "shtml,ehtml" }, |
| - { "application/rss+xml", "rss" }, |
| - { "application/rdf+xml", "rdf" }, |
| - { "text/xml", "xsl,xbl" }, |
| - { "application/vnd.mozilla.xul+xml", "xul" }, |
| - { "application/x-shockwave-flash", "swf,swl" } |
| -}; |
| - |
| static const char* FindMimeType(const MimeInfo* mappings, |
| size_t mappings_len, |
| const char* ext) { |
| @@ -156,7 +285,7 @@ |
| #endif |
| const char* mime_type; |
| - mime_type = FindMimeType(primary_mappings, arraysize(primary_mappings), |
| + mime_type = FindMimeType(kPrimaryMappings, arraysize(kPrimaryMappings), |
| ext_narrow_str.c_str()); |
| if (mime_type) { |
| *result = mime_type; |
| @@ -166,7 +295,7 @@ |
| if (GetPlatformMimeTypeFromExtension(ext, result)) |
| return true; |
| - mime_type = FindMimeType(secondary_mappings, arraysize(secondary_mappings), |
| + mime_type = FindMimeType(kSecondaryMappings, arraysize(kSecondaryMappings), |
| ext_narrow_str.c_str()); |
| if (mime_type) { |
| *result = mime_type; |
| @@ -531,4 +660,53 @@ |
| GetMimeUtil()->ParseCodecString(codecs, codecs_out, strip); |
| } |
| +void GetImageExtensions(std::vector<FilePath::StringType>* extensions) { |
| + base::hash_set<FilePath::StringType> unique_extensions; |
| + GetExtensionsHelper(kStandardImageTypes, |
| + arraysize(kStandardImageTypes), |
| + "image/", |
| + &unique_extensions); |
| + HashSetToVector(&unique_extensions, extensions); |
| +} |
| + |
| +void GetAudioExtensions(std::vector<FilePath::StringType>* extensions) { |
| + base::hash_set<FilePath::StringType> unique_extensions; |
| + GetExtensionsHelper(kStandardAudioTypes, |
| + arraysize(kStandardAudioTypes), |
| + "audio/", |
| + &unique_extensions); |
| + HashSetToVector(&unique_extensions, extensions); |
| +} |
| + |
| +void GetVideoExtensions(std::vector<FilePath::StringType>* extensions) { |
| + base::hash_set<FilePath::StringType> unique_extensions; |
| + GetExtensionsHelper(kStandardVideoTypes, |
| + arraysize(kStandardVideoTypes), |
| + "video/", |
| + &unique_extensions); |
| + HashSetToVector(&unique_extensions, extensions); |
| +} |
| + |
| +void GetExtensionsForMimeType(const std::string& mime_type, |
| + std::vector<FilePath::StringType>* extensions) { |
| + base::hash_set<FilePath::StringType> unique_extensions; |
| + FilePath::StringType extension; |
| + if (net::GetPreferredExtensionForMimeType(mime_type, &extension)) |
| + unique_extensions.insert(extension); |
| + |
| + // Also look up the extensions from hard-coded mappings in case that some |
| + // supported extensions are not registered in the system registry, like ogg. |
| + GetExtensionsFromHardCodedMappings(kPrimaryMappings, |
| + arraysize(kPrimaryMappings), |
| + mime_type, |
| + &unique_extensions); |
| + |
| + GetExtensionsFromHardCodedMappings(kSecondaryMappings, |
| + arraysize(kSecondaryMappings), |
| + mime_type, |
| + &unique_extensions); |
| + |
| + HashSetToVector(&unique_extensions, extensions); |
| +} |
| + |
| } // namespace net |