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
initializeSupportedImageMIMETypes()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
initializeSupportedImageMIMETypesForEncoding()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
initializeSupportedJavaScriptMIMETypes()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
initializeSupportedNonImageMimeTypes()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
mediaMIMETypeMap()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)
getMIMETypeForExtension(const String & extension)376 String MIMETypeRegistry::getMIMETypeForExtension(const String& extension)
377 {
378 return getMIMETypeForExtensionThreadSafe(extension);
379 }
380 #endif
381
getMediaMIMETypeForExtension(const String & ext)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
getMediaMIMETypesForExtension(const String & ext)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
initializeSupportedMediaMIMETypes()415 static void initializeSupportedMediaMIMETypes()
416 {
417 supportedMediaMIMETypes = new HashSet<String>;
418 #if ENABLE(VIDEO)
419 MediaPlayer::getSupportedTypes(*supportedMediaMIMETypes);
420 #endif
421 }
422
initializeUnsupportedTextMIMETypes()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
initializeMIMETypeRegistry()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
getMIMETypeForPath(const String & path)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
isSupportedImageMIMEType(const String & mimeType)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
isSupportedImageResourceMIMEType(const String & mimeType)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
isSupportedImageMIMETypeForEncoding(const String & mimeType)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
isSupportedJavaScriptMIMEType(const String & mimeType)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
isSupportedNonImageMIMEType(const String & mimeType)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
isSupportedMediaMIMEType(const String & mimeType)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
isUnsupportedTextMIMEType(const String & mimeType)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
isJavaAppletMIMEType(const String & mimeType)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
getSupportedImageMIMETypes()548 HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypes()
549 {
550 if (!supportedImageMIMETypes)
551 initializeMIMETypeRegistry();
552 return *supportedImageMIMETypes;
553 }
554
getSupportedImageResourceMIMETypes()555 HashSet<String>& MIMETypeRegistry::getSupportedImageResourceMIMETypes()
556 {
557 if (!supportedImageResourceMIMETypes)
558 initializeMIMETypeRegistry();
559 return *supportedImageResourceMIMETypes;
560 }
561
getSupportedImageMIMETypesForEncoding()562 HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypesForEncoding()
563 {
564 if (!supportedImageMIMETypesForEncoding)
565 initializeSupportedImageMIMETypesForEncoding();
566 return *supportedImageMIMETypesForEncoding;
567 }
568
getSupportedNonImageMIMETypes()569 HashSet<String>& MIMETypeRegistry::getSupportedNonImageMIMETypes()
570 {
571 if (!supportedNonImageMIMETypes)
572 initializeMIMETypeRegistry();
573 return *supportedNonImageMIMETypes;
574 }
575
getSupportedMediaMIMETypes()576 HashSet<String>& MIMETypeRegistry::getSupportedMediaMIMETypes()
577 {
578 if (!supportedMediaMIMETypes)
579 initializeSupportedMediaMIMETypes();
580 return *supportedMediaMIMETypes;
581 }
582
getUnsupportedTextMIMETypes()583 HashSet<String>& MIMETypeRegistry::getUnsupportedTextMIMETypes()
584 {
585 if (!unsupportedTextMIMETypes)
586 initializeMIMETypeRegistry();
587 return *unsupportedTextMIMETypes;
588 }
589
defaultMIMEType()590 const String& defaultMIMEType()
591 {
592 DEFINE_STATIC_LOCAL(const String, defaultMIMEType, ("application/octet-stream"));
593 return defaultMIMEType;
594 }
595
596 } // namespace WebCore
597