Home | History | Annotate | Download | only in platform
      1 /*
      2  * Copyright (C) 2006, 2008, 2009 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "MIMETypeRegistry.h"
     29 
     30 #include "MediaPlayer.h"
     31 #include <wtf/HashMap.h>
     32 #include <wtf/HashSet.h>
     33 #include <wtf/StdLibExtras.h>
     34 #include <wtf/text/StringHash.h>
     35 
     36 #if USE(CG)
     37 #include "ImageSourceCG.h"
     38 #include <ApplicationServices/ApplicationServices.h>
     39 #include <wtf/RetainPtr.h>
     40 #endif
     41 #if PLATFORM(QT)
     42 #include <qimagereader.h>
     43 #include <qimagewriter.h>
     44 #endif
     45 
     46 #if ENABLE(WEB_ARCHIVE)
     47 #include "ArchiveFactory.h"
     48 #endif
     49 
     50 namespace WebCore {
     51 
     52 static HashSet<String>* supportedImageResourceMIMETypes;
     53 static HashSet<String>* supportedImageMIMETypes;
     54 static HashSet<String>* supportedImageMIMETypesForEncoding;
     55 static HashSet<String>* supportedJavaScriptMIMETypes;
     56 static HashSet<String>* supportedNonImageMIMETypes;
     57 static HashSet<String>* supportedMediaMIMETypes;
     58 static HashSet<String>* unsupportedTextMIMETypes;
     59 
     60 typedef HashMap<String, Vector<String>*, CaseFoldingHash> MediaMIMETypeMap;
     61 
     62 static void initializeSupportedImageMIMETypes()
     63 {
     64 #if USE(CG)
     65     RetainPtr<CFArrayRef> supportedTypes(AdoptCF, CGImageSourceCopyTypeIdentifiers());
     66     CFIndex count = CFArrayGetCount(supportedTypes.get());
     67     for (CFIndex i = 0; i < count; i++) {
     68         RetainPtr<CFStringRef> supportedType(AdoptCF, reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(supportedTypes.get(), i)));
     69         String mimeType = MIMETypeForImageSourceType(supportedType.get());
     70         if (!mimeType.isEmpty()) {
     71             supportedImageMIMETypes->add(mimeType);
     72             supportedImageResourceMIMETypes->add(mimeType);
     73         }
     74     }
     75 
     76     // On Tiger and Leopard, com.microsoft.bmp doesn't have a MIME type in the registry.
     77     supportedImageMIMETypes->add("image/bmp");
     78     supportedImageResourceMIMETypes->add("image/bmp");
     79 
     80     // Favicons don't have a MIME type in the registry either.
     81     supportedImageMIMETypes->add("image/vnd.microsoft.icon");
     82     supportedImageMIMETypes->add("image/x-icon");
     83     supportedImageResourceMIMETypes->add("image/vnd.microsoft.icon");
     84     supportedImageResourceMIMETypes->add("image/x-icon");
     85 
     86     //  We only get one MIME type per UTI, hence our need to add these manually
     87     supportedImageMIMETypes->add("image/pjpeg");
     88     supportedImageResourceMIMETypes->add("image/pjpeg");
     89 
     90     //  We don't want to try to treat all binary data as an image
     91     supportedImageMIMETypes->remove("application/octet-stream");
     92     supportedImageResourceMIMETypes->remove("application/octet-stream");
     93 
     94     //  Don't treat pdf/postscript as images directly
     95     supportedImageMIMETypes->remove("application/pdf");
     96     supportedImageMIMETypes->remove("application/postscript");
     97 
     98 #elif PLATFORM(QT)
     99     QList<QByteArray> formats = QImageReader::supportedImageFormats();
    100     for (size_t i = 0; i < static_cast<size_t>(formats.size()); ++i) {
    101 #if ENABLE(SVG)
    102         /*
    103          * Qt has support for SVG, but we want to use KSVG2
    104          */
    105         if (formats.at(i).toLower().startsWith("svg"))
    106             continue;
    107 #endif
    108         String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData());
    109         if (!mimeType.isEmpty()) {
    110             supportedImageMIMETypes->add(mimeType);
    111             supportedImageResourceMIMETypes->add(mimeType);
    112         }
    113     }
    114 #elif PLATFORM(ANDROID)
    115     static const char* types[] = {
    116         "image/jpeg",
    117         "image/webp",
    118         "image/png",
    119         "image/gif",
    120         "image/bmp",
    121         "image/x-icon",    // ico
    122         "image/ico",
    123         "image/x-xbitmap"  // xbm
    124     };
    125     for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) {
    126         supportedImageMIMETypes->add(types[i]);
    127         supportedImageResourceMIMETypes->add(types[i]);
    128     }
    129     // Checked Safari impl, it seems that the HTTP stack returns
    130     // multiple responses, the initial response, and then one for
    131     // multipart segment. Each response is sent to the same ResourceLoader
    132     // so for us to support this we would need to do the same.
    133     supportedNonImageMIMETypes->remove("multipart/x-mixed-replace");
    134 #if !ENABLE(XSLT)
    135     supportedNonImageMIMETypes->remove("text/xsl");
    136 #endif
    137 #else
    138     // assume that all implementations at least support the following standard
    139     // image types:
    140     static const char* types[] = {
    141         "image/jpeg",
    142         "image/png",
    143         "image/gif",
    144         "image/bmp",
    145         "image/vnd.microsoft.icon",    // ico
    146         "image/x-icon",    // ico
    147         "image/x-xbitmap"  // xbm
    148     };
    149     for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i) {
    150         supportedImageMIMETypes->add(types[i]);
    151         supportedImageResourceMIMETypes->add(types[i]);
    152     }
    153 #endif
    154 }
    155 
    156 static void initializeSupportedImageMIMETypesForEncoding()
    157 {
    158     supportedImageMIMETypesForEncoding = new HashSet<String>;
    159 
    160 #if USE(CG)
    161 #if PLATFORM(MAC)
    162     RetainPtr<CFArrayRef> supportedTypes(AdoptCF, CGImageDestinationCopyTypeIdentifiers());
    163     CFIndex count = CFArrayGetCount(supportedTypes.get());
    164     for (CFIndex i = 0; i < count; i++) {
    165         RetainPtr<CFStringRef> supportedType(AdoptCF, reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(supportedTypes.get(), i)));
    166         String mimeType = MIMETypeForImageSourceType(supportedType.get());
    167         if (!mimeType.isEmpty())
    168             supportedImageMIMETypesForEncoding->add(mimeType);
    169     }
    170 #else
    171     // FIXME: Add Windows support for all the supported UTI's when a way to convert from MIMEType to UTI reliably is found.
    172     // For now, only support PNG, JPEG and GIF.  See <rdar://problem/6095286>.
    173     supportedImageMIMETypesForEncoding->add("image/png");
    174     supportedImageMIMETypesForEncoding->add("image/jpeg");
    175     supportedImageMIMETypesForEncoding->add("image/gif");
    176 #endif
    177 #elif PLATFORM(QT)
    178     QList<QByteArray> formats = QImageWriter::supportedImageFormats();
    179     for (int i = 0; i < formats.size(); ++i) {
    180         String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData());
    181         if (!mimeType.isEmpty())
    182             supportedImageMIMETypesForEncoding->add(mimeType);
    183     }
    184 #elif PLATFORM(GTK)
    185     supportedImageMIMETypesForEncoding->add("image/png");
    186     supportedImageMIMETypesForEncoding->add("image/jpeg");
    187     supportedImageMIMETypesForEncoding->add("image/tiff");
    188     supportedImageMIMETypesForEncoding->add("image/bmp");
    189     supportedImageMIMETypesForEncoding->add("image/ico");
    190 #elif USE(CAIRO)
    191     supportedImageMIMETypesForEncoding->add("image/png");
    192 #endif
    193 }
    194 
    195 static void initializeSupportedJavaScriptMIMETypes()
    196 {
    197     /*
    198         Mozilla 1.8 and WinIE 7 both accept text/javascript and text/ecmascript.
    199         Mozilla 1.8 accepts application/javascript, application/ecmascript, and application/x-javascript, but WinIE 7 doesn't.
    200         WinIE 7 accepts text/javascript1.1 - text/javascript1.3, text/jscript, and text/livescript, but Mozilla 1.8 doesn't.
    201         Mozilla 1.8 allows leading and trailing whitespace, but WinIE 7 doesn't.
    202         Mozilla 1.8 and WinIE 7 both accept the empty string, but neither accept a whitespace-only string.
    203         We want to accept all the values that either of these browsers accept, but not other values.
    204      */
    205     static const char* types[] = {
    206         "text/javascript",
    207         "text/ecmascript",
    208         "application/javascript",
    209         "application/ecmascript",
    210         "application/x-javascript",
    211         "text/javascript1.1",
    212         "text/javascript1.2",
    213         "text/javascript1.3",
    214         "text/jscript",
    215         "text/livescript",
    216     };
    217     for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
    218       supportedJavaScriptMIMETypes->add(types[i]);
    219 }
    220 
    221 static void initializeSupportedNonImageMimeTypes()
    222 {
    223     static const char* types[] = {
    224 #if ENABLE(WML)
    225         "text/vnd.wap.wml",
    226         "application/vnd.wap.wmlc",
    227 #endif
    228         "text/html",
    229         "text/xml",
    230         "text/xsl",
    231         "text/plain",
    232         "text/",
    233         "application/xml",
    234         "application/xhtml+xml",
    235         "application/vnd.wap.xhtml+xml",
    236         "application/rss+xml",
    237         "application/atom+xml",
    238         "application/json",
    239 #if ENABLE(SVG)
    240         "image/svg+xml",
    241 #endif
    242 #if ENABLE(FTPDIR)
    243         "application/x-ftp-directory",
    244 #endif
    245         "multipart/x-mixed-replace"
    246         // Note: ADDING a new type here will probably render it as HTML. This can
    247         // result in cross-site scripting.
    248     };
    249     COMPILE_ASSERT(sizeof(types) / sizeof(types[0]) <= 16,
    250                    nonimage_mime_types_must_be_less_than_or_equal_to_16);
    251 
    252     for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
    253         supportedNonImageMIMETypes->add(types[i]);
    254 
    255 #if ENABLE(WEB_ARCHIVE)
    256     ArchiveFactory::registerKnownArchiveMIMETypes();
    257 #endif
    258 }
    259 
    260 static MediaMIMETypeMap& mediaMIMETypeMap()
    261 {
    262     struct TypeExtensionPair {
    263         const char* type;
    264         const char* extension;
    265     };
    266 
    267     // A table of common media MIME types and file extenstions used when a platform's
    268     // specific MIME type lookup doesn't have a match for a media file extension.
    269     static const TypeExtensionPair pairs[] = {
    270 
    271         // Ogg
    272         { "application/ogg", "ogx" },
    273         { "audio/ogg", "ogg" },
    274         { "audio/ogg", "oga" },
    275         { "video/ogg", "ogv" },
    276 
    277         // Annodex
    278         { "application/annodex", "anx" },
    279         { "audio/annodex", "axa" },
    280         { "video/annodex", "axv" },
    281         { "audio/speex", "spx" },
    282 
    283         // WebM
    284         { "video/webm", "webm" },
    285         { "audio/webm", "webm" },
    286 
    287         // MPEG
    288         { "audio/mpeg", "m1a" },
    289         { "audio/mpeg", "m2a" },
    290         { "audio/mpeg", "m1s" },
    291         { "audio/mpeg", "mpa" },
    292         { "video/mpeg", "mpg" },
    293         { "video/mpeg", "m15" },
    294         { "video/mpeg", "m1s" },
    295         { "video/mpeg", "m1v" },
    296         { "video/mpeg", "m75" },
    297         { "video/mpeg", "mpa" },
    298         { "video/mpeg", "mpeg" },
    299         { "video/mpeg", "mpm" },
    300         { "video/mpeg", "mpv" },
    301 
    302         // MPEG playlist
    303         { "application/vnd.apple.mpegurl", "m3u8" },
    304         { "application/mpegurl", "m3u8" },
    305         { "application/x-mpegurl", "m3u8" },
    306         { "audio/mpegurl", "m3url" },
    307         { "audio/x-mpegurl", "m3url" },
    308         { "audio/mpegurl", "m3u" },
    309         { "audio/x-mpegurl", "m3u" },
    310 
    311         // MPEG-4
    312         { "video/x-m4v", "m4v" },
    313         { "audio/x-m4a", "m4a" },
    314         { "audio/x-m4b", "m4b" },
    315         { "audio/x-m4p", "m4p" },
    316         { "audio/mp4", "m4a" },
    317 
    318         // MP3
    319         { "audio/mp3", "mp3" },
    320         { "audio/x-mp3", "mp3" },
    321         { "audio/x-mpeg", "mp3" },
    322 
    323         // MPEG-2
    324         { "video/x-mpeg2", "mp2" },
    325         { "video/mpeg2", "vob" },
    326         { "video/mpeg2", "mod" },
    327         { "video/m2ts", "m2ts" },
    328         { "video/x-m2ts", "m2t" },
    329         { "video/x-m2ts", "ts" },
    330 
    331         // 3GP/3GP2
    332         { "audio/3gpp", "3gpp" },
    333         { "audio/3gpp2", "3g2" },
    334         { "application/x-mpeg", "amc" },
    335 
    336         // AAC
    337         { "audio/aac", "aac" },
    338         { "audio/aac", "adts" },
    339         { "audio/x-aac", "m4r" },
    340 
    341         // CoreAudio File
    342         { "audio/x-caf", "caf" },
    343         { "audio/x-gsm", "gsm" },
    344 
    345         // ADPCM
    346         { "audio/x-wav", "wav" }
    347     };
    348 
    349     DEFINE_STATIC_LOCAL(MediaMIMETypeMap, mediaMIMETypeForExtensionMap, ());
    350 
    351     if (!mediaMIMETypeForExtensionMap.isEmpty())
    352         return mediaMIMETypeForExtensionMap;
    353 
    354     const unsigned numPairs = sizeof(pairs) / sizeof(pairs[0]);
    355     for (unsigned ndx = 0; ndx < numPairs; ++ndx) {
    356 
    357         if (mediaMIMETypeForExtensionMap.contains(pairs[ndx].extension))
    358             mediaMIMETypeForExtensionMap.get(pairs[ndx].extension)->append(pairs[ndx].type);
    359         else {
    360             Vector<String>* synonyms = new Vector<String>;
    361 
    362             // If there is a system specific type for this extension, add it as the first type so
    363             // getMediaMIMETypeForExtension will always return it.
    364             String systemType = MIMETypeRegistry::getMIMETypeForExtension(pairs[ndx].extension);
    365             if (!systemType.isEmpty() && pairs[ndx].type != systemType)
    366                 synonyms->append(systemType);
    367             synonyms->append(pairs[ndx].type);
    368             mediaMIMETypeForExtensionMap.add(pairs[ndx].extension, synonyms);
    369         }
    370     }
    371 
    372     return mediaMIMETypeForExtensionMap;
    373 }
    374 
    375 #if ENABLE(FILE_SYSTEM) && ENABLE(WORKERS)
    376 String MIMETypeRegistry::getMIMETypeForExtension(const String& extension)
    377 {
    378     return getMIMETypeForExtensionThreadSafe(extension);
    379 }
    380 #endif
    381 
    382 String MIMETypeRegistry::getMediaMIMETypeForExtension(const String& ext)
    383 {
    384     // Look in the system-specific registry first.
    385     String type = getMIMETypeForExtension(ext);
    386     if (!type.isEmpty())
    387         return type;
    388 
    389     Vector<String>* typeList = mediaMIMETypeMap().get(ext);
    390     if (typeList)
    391         return (*typeList)[0];
    392 
    393     return String();
    394 }
    395 
    396 Vector<String> MIMETypeRegistry::getMediaMIMETypesForExtension(const String& ext)
    397 {
    398     Vector<String>* typeList = mediaMIMETypeMap().get(ext);
    399     if (typeList)
    400         return *typeList;
    401 
    402     // Only need to look in the system-specific registry if mediaMIMETypeMap() doesn't contain
    403     // the extension at all, because it always contains the system-specific type if the
    404     // extension is in the static mapping table.
    405     String type = getMIMETypeForExtension(ext);
    406     if (!type.isEmpty()) {
    407         Vector<String> typeList;
    408         typeList.append(type);
    409         return typeList;
    410     }
    411 
    412     return Vector<String>();
    413 }
    414 
    415 static void initializeSupportedMediaMIMETypes()
    416 {
    417     supportedMediaMIMETypes = new HashSet<String>;
    418 #if ENABLE(VIDEO)
    419     MediaPlayer::getSupportedTypes(*supportedMediaMIMETypes);
    420 #endif
    421 }
    422 
    423 static void initializeUnsupportedTextMIMETypes()
    424 {
    425     static const char* types[] = {
    426         "text/calendar",
    427         "text/x-calendar",
    428         "text/x-vcalendar",
    429         "text/vcalendar",
    430         "text/vcard",
    431         "text/x-vcard",
    432         "text/directory",
    433         "text/ldif",
    434         "text/qif",
    435         "text/x-qif",
    436         "text/x-csv",
    437         "text/x-vcf",
    438         "text/rtf",
    439     };
    440     for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
    441       unsupportedTextMIMETypes->add(types[i]);
    442 }
    443 
    444 static void initializeMIMETypeRegistry()
    445 {
    446     supportedJavaScriptMIMETypes = new HashSet<String>;
    447     initializeSupportedJavaScriptMIMETypes();
    448 
    449     supportedNonImageMIMETypes = new HashSet<String>(*supportedJavaScriptMIMETypes);
    450     initializeSupportedNonImageMimeTypes();
    451 
    452     supportedImageResourceMIMETypes = new HashSet<String>;
    453     supportedImageMIMETypes = new HashSet<String>;
    454     initializeSupportedImageMIMETypes();
    455 
    456     unsupportedTextMIMETypes = new HashSet<String>;
    457     initializeUnsupportedTextMIMETypes();
    458 }
    459 
    460 String MIMETypeRegistry::getMIMETypeForPath(const String& path)
    461 {
    462     size_t pos = path.reverseFind('.');
    463     if (pos != notFound) {
    464         String extension = path.substring(pos + 1);
    465         String result = getMIMETypeForExtension(extension);
    466         if (result.length())
    467             return result;
    468     }
    469     return "application/octet-stream";
    470 }
    471 
    472 bool MIMETypeRegistry::isSupportedImageMIMEType(const String& mimeType)
    473 {
    474     if (mimeType.isEmpty())
    475         return false;
    476     if (!supportedImageMIMETypes)
    477         initializeMIMETypeRegistry();
    478     return supportedImageMIMETypes->contains(mimeType);
    479 }
    480 
    481 bool MIMETypeRegistry::isSupportedImageResourceMIMEType(const String& mimeType)
    482 {
    483     if (mimeType.isEmpty())
    484         return false;
    485     if (!supportedImageResourceMIMETypes)
    486         initializeMIMETypeRegistry();
    487     return supportedImageResourceMIMETypes->contains(mimeType);
    488 }
    489 
    490 bool MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(const String& mimeType)
    491 {
    492     ASSERT(isMainThread());
    493 
    494     if (mimeType.isEmpty())
    495         return false;
    496     if (!supportedImageMIMETypesForEncoding)
    497         initializeSupportedImageMIMETypesForEncoding();
    498     return supportedImageMIMETypesForEncoding->contains(mimeType);
    499 }
    500 
    501 bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType)
    502 {
    503     if (mimeType.isEmpty())
    504         return false;
    505     if (!supportedJavaScriptMIMETypes)
    506         initializeMIMETypeRegistry();
    507     return supportedJavaScriptMIMETypes->contains(mimeType);
    508 }
    509 
    510 bool MIMETypeRegistry::isSupportedNonImageMIMEType(const String& mimeType)
    511 {
    512     if (mimeType.isEmpty())
    513         return false;
    514     if (!supportedNonImageMIMETypes)
    515         initializeMIMETypeRegistry();
    516     return supportedNonImageMIMETypes->contains(mimeType);
    517 }
    518 
    519 bool MIMETypeRegistry::isSupportedMediaMIMEType(const String& mimeType)
    520 {
    521     if (mimeType.isEmpty())
    522         return false;
    523     if (!supportedMediaMIMETypes)
    524         initializeSupportedMediaMIMETypes();
    525     return supportedMediaMIMETypes->contains(mimeType);
    526 }
    527 
    528 bool MIMETypeRegistry::isUnsupportedTextMIMEType(const String& mimeType)
    529 {
    530     if (mimeType.isEmpty())
    531         return false;
    532     if (!unsupportedTextMIMETypes)
    533         initializeMIMETypeRegistry();
    534     return unsupportedTextMIMETypes->contains(mimeType);
    535 }
    536 
    537 bool MIMETypeRegistry::isJavaAppletMIMEType(const String& mimeType)
    538 {
    539     // Since this set is very limited and is likely to remain so we won't bother with the overhead
    540     // of using a hash set.
    541     // Any of the MIME types below may be followed by any number of specific versions of the JVM,
    542     // which is why we use startsWith()
    543     return mimeType.startsWith("application/x-java-applet", false)
    544         || mimeType.startsWith("application/x-java-bean", false)
    545         || mimeType.startsWith("application/x-java-vm", false);
    546 }
    547 
    548 HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypes()
    549 {
    550     if (!supportedImageMIMETypes)
    551         initializeMIMETypeRegistry();
    552     return *supportedImageMIMETypes;
    553 }
    554 
    555 HashSet<String>& MIMETypeRegistry::getSupportedImageResourceMIMETypes()
    556 {
    557     if (!supportedImageResourceMIMETypes)
    558         initializeMIMETypeRegistry();
    559     return *supportedImageResourceMIMETypes;
    560 }
    561 
    562 HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypesForEncoding()
    563 {
    564     if (!supportedImageMIMETypesForEncoding)
    565         initializeSupportedImageMIMETypesForEncoding();
    566     return *supportedImageMIMETypesForEncoding;
    567 }
    568 
    569 HashSet<String>& MIMETypeRegistry::getSupportedNonImageMIMETypes()
    570 {
    571     if (!supportedNonImageMIMETypes)
    572         initializeMIMETypeRegistry();
    573     return *supportedNonImageMIMETypes;
    574 }
    575 
    576 HashSet<String>& MIMETypeRegistry::getSupportedMediaMIMETypes()
    577 {
    578     if (!supportedMediaMIMETypes)
    579         initializeSupportedMediaMIMETypes();
    580     return *supportedMediaMIMETypes;
    581 }
    582 
    583 HashSet<String>& MIMETypeRegistry::getUnsupportedTextMIMETypes()
    584 {
    585     if (!unsupportedTextMIMETypes)
    586         initializeMIMETypeRegistry();
    587     return *unsupportedTextMIMETypes;
    588 }
    589 
    590 const String& defaultMIMEType()
    591 {
    592     DEFINE_STATIC_LOCAL(const String, defaultMIMEType, ("application/octet-stream"));
    593     return defaultMIMEType;
    594 }
    595 
    596 } // namespace WebCore
    597