Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "mcnttype.hxx"
21 : :
22 : : //------------------------------------------------------------------------
23 : : // namespace directives
24 : : //------------------------------------------------------------------------
25 : :
26 : : using namespace com::sun::star::uno;
27 : : using namespace com::sun::star::lang;
28 : : using namespace com::sun::star::container;
29 : : using namespace std;
30 : : using namespace osl;
31 : :
32 : : using ::rtl::OUString;
33 : :
34 : : //------------------------------------------------------------------------
35 : : // constants
36 : : //------------------------------------------------------------------------
37 : :
38 : : const char TSPECIALS[] = "()<>@,;:\\\"/[]?=";
39 : : const char TOKEN[] = "!#$%&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~.";
40 : : const char SPACE[] = " ";
41 : : const char SEMICOLON[] = ";";
42 : :
43 : : //------------------------------------------------------------------------
44 : : // ctor
45 : : //------------------------------------------------------------------------
46 : :
47 : 0 : CMimeContentType::CMimeContentType( const OUString& aCntType )
48 : : {
49 : 0 : init( aCntType );
50 : 0 : }
51 : :
52 : : //------------------------------------------------------------------------
53 : : //
54 : : //------------------------------------------------------------------------
55 : :
56 : 0 : OUString SAL_CALL CMimeContentType::getMediaType( ) throw(RuntimeException)
57 : : {
58 : 0 : return m_MediaType;
59 : : }
60 : :
61 : : //------------------------------------------------------------------------
62 : : //
63 : : //------------------------------------------------------------------------
64 : :
65 : 0 : OUString SAL_CALL CMimeContentType::getMediaSubtype( ) throw(RuntimeException)
66 : : {
67 : 0 : return m_MediaSubtype;
68 : : }
69 : :
70 : : //------------------------------------------------------------------------
71 : : //
72 : : //------------------------------------------------------------------------
73 : :
74 : 0 : OUString SAL_CALL CMimeContentType::getFullMediaType( ) throw(RuntimeException)
75 : : {
76 : 0 : return m_MediaType + OUString("/") + m_MediaSubtype;
77 : : }
78 : :
79 : : //------------------------------------------------------------------------
80 : : //
81 : : //------------------------------------------------------------------------
82 : :
83 : 0 : Sequence< OUString > SAL_CALL CMimeContentType::getParameters( ) throw(RuntimeException)
84 : : {
85 : 0 : MutexGuard aGuard( m_aMutex );
86 : :
87 : 0 : Sequence< OUString > seqParams;
88 : :
89 : 0 : map< OUString, OUString >::iterator iter;
90 : 0 : map< OUString, OUString >::iterator iter_end = m_ParameterMap.end( );
91 : :
92 : 0 : for ( iter = m_ParameterMap.begin( ); iter != iter_end; ++iter )
93 : : {
94 : 0 : seqParams.realloc( seqParams.getLength( ) + 1 );
95 : 0 : seqParams[seqParams.getLength( ) - 1] = iter->first;
96 : : }
97 : :
98 : 0 : return seqParams;
99 : : }
100 : :
101 : : //------------------------------------------------------------------------
102 : : //
103 : : //------------------------------------------------------------------------
104 : :
105 : 0 : sal_Bool SAL_CALL CMimeContentType::hasParameter( const OUString& aName ) throw(RuntimeException)
106 : : {
107 : 0 : MutexGuard aGuard( m_aMutex );
108 : 0 : return ( m_ParameterMap.end( ) != m_ParameterMap.find( aName ) );
109 : : }
110 : :
111 : : //------------------------------------------------------------------------
112 : : //
113 : : //------------------------------------------------------------------------
114 : :
115 : 0 : OUString SAL_CALL CMimeContentType::getParameterValue( const OUString& aName ) throw(NoSuchElementException, RuntimeException)
116 : : {
117 : 0 : MutexGuard aGuard( m_aMutex );
118 : :
119 : 0 : if ( !hasParameter( aName ) )
120 : 0 : throw NoSuchElementException( );
121 : :
122 : 0 : return m_ParameterMap.find( aName )->second;
123 : : }
124 : :
125 : : //------------------------------------------------------------------------
126 : : //
127 : : //------------------------------------------------------------------------
128 : :
129 : 0 : void SAL_CALL CMimeContentType::init( const OUString& aCntType ) throw( IllegalArgumentException )
130 : : {
131 : 0 : if ( aCntType.isEmpty( ) )
132 : 0 : throw IllegalArgumentException( );
133 : :
134 : 0 : m_nPos = 0;
135 : 0 : m_ContentType = aCntType;
136 : 0 : getSym( );
137 : 0 : type();
138 : 0 : }
139 : :
140 : : //------------------------------------------------------------------------
141 : : //
142 : : //------------------------------------------------------------------------
143 : :
144 : 0 : void SAL_CALL CMimeContentType::getSym( void )
145 : : {
146 : 0 : if ( m_nPos < m_ContentType.getLength( ) )
147 : : {
148 : 0 : m_nxtSym = m_ContentType.copy(m_nPos, 1);
149 : 0 : ++m_nPos;
150 : 0 : return;
151 : : }
152 : :
153 : 0 : m_nxtSym = OUString( );
154 : : }
155 : :
156 : : //------------------------------------------------------------------------
157 : : //
158 : : //------------------------------------------------------------------------
159 : :
160 : 0 : void SAL_CALL CMimeContentType::acceptSym( const OUString& pSymTlb )
161 : : {
162 : 0 : if ( pSymTlb.indexOf( m_nxtSym ) < 0 )
163 : 0 : throw IllegalArgumentException( );
164 : :
165 : 0 : getSym();
166 : 0 : }
167 : :
168 : : //------------------------------------------------------------------------
169 : : //
170 : : //------------------------------------------------------------------------
171 : :
172 : 0 : void SAL_CALL CMimeContentType::skipSpaces( void )
173 : : {
174 : 0 : while (m_nxtSym.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(SPACE)))
175 : 0 : getSym( );
176 : 0 : }
177 : :
178 : : //------------------------------------------------------------------------
179 : : //
180 : : //------------------------------------------------------------------------
181 : :
182 : 0 : void SAL_CALL CMimeContentType::type( void )
183 : : {
184 : 0 : skipSpaces( );
185 : :
186 : 0 : rtl::OUString sToken(TOKEN);
187 : :
188 : : // check FIRST( type )
189 : 0 : if ( !isInRange( m_nxtSym, sToken ) )
190 : 0 : throw IllegalArgumentException( );
191 : :
192 : : // parse
193 : 0 : while( !m_nxtSym.isEmpty( ) )
194 : : {
195 : 0 : if ( isInRange( m_nxtSym, sToken ) )
196 : 0 : m_MediaType += m_nxtSym;
197 : 0 : else if ( isInRange( m_nxtSym, OUString("/ ") ) )
198 : 0 : break;
199 : : else
200 : 0 : throw IllegalArgumentException( );
201 : 0 : getSym( );
202 : : }
203 : :
204 : : // check FOLLOW( type )
205 : 0 : skipSpaces( );
206 : 0 : acceptSym( OUString("/") );
207 : :
208 : 0 : subtype( );
209 : 0 : }
210 : :
211 : : //------------------------------------------------------------------------
212 : : //
213 : : //------------------------------------------------------------------------
214 : :
215 : 0 : void SAL_CALL CMimeContentType::subtype( void )
216 : : {
217 : 0 : skipSpaces( );
218 : :
219 : 0 : rtl::OUString sToken(TOKEN);
220 : :
221 : : // check FIRST( subtype )
222 : 0 : if ( !isInRange( m_nxtSym, sToken ) )
223 : 0 : throw IllegalArgumentException( );
224 : :
225 : 0 : while( !m_nxtSym.isEmpty( ) )
226 : : {
227 : 0 : if ( isInRange( m_nxtSym, sToken ) )
228 : 0 : m_MediaSubtype += m_nxtSym;
229 : 0 : else if ( isInRange( m_nxtSym, OUString("; ") ) )
230 : 0 : break;
231 : : else
232 : 0 : throw IllegalArgumentException( );
233 : 0 : getSym( );
234 : : }
235 : :
236 : : // parse the rest
237 : 0 : skipSpaces( );
238 : 0 : trailer();
239 : 0 : }
240 : :
241 : : //------------------------------------------------------------------------
242 : : //
243 : : //------------------------------------------------------------------------
244 : :
245 : 0 : void SAL_CALL CMimeContentType::trailer( void )
246 : : {
247 : 0 : rtl::OUString sToken(TOKEN);
248 : 0 : while( !m_nxtSym.isEmpty( ) )
249 : : {
250 : 0 : if ( m_nxtSym == OUString("(") )
251 : : {
252 : 0 : getSym( );
253 : 0 : comment( );
254 : 0 : acceptSym( OUString(")") );
255 : : }
256 : 0 : else if ( m_nxtSym == OUString(";") )
257 : : {
258 : : // get the parameter name
259 : 0 : getSym( );
260 : 0 : skipSpaces( );
261 : :
262 : 0 : if ( !isInRange( m_nxtSym, sToken ) )
263 : 0 : throw IllegalArgumentException( );
264 : :
265 : 0 : OUString pname = pName( );
266 : :
267 : 0 : skipSpaces();
268 : 0 : acceptSym( OUString("=") );
269 : :
270 : : // get the parameter value
271 : 0 : skipSpaces( );
272 : :
273 : 0 : OUString pvalue = pValue( );
274 : :
275 : : // insert into map
276 : 0 : if ( !m_ParameterMap.insert( pair < const OUString, OUString > ( pname, pvalue ) ).second )
277 : 0 : throw IllegalArgumentException( );
278 : : }
279 : : else
280 : 0 : throw IllegalArgumentException( );
281 : :
282 : 0 : skipSpaces( );
283 : 0 : }
284 : 0 : }
285 : :
286 : : //------------------------------------------------------------------------
287 : : //
288 : : //------------------------------------------------------------------------
289 : :
290 : 0 : OUString SAL_CALL CMimeContentType::pName( )
291 : : {
292 : 0 : OUString pname;
293 : :
294 : 0 : rtl::OUString sToken(TOKEN);
295 : 0 : while( !m_nxtSym.isEmpty( ) )
296 : : {
297 : 0 : if ( isInRange( m_nxtSym, sToken ) )
298 : 0 : pname += m_nxtSym;
299 : 0 : else if ( isInRange( m_nxtSym, OUString("= ") ) )
300 : 0 : break;
301 : : else
302 : 0 : throw IllegalArgumentException( );
303 : 0 : getSym( );
304 : : }
305 : :
306 : 0 : return pname;
307 : : }
308 : :
309 : : //------------------------------------------------------------------------
310 : : //
311 : : //------------------------------------------------------------------------
312 : :
313 : 0 : OUString SAL_CALL CMimeContentType::pValue( )
314 : : {
315 : 0 : OUString pvalue;
316 : :
317 : 0 : rtl::OUString sToken(TOKEN);
318 : : // quoted pvalue
319 : 0 : if ( m_nxtSym == OUString( "\"" ) )
320 : : {
321 : 0 : getSym( );
322 : 0 : pvalue = quotedPValue( );
323 : :
324 : 0 : if ( pvalue[pvalue.getLength() - 1] != '"' )
325 : 0 : throw IllegalArgumentException( );
326 : :
327 : : // remove the last quote-sign
328 : 0 : pvalue = pvalue.copy(0, pvalue.getLength() - 1);
329 : :
330 : 0 : if ( pvalue.isEmpty( ) )
331 : 0 : throw IllegalArgumentException( );
332 : : }
333 : 0 : else if ( isInRange( m_nxtSym, sToken ) ) // unquoted pvalue
334 : : {
335 : 0 : pvalue = nonquotedPValue( );
336 : : }
337 : : else
338 : 0 : throw IllegalArgumentException( );
339 : :
340 : 0 : return pvalue;
341 : : }
342 : :
343 : : //------------------------------------------------------------------------
344 : : // the following combinations within a quoted value are not allowed:
345 : : // '";' (quote sign followed by semicolon) and '" ' (quote sign followed
346 : : // by space)
347 : : //------------------------------------------------------------------------
348 : :
349 : 0 : OUString SAL_CALL CMimeContentType::quotedPValue( )
350 : : {
351 : 0 : OUString pvalue;
352 : 0 : sal_Bool bAfterQuoteSign = sal_False;
353 : :
354 : 0 : while ( !m_nxtSym.isEmpty( ) )
355 : : {
356 : 0 : if ( bAfterQuoteSign && (
357 : 0 : (m_nxtSym.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(SPACE))) ||
358 : 0 : (m_nxtSym.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(SEMICOLON))))
359 : : )
360 : : {
361 : 0 : break;
362 : : }
363 : 0 : else if ( isInRange( m_nxtSym, rtl::OUString(TOKEN) + rtl::OUString(TSPECIALS) + rtl::OUString(SPACE) ) )
364 : : {
365 : 0 : pvalue += m_nxtSym;
366 : 0 : if ( m_nxtSym == OUString( "\"" ) )
367 : 0 : bAfterQuoteSign = sal_True;
368 : : else
369 : 0 : bAfterQuoteSign = sal_False;
370 : : }
371 : : else
372 : 0 : throw IllegalArgumentException( );
373 : 0 : getSym( );
374 : : }
375 : :
376 : 0 : return pvalue;
377 : : }
378 : :
379 : : //------------------------------------------------------------------------
380 : : //
381 : : //------------------------------------------------------------------------
382 : :
383 : 0 : OUString SAL_CALL CMimeContentType::nonquotedPValue( )
384 : : {
385 : 0 : OUString pvalue;
386 : :
387 : 0 : rtl::OUString sToken(TOKEN);
388 : 0 : while ( !m_nxtSym.isEmpty( ) )
389 : : {
390 : 0 : if ( isInRange( m_nxtSym, sToken ) )
391 : 0 : pvalue += m_nxtSym;
392 : 0 : else if ( isInRange( m_nxtSym, OUString("; ") ) )
393 : 0 : break;
394 : : else
395 : 0 : throw IllegalArgumentException( );
396 : 0 : getSym( );
397 : : }
398 : :
399 : 0 : return pvalue;
400 : : }
401 : :
402 : : //------------------------------------------------------------------------
403 : : //
404 : : //------------------------------------------------------------------------
405 : :
406 : 0 : void SAL_CALL CMimeContentType::comment( void )
407 : : {
408 : 0 : while ( !m_nxtSym.isEmpty( ) )
409 : : {
410 : 0 : if ( isInRange( m_nxtSym, rtl::OUString(TOKEN) + rtl::OUString(SPACE) ) )
411 : 0 : getSym( );
412 : 0 : else if ( m_nxtSym == OUString(")") )
413 : 0 : break;
414 : : else
415 : 0 : throw IllegalArgumentException( );
416 : : }
417 : 0 : }
418 : :
419 : : //------------------------------------------------------------------------
420 : : //
421 : : //------------------------------------------------------------------------
422 : :
423 : 0 : sal_Bool SAL_CALL CMimeContentType::isInRange( const rtl::OUString& aChr, const rtl::OUString& aRange )
424 : : {
425 : 0 : return ( aRange.indexOf( aChr ) > -1 );
426 : : }
427 : :
428 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|