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