JavaScriptCore:
[WebKit-https.git] / WebCore / platform / MimeTypeRegistry.cpp
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "MimeTypeRegistry.h"
28 #include "StringHash.h"
29 #include <wtf/HashMap.h>
30 #include <wtf/HashSet.h>
31 #if PLATFORM(CG)
32 #include <ApplicationServices/ApplicationServices.h>
33 #endif
34 #if PLATFORM(MAC)
35 #include "WebCoreSystemInterface.h"
36 #endif
37 #if PLATFORM(QT)
38 #include <qimagereader.h>
39 #endif
40
41 namespace WebCore
42 {
43 static WTF::HashSet<String>* supportedImageResourceMIMETypes;
44 static WTF::HashSet<String>* supportedImageMIMETypes;
45 static WTF::HashSet<String>* supportedNonImageMIMETypes;
46     
47 #if PLATFORM(CG)
48 extern String getMIMETypeForUTI(const String& uti);
49 #endif
50
51 static void initialiseSupportedImageMIMETypes()
52 {    
53 #if PLATFORM(CG)
54     CFArrayRef supportedTypes = CGImageSourceCopyTypeIdentifiers();
55     int cnt = CFArrayGetCount(supportedTypes);
56     for(int i = 0; i < cnt; i++) {
57         CFStringRef supportedType = (CFStringRef)CFArrayGetValueAtIndex(supportedTypes, i);
58         String mimeType=getMIMETypeForUTI(supportedType);
59         if (!mimeType.isEmpty()) {
60             supportedImageMIMETypes->add(mimeType);
61             supportedImageResourceMIMETypes->add(mimeType);
62         }
63         CFRelease(supportedType);
64     }
65     CFRelease(supportedTypes);
66     
67     // On Tiger, com.microsoft.bmp doesn't have a MIME type in the registry.
68     supportedImageMIMETypes->add("image/bmp");
69     supportedImageResourceMIMETypes->add("image/bmp");
70     
71     //  We only get one MIME type per UTI, hence our need to add these manually
72     supportedImageMIMETypes->add("image/pjpeg");
73     supportedImageResourceMIMETypes->add("image/pjpeg");
74     
75     //  We don't want to try to treat all binary data as an image
76     supportedImageMIMETypes->remove("application/octet-stream");
77     supportedImageResourceMIMETypes->remove("application/octet-stream");
78     
79     //  Don't treat pdf/postscript as images directly
80     supportedImageMIMETypes->remove("application/pdf");
81     supportedImageMIMETypes->remove("application/postscript");
82
83 #elif PLATFORM(QT)
84     QList<QByteArray> formats = QImageReader::supportedImageFormats();
85     for (size_t i = 0; i < formats.size(); ++i) {
86         String mimeType = MimeTypeRegistry::getMIMETypeForExtension(formats.at(i).constData());
87         supportedImageMIMETypes->add(mimeType);
88         supportedImageResourceMIMETypes->add(mimeType);
89     }
90 #else
91     // assume that all implementations at least support the following standard
92     // image types:
93     static const char* types[] = {
94       "image/jpeg",
95       "image/png",
96       "image/gif",
97       "image/bmp",
98       "image/x-icon",    // ico
99       "image/x-xbitmap"  // xbm
100     };
101     for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i) {
102       supportedImageMIMETypes->add(types[i]);
103       supportedImageResourceMIMETypes->add(types[i]);
104     }
105 #endif
106 }
107
108 static void initialiseSupportedNonImageMimeTypes()
109 {
110     static const char* types[] = {
111       "text/html",
112       "text/xml",
113       "text/xsl",
114       "text/plain",
115       "text/",
116       "application/x-javascript",
117       "application/xml",
118       "application/xhtml+xml",
119       "application/rss+xml",
120       "application/atom+xml",
121 #if PLATFORM(MAC)
122       "application/x-webarchive",
123 #endif
124       "multipart/x-mixed-replace"
125 #if ENABLE(SVG)
126       , "image/svg+xml"
127 #endif
128 #if ENABLE(FTPDIR)
129       , "application/x-ftp-directory"
130 #endif
131     };
132     for (size_t i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
133       supportedNonImageMIMETypes->add(types[i]);
134 }
135
136 static void initialiseMimeTypeRegistry()
137 {
138     supportedImageResourceMIMETypes = new WTF::HashSet<String>();
139     supportedImageMIMETypes = new WTF::HashSet<String>();
140     supportedNonImageMIMETypes = new WTF::HashSet<String>();
141     
142     initialiseSupportedNonImageMimeTypes();
143     initialiseSupportedImageMIMETypes();
144 }
145
146 String MimeTypeRegistry::getMIMETypeForPath(const String& path)
147 {
148     int pos = path.reverseFind('.');
149     if(pos >= 0) {
150         String extension = path.substring(pos + 1);
151         return getMIMETypeForExtension(extension);
152     }
153     return "application/octet-stream";
154 }
155
156 bool MimeTypeRegistry::isSupportedImageMIMEType(const String& mimeType)
157
158     if (!supportedImageMIMETypes)
159         initialiseMimeTypeRegistry();
160     return !mimeType.isEmpty() && supportedImageMIMETypes->contains(mimeType); 
161 }
162
163 bool MimeTypeRegistry::isSupportedImageResourceMIMEType(const String& mimeType)
164
165     if (!supportedImageResourceMIMETypes)
166         initialiseMimeTypeRegistry();
167     return !mimeType.isEmpty() && supportedImageResourceMIMETypes->contains(mimeType); 
168 }
169     
170 bool MimeTypeRegistry::isSupportedNonImageMIMEType(const String& mimeType)
171 {
172     if (!supportedNonImageMIMETypes)
173         initialiseMimeTypeRegistry();
174     return !mimeType.isEmpty() && supportedNonImageMIMETypes->contains(mimeType);
175 }
176
177 bool MimeTypeRegistry::isJavaAppletMIMEType(const String& mimeType)
178 {
179     // Since this set is very limited and is likely to remain so we won't bother with the overhead
180     // of using a hash set.
181     // Any of the MIME types below may be followed by any number of specific versions of the JVM,
182     // which is why we use startsWith()
183     return mimeType.startsWith("application/x-java-applet", false) 
184         || mimeType.startsWith("application/x-java-bean", false) 
185         || mimeType.startsWith("application/x-java-vm", false);
186 }
187
188 const HashSet<String> &MimeTypeRegistry::getSupportedImageMIMETypes()
189 {
190     if (!supportedImageMIMETypes)
191         initialiseMimeTypeRegistry();
192     return *supportedImageMIMETypes;
193 }
194
195 const HashSet<String> &MimeTypeRegistry::getSupportedImageResourceMIMETypes()
196 {
197     if (!supportedImageResourceMIMETypes)
198         initialiseMimeTypeRegistry();
199     return *supportedImageResourceMIMETypes;
200 }
201
202 const HashSet<String> &MimeTypeRegistry::getSupportedNonImageMIMETypes()
203 {
204     if (!supportedNonImageMIMETypes)
205         initialiseMimeTypeRegistry();
206     return *supportedNonImageMIMETypes;
207 }
208
209 }