xref: /aoo42x/main/svl/source/misc/inettype.cxx (revision 40df464e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svl.hxx"
26 #include <tools/table.hxx>
27 #include <tools/wldcrd.hxx>
28 #include <svl/inettype.hxx>
29 #include <svl/svldata.hxx>
30 #include <svl/svl.hrc>
31 
32 #ifndef _SVSTDARR_STRINGSSORT_DECL
33 #define _SVSTDARR_STRINGSSORT
34 #include <svl/svstdarr.hxx>
35 #undef _SVSTDARR_STRINGSSORT
36 #endif
37 
38 namespace unnamed_svl_inettype {}
39 using namespace unnamed_svl_inettype;
40 	// unnamed namespaces don't work well yet
41 
42 //============================================================================
43 namespace unnamed_svl_inettype {
44 
45 //============================================================================
46 struct MediaTypeEntry
47 {
48 	sal_Char const * m_pTypeName;
49 	INetContentType	m_eTypeID;
50 	sal_Char const * m_pExtension;
51 };
52 
53 //============================================================================
54 struct TypeIDMapEntry
55 {
56 	UniString m_aTypeName;
57 	UniString m_aPresentation;
58 	UniString m_aSystemFileType;
59 };
60 
61 //============================================================================
62 struct TypeNameMapEntry: public UniString
63 {
64 	UniString m_aExtension;
65 	INetContentType m_eTypeID;
66 
TypeNameMapEntryunnamed_svl_inettype::TypeNameMapEntry67 	TypeNameMapEntry(const UniString & rType):
68 		UniString(rType), m_eTypeID(CONTENT_TYPE_UNKNOWN) {}
69 };
70 
71 //============================================================================
72 struct ExtensionMapEntry: public UniString
73 {
74 	INetContentType	m_eTypeID;
75 
ExtensionMapEntryunnamed_svl_inettype::ExtensionMapEntry76 	ExtensionMapEntry(const UniString & rExt):
77 		UniString(rExt), m_eTypeID(CONTENT_TYPE_UNKNOWN) {}
78 };
79 
80 //============================================================================
81 class Registration
82 {
83 	static Registration * m_pRegistration;
84 
85 	Table m_aTypeIDMap; // map TypeID to TypeName, Presentation
86 	SvStringsSort m_aTypeNameMap; // map TypeName to TypeID, Extension
87 	SvStringsSort m_aExtensionMap; // map Extension to TypeID
88 	sal_uInt32 m_nNextDynamicID;
89 
90 public:
Registration()91 	Registration(): m_nNextDynamicID(CONTENT_TYPE_LAST + 1) {}
92 
93 	~Registration();
94 
95 	static inline void deinitialize();
96 
97 	static inline TypeIDMapEntry * getEntry(INetContentType eTypeID);
98 
99 	static TypeNameMapEntry * getExtensionEntry(UniString const & rTypeName);
100 
101 	static INetContentType RegisterContentType(UniString const & rTypeName,
102 											   UniString const &
103 											       rPresentation,
104 											   UniString const * pExtension,
105 											   UniString const *
106 											       pSystemFileType);
107 
108 	static INetContentType GetContentType(UniString const & rTypeName);
109 
110 	static UniString GetContentType(INetContentType eTypeID);
111 
112 	static UniString GetPresentation(INetContentType eTypeID);
113 
114 	static UniString GetExtension(const UniString & rTypeName);
115 
116 	static INetContentType GetContentType4Extension(UniString const &
117 													    rExtension);
118 
119 };
120 
121 // static
deinitialize()122 inline void Registration::deinitialize()
123 {
124 	delete m_pRegistration;
125 	m_pRegistration = 0;
126 }
127 
128 // static
getEntry(INetContentType eTypeID)129 inline TypeIDMapEntry * Registration::getEntry(INetContentType eTypeID)
130 {
131 	return
132 		m_pRegistration ?
133 		    static_cast< TypeIDMapEntry * >(m_pRegistration->
134 											    m_aTypeIDMap.Get(eTypeID)) :
135 		    0;
136 }
137 
138 //============================================================================
139 MediaTypeEntry const * seekEntry(UniString const & rTypeName,
140 								 MediaTypeEntry const * pMap, sal_Size nSize);
141 
142 //============================================================================
143 /** A mapping from type names to type ids and extensions.  Sorted by type
144 	name.
145  */
146 MediaTypeEntry const aStaticTypeNameMap[CONTENT_TYPE_LAST + 1]
147 	= { { " ", CONTENT_TYPE_UNKNOWN, "" },
148 		{ CONTENT_TYPE_STR_X_CNT_DOCUMENT, CONTENT_TYPE_X_CNT_DOCUMENT,
149 		  "tmp" },
150 		{ CONTENT_TYPE_STR_X_CNT_FSYSBOX, CONTENT_TYPE_X_CNT_FSYSBOX, "tmp" },
151 		{ CONTENT_TYPE_STR_X_CNT_CDROM_VOLUME,
152 		  CONTENT_TYPE_X_CNT_CDROM_VOLUME, "tmp" },
153 		{ CONTENT_TYPE_STR_X_CNT_DISK_35, CONTENT_TYPE_X_CNT_DISK_35, "tmp" },
154 		{ CONTENT_TYPE_STR_X_CNT_DISK_525, CONTENT_TYPE_X_CNT_DISK_525,
155 		  "tmp" },
156 		{ CONTENT_TYPE_STR_X_CNT_FSYSFILE, CONTENT_TYPE_X_CNT_FSYSFILE,
157 		  "tmp" },
158 		{ CONTENT_TYPE_STR_X_CNT_FIXED_VOLUME,
159 		  CONTENT_TYPE_X_CNT_FIXED_VOLUME, "tmp" },
160 		{ CONTENT_TYPE_STR_X_CNT_FSYSFOLDER, CONTENT_TYPE_X_CNT_FSYSFOLDER,
161 		  "tmp" },
162 		{ CONTENT_TYPE_STR_X_CNT_RAM_VOLUME, CONTENT_TYPE_X_CNT_RAM_VOLUME,
163 		  "tmp" },
164 		{ CONTENT_TYPE_STR_X_CNT_REMOTE_VOLUME,
165 		  CONTENT_TYPE_X_CNT_REMOTE_VOLUME, "tmp" },
166 		{ CONTENT_TYPE_STR_X_CNT_REMOVEABLE_VOLUME,
167 		  CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME, "tmp" },
168 		{ CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFILE,
169 		  CONTENT_TYPE_X_CNT_FSYSSPECIALFILE, "tmp" },
170 		{ CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFOLDER,
171 		  CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER, "tmp" },
172 		{ CONTENT_TYPE_STR_X_CNT_TAPEDRIVE, CONTENT_TYPE_X_CNT_TAPEDRIVE,
173 		  "tmp" },
174 		{ CONTENT_TYPE_STR_X_CNT_FSYSURLFILE, CONTENT_TYPE_X_CNT_FSYSURLFILE,
175 		  "tmp" },
176 		{ CONTENT_TYPE_STR_X_CNT_FTPBOX, CONTENT_TYPE_X_CNT_FTPBOX, "tmp" },
177 		{ CONTENT_TYPE_STR_X_CNT_FTPFILE, CONTENT_TYPE_X_CNT_FTPFILE, "tmp" },
178 		{ CONTENT_TYPE_STR_X_CNT_FTPFOLDER, CONTENT_TYPE_X_CNT_FTPFOLDER,
179 		  "tmp" },
180 		{ CONTENT_TYPE_STR_X_CNT_FTPLINK, CONTENT_TYPE_X_CNT_FTPLINK, "tmp" },
181 		{ CONTENT_TYPE_STR_X_CNT_HTTPBOX, CONTENT_TYPE_X_CNT_HTTPBOX, "tmp" },
182 		{ CONTENT_TYPE_STR_X_CNT_HTTPFILE, CONTENT_TYPE_X_CNT_HTTPFILE,
183 		  "tmp" },
184 		{ CONTENT_TYPE_STR_X_CNT_IMAPBOX, CONTENT_TYPE_X_CNT_IMAPBOX, "tmp" },
185 		{ CONTENT_TYPE_STR_X_CNT_IMAPFOLDER, CONTENT_TYPE_X_CNT_IMAPFOLDER,
186 		  "tmp" },
187 		{ CONTENT_TYPE_STR_X_CNT_MESSAGE, CONTENT_TYPE_X_CNT_MESSAGE, "tmp" },
188 		{ CONTENT_TYPE_STR_X_CNT_NEWSBOX, CONTENT_TYPE_X_CNT_NEWSBOX, "tmp" },
189 		{ CONTENT_TYPE_STR_X_CNT_NEWSGROUP, CONTENT_TYPE_X_CNT_NEWSGROUP,
190 		  "tmp" },
191 		{ CONTENT_TYPE_STR_X_CNT_OUTBOX, CONTENT_TYPE_X_CNT_OUTBOX, "tmp" },
192 		{ CONTENT_TYPE_STR_X_CNT_POP3BOX, CONTENT_TYPE_X_CNT_POP3BOX, "tmp" },
193 		{ CONTENT_TYPE_STR_X_CNT_PUBLISHBOX, CONTENT_TYPE_X_CNT_PUBLISHBOX,
194 		  "tmp" },
195 		{ CONTENT_TYPE_STR_X_CNT_SEARCHBOX, CONTENT_TYPE_X_CNT_SEARCHBOX,
196 		  "tmp" },
197 		{ CONTENT_TYPE_STR_X_CNT_SEPARATOR, CONTENT_TYPE_X_CNT_SEPARATOR,
198 		  "tmp" },
199 		{ CONTENT_TYPE_STR_X_CNT_BOOKMARK, CONTENT_TYPE_X_CNT_BOOKMARK,
200 		  "tmp" },
201 		{ CONTENT_TYPE_STR_X_CNT_SUBSCRIBEBOX,
202 		  CONTENT_TYPE_X_CNT_SUBSCRIBEBOX, "tmp" },
203 		{ CONTENT_TYPE_STR_X_CNT_CDF, CONTENT_TYPE_X_CNT_CDF, "tmp" },
204 		{ CONTENT_TYPE_STR_X_CNT_CDFITEM, CONTENT_TYPE_X_CNT_CDFITEM, "tmp" },
205 		{ CONTENT_TYPE_STR_X_CNT_CDFSUB, CONTENT_TYPE_X_CNT_CDFSUB, "tmp" },
206 		{ CONTENT_TYPE_STR_X_CNT_STARCHANNEL, CONTENT_TYPE_X_CNT_STARCHANNEL,
207 		  "tmp" },
208 		{ CONTENT_TYPE_STR_X_CNT_TRASHBOX, CONTENT_TYPE_X_CNT_TRASHBOX,
209 		  "tmp" },
210 		{ CONTENT_TYPE_STR_X_CNT_TRASH, CONTENT_TYPE_X_CNT_TRASH, "tmp" },
211 		{ CONTENT_TYPE_STR_X_CNT_VIMBBOARD, CONTENT_TYPE_X_CNT_VIMBBOARD,
212 		  "tmp" },
213 		{ CONTENT_TYPE_STR_X_CNT_VIMBBOARDBOX,
214 		  CONTENT_TYPE_X_CNT_VIMBBOARDBOX, "tmp" },
215 		{ CONTENT_TYPE_STR_X_CNT_VIMBOX, CONTENT_TYPE_X_CNT_VIMBOX, "tmp" },
216 		{ CONTENT_TYPE_STR_X_CNT_VIMINBOX, CONTENT_TYPE_X_CNT_VIMINBOX,
217 		  "tmp" },
218 		{ CONTENT_TYPE_STR_APP_OCTSTREAM, CONTENT_TYPE_APP_OCTSTREAM, "tmp" },
219 		{ CONTENT_TYPE_STR_APP_PDF, CONTENT_TYPE_APP_PDF, "pdf" },
220 		{ CONTENT_TYPE_STR_APP_RTF, CONTENT_TYPE_APP_RTF, "rtf" },
221 		{ CONTENT_TYPE_STR_APP_VND_CALC, CONTENT_TYPE_APP_VND_CALC, "sdc" },
222 		{ CONTENT_TYPE_STR_APP_VND_CHART, CONTENT_TYPE_APP_VND_CHART, "sds" },
223 		{ CONTENT_TYPE_STR_APP_VND_DRAW, CONTENT_TYPE_APP_VND_DRAW, "sda" },
224 		{ CONTENT_TYPE_STR_APP_VND_IMAGE, CONTENT_TYPE_APP_VND_IMAGE, "sim" },
225 		{ CONTENT_TYPE_STR_APP_VND_IMPRESS, CONTENT_TYPE_APP_VND_IMPRESS,
226 		  "sdd" },
227 		{ CONTENT_TYPE_STR_APP_VND_IMPRESSPACKED,
228 		  CONTENT_TYPE_APP_VND_IMPRESSPACKED, "sdp" },
229 		{ CONTENT_TYPE_STR_APP_VND_MAIL, CONTENT_TYPE_APP_VND_MAIL, "sdm" },
230 		{ CONTENT_TYPE_STR_APP_VND_MATH, CONTENT_TYPE_APP_VND_MATH, "smf" },
231 		{ CONTENT_TYPE_STR_APP_VND_NEWS, CONTENT_TYPE_APP_VND_NEWS, "sdm" },
232 		{ CONTENT_TYPE_STR_APP_VND_OUTTRAY, CONTENT_TYPE_APP_VND_OUTTRAY,
233 		  "sdm" },
234 		{ CONTENT_TYPE_STR_APP_VND_TEMPLATE, CONTENT_TYPE_APP_VND_TEMPLATE,
235 		  "vor" },
236 		{ CONTENT_TYPE_STR_APP_VND_WRITER, CONTENT_TYPE_APP_VND_WRITER,
237 		  "sdw" },
238 		{ CONTENT_TYPE_STR_APP_VND_WRITER_GLOBAL,
239 		  CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "sgl" },
240 		{ CONTENT_TYPE_STR_APP_VND_WRITER_WEB,
241 		  CONTENT_TYPE_APP_VND_WRITER_WEB, "htm" },
242 		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_CALC, CONTENT_TYPE_APP_VND_SUN_XML_CALC, "sxc" },
243 		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_CHART, CONTENT_TYPE_APP_VND_SUN_XML_CHART, "sxs" },
244 		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_DRAW, CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "sxd" },
245  		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESS, CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "sxi" },
246  		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESSPACKED, CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, "sxp" },
247 		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_MATH, CONTENT_TYPE_APP_VND_SUN_XML_MATH, "sxm" },
248 		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER, CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "sxw" },
249 		{ CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER_GLOBAL, CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, "sxg" },
250 		{ CONTENT_TYPE_STR_APP_FRAMESET, CONTENT_TYPE_APP_FRAMESET, "sfs" },
251 		{ CONTENT_TYPE_STR_APP_GALLERY, CONTENT_TYPE_APP_GALLERY, "gal" },
252 		{ CONTENT_TYPE_STR_APP_GALLERY_THEME, CONTENT_TYPE_APP_GALLERY_THEME,
253 		  "thm" },
254 		{ CONTENT_TYPE_STR_APP_JAR, CONTENT_TYPE_APP_JAR, "jar" },
255 		{ CONTENT_TYPE_STR_APP_MACRO, CONTENT_TYPE_APP_MACRO, "tmp" },
256 		{ CONTENT_TYPE_STR_APP_MSEXCEL, CONTENT_TYPE_APP_MSEXCEL, "xls" },
257 		{ CONTENT_TYPE_STR_APP_MSEXCEL_TEMPL, CONTENT_TYPE_APP_MSEXCEL_TEMPL,
258 		  "xlt" },
259 		{ CONTENT_TYPE_STR_APP_MSPPOINT, CONTENT_TYPE_APP_MSPPOINT, "ppt" },
260 		{ CONTENT_TYPE_STR_APP_MSPPOINT_TEMPL,
261 		  CONTENT_TYPE_APP_MSPPOINT_TEMPL, "pot" },
262 		{ CONTENT_TYPE_STR_APP_MSWORD, CONTENT_TYPE_APP_MSWORD, "doc" },
263 		{ CONTENT_TYPE_STR_APP_MSWORD_TEMPL, CONTENT_TYPE_APP_MSWORD_TEMPL,
264 		  "dot" },
265 		{ CONTENT_TYPE_STR_APP_SCHEDULE_CMB, CONTENT_TYPE_APP_SCHEDULE,
266 		  "tmp" },
267 		{ CONTENT_TYPE_STR_APP_SCHEDULE_EVT, CONTENT_TYPE_APP_SCHEDULE_EVT,
268 		  "tmp" },
269 		{ CONTENT_TYPE_STR_APP_SCHEDULE_FEVT,
270 		  CONTENT_TYPE_APP_SCHEDULE_FORM_EVT, "tmp" },
271 		{ CONTENT_TYPE_STR_APP_SCHEDULE_FTASK,
272 		  CONTENT_TYPE_APP_SCHEDULE_FORM_TASK, "tmp" },
273 		{ CONTENT_TYPE_STR_APP_SCHEDULE_TASK, CONTENT_TYPE_APP_SCHEDULE_TASK,
274 		  "tmp" },
275 		{ CONTENT_TYPE_STR_APP_STARCALC, CONTENT_TYPE_APP_STARCALC, "sdc" },
276 		{ CONTENT_TYPE_STR_APP_STARCHART, CONTENT_TYPE_APP_STARCHART, "sds" },
277 		{ CONTENT_TYPE_STR_APP_STARDRAW, CONTENT_TYPE_APP_STARDRAW, "sda" },
278 		{ CONTENT_TYPE_STR_APP_STARHELP, CONTENT_TYPE_APP_STARHELP, "svh" },
279 		{ CONTENT_TYPE_STR_APP_STARIMAGE, CONTENT_TYPE_APP_STARIMAGE, "sim" },
280 		{ CONTENT_TYPE_STR_APP_STARIMPRESS, CONTENT_TYPE_APP_STARIMPRESS,
281 		  "sdd" },
282 		{ CONTENT_TYPE_STR_APP_STARMAIL_SDM, CONTENT_TYPE_APP_STARMAIL_SDM,
283 		  "sdm" },
284 		{ CONTENT_TYPE_STR_APP_STARMAIL_SMD, CONTENT_TYPE_APP_STARMAIL_SMD,
285 		  "smd" },
286 		{ CONTENT_TYPE_STR_APP_STARMATH, CONTENT_TYPE_APP_STARMATH, "smf" },
287 		{ CONTENT_TYPE_STR_APP_STARWRITER, CONTENT_TYPE_APP_STARWRITER,
288 		  "sdw" },
289 		{ CONTENT_TYPE_STR_APP_STARWRITER_GLOB,
290 		  CONTENT_TYPE_APP_STARWRITER_GLOB, "sgl" },
291 		{ CONTENT_TYPE_STR_APP_CDE_CALENDAR_APP,
292 		  CONTENT_TYPE_APP_CDE_CALENDAR_APP, "appt" },
293 		{ CONTENT_TYPE_STR_APP_ZIP, CONTENT_TYPE_APP_ZIP, "zip" },
294 		{ CONTENT_TYPE_STR_AUDIO_AIFF, CONTENT_TYPE_AUDIO_AIFF, "aif" },
295 		{ CONTENT_TYPE_STR_AUDIO_BASIC, CONTENT_TYPE_AUDIO_BASIC, "au" },
296 		{ CONTENT_TYPE_STR_AUDIO_MIDI, CONTENT_TYPE_AUDIO_MIDI, "mid" },
297 		{ CONTENT_TYPE_STR_AUDIO_WAV, CONTENT_TYPE_AUDIO_WAV, "wav" },
298 		{ CONTENT_TYPE_STR_IMAGE_GENERIC, CONTENT_TYPE_IMAGE_GENERIC, "tmp" },
299 		{ CONTENT_TYPE_STR_IMAGE_GIF, CONTENT_TYPE_IMAGE_GIF, "gif" },
300 		{ CONTENT_TYPE_STR_IMAGE_JPEG, CONTENT_TYPE_IMAGE_JPEG, "jpg" },
301 		{ CONTENT_TYPE_STR_IMAGE_PCX, CONTENT_TYPE_IMAGE_PCX, "pcx" },
302 		{ CONTENT_TYPE_STR_IMAGE_PNG, CONTENT_TYPE_IMAGE_PNG, "png" },
303 		{ CONTENT_TYPE_STR_IMAGE_TIFF, CONTENT_TYPE_IMAGE_TIFF, "tif" },
304 		{ CONTENT_TYPE_STR_IMAGE_BMP, CONTENT_TYPE_IMAGE_BMP, "bmp" },
305 		{ CONTENT_TYPE_STR_INET_MSG_RFC822, CONTENT_TYPE_INET_MESSAGE_RFC822,
306 		  "tmp" },
307 		{ CONTENT_TYPE_STR_INET_MULTI_ALTERNATIVE,
308 		  CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE, "tmp" },
309 		{ CONTENT_TYPE_STR_INET_MULTI_DIGEST,
310 		  CONTENT_TYPE_INET_MULTIPART_DIGEST, "tmp" },
311 		{ CONTENT_TYPE_STR_INET_MULTI_MIXED,
312 		  CONTENT_TYPE_INET_MULTIPART_MIXED, "tmp" },
313 		{ CONTENT_TYPE_STR_INET_MULTI_PARALLEL,
314 		  CONTENT_TYPE_INET_MULTIPART_PARALLEL, "tmp" },
315 		{ CONTENT_TYPE_STR_INET_MULTI_RELATED,
316 		  CONTENT_TYPE_INET_MULTIPART_RELATED, "tmp" },
317 		{ CONTENT_TYPE_STR_TEXT_ICALENDAR, CONTENT_TYPE_TEXT_ICALENDAR,
318 		  "ics" },
319 		{ CONTENT_TYPE_STR_TEXT_HTML, CONTENT_TYPE_TEXT_HTML, "htm" },
320 		{ CONTENT_TYPE_STR_TEXT_PLAIN, CONTENT_TYPE_TEXT_PLAIN, "txt" },
321 		{ CONTENT_TYPE_STR_TEXT_XMLICALENDAR, CONTENT_TYPE_TEXT_XMLICALENDAR,
322 		  "xcs" },
323 		{ CONTENT_TYPE_STR_TEXT_URL, CONTENT_TYPE_TEXT_URL, "url" },
324 		{ CONTENT_TYPE_STR_TEXT_VCALENDAR, CONTENT_TYPE_TEXT_VCALENDAR,
325 		  "vcs" },
326 		{ CONTENT_TYPE_STR_TEXT_VCARD, CONTENT_TYPE_TEXT_VCARD, "vcf" },
327 		{ CONTENT_TYPE_STR_VIDEO_VDO, CONTENT_TYPE_VIDEO_VDO, "vdo" },
328 		{ CONTENT_TYPE_STR_VIDEO_MSVIDEO, CONTENT_TYPE_VIDEO_MSVIDEO, "avi" },
329 		{ CONTENT_TYPE_STR_X_STARMAIL, CONTENT_TYPE_X_STARMAIL, "smd" },
330 		{ CONTENT_TYPE_STR_X_VRML, CONTENT_TYPE_X_VRML, "wrl" }
331 };
332 
333 //============================================================================
334 /** A mapping from type IDs to presentation resource IDs.  Sorted by type ID.
335  */
336 sal_uInt16 const aStaticResourceIDMap[CONTENT_TYPE_LAST + 1]
337 	= {	STR_SVT_MIMETYPE_APP_OCTSTREAM, // CONTENT_TYPE_UNKNOWN
338 		STR_SVT_MIMETYPE_APP_OCTSTREAM, // CONTENT_TYPE_APP_OCTSTREAM
339 		STR_SVT_MIMETYPE_APP_PDF, // CONTENT_TYPE_APP_PDF
340 		STR_SVT_MIMETYPE_APP_RTF, // CONTENT_TYPE_APP_RTF
341 		STR_SVT_MIMETYPE_APP_MSWORD, // CONTENT_TYPE_APP_MSWORD
342 		STR_SVT_MIMETYPE_APP_MSWORD, // CONTENT_TYPE_APP_MSWORD_TEMPL //@todo new presentation string?
343 		STR_SVT_MIMETYPE_APP_STARCALC, // CONTENT_TYPE_APP_STARCALC
344 		STR_SVT_MIMETYPE_APP_STARCHART, // CONTENT_TYPE_APP_STARCHART
345 		STR_SVT_MIMETYPE_APP_STARDRAW, // CONTENT_TYPE_APP_STARDRAW
346 		STR_SVT_MIMETYPE_APP_STARHELP, // CONTENT_TYPE_APP_STARHELP
347 		STR_SVT_MIMETYPE_APP_STARIMAGE, // CONTENT_TYPE_APP_STARIMAGE
348 		STR_SVT_MIMETYPE_APP_STARIMPRESS, // CONTENT_TYPE_APP_STARIMPRESS
349 		STR_SVT_MIMETYPE_APP_STARMATH, // CONTENT_TYPE_APP_STARMATH
350 		STR_SVT_MIMETYPE_APP_STARWRITER, // CONTENT_TYPE_APP_STARWRITER
351 		STR_SVT_MIMETYPE_APP_ZIP, // CONTENT_TYPE_APP_ZIP
352 		STR_SVT_MIMETYPE_AUDIO_AIFF, // CONTENT_TYPE_AUDIO_AIFF
353 		STR_SVT_MIMETYPE_AUDIO_BASIC, // CONTENT_TYPE_AUDIO_BASIC
354 		STR_SVT_MIMETYPE_AUDIO_MIDI, // CONTENT_TYPE_AUDIO_MIDI
355 		STR_SVT_MIMETYPE_AUDIO_WAV, // CONTENT_TYPE_AUDIO_WAV
356 		STR_SVT_MIMETYPE_IMAGE_GIF, // CONTENT_TYPE_IMAGE_GIF
357 		STR_SVT_MIMETYPE_IMAGE_JPEG, // CONTENT_TYPE_IMAGE_JPEG
358 		STR_SVT_MIMETYPE_IMAGE_PCX, // CONTENT_TYPE_IMAGE_PCX
359 		STR_SVT_MIMETYPE_IMAGE_PNG, // CONTENT_TYPE_IMAGE_PNG
360 		STR_SVT_MIMETYPE_IMAGE_TIFF, // CONTENT_TYPE_IMAGE_TIFF
361 		STR_SVT_MIMETYPE_IMAGE_BMP, // CONTENT_TYPE_IMAGE_BMP
362 		STR_SVT_MIMETYPE_TEXT_HTML, // CONTENT_TYPE_TEXT_HTML
363 		STR_SVT_MIMETYPE_TEXT_PLAIN, // CONTENT_TYPE_TEXT_PLAIN
364 		STR_SVT_MIMETYPE_TEXT_URL, // CONTENT_TYPE_TEXT_URL
365 		STR_SVT_MIMETYPE_TEXT_VCARD, // CONTENT_TYPE_TEXT_VCARD
366 		STR_SVT_MIMETYPE_VIDEO_VDO, // CONTENT_TYPE_VIDEO_VDO
367 		STR_SVT_MIMETYPE_VIDEO_MSVIDEO, // CONTENT_TYPE_VIDEO_MSVIDEO
368 		STR_SVT_MIMETYPE_CNT_MSG, // CONTENT_TYPE_X_CNT_MESSAGE
369 		STR_SVT_MIMETYPE_CNT_DOCUMENT, // CONTENT_TYPE_X_CNT_DOCUMENT
370 		STR_SVT_MIMETYPE_CNT_POP3BOX, // CONTENT_TYPE_X_CNT_POP3BOX
371 		STR_SVT_MIMETYPE_CNT_IMAPBOX, // CONTENT_TYPE_X_CNT_IMAPBOX
372 		STR_SVT_MIMETYPE_CNT_IMAPFLD, // CONTENT_TYPE_X_CNT_IMAPFOLDER
373 		STR_SVT_MIMETYPE_CNT_VIMBOX, // CONTENT_TYPE_X_CNT_VIMBOX
374 		STR_SVT_MIMETYPE_CNT_VIMINBOX, // CONTENT_TYPE_X_CNT_VIMINBOX
375 		STR_SVT_MIMETYPE_CNT_BBBOX, // CONTENT_TYPE_X_CNT_VIMBBOARDBOX
376 		STR_SVT_MIMETYPE_CNT_VIM_BB, // CONTENT_TYPE_X_CNT_VIMBBOARD
377 		STR_SVT_MIMETYPE_CNT_NEWSBOX, // CONTENT_TYPE_X_CNT_NEWSBOX
378 		STR_SVT_MIMETYPE_CNT_NEWSGRP, // CONTENT_TYPE_X_CNT_NEWSGROUP
379 		STR_SVT_MIMETYPE_CNT_OUTBOX, // CONTENT_TYPE_X_CNT_OUTBOX
380 		STR_SVT_MIMETYPE_CNT_FTPBOX, // CONTENT_TYPE_X_CNT_FTPBOX
381 		STR_SVT_MIMETYPE_CNT_FTPFLD, // CONTENT_TYPE_X_CNT_FTPFOLDER
382 		STR_SVT_MIMETYPE_CNT_FTPFILE, // CONTENT_TYPE_X_CNT_FTPFILE
383 		STR_SVT_MIMETYPE_CNT_FTPLINK, // CONTENT_TYPE_X_CNT_FTPLINK
384 		STR_SVT_MIMETYPE_CNT_HTTPBOX, // CONTENT_TYPE_X_CNT_HTTPBOX
385 		STR_SVT_MIMETYPE_CNT_FSYSBOX, // CONTENT_TYPE_X_CNT_FSYSBOX
386 		STR_SVT_MIMETYPE_CNT_FSYSFLD, // CONTENT_TYPE_X_CNT_FSYSFOLDER
387 		STR_SVT_MIMETYPE_CNT_FSYSFILE, // CONTENT_TYPE_X_CNT_FSYSFILE
388 		STR_SVT_MIMETYPE_CNT_FSYSURLFILE, // CONTENT_TYPE_X_CNT_FSYSURLFILE
389 		STR_SVT_MIMETYPE_CNT_PUBLBOX, // CONTENT_TYPE_X_CNT_PUBLISHBOX
390 		STR_SVT_MIMETYPE_CNT_SRCHBOX, // CONTENT_TYPE_X_CNT_SEARCHBOX
391 		STR_SVT_MIMETYPE_CNT_SUBSCRBOX, // CONTENT_TYPE_X_CNT_SUBSCRIBEBOX
392 		STR_SVT_MIMETYPE_CNT_BOOKMARK, // CONTENT_TYPE_X_CNT_BOOKMARK
393 		STR_SVT_MIMETYPE_CNT_CDF, // CONTENT_TYPE_X_CNT_CDF
394 		STR_SVT_MIMETYPE_CNT_CDFSUB, // CONTENT_TYPE_X_CNT_CDFSUB
395 		STR_SVT_MIMETYPE_CNT_CDFITEM, // CONTENT_TYPE_X_CNT_CDFITEM
396 		STR_SVT_MIMETYPE_CNT_TRASHBOX, // CONTENT_TYPE_X_CNT_TRASHBOX
397 		STR_SVT_MIMETYPE_CNT_TRASH, // CONTENT_TYPE_X_CNT_TRASH
398 		STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_X_STARMAIL
399 		STR_SVT_MIMETYPE_X_VRML, // CONTENT_TYPE_X_VRML
400 		STR_SVT_MIMETYPE_CNT_REMOV_VOL,
401 			// CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME
402 		STR_SVT_MIMETYPE_CNT_FIX_VOL, // CONTENT_TYPE_X_CNT_FIXED_VOLUME
403 		STR_SVT_MIMETYPE_CNT_REM_VOL, // CONTENT_TYPE_X_CNT_REMOTE_VOLUME
404 		STR_SVT_MIMETYPE_CNT_RAM_VOL, // CONTENT_TYPE_X_CNT_RAM_VOLUME
405 		STR_SVT_MIMETYPE_CNT_CDROM, // CONTENT_TYPE_X_CNT_CDROM_VOLUME
406 		STR_SVT_MIMETYPE_CNT_DISK_35, // CONTENT_TYPE_X_CNT_DISK_35
407 		STR_SVT_MIMETYPE_CNT_DISK_525, // CONTENT_TYPE_X_CNT_DISK_525
408 		STR_SVT_MIMETYPE_CNT_TAPEDRIVE, // CONTENT_TYPE_X_CNT_TAPEDRIVE
409 		STR_SVT_MIMETYPE_APP_GAL, // CONTENT_TYPE_APP_GALLERY
410 		STR_SVT_MIMETYPE_APP_GAL_THEME, // CONTENT_TYPE_APP_GALLERY_THEME
411 		STR_SVT_MIMETYPE_CNT_STARCHANNEL, // CONTENT_TYPE_X_CNT_STARCHANNEL
412 		STR_SVT_MIMETYPE_CNT_SEPARATOR, // CONTENT_TYPE_X_CNT_SEPARATOR
413 		STR_SVT_MIMETYPE_APP_STARW_GLOB, // CONTENT_TYPE_APP_STARWRITER_GLOB
414 		STR_SVT_MIMETYPE_APP_SDM, // CONTENT_TYPE_APP_STARMAIL_SDM
415 		STR_SVT_MIMETYPE_APP_SMD, // CONTENT_TYPE_APP_STARMAIL_SMD
416 		STR_SVT_MIMETYPE_APP_STARCALC, // CONTENT_TYPE_APP_VND_CALC
417 		STR_SVT_MIMETYPE_APP_STARCHART, // CONTENT_TYPE_APP_VND_CHART
418 		STR_SVT_MIMETYPE_APP_STARDRAW, // CONTENT_TYPE_APP_VND_DRAW
419 		STR_SVT_MIMETYPE_APP_STARIMAGE, // CONTENT_TYPE_APP_VND_IMAGE
420 		STR_SVT_MIMETYPE_APP_STARIMPRESS, // CONTENT_TYPE_APP_VND_IMPRESS
421 		STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_MAIL
422 		STR_SVT_MIMETYPE_APP_STARMATH, // CONTENT_TYPE_APP_VND_MATH
423 		STR_SVT_MIMETYPE_APP_STARWRITER, // CONTENT_TYPE_APP_VND_WRITER
424 		STR_SVT_MIMETYPE_APP_STARW_GLOB, // CONTENT_TYPE_APP_VND_WRITER_GLOBAL
425 		STR_SVT_MIMETYPE_APP_STARW_WEB, // CONTENT_TYPE_APP_VND_WRITER_WEB
426 		STR_SVT_MIMETYPE_SCHEDULE, // CONTENT_TYPE_APP_SCHEDULE
427 		STR_SVT_MIMETYPE_SCHEDULE_EVT, // CONTENT_TYPE_APP_SCHEDULE_EVT
428 		STR_SVT_MIMETYPE_SCHEDULE_TASK, // CONTENT_TYPE_APP_SCHEDULE_TASK
429 		STR_SVT_MIMETYPE_SCHEDULE_FEVT, // CONTENT_TYPE_APP_SCHEDULE_FORM_EVT
430 		STR_SVT_MIMETYPE_SCHEDULE_FTASK,
431 			// CONTENT_TYPE_APP_SCHEDULE_FORM_TASK
432 		STR_SVT_MIMETYPE_FRAMESET, // CONTENT_TYPE_APP_FRAMESET
433 		STR_SVT_MIMETYPE_MACRO, // CONTENT_TYPE_APP_MACRO
434 		STR_SVT_MIMETYPE_CNT_SFSYSFOLDER,
435 			// CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER
436 		STR_SVT_MIMETYPE_CNT_SFSYSFILE, // CONTENT_TYPE_X_CNT_FSYSSPECIALFILE
437 		STR_SVT_MIMETYPE_APP_TEMPLATE, // CONTENT_TYPE_APP_VND_TEMPLATE
438 		STR_SVT_MIMETYPE_IMAGE_GENERIC, // CONTENT_TYPE_IMAGE_GENERIC
439 		STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_NEWS
440 		STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_OUTTRAY
441 		STR_SVT_MIMETYPE_TEXT_HTML, // CONTENT_TYPE_X_CNT_HTTPFILE
442 		STR_SVT_MIMETYPE_APP_MSEXCEL, // CONTENT_TYPE_APP_MSEXCEL
443 		STR_SVT_MIMETYPE_APP_MSEXCEL_TEMPL, // CONTENT_TYPE_APP_MSEXCEL_TEMPL
444 		STR_SVT_MIMETYPE_APP_MSPPOINT, // CONTENT_TYPE_APP_MSPPOINT
445 		STR_SVT_MIMETYPE_APP_MSPPOINT, // CONTENT_TYPE_APP_MSPPOINT_TEMPL //@todo new presentation string?
446 		STR_SVT_MIMETYPE_TEXT_VCALENDAR, // CONTENT_TYPE_TEXT_VCALENDAR
447 		STR_SVT_MIMETYPE_TEXT_ICALENDAR, // CONTENT_TYPE_TEXT_ICALENDAR
448 		STR_SVT_MIMETYPE_TEXT_XMLICALENDAR, // CONTENT_TYPE_TEXT_XMLICALENDAR
449 		STR_SVT_MIMETYPE_TEXT_CDE_CALENDAR_APP,
450 			// CONTENT_TYPE_APP_CDE_CALENDAR_APP
451 		STR_SVT_MIMETYPE_INET_MSG_RFC822, // CONTENT_TYPE_INET_MESSAGE_RFC822
452 		STR_SVT_MIMETYPE_INET_MULTI_ALTERNATIVE,
453 			// CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE
454 		STR_SVT_MIMETYPE_INET_MULTI_DIGEST,
455 			// CONTENT_TYPE_INET_MULTIPART_DIGEST
456 		STR_SVT_MIMETYPE_INET_MULTI_PARALLEL,
457 			// CONTENT_TYPE_INET_MULTIPART_PARALLEL
458 		STR_SVT_MIMETYPE_INET_MULTI_RELATED,
459 			// CONTENT_TYPE_INET_MULTIPART_RELATED
460 		STR_SVT_MIMETYPE_INET_MULTI_MIXED,
461 			// CONTENT_TYPE_INET_MULTIPART_MIXED
462 		STR_SVT_MIMETYPE_APP_IMPRESSPACKED,
463 			// CONTENT_TYPE_APP_VND_IMPRESSPACKED
464 		STR_SVT_MIMETYPE_APP_JAR, // CONTENT_TYPE_APP_JAR
465 		STR_SVT_MIMETYPE_APP_SXWRITER, // CONTENT_TYPE_APP_VND_SUN_XML_WRITER
466 		STR_SVT_MIMETYPE_APP_SXCALC, // CONTENT_TYPE_APP_VND_SUN_XML_CALC
467 		STR_SVT_MIMETYPE_APP_SXIMPRESS, // CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS
468 		STR_SVT_MIMETYPE_APP_SXDRAW, // CONTENT_TYPE_APP_VND_SUN_XML_DRAW
469 		STR_SVT_MIMETYPE_APP_SXCHART, // CONTENT_TYPE_APP_VND_SUN_XML_CHART
470 		STR_SVT_MIMETYPE_APP_SXMATH, // CONTENT_TYPE_APP_VND_SUN_XML_MATH
471 		STR_SVT_MIMETYPE_APP_SXGLOBAL, // CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL
472 		STR_SVT_MIMETYPE_APP_SXIPACKED, // CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED
473  };
474 
475 //============================================================================
476 /** A mapping from extensions to type IDs.  Sorted by extension.
477  */
478 MediaTypeEntry const aStaticExtensionMap[]
479 	= { { "aif", CONTENT_TYPE_AUDIO_AIFF, "" },
480 		{ "aiff", CONTENT_TYPE_AUDIO_AIFF, "" },
481 		{ "appt", CONTENT_TYPE_APP_CDE_CALENDAR_APP, "" },
482 		{ "au", CONTENT_TYPE_AUDIO_BASIC, "" },
483 		{ "avi", CONTENT_TYPE_VIDEO_MSVIDEO, "" },
484 		{ "bmp", CONTENT_TYPE_IMAGE_BMP, "" },
485 		{ "cgm", CONTENT_TYPE_IMAGE_GENERIC, "" },
486 		{ "doc", CONTENT_TYPE_APP_MSWORD, "" },
487 		{ "dot", CONTENT_TYPE_APP_MSWORD_TEMPL, "" },
488 		{ "dxf", CONTENT_TYPE_IMAGE_GENERIC, "" },
489 		{ "eps", CONTENT_TYPE_IMAGE_GENERIC, "" },
490 		{ "gal", CONTENT_TYPE_APP_GALLERY, "" },
491 		{ "gif", CONTENT_TYPE_IMAGE_GIF, "" },
492 		{ "htm", CONTENT_TYPE_TEXT_HTML, "" },
493 		{ "html", CONTENT_TYPE_TEXT_HTML, "" },
494 		{ "ics", CONTENT_TYPE_TEXT_ICALENDAR, "" },
495 		{ "jar", CONTENT_TYPE_APP_JAR, "" },
496 		{ "jpeg", CONTENT_TYPE_IMAGE_JPEG, "" },
497 		{ "jpg", CONTENT_TYPE_IMAGE_JPEG, "" },
498 		{ "met", CONTENT_TYPE_IMAGE_GENERIC, "" },
499 		{ "mid", CONTENT_TYPE_AUDIO_MIDI, "" },
500 		{ "midi", CONTENT_TYPE_AUDIO_MIDI, "" },
501 		{ "pbm", CONTENT_TYPE_IMAGE_GENERIC, "" },
502 		{ "pcd", CONTENT_TYPE_IMAGE_GENERIC, "" },
503 		{ "pct", CONTENT_TYPE_IMAGE_GENERIC, "" },
504 		{ "pcx", CONTENT_TYPE_IMAGE_PCX, "" },
505 		{ "pdf", CONTENT_TYPE_APP_PDF, "" },
506 		{ "pgm", CONTENT_TYPE_IMAGE_GENERIC, "" },
507 		{ "png", CONTENT_TYPE_IMAGE_PNG, "" },
508 		{ "pot", CONTENT_TYPE_APP_MSPPOINT_TEMPL, "" },
509 		{ "ppm", CONTENT_TYPE_IMAGE_GENERIC, "" },
510 		{ "ppt", CONTENT_TYPE_APP_MSPPOINT, "" },
511 		{ "psd", CONTENT_TYPE_IMAGE_GENERIC, "" },
512 		{ "ras", CONTENT_TYPE_IMAGE_GENERIC, "" },
513 		{ "rtf", CONTENT_TYPE_APP_RTF, "" },
514 		{ "sda", CONTENT_TYPE_APP_VND_DRAW, "" },
515 		{ "sdc", CONTENT_TYPE_APP_VND_CALC, "" },
516 		{ "sdd", CONTENT_TYPE_APP_VND_IMPRESS, "" },
517 		{ "sdm", CONTENT_TYPE_APP_VND_MAIL, "" },
518 		{ "sdp", CONTENT_TYPE_APP_VND_IMPRESSPACKED, "" },
519 		{ "sds", CONTENT_TYPE_APP_VND_CHART, "" },
520 		{ "sdw", CONTENT_TYPE_APP_VND_WRITER, "" },
521 		{ "sd~", CONTENT_TYPE_X_STARMAIL, "" },
522 		{ "sfs", CONTENT_TYPE_APP_FRAMESET , "" },
523 		{ "sgl", CONTENT_TYPE_APP_VND_WRITER_GLOBAL , "" },
524 		{ "sim", CONTENT_TYPE_APP_VND_IMAGE, "" },
525 		{ "smd", CONTENT_TYPE_APP_STARMAIL_SMD, "" }, //CONTENT_TYPE_X_STARMAIL
526 		{ "smf", CONTENT_TYPE_APP_VND_MATH, "" },
527 		{ "svh", CONTENT_TYPE_APP_STARHELP, "" },
528 		{ "svm", CONTENT_TYPE_IMAGE_GENERIC, "" },
529 		{ "sxc", CONTENT_TYPE_APP_VND_SUN_XML_CALC, "" },
530 		{ "sxd", CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "" },
531 		{ "sxg", CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, "" },
532 		{ "sxi", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "" },
533 		{ "sxm", CONTENT_TYPE_APP_VND_SUN_XML_MATH, "" },
534 		{ "sxp", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, "" },
535 		{ "sxs", CONTENT_TYPE_APP_VND_SUN_XML_CHART, "" },
536 		{ "sxw", CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "" },
537 		{ "tga", CONTENT_TYPE_IMAGE_GENERIC, "" },
538 		{ "thm", CONTENT_TYPE_APP_GALLERY_THEME, "" },
539 		{ "tif", CONTENT_TYPE_IMAGE_TIFF, "" },
540 		{ "tiff", CONTENT_TYPE_IMAGE_TIFF, "" },
541 		{ "txt", CONTENT_TYPE_TEXT_PLAIN, "" },
542 		{ "url", CONTENT_TYPE_TEXT_URL, "" },
543 		{ "vcf", CONTENT_TYPE_TEXT_VCARD, "" },
544 		{ "vcs", CONTENT_TYPE_TEXT_VCALENDAR, "" },
545 		{ "vdo", CONTENT_TYPE_VIDEO_VDO, "" },
546 		{ "vor", CONTENT_TYPE_APP_VND_TEMPLATE, "" },
547 		{ "wav", CONTENT_TYPE_AUDIO_WAV, "" },
548 		{ "wmf", CONTENT_TYPE_IMAGE_GENERIC, "" },
549 		{ "wrl", CONTENT_TYPE_X_VRML, "" },
550 		{ "xbm", CONTENT_TYPE_IMAGE_GENERIC, "" },
551 		{ "xcs", CONTENT_TYPE_TEXT_XMLICALENDAR, "" },
552 		{ "xls", CONTENT_TYPE_APP_MSEXCEL, "" },
553 		{ "xlt", CONTENT_TYPE_APP_MSEXCEL_TEMPL, "" },
554 		{ "xlw", CONTENT_TYPE_APP_MSEXCEL, "" },
555 		{ "xpm", CONTENT_TYPE_IMAGE_GENERIC, "" },
556 		{ "zip", CONTENT_TYPE_APP_ZIP, "" } };
557 
558 //============================================================================
559 /** A mapping from presentations to type IDs.  Sorted by presentations.
560  */
561 MediaTypeEntry const aStaticPresentationMap[]
562 	= { { "Binary Data", CONTENT_TYPE_APP_OCTSTREAM, "" },
563 		{ "Bitmap", CONTENT_TYPE_IMAGE_BMP, "" },
564 		{ "DOS Command File", CONTENT_TYPE_APP_OCTSTREAM, "" },
565 		{ "Digital Video", CONTENT_TYPE_VIDEO_MSVIDEO, "" },
566 		{ "Executable", CONTENT_TYPE_APP_OCTSTREAM, "" },
567 		{ "Grafik", CONTENT_TYPE_IMAGE_GENERIC, "" },
568 		{ "HTM", CONTENT_TYPE_TEXT_HTML, "" },
569 		{ "HTML", CONTENT_TYPE_TEXT_HTML, "" },
570 		{ "Hypertext", CONTENT_TYPE_TEXT_HTML, "" },
571 		{ "Icon", CONTENT_TYPE_IMAGE_GENERIC, "" },
572 		{ "Image File", CONTENT_TYPE_IMAGE_GENERIC, "" },
573 		{ "MIDI", CONTENT_TYPE_AUDIO_MIDI, "" },
574 		{ "Master Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" },
575 		{ "Plain Text", CONTENT_TYPE_TEXT_PLAIN, "" },
576 		{ "StarCalc", CONTENT_TYPE_APP_VND_CALC, "" },
577 		{ "StarCalc 3.0", CONTENT_TYPE_APP_VND_CALC, "" },
578 		{ "StarCalc 4.0", CONTENT_TYPE_APP_VND_CALC, "" },
579 		{ "StarCalc 5.0", CONTENT_TYPE_APP_VND_CALC, "" },
580 		{ "StarCalc Datei", CONTENT_TYPE_APP_VND_CALC, "" },
581 		{ "StarCalc Document", CONTENT_TYPE_APP_VND_CALC, "" },
582 		{ "StarCalc File", CONTENT_TYPE_APP_VND_CALC, "" },
583 		{ "StarChart 3.0", CONTENT_TYPE_APP_VND_CHART, "" },
584 		{ "StarChart 4.0", CONTENT_TYPE_APP_VND_CHART, "" },
585 		{ "StarChart 5.0", CONTENT_TYPE_APP_VND_CHART, "" },
586 		{ "StarChart Document", CONTENT_TYPE_APP_VND_CHART, "" },
587 		{ "StarDraw 3.0", CONTENT_TYPE_APP_VND_DRAW, "" },
588 		{ "StarDraw 5.0", CONTENT_TYPE_APP_VND_DRAW, "" },
589 		{ "StarDraw", CONTENT_TYPE_APP_VND_DRAW, "" },
590 		{ "StarDraw Document", CONTENT_TYPE_APP_VND_DRAW, "" },
591 		{ "StarImpress 4.0", CONTENT_TYPE_APP_VND_IMPRESS, "" },
592 		{ "StarImpress 5.0 (packed)", CONTENT_TYPE_APP_VND_IMPRESSPACKED, "" },
593 		{ "StarImpress 5.0", CONTENT_TYPE_APP_VND_IMPRESS, "" },
594 		{ "StarImpress Document", CONTENT_TYPE_APP_VND_IMPRESS, "" },
595 		{ "StarMath 3.0", CONTENT_TYPE_APP_VND_MATH, "" },
596 		{ "StarMath 4.0", CONTENT_TYPE_APP_VND_MATH, "" },
597 		{ "StarMath 5.0", CONTENT_TYPE_APP_VND_MATH, "" },
598 		{ "StarMath Document", CONTENT_TYPE_APP_VND_MATH, "" },
599 		{ "StarMessage5", CONTENT_TYPE_APP_VND_MAIL, "" },
600 		{ "StarOffice XML (Calc)", CONTENT_TYPE_APP_VND_SUN_XML_CALC, "" },
601 		{ "StarOffice XML (Impress)", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "" },
602 		{ "StarOffice XML (Draw)", CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "" },
603 		{ "StarOffice XML (Chart)", CONTENT_TYPE_APP_VND_SUN_XML_CHART, "" },
604 		{ "StarOffice XML (Writer)", CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "" },
605 		{ "StarWriter", CONTENT_TYPE_APP_VND_WRITER, "" },
606 		{ "StarWriter 3.0", CONTENT_TYPE_APP_VND_WRITER, "" },
607 		{ "StarWriter 4.0", CONTENT_TYPE_APP_VND_WRITER, "" },
608 		{ "StarWriter 5.0", CONTENT_TYPE_APP_VND_WRITER, "" },
609 		{ "StarWriter Document", CONTENT_TYPE_APP_VND_WRITER, "" },
610 		{ "StarWriter/Global 5.0", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" },
611 		{ "StarWriter/Global Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" },
612 		{ "StarWriter/Web 5.0", CONTENT_TYPE_APP_VND_WRITER_WEB, "" },
613 		{ "StarWriterGlobal Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" },
614 		{ "StarWriterHtml Document", CONTENT_TYPE_APP_VND_WRITER_WEB, "" },
615 		{ "UniformResourceLocator", CONTENT_TYPE_TEXT_URL, "" },
616 		{ "text/html", CONTENT_TYPE_TEXT_HTML, "" } };
617 
618 }
619 
620 //============================================================================
621 //
622 //  Registration
623 //
624 //============================================================================
625 
626 // static
627 Registration * Registration::m_pRegistration = 0;
628 
629 //============================================================================
~Registration()630 Registration::~Registration()
631 {
632 	{for (sal_uLong i = 0; i < m_aTypeIDMap.Count(); ++i)
633 		delete static_cast< TypeIDMapEntry * >(m_aTypeIDMap.GetObject(i));
634 	}
635 	m_aTypeIDMap.Clear();
636 	{for (sal_uInt16 i = 0; i < m_aTypeNameMap.Count(); ++i)
637 		delete static_cast< TypeNameMapEntry * >(m_aTypeNameMap.GetObject(i));
638 	}
639 	m_aTypeNameMap.Remove(sal_uInt16(0), m_aTypeNameMap.Count());
640 	{for (sal_uInt16 i = 0; i < m_aExtensionMap.Count(); ++i)
641 		delete
642 			static_cast< ExtensionMapEntry * >(m_aExtensionMap.GetObject(i));
643 	}
644 	m_aExtensionMap.Remove(sal_uInt16(0), m_aExtensionMap.Count());
645 }
646 
647 //============================================================================
648 // static
getExtensionEntry(UniString const & rTypeName)649 TypeNameMapEntry * Registration::getExtensionEntry(UniString const &
650 												       rTypeName)
651 {
652 	if (m_pRegistration)
653 	{
654 		UniString aTheTypeName = rTypeName;
655 		aTheTypeName.ToLowerAscii();
656 		sal_uInt16 nPos;
657 		if (m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos))
658 			return static_cast< TypeNameMapEntry * >(m_pRegistration->
659 													     m_aTypeNameMap.
660 													         GetObject(nPos));
661 	}
662 	return 0;
663 }
664 
665 //============================================================================
666 // static
RegisterContentType(UniString const & rTypeName,UniString const & rPresentation,UniString const * pExtension,UniString const * pSystemFileType)667 INetContentType Registration::RegisterContentType(UniString const & rTypeName,
668 												  UniString const &
669 												      rPresentation,
670 												  UniString const *
671 												      pExtension,
672 												  UniString const *
673 												      pSystemFileType)
674 {
675 	if (!m_pRegistration)
676 		m_pRegistration = new Registration;
677 
678 	DBG_ASSERT(GetContentType(rTypeName) == CONTENT_TYPE_UNKNOWN,
679 			   "Registration::RegisterContentType(): Already registered");
680 
681 	INetContentType eTypeID
682 		= INetContentType(m_pRegistration->m_nNextDynamicID++);
683 	UniString aTheTypeName = rTypeName;
684 	aTheTypeName.ToLowerAscii();
685 
686 	TypeIDMapEntry * pTypeIDMapEntry = new TypeIDMapEntry;
687 	pTypeIDMapEntry->m_aTypeName = aTheTypeName;
688 	pTypeIDMapEntry->m_aPresentation = rPresentation;
689 	if (pSystemFileType)
690 		pTypeIDMapEntry->m_aSystemFileType = *pSystemFileType;
691 	m_pRegistration->m_aTypeIDMap.Insert(eTypeID, pTypeIDMapEntry);
692 
693 	TypeNameMapEntry * pTypeNameMapEntry = new TypeNameMapEntry(aTheTypeName);
694 	if (pExtension)
695 		pTypeNameMapEntry->m_aExtension = *pExtension;
696 	pTypeNameMapEntry->m_eTypeID = eTypeID;
697 	m_pRegistration->m_aTypeNameMap.Insert(pTypeNameMapEntry);
698 
699 	if (pExtension)
700 	{
701 		ExtensionMapEntry * pExtensionMapEntry
702 			= new ExtensionMapEntry(*pExtension);
703 		pExtensionMapEntry->m_eTypeID = eTypeID;
704 		m_pRegistration->m_aExtensionMap.Insert(pExtensionMapEntry);
705 	}
706 
707 	return eTypeID;
708 }
709 
710 //============================================================================
711 // static
GetContentType(UniString const & rTypeName)712 INetContentType Registration::GetContentType(UniString const & rTypeName)
713 {
714 	if (!m_pRegistration)
715 		m_pRegistration = new Registration;
716 
717 	UniString aTheTypeName = rTypeName;
718 	aTheTypeName.ToLowerAscii();
719 	sal_uInt16 nPos;
720 	return m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos) ?
721 		       static_cast< TypeNameMapEntry * >(m_pRegistration->
722 												     m_aTypeNameMap.
723 												         GetObject(nPos))->
724 		           m_eTypeID :
725 		       CONTENT_TYPE_UNKNOWN;
726 }
727 
728 //============================================================================
729 // static
GetContentType(INetContentType eTypeID)730 UniString Registration::GetContentType(INetContentType eTypeID)
731 {
732 	if (!m_pRegistration)
733 		m_pRegistration = new Registration;
734 
735 	TypeIDMapEntry * pEntry
736 		= static_cast< TypeIDMapEntry * >(m_pRegistration->
737 										      m_aTypeIDMap.Get(eTypeID));
738 	return pEntry ? pEntry->m_aTypeName : UniString();
739 }
740 
741 //============================================================================
742 // static
GetPresentation(INetContentType eTypeID)743 UniString Registration::GetPresentation(INetContentType eTypeID)
744 {
745 	if (!m_pRegistration)
746 		m_pRegistration = new Registration;
747 
748 	TypeIDMapEntry * pEntry
749 		= static_cast< TypeIDMapEntry * >(m_pRegistration->
750 										      m_aTypeIDMap.Get(eTypeID));
751 	return pEntry ? pEntry->m_aPresentation : UniString();
752 }
753 
754 //============================================================================
755 // static
GetExtension(UniString const & rTypeName)756 UniString Registration::GetExtension(UniString const & rTypeName)
757 {
758 	if (!m_pRegistration)
759 		m_pRegistration = new Registration;
760 
761 	UniString aTheTypeName = rTypeName;
762 	aTheTypeName.ToLowerAscii();
763 	sal_uInt16 nPos;
764 	return m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos) ?
765 		       static_cast< TypeNameMapEntry * >(m_pRegistration->
766 												     m_aTypeNameMap.
767 												         GetObject(nPos))->
768 		           m_aExtension :
769 		       UniString();
770 }
771 
772 //============================================================================
773 // static
GetContentType4Extension(UniString const & rExtension)774 INetContentType Registration::GetContentType4Extension(UniString const &
775 													       rExtension)
776 {
777 	if (!m_pRegistration)
778 		m_pRegistration = new Registration;
779 
780 	sal_uInt16 nPos;
781 	return m_pRegistration->
782 		           m_aExtensionMap.
783 		               Seek_Entry(const_cast< UniString * >(&rExtension),
784 								  &nPos) ?
785 		       static_cast< ExtensionMapEntry * >(m_pRegistration->
786 												      m_aExtensionMap.
787 												          GetObject(nPos))->
788 		           m_eTypeID :
789 		       CONTENT_TYPE_UNKNOWN;
790 }
791 
792 //============================================================================
793 //
794 //  seekEntry
795 //
796 //============================================================================
797 
798 namespace unnamed_svl_inettype {
799 
seekEntry(UniString const & rTypeName,MediaTypeEntry const * pMap,sal_Size nSize)800 MediaTypeEntry const * seekEntry(UniString const & rTypeName,
801 								 MediaTypeEntry const * pMap, sal_Size nSize)
802 {
803 #if defined DBG_UTIL
804     for (sal_Size i = 0; i < nSize - 1; ++i)
805         DBG_ASSERT(
806             rtl_str_compare(
807                 pMap[i].m_pTypeName, pMap[i + 1].m_pTypeName) < 0,
808             "seekEntry(): Bad map");
809 #endif
810 
811 	sal_Size nLow = 0;
812 	sal_Size nHigh = nSize;
813 	while (nLow != nHigh)
814 	{
815 		sal_Size nMiddle = (nLow + nHigh) / 2;
816 		MediaTypeEntry const * pEntry = pMap + nMiddle;
817 		switch (rTypeName.CompareIgnoreCaseToAscii(pEntry->m_pTypeName))
818 		{
819 			case COMPARE_LESS:
820 				nHigh = nMiddle;
821 				break;
822 
823 			case COMPARE_EQUAL:
824 				return pEntry;
825 
826 			case COMPARE_GREATER:
827 				nLow = nMiddle + 1;
828 				break;
829 		}
830 	}
831 	return 0;
832 }
833 
834 }
835 
836 //============================================================================
837 //
838 //  INetContentTypes
839 //
840 //============================================================================
841 
842 //static
Uninitialize()843 void INetContentTypes::Uninitialize()
844 {
845 	Registration::deinitialize();
846 }
847 
848 //============================================================================
849 //static
RegisterContentType(UniString const & rTypeName,UniString const & rPresentation,UniString const * pExtension,UniString const * pSystemFileType)850 INetContentType INetContentTypes::RegisterContentType(UniString const &
851 													      rTypeName,
852 													  UniString const &
853 													      rPresentation,
854 													  UniString const *
855 													      pExtension,
856 													  UniString const *
857 													      pSystemFileType)
858 {
859 	INetContentType eTypeID = GetContentType(rTypeName);
860 	if (eTypeID == CONTENT_TYPE_UNKNOWN)
861 		eTypeID = Registration::RegisterContentType(rTypeName, rPresentation,
862 													pExtension,
863 													pSystemFileType);
864 	else if (eTypeID > CONTENT_TYPE_LAST)
865 	{
866 		TypeIDMapEntry * pTypeEntry = Registration::getEntry(eTypeID);
867 		if (pTypeEntry)
868 		{
869 			if (rPresentation.Len() != 0)
870 				pTypeEntry->m_aPresentation = rPresentation;
871 			if (pSystemFileType)
872 				pTypeEntry->m_aSystemFileType = *pSystemFileType;
873 		}
874 		if (pExtension)
875 		{
876 			TypeNameMapEntry * pEntry
877 				= Registration::getExtensionEntry(rTypeName);
878 			if (pEntry)
879 				pEntry->m_aExtension = *pExtension;
880 		}
881 	}
882 	return eTypeID;
883 }
884 
885 //============================================================================
886 // static
GetContentType(UniString const & rTypeName)887 INetContentType INetContentTypes::GetContentType(UniString const & rTypeName)
888 {
889 	UniString aType;
890 	UniString aSubType;
891 	if (parse(rTypeName, aType, aSubType))
892 	{
893 		aType += '/';
894 		aType += aSubType;
895 		MediaTypeEntry const * pEntry = seekEntry(aType, aStaticTypeNameMap,
896 												  CONTENT_TYPE_LAST + 1);
897 		return pEntry ? pEntry->m_eTypeID :
898 			            Registration::GetContentType(aType);
899 	}
900 	else
901 		return
902 			rTypeName.EqualsIgnoreCaseAscii(CONTENT_TYPE_STR_X_STARMAIL) ?
903 			    CONTENT_TYPE_X_STARMAIL : CONTENT_TYPE_UNKNOWN;
904 			// the content type "x-starmail" has no sub type
905 }
906 
907 //============================================================================
908 //static
GetContentType(INetContentType eTypeID)909 UniString INetContentTypes::GetContentType(INetContentType eTypeID)
910 {
911 	static sal_Char const * aMap[CONTENT_TYPE_LAST + 1];
912 	static bool bInitialized = false;
913 	if (!bInitialized)
914 	{
915 		for (sal_Size i = 0; i <= CONTENT_TYPE_LAST; ++i)
916 			aMap[aStaticTypeNameMap[i].m_eTypeID]
917 				= aStaticTypeNameMap[i].m_pTypeName;
918 		aMap[CONTENT_TYPE_UNKNOWN] = CONTENT_TYPE_STR_APP_OCTSTREAM;
919 		aMap[CONTENT_TYPE_TEXT_PLAIN] = CONTENT_TYPE_STR_TEXT_PLAIN
920 			                                "; charset=iso-8859-1";
921 		bInitialized = true;
922 	}
923 
924 	UniString aTypeName = eTypeID <= CONTENT_TYPE_LAST ?
925 		                      UniString::CreateFromAscii(aMap[eTypeID]) :
926 		                      Registration::GetContentType(eTypeID);
927 	if (aTypeName.Len() == 0)
928 	{
929 		DBG_ERROR("INetContentTypes::GetContentType(): Bad ID");
930 		return
931 			UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
932 				                           CONTENT_TYPE_STR_APP_OCTSTREAM));
933 	}
934 	return aTypeName;
935 }
936 
937 //============================================================================
938 //static
GetPresentation(INetContentType eTypeID,const::com::sun::star::lang::Locale & aLocale)939 UniString INetContentTypes::GetPresentation(INetContentType eTypeID,
940 											const ::com::sun::star::lang::Locale& aLocale)
941 {
942 	sal_uInt16 nResID = sal_uInt16();
943 	if (eTypeID <= CONTENT_TYPE_LAST)
944 		nResID = aStaticResourceIDMap[eTypeID];
945 	else
946 	{
947 		UniString aPresentation = Registration::GetPresentation(eTypeID);
948 		if (aPresentation.Len() == 0)
949 			nResID = STR_SVT_MIMETYPE_APP_OCTSTREAM;
950 		else
951 			return aPresentation;
952 	}
953 	return SvtSimpleResId(nResID, aLocale);
954 }
955 
956 //============================================================================
957 //static
GetExtension(UniString const & rTypeName)958 UniString INetContentTypes::GetExtension(UniString const & rTypeName)
959 {
960 	MediaTypeEntry const * pEntry = seekEntry(rTypeName, aStaticTypeNameMap,
961 											  CONTENT_TYPE_LAST + 1);
962 	if (pEntry)
963 		return UniString::CreateFromAscii(pEntry->m_pExtension);
964 
965 	UniString aExtension = Registration::GetExtension(rTypeName);
966 	if (aExtension.Len() != 0)
967 		return aExtension;
968 	// special handling of text types, which come in uncounted variations:
969 	return rTypeName.EqualsIgnoreCaseAscii("text", 0,
970 										   RTL_CONSTASCII_LENGTH("text")) ?
971 		       UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("txt")) :
972 		       UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("tmp"));
973 }
974 
975 //============================================================================
976 //static
GetContentType4Extension(UniString const & rExtension)977 INetContentType INetContentTypes::GetContentType4Extension(UniString const &
978 														       rExtension)
979 {
980 	MediaTypeEntry const * pEntry = seekEntry(rExtension, aStaticExtensionMap,
981 											  sizeof aStaticExtensionMap
982 											      / sizeof (MediaTypeEntry));
983 	if (pEntry)
984 		return pEntry->m_eTypeID;
985 	INetContentType eTypeID
986 		= Registration::GetContentType4Extension(rExtension);
987 	return eTypeID == CONTENT_TYPE_UNKNOWN ? CONTENT_TYPE_APP_OCTSTREAM :
988 		                                     eTypeID;
989 }
990 
991 //============================================================================
992 //static
GetContentTypeFromURL(UniString const & rURL)993 INetContentType INetContentTypes::GetContentTypeFromURL(UniString const &
994 														    rURL)
995 {
996 	INetContentType eTypeID = CONTENT_TYPE_UNKNOWN;
997 	UniString aToken = rURL.GetToken(0, ':');
998 	if (aToken.Len() != 0)
999 	{
1000 		if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_FILE))
1001 			if (rURL.GetChar(rURL.Len() - 1) == '/') // folder
1002 				if (rURL.Len() > RTL_CONSTASCII_LENGTH("file:///"))
1003 					if (WildCard(UniString(RTL_CONSTASCII_USTRINGPARAM(
1004 						                       "*/{*}/"))).
1005 						    Matches(rURL)) // special folder
1006 						eTypeID = CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER;
1007 					else
1008 						// drive? -> "file:///?|/"
1009 						if (rURL.Len() == 11
1010 							&& rURL.GetChar(rURL.Len() - 2) == '|')
1011 						{
1012 							// Drives need further processing, because of
1013 							// dynamic type according to underlying volume,
1014 							// which cannot be determined here.
1015 						}
1016 						else // normal folder
1017 							eTypeID = CONTENT_TYPE_X_CNT_FSYSFOLDER;
1018 				else // file system root
1019 					eTypeID = CONTENT_TYPE_X_CNT_FSYSBOX;
1020 			else // file
1021 			{
1022 				//@@@
1023 			}
1024 		else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_HTTP)
1025 				 || aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_HTTPS))
1026 			eTypeID = CONTENT_TYPE_TEXT_HTML;
1027 		else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_PRIVATE))
1028 		{
1029 			UniString aSecondPart = rURL.GetToken(1, ':');
1030 			aToken = aSecondPart.GetToken(0, '/');
1031 			if (aToken.EqualsAscii(INETTYPE_URL_SUB_FACTORY))
1032 			{
1033 				aToken = aSecondPart.GetToken(1, '/');
1034 				if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SWRITER))
1035 				{
1036 					aToken = aSecondPart.GetToken(2, '/');
1037 					eTypeID = aToken.EqualsAscii(INETTYPE_URL_SSSUB_WEB) ?
1038 						          CONTENT_TYPE_APP_VND_WRITER_WEB :
1039 						      aToken.EqualsAscii(INETTYPE_URL_SSSUB_GLOB) ?
1040 						          CONTENT_TYPE_APP_VND_WRITER_GLOBAL :
1041 						          CONTENT_TYPE_APP_VND_WRITER;
1042 				}
1043 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SCALC))
1044 					eTypeID = CONTENT_TYPE_APP_VND_CALC;
1045 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SDRAW))
1046 					eTypeID = CONTENT_TYPE_APP_VND_DRAW;
1047 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SIMPRESS))
1048 					eTypeID = CONTENT_TYPE_APP_VND_IMPRESS;
1049 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SCHART))
1050 					eTypeID = CONTENT_TYPE_APP_VND_CHART;
1051 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SIMAGE))
1052 					eTypeID = CONTENT_TYPE_APP_VND_IMAGE;
1053 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SMATH))
1054 					eTypeID = CONTENT_TYPE_APP_VND_MATH;
1055 				else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_FRAMESET))
1056 					eTypeID = CONTENT_TYPE_APP_FRAMESET;
1057 			}
1058 			else if (aToken.EqualsAscii(INETTYPE_URL_SUB_HELPID))
1059 				eTypeID = CONTENT_TYPE_APP_STARHELP;
1060 		}
1061 		else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_COMPONENT))
1062 		{
1063 			aToken = rURL.GetToken(1, ':'); // aToken now equals ss / *
1064 			aToken = aToken.GetToken(0, '/');
1065   			if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SS))
1066   				eTypeID = rURL.SearchAscii(INETTYPE_URL_SCHED_CMB)
1067 					          == STRING_NOTFOUND
1068 					      && rURL.SearchAscii(INETTYPE_URL_SCHED_FORM)
1069 					             == STRING_NOTFOUND ?
1070 					          CONTENT_TYPE_APP_SCHEDULE :
1071 				          rURL.SearchAscii(INETTYPE_URL_SCHED_TASK)
1072 					              == STRING_NOTFOUND ?
1073 					          CONTENT_TYPE_APP_SCHEDULE_EVT :
1074 				              CONTENT_TYPE_APP_SCHEDULE_TASK;
1075 		}
1076 		else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_MAILTO))
1077 			eTypeID = CONTENT_TYPE_APP_VND_OUTTRAY;
1078 		else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_MACRO))
1079 			eTypeID = CONTENT_TYPE_APP_MACRO;
1080 		else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_DATA))
1081 		{
1082 			UniString aSecondPart = rURL.GetToken(1, ':');
1083 			aToken = aSecondPart.GetToken(0, ',');
1084 			eTypeID = GetContentType(aToken);
1085 		}
1086     }
1087 	if (eTypeID == CONTENT_TYPE_UNKNOWN)
1088 	{
1089 		UniString aExtension;
1090 		if (GetExtensionFromURL(rURL, aExtension))
1091 			eTypeID = GetContentType4Extension(aExtension);
1092 	}
1093 	return eTypeID;
1094 }
1095 
1096 //============================================================================
1097 //static
GetExtensionFromURL(UniString const & rURL,UniString & rExtension)1098 bool INetContentTypes::GetExtensionFromURL(UniString const & rURL,
1099 										   UniString & rExtension)
1100 {
1101 	xub_StrLen nSlashPos = 0;
1102 	xub_StrLen i = 0;
1103 	while (i != STRING_NOTFOUND)
1104 	{
1105 		nSlashPos = i;
1106 		i = rURL.Search('/', i + 1);
1107 	}
1108 	if (nSlashPos != 0)
1109 	{
1110 		xub_StrLen nLastDotPos = i = rURL.Search('.', nSlashPos);
1111 		while (i != STRING_NOTFOUND)
1112 		{
1113 			nLastDotPos = i;
1114 			i = rURL.Search('.', i + 1);
1115 		}
1116 		if (nLastDotPos != STRING_NOTFOUND)
1117 			rExtension = rURL.Copy(nLastDotPos + 1);
1118 		return true;
1119 	}
1120 	return false;
1121 }
1122 
1123 //============================================================================
1124 //static
MapStringToContentType(UniString const & rPresentation)1125 INetContentType INetContentTypes::MapStringToContentType(UniString const &
1126 														     rPresentation)
1127 {
1128 	MediaTypeEntry const * pEntry = seekEntry(rPresentation,
1129 											  aStaticPresentationMap,
1130 											  sizeof aStaticPresentationMap
1131 											      / sizeof (MediaTypeEntry));
1132 	return pEntry ? pEntry->m_eTypeID : CONTENT_TYPE_UNKNOWN;
1133 }
1134 
1135 //============================================================================
1136 // static
parse(ByteString const & rMediaType,ByteString & rType,ByteString & rSubType,INetContentTypeParameterList * pParameters)1137 bool INetContentTypes::parse(ByteString const & rMediaType,
1138 							 ByteString & rType, ByteString & rSubType,
1139 							 INetContentTypeParameterList * pParameters)
1140 {
1141 	sal_Char const * p = rMediaType.GetBuffer();
1142 	sal_Char const * pEnd = p + rMediaType.Len();
1143 
1144 	p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
1145 	sal_Char const * pToken = p;
1146 	bool bDowncase = false;
1147 	while (p != pEnd && INetMIME::isTokenChar(*p))
1148 	{
1149 		bDowncase = bDowncase || INetMIME::isUpperCase(*p);
1150 		++p;
1151 	}
1152 	if (p == pToken)
1153 		return false;
1154 	rType = ByteString(pToken, sal::static_int_cast< xub_StrLen >(p - pToken));
1155 	if (bDowncase)
1156 		rType.ToLowerAscii();
1157 
1158 	p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
1159 	if (p == pEnd || *p++ != '/')
1160 		return false;
1161 
1162 	p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
1163 	pToken = p;
1164 	bDowncase = false;
1165 	while (p != pEnd && INetMIME::isTokenChar(*p))
1166 	{
1167 		bDowncase = bDowncase || INetMIME::isUpperCase(*p);
1168 		++p;
1169 	}
1170 	if (p == pToken)
1171 		return false;
1172 	rSubType = ByteString(
1173         pToken, sal::static_int_cast< xub_StrLen >(p - pToken));
1174 	if (bDowncase)
1175 		rSubType.ToLowerAscii();
1176 
1177 	return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd;
1178 }
1179 
1180 //============================================================================
1181 // static
parse(UniString const & rMediaType,UniString & rType,UniString & rSubType,INetContentTypeParameterList * pParameters)1182 bool INetContentTypes::parse(UniString const & rMediaType,
1183 							 UniString & rType, UniString & rSubType,
1184 							 INetContentTypeParameterList * pParameters)
1185 {
1186 	sal_Unicode const * p = rMediaType.GetBuffer();
1187 	sal_Unicode const * pEnd = p + rMediaType.Len();
1188 
1189 	p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
1190 	sal_Unicode const * pToken = p;
1191 	bool bDowncase = false;
1192 	while (p != pEnd && INetMIME::isTokenChar(*p))
1193 	{
1194 		bDowncase = bDowncase || INetMIME::isUpperCase(*p);
1195 		++p;
1196 	}
1197 	if (p == pToken)
1198 		return false;
1199 	rType = UniString(pToken, sal::static_int_cast< xub_StrLen >(p - pToken));
1200 	if (bDowncase)
1201 		rType.ToLowerAscii();
1202 
1203 	p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
1204 	if (p == pEnd || *p++ != '/')
1205 		return false;
1206 
1207 	p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
1208 	pToken = p;
1209 	bDowncase = false;
1210 	while (p != pEnd && INetMIME::isTokenChar(*p))
1211 	{
1212 		bDowncase = bDowncase || INetMIME::isUpperCase(*p);
1213 		++p;
1214 	}
1215 	if (p == pToken)
1216 		return false;
1217 	rSubType = UniString(
1218         pToken, sal::static_int_cast< xub_StrLen >(p - pToken));
1219 	if (bDowncase)
1220 		rSubType.ToLowerAscii();
1221 
1222 	return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd;
1223 }
1224 
1225 //============================================================================
1226 // static
appendUSASCIIParameter(ByteString const & rMediaType,ByteString const & rAttribute,ByteString const & rValue)1227 ByteString INetContentTypes::appendUSASCIIParameter(ByteString const &
1228 													    rMediaType,
1229 													ByteString const &
1230 													    rAttribute,
1231 													ByteString const & rValue)
1232 {
1233 	ByteString aResult = rMediaType;
1234 	aResult.Append(RTL_CONSTASCII_STRINGPARAM("; "));
1235 	aResult += rAttribute;
1236 	aResult += '=';
1237 	bool bQuote = false;
1238 	for (xub_StrLen i = 0; i < rValue.Len(); ++i)
1239 	{
1240 		// When the value contains any ' characters, use a quoted string
1241 		// instead of a token, in order to avoid confusion with RFC 2231
1242 		// extensions:
1243 		sal_uInt32 nChar = sal_uChar(rValue.GetChar(i));
1244 		DBG_ASSERT(INetMIME::isUSASCII(nChar),
1245 				   "INetContentTypes::appendUSASCIIParameter(): Bad value");
1246 		if (!INetMIME::isTokenChar(nChar) || nChar == '\'')
1247 		{
1248 			bQuote = true;
1249 			break;
1250 		}
1251 	}
1252 	if (bQuote)
1253 	{
1254 		aResult += '"';
1255 		for (xub_StrLen i = 0; i < rValue.Len(); ++i)
1256 		{
1257 			// Escape LF as well as CR to avoid confusion with line folding:
1258 			sal_uInt32 nChar = sal_uChar(rValue.GetChar(i));
1259 			DBG_ASSERT(INetMIME::isUSASCII(nChar),
1260 					   "INetContentTypes::appendUSASCIIParameter():"
1261 					       " Bad value");
1262 			switch (nChar)
1263 			{
1264 				case 0x0A: // LF
1265 				case 0x0D: // CR
1266 				case '"':
1267 				case '\\':
1268 					aResult += '\\';
1269 				default:
1270 					aResult += static_cast< char >(nChar);
1271 					break;
1272 			}
1273 		}
1274 		aResult += '"';
1275 	}
1276 	else
1277 		aResult += rValue;
1278 	return aResult;
1279 }
1280 
1281 //============================================================================
1282 // static
appendUSASCIIParameter(UniString const & rMediaType,UniString const & rAttribute,UniString const & rValue)1283 UniString INetContentTypes::appendUSASCIIParameter(UniString const &
1284 												       rMediaType,
1285 												   UniString const &
1286 												       rAttribute,
1287 												   UniString const & rValue)
1288 {
1289 	UniString aResult = rMediaType;
1290 	aResult.AppendAscii(RTL_CONSTASCII_STRINGPARAM("; "));
1291 	aResult += rAttribute;
1292 	aResult += '=';
1293 	bool bQuote = false;
1294 	for (xub_StrLen i = 0; i < rValue.Len(); ++i)
1295 	{
1296 		// When the value contains any ' characters, use a quoted string
1297 		// instead of a token, in order to avoid confusion with RFC 2231
1298 		// extensions:
1299 		sal_uInt32 nChar = rValue.GetChar(i);
1300 		DBG_ASSERT(INetMIME::isUSASCII(nChar),
1301 				   "INetContentTypes::appendUSASCIIParameter(): Bad value");
1302 		if (!INetMIME::isTokenChar(nChar) || nChar == '\'')
1303 		{
1304 			bQuote = true;
1305 			break;
1306 		}
1307 	}
1308 	if (bQuote)
1309 	{
1310 		aResult += '"';
1311 		for (xub_StrLen i = 0; i < rValue.Len(); ++i)
1312 		{
1313 			// Escape LF as well as CR to avoid confusion with line folding:
1314 			sal_uInt32 nChar = rValue.GetChar(i);
1315 			DBG_ASSERT(INetMIME::isUSASCII(nChar),
1316 					   "INetContentTypes::appendUSASCIIParameter():"
1317 					       " Bad value");
1318 			switch (nChar)
1319 			{
1320 				case 0x0A: // LF
1321 				case 0x0D: // CR
1322 				case '"':
1323 				case '\\':
1324 					aResult += '\\';
1325 				default:
1326 					aResult += sal_Unicode(nChar);
1327 					break;
1328 			}
1329 		}
1330 		aResult += '"';
1331 	}
1332 	else
1333 		aResult += rValue;
1334 	return aResult;
1335 }
1336 
1337