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