Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <stdio.h> // for EOF
31 : : #include <rtl/tencinfo.h>
32 : : #include <tools/stream.hxx>
33 : : #include <tools/debug.hxx>
34 : : #include <svtools/rtftoken.h>
35 : : #include <svtools/rtfkeywd.hxx>
36 : : #include <svtools/parrtf.hxx>
37 : : #include <comphelper/string.hxx>
38 : :
39 : : const int MAX_STRING_LEN = 1024;
40 : : const int MAX_TOKEN_LEN = 128;
41 : :
42 : : #define RTF_ISDIGIT( c ) comphelper::string::isdigitAscii(c)
43 : : #define RTF_ISALPHA( c ) comphelper::string::isalphaAscii(c)
44 : :
45 : 0 : SvRTFParser::SvRTFParser( SvStream& rIn, sal_uInt8 nStackSize )
46 : : : SvParser( rIn, nStackSize ),
47 : : eUNICodeSet( RTL_TEXTENCODING_MS_1252 ), // default ist ANSI-CodeSet
48 [ # # ][ # # ]: 0 : nUCharOverread( 1 )
49 : : {
50 : : // default ist ANSI-CodeSet
51 [ # # ]: 0 : SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
52 : 0 : bRTF_InTextRead = false;
53 : 0 : }
54 : :
55 : 0 : SvRTFParser::~SvRTFParser()
56 : : {
57 [ # # ]: 0 : }
58 : :
59 : :
60 : :
61 : :
62 : 0 : int SvRTFParser::_GetNextToken()
63 : : {
64 : 0 : int nRet = 0;
65 [ # # ][ # # ]: 0 : do {
[ # # ]
66 : 0 : int bNextCh = true;
67 [ # # # # : 0 : switch( nNextCh )
# # ]
68 : : {
69 : : case '\\':
70 : : {
71 : : // Steuerzeichen
72 [ # # # # : 0 : switch( nNextCh = GetNextChar() )
# # ]
73 : : {
74 : : case '{':
75 : : case '}':
76 : : case '\\':
77 : : case '+': // habe ich in einem RTF-File gefunden
78 : : case '~': // nonbreaking space
79 : : case '-': // optional hyphen
80 : : case '_': // nonbreaking hyphen
81 : : case '\'': // HexValue
82 : 0 : nNextCh = '\\';
83 : 0 : rInput.SeekRel( -1 );
84 : 0 : ScanText();
85 : 0 : nRet = RTF_TEXTTOKEN;
86 : 0 : bNextCh = 0 == nNextCh;
87 : 0 : break;
88 : :
89 : : case '*': // ignoreflag
90 : 0 : nRet = RTF_IGNOREFLAG;
91 : 0 : break;
92 : : case ':': // subentry in an index entry
93 : 0 : nRet = RTF_SUBENTRYINDEX;
94 : 0 : break;
95 : : case '|': // formula-charakter
96 : 0 : nRet = RTF_FORMULA;
97 : 0 : break;
98 : :
99 : : case 0x0a:
100 : : case 0x0d:
101 : 0 : nRet = RTF_PAR;
102 : 0 : break;
103 : :
104 : : default:
105 [ # # ]: 0 : if( RTF_ISALPHA( nNextCh ) )
106 : : {
107 : 0 : aToken = '\\';
108 : : {
109 [ # # ]: 0 : String aStrBuffer;
110 : : sal_Unicode* pStr = aStrBuffer.AllocBuffer(
111 [ # # ]: 0 : MAX_TOKEN_LEN );
112 : 0 : xub_StrLen nStrLen = 0;
113 [ # # ][ # # ]: 0 : do {
114 : 0 : *(pStr + nStrLen++) = nNextCh;
115 [ # # ]: 0 : if( MAX_TOKEN_LEN == nStrLen )
116 : : {
117 [ # # ]: 0 : aToken += aStrBuffer;
118 [ # # ]: 0 : aToken.GetBufferAccess(); // make unique string!
119 : 0 : nStrLen = 0;
120 : : }
121 [ # # ]: 0 : nNextCh = GetNextChar();
122 : 0 : } while( RTF_ISALPHA( nNextCh ) );
123 [ # # ]: 0 : if( nStrLen )
124 : : {
125 [ # # ]: 0 : aStrBuffer.ReleaseBufferAccess( nStrLen );
126 [ # # ]: 0 : aToken += aStrBuffer;
127 [ # # ]: 0 : }
128 : : }
129 : :
130 : : // Minus fuer numerischen Parameter
131 : 0 : int bNegValue = false;
132 [ # # ]: 0 : if( '-' == nNextCh )
133 : : {
134 : 0 : bNegValue = true;
135 : 0 : nNextCh = GetNextChar();
136 : : }
137 : :
138 : : // evt. Numerischer Parameter
139 [ # # ]: 0 : if( RTF_ISDIGIT( nNextCh ) )
140 : : {
141 : 0 : nTokenValue = 0;
142 [ # # ]: 0 : do {
143 : 0 : nTokenValue *= 10;
144 : 0 : nTokenValue += nNextCh - '0';
145 : 0 : nNextCh = GetNextChar();
146 : 0 : } while( RTF_ISDIGIT( nNextCh ) );
147 [ # # ]: 0 : if( bNegValue )
148 : 0 : nTokenValue = -nTokenValue;
149 : 0 : bTokenHasValue=true;
150 : : }
151 [ # # ]: 0 : else if( bNegValue ) // das Minus wieder zurueck
152 : : {
153 : 0 : nNextCh = '-';
154 : 0 : rInput.SeekRel( -1 );
155 : : }
156 [ # # ]: 0 : if( ' ' == nNextCh ) // Blank gehoert zum Token!
157 : 0 : nNextCh = GetNextChar();
158 : :
159 : : // suche das Token in der Tabelle:
160 [ # # ]: 0 : if( 0 == (nRet = GetRTFToken( aToken )) )
161 : : // Unknown Control
162 : 0 : nRet = RTF_UNKNOWNCONTROL;
163 : :
164 : : // bug 76812 - unicode token handled as normal text
165 : 0 : bNextCh = false;
166 [ # # # # ]: 0 : switch( nRet )
167 : : {
168 : : case RTF_UC:
169 [ # # ]: 0 : if( 0 <= nTokenValue )
170 : : {
171 : 0 : nUCharOverread = (sal_uInt8)nTokenValue;
172 : : //cmc: other ifdef breaks #i3584
173 : 0 : aParserStates.top().
174 : 0 : nUCharOverread = nUCharOverread;
175 : : }
176 : 0 : aToken.Erase(); // #i47831# erase token to prevent the token from beeing treated as text
177 : : // read next token
178 : 0 : nRet = 0;
179 : 0 : break;
180 : :
181 : : case RTF_UPR:
182 [ # # ]: 0 : if (!_inSkipGroup) {
183 : : // UPR - overread the group with the ansi
184 : : // informations
185 [ # # ]: 0 : while( '{' != _GetNextToken() )
186 : : ;
187 : 0 : SkipGroup();
188 : 0 : _GetNextToken(); // overread the last bracket
189 : 0 : nRet = 0;
190 : : }
191 : 0 : break;
192 : :
193 : : case RTF_U:
194 [ # # ]: 0 : if( !bRTF_InTextRead )
195 : : {
196 : 0 : nRet = RTF_TEXTTOKEN;
197 : 0 : aToken = (sal_Unicode)nTokenValue;
198 : :
199 : : // overread the next n "RTF" characters. This
200 : : // can be also \{, \}, \'88
201 [ # # ]: 0 : for( sal_uInt8 m = 0; m < nUCharOverread; ++m )
202 : : {
203 : 0 : sal_Unicode cAnsi = nNextCh;
204 [ # # ]: 0 : while( 0xD == cAnsi )
205 : 0 : cAnsi = GetNextChar();
206 [ # # ]: 0 : while( 0xA == cAnsi )
207 : 0 : cAnsi = GetNextChar();
208 : :
209 [ # # ][ # # ]: 0 : if( '\\' == cAnsi &&
[ # # ]
210 : 0 : '\'' == ( cAnsi = GetNextChar() ))
211 : : // HexValue ueberlesen
212 : 0 : cAnsi = GetHexValue();
213 : 0 : nNextCh = GetNextChar();
214 : : }
215 : 0 : ScanText();
216 : 0 : bNextCh = 0 == nNextCh;
217 : : }
218 : 0 : break;
219 : : }
220 : : }
221 [ # # ]: 0 : else if( SVPAR_PENDING != eState )
222 : : {
223 : : // Bug 34631 - "\ " ueberlesen - Blank als Zeichen
224 : : // eState = SVPAR_ERROR;
225 : 0 : bNextCh = false;
226 : : }
227 : 0 : break;
228 : : }
229 : : }
230 : 0 : break;
231 : :
232 : : case sal_Unicode(EOF):
233 : 0 : eState = SVPAR_ACCEPTED;
234 : 0 : nRet = nNextCh;
235 : 0 : break;
236 : :
237 : : case '{':
238 : : {
239 [ # # ]: 0 : if( 0 <= nOpenBrakets )
240 : : {
241 : 0 : RtfParserState_Impl aState( nUCharOverread, GetSrcEncoding() );
242 [ # # ]: 0 : aParserStates.push( aState );
243 : : }
244 : 0 : ++nOpenBrakets;
245 : : DBG_ASSERT(
246 : : static_cast<size_t>(nOpenBrakets) == aParserStates.size(),
247 : : "ParserStateStack unequal to bracket count" );
248 : 0 : nRet = nNextCh;
249 : : }
250 : 0 : break;
251 : :
252 : : case '}':
253 : 0 : --nOpenBrakets;
254 [ # # ]: 0 : if( 0 <= nOpenBrakets )
255 : : {
256 : 0 : aParserStates.pop();
257 [ # # ]: 0 : if( !aParserStates.empty() )
258 : : {
259 : : const RtfParserState_Impl& rRPS =
260 : 0 : aParserStates.top();
261 : 0 : nUCharOverread = rRPS.nUCharOverread;
262 : 0 : SetSrcEncoding( rRPS.eCodeSet );
263 : : }
264 : : else
265 : : {
266 : 0 : nUCharOverread = 1;
267 : 0 : SetSrcEncoding( GetCodeSet() );
268 : : }
269 : : }
270 : : DBG_ASSERT(
271 : : static_cast<size_t>(nOpenBrakets) == aParserStates.size(),
272 : : "ParserStateStack unequal to bracket count" );
273 : 0 : nRet = nNextCh;
274 : 0 : break;
275 : :
276 : : case 0x0d:
277 : : case 0x0a:
278 : 0 : break;
279 : :
280 : : default:
281 : : // es folgt normaler Text
282 : 0 : ScanText();
283 : 0 : nRet = RTF_TEXTTOKEN;
284 : 0 : bNextCh = 0 == nNextCh;
285 : 0 : break;
286 : : }
287 : :
288 [ # # ]: 0 : if( bNextCh )
289 : 0 : nNextCh = GetNextChar();
290 : :
291 : : } while( !nRet && SVPAR_WORKING == eState );
292 : 0 : return nRet;
293 : : }
294 : :
295 : :
296 : 0 : sal_Unicode SvRTFParser::GetHexValue()
297 : : {
298 : : // Hex-Wert sammeln
299 : : register int n;
300 : 0 : register sal_Unicode nHexVal = 0;
301 : :
302 [ # # ]: 0 : for( n = 0; n < 2; ++n )
303 : : {
304 : 0 : nHexVal *= 16;
305 : 0 : nNextCh = GetNextChar();
306 [ # # ][ # # ]: 0 : if( nNextCh >= '0' && nNextCh <= '9' )
307 : 0 : nHexVal += (nNextCh - 48);
308 [ # # ][ # # ]: 0 : else if( nNextCh >= 'a' && nNextCh <= 'f' )
309 : 0 : nHexVal += (nNextCh - 87);
310 [ # # ][ # # ]: 0 : else if( nNextCh >= 'A' && nNextCh <= 'F' )
311 : 0 : nHexVal += (nNextCh - 55);
312 : : }
313 : 0 : return nHexVal;
314 : : }
315 : :
316 : 0 : void SvRTFParser::ScanText( const sal_Unicode cBreak )
317 : : {
318 [ # # ]: 0 : String aStrBuffer;
319 : 0 : int bWeiter = true;
320 [ # # ][ # # ]: 0 : while( bWeiter && IsParserWorking() && aStrBuffer.Len() < MAX_STRING_LEN)
[ # # ][ # # ]
321 : : {
322 : 0 : int bNextCh = true;
323 [ # # # # : 0 : switch( nNextCh )
# ]
324 : : {
325 : : case '\\':
326 : : {
327 [ # # ][ # # : 0 : switch (nNextCh = GetNextChar())
# # # #
# ]
328 : : {
329 : : case '\'':
330 : : {
331 : :
332 : 0 : rtl::OStringBuffer aByteString;
333 : 0 : while (1)
334 : : {
335 [ # # ]: 0 : char c = (char)GetHexValue();
336 : : /*
337 : : * Note: \'00 is a valid internal character in a
338 : : * string in RTF. rtl::OStringBuffer supports
339 : : * appending nulls fine
340 : : */
341 [ # # ]: 0 : aByteString.append(c);
342 : :
343 : 0 : bool bBreak = false;
344 : 0 : sal_Char nSlash = '\\';
345 [ # # ]: 0 : while (!bBreak)
346 : : {
347 [ # # ]: 0 : wchar_t __next=GetNextChar();
348 [ # # ]: 0 : if (__next>0xFF) // fix for #i43933# and #i35653#
349 : : {
350 [ # # ]: 0 : if (aByteString.getLength())
351 [ # # ][ # # ]: 0 : aStrBuffer.Append(String(rtl::OStringToOUString(aByteString.makeStringAndClear(), GetSrcEncoding())));
[ # # ][ # # ]
352 [ # # ]: 0 : aStrBuffer.Append((sal_Unicode)__next);
353 : :
354 : 0 : continue;
355 : : }
356 : 0 : nSlash = (sal_Char)__next;
357 [ # # ][ # # ]: 0 : while (nSlash == 0xD || nSlash == 0xA)
[ # # ]
358 [ # # ]: 0 : nSlash = (sal_Char)GetNextChar();
359 : :
360 [ # # ]: 0 : switch (nSlash)
361 : : {
362 : : case '{':
363 : : case '}':
364 : : case '\\':
365 : 0 : bBreak = true;
366 : 0 : break;
367 : : default:
368 [ # # ]: 0 : aByteString.append(nSlash);
369 : 0 : break;
370 : : }
371 : : }
372 : :
373 [ # # ]: 0 : nNextCh = GetNextChar();
374 : :
375 [ # # ][ # # ]: 0 : if (nSlash != '\\' || nNextCh != '\'')
376 : : {
377 [ # # ]: 0 : rInput.SeekRel(-1);
378 : 0 : nNextCh = nSlash;
379 : 0 : break;
380 : : }
381 : : }
382 : :
383 : 0 : bNextCh = false;
384 : :
385 [ # # ]: 0 : if (aByteString.getLength())
386 [ # # ][ # # ]: 0 : aStrBuffer.Append(String(rtl::OStringToOUString(aByteString.makeStringAndClear(), GetSrcEncoding())));
[ # # ][ # # ]
387 : : }
388 : 0 : break;
389 : : case '\\':
390 : : case '}':
391 : : case '{':
392 : : case '+': // habe ich in einem RTF-File gefunden
393 [ # # ]: 0 : aStrBuffer.Append(nNextCh);
394 : 0 : break;
395 : : case '~': // nonbreaking space
396 [ # # ]: 0 : aStrBuffer.Append(static_cast< sal_Unicode >(0xA0));
397 : 0 : break;
398 : : case '-': // optional hyphen
399 [ # # ]: 0 : aStrBuffer.Append(static_cast< sal_Unicode >(0xAD));
400 : 0 : break;
401 : : case '_': // nonbreaking hyphen
402 [ # # ]: 0 : aStrBuffer.Append(static_cast< sal_Unicode >(0x2011));
403 : 0 : break;
404 : :
405 : : case 'u':
406 : : // UNI-Code Zeichen lesen
407 : : {
408 [ # # ]: 0 : nNextCh = GetNextChar();
409 [ # # ]: 0 : rInput.SeekRel( -2 );
410 : :
411 [ # # ][ # # ]: 0 : if( '-' == nNextCh || RTF_ISDIGIT( nNextCh ) )
[ # # ][ # # ]
412 : : {
413 : 0 : bRTF_InTextRead = true;
414 : :
415 [ # # ]: 0 : String sSave( aToken );
416 : 0 : nNextCh = '\\';
417 : : #ifdef DBG_UTIL
418 : : int nToken =
419 : : #endif
420 [ # # ]: 0 : _GetNextToken();
421 : : DBG_ASSERT( RTF_U == nToken, "doch kein UNI-Code Zeichen" );
422 : : // dont convert symbol chars
423 : : aStrBuffer.Append(
424 [ # # ]: 0 : static_cast< sal_Unicode >(nTokenValue));
425 : :
426 : : // overread the next n "RTF" characters. This
427 : : // can be also \{, \}, \'88
428 [ # # ]: 0 : for( sal_uInt8 m = 0; m < nUCharOverread; ++m )
429 : : {
430 : 0 : sal_Unicode cAnsi = nNextCh;
431 [ # # ]: 0 : while( 0xD == cAnsi )
432 [ # # ]: 0 : cAnsi = GetNextChar();
433 [ # # ]: 0 : while( 0xA == cAnsi )
434 [ # # ]: 0 : cAnsi = GetNextChar();
435 : :
436 [ # # ][ # # ]: 0 : if( '\\' == cAnsi &&
[ # # ][ # # ]
437 : 0 : '\'' == ( cAnsi = GetNextChar() ))
438 : : // HexValue ueberlesen
439 [ # # ]: 0 : cAnsi = GetHexValue();
440 [ # # ]: 0 : nNextCh = GetNextChar();
441 : : }
442 : 0 : bNextCh = false;
443 [ # # ]: 0 : aToken = sSave;
444 [ # # ]: 0 : bRTF_InTextRead = false;
445 : : }
446 : : else
447 : : {
448 : 0 : nNextCh = '\\';
449 : 0 : bWeiter = false; // Abbrechen, String zusammen
450 : : }
451 : : }
452 : 0 : break;
453 : :
454 : : default:
455 [ # # ]: 0 : rInput.SeekRel( -1 );
456 : 0 : nNextCh = '\\';
457 : 0 : bWeiter = false; // Abbrechen, String zusammen
458 : 0 : break;
459 : : }
460 : : }
461 : 0 : break;
462 : :
463 : : case sal_Unicode(EOF):
464 : 0 : eState = SVPAR_ERROR;
465 : : // weiter
466 : : case '{':
467 : : case '}':
468 : 0 : bWeiter = false;
469 : 0 : break;
470 : :
471 : : case 0x0a:
472 : : case 0x0d:
473 : 0 : break;
474 : :
475 : : default:
476 [ # # ][ # # ]: 0 : if( nNextCh == cBreak || aStrBuffer.Len() >= MAX_STRING_LEN)
[ # # ]
477 : 0 : bWeiter = false;
478 : : else
479 : : {
480 [ # # ]: 0 : do {
[ # # # # ]
[ # # ]
481 : : // alle anderen Zeichen kommen in den Text
482 [ # # ]: 0 : aStrBuffer.Append(nNextCh);
483 : :
484 [ # # ][ # # ]: 0 : if (sal_Unicode(EOF) == (nNextCh = GetNextChar()))
485 : : {
486 [ # # ]: 0 : if (aStrBuffer.Len())
487 [ # # ]: 0 : aToken += aStrBuffer;
488 : 0 : return;
489 : : }
490 : : } while
491 : : (
492 [ # # ][ # # ]: 0 : (RTF_ISALPHA(nNextCh) || RTF_ISDIGIT(nNextCh)) &&
493 : 0 : (aStrBuffer.Len() < MAX_STRING_LEN)
494 : : );
495 : 0 : bNextCh = false;
496 : : }
497 : : }
498 : :
499 [ # # ][ # # ]: 0 : if( bWeiter && bNextCh )
500 [ # # ]: 0 : nNextCh = GetNextChar();
501 : : }
502 : :
503 [ # # ]: 0 : if (aStrBuffer.Len())
504 [ # # ][ # # ]: 0 : aToken += aStrBuffer;
[ # # ]
505 : : }
506 : :
507 : :
508 : : short SvRTFParser::_inSkipGroup=0;
509 : :
510 : 0 : void SvRTFParser::SkipGroup()
511 : : {
512 : 0 : short nBrackets=1;
513 [ # # ]: 0 : if (_inSkipGroup>0)
514 : 0 : return;
515 : 0 : _inSkipGroup++;
516 : : //#i16185# fecking \bin keyword
517 [ # # # # ]: 0 : do
[ # # ]
518 : : {
519 [ # # # ]: 0 : switch (nNextCh)
520 : : {
521 : : case '{':
522 : 0 : ++nBrackets;
523 : 0 : break;
524 : : case '}':
525 [ # # ]: 0 : if (!--nBrackets) {
526 : 0 : _inSkipGroup--;
527 : 0 : return;
528 : : }
529 : 0 : break;
530 : : }
531 : 0 : int nToken = _GetNextToken();
532 [ # # ]: 0 : if (nToken == RTF_BIN)
533 : : {
534 : 0 : rInput.SeekRel(-1);
535 : 0 : rInput.SeekRel(nTokenValue);
536 : 0 : nNextCh = GetNextChar();
537 : : }
538 [ # # ][ # # ]: 0 : while (nNextCh==0xa || nNextCh==0xd)
[ # # ]
539 : : {
540 : 0 : nNextCh = GetNextChar();
541 : : }
542 : 0 : } while (sal_Unicode(EOF) != nNextCh && IsParserWorking());
543 : :
544 [ # # ][ # # ]: 0 : if( SVPAR_PENDING != eState && '}' != nNextCh )
545 : 0 : eState = SVPAR_ERROR;
546 : 0 : _inSkipGroup--;
547 : : }
548 : :
549 : 0 : void SvRTFParser::ReadUnknownData() { SkipGroup(); }
550 : 0 : void SvRTFParser::ReadBitmapData() { SkipGroup(); }
551 : 0 : void SvRTFParser::ReadOLEData() { SkipGroup(); }
552 : :
553 : :
554 : 0 : SvParserState SvRTFParser::CallParser()
555 : : {
556 : : sal_Char cFirstCh;
557 : 0 : nNextChPos = rInput.Tell();
558 [ # # ]: 0 : rInput >> cFirstCh; nNextCh = cFirstCh;
559 : 0 : eState = SVPAR_WORKING;
560 : 0 : nOpenBrakets = 0;
561 [ # # ]: 0 : SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_MS_1252 );
562 : 0 : eUNICodeSet = RTL_TEXTENCODING_MS_1252; // default ist ANSI-CodeSet
563 : :
564 : : // die 1. beiden Token muessen '{' und \\rtf sein !!
565 [ # # ][ # # ]: 0 : if( '{' == GetNextToken() && RTF_RTF == GetNextToken() )
[ # # ][ # # ]
[ # # ]
566 : : {
567 : 0 : AddRef();
568 [ # # ]: 0 : Continue( 0 );
569 [ # # ]: 0 : if( SVPAR_PENDING != eState )
570 [ # # ]: 0 : ReleaseRef(); // dann brauchen wir den Parser nicht mehr!
571 : : }
572 : : else
573 : 0 : eState = SVPAR_ERROR;
574 : :
575 : 0 : return eState;
576 : : }
577 : :
578 : 0 : void SvRTFParser::Continue( int nToken )
579 : : {
580 : : // DBG_ASSERT( SVPAR_CS_DONTKNOW == GetCharSet(),
581 : : // "Zeichensatz wurde geaendert." );
582 : :
583 [ # # ]: 0 : if( !nToken )
584 : 0 : nToken = GetNextToken();
585 : :
586 [ # # ]: 0 : while( IsParserWorking() )
587 : : {
588 : 0 : SaveState( nToken );
589 [ # # # # : 0 : switch( nToken )
# # # #
# ]
590 : : {
591 : : case '}':
592 [ # # ]: 0 : if( nOpenBrakets )
593 : 0 : goto NEXTTOKEN;
594 : 0 : eState = SVPAR_ACCEPTED;
595 : 0 : break;
596 : :
597 : : case '{':
598 : : // eine unbekannte Gruppe ?
599 : : {
600 [ # # ]: 0 : if( RTF_IGNOREFLAG != GetNextToken() )
601 : 0 : nToken = SkipToken( -1 );
602 [ # # ]: 0 : else if( RTF_UNKNOWNCONTROL != GetNextToken() )
603 : 0 : nToken = SkipToken( -2 );
604 : : else
605 : : {
606 : : // gleich herausfiltern
607 : 0 : ReadUnknownData();
608 : 0 : nToken = GetNextToken();
609 [ # # ]: 0 : if( '}' != nToken )
610 : 0 : eState = SVPAR_ERROR;
611 : 0 : break; // auf zum naechsten Token!!
612 : : }
613 : : }
614 : 0 : goto NEXTTOKEN;
615 : :
616 : : case RTF_UNKNOWNCONTROL:
617 : 0 : break; // unbekannte Token ueberspringen
618 : : case RTF_NEXTTYPE:
619 : : case RTF_ANSITYPE:
620 : 0 : SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_MS_1252 );
621 : 0 : break;
622 : : case RTF_MACTYPE:
623 : 0 : SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_APPLE_ROMAN );
624 : 0 : break;
625 : : case RTF_PCTYPE:
626 : 0 : SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_IBM_437 );
627 : 0 : break;
628 : : case RTF_PCATYPE:
629 : 0 : SetSrcEncoding( eCodeSet = RTL_TEXTENCODING_IBM_850 );
630 : 0 : break;
631 : : case RTF_ANSICPG:
632 : 0 : eCodeSet = rtl_getTextEncodingFromWindowsCodePage(nTokenValue);
633 : 0 : SetSrcEncoding(eCodeSet);
634 : 0 : break;
635 : : default:
636 : : NEXTTOKEN:
637 : 0 : NextToken( nToken );
638 : 0 : break;
639 : : }
640 [ # # ]: 0 : if( IsParserWorking() )
641 : 0 : SaveState( 0 ); // bis hierhin abgearbeitet,
642 : : // weiter mit neuem Token!
643 : 0 : nToken = GetNextToken();
644 : : }
645 [ # # ][ # # ]: 0 : if( SVPAR_ACCEPTED == eState && 0 < nOpenBrakets )
646 : 0 : eState = SVPAR_ERROR;
647 : 0 : }
648 : :
649 : 0 : void SvRTFParser::SetEncoding( rtl_TextEncoding eEnc )
650 : : {
651 [ # # ]: 0 : if (eEnc == RTL_TEXTENCODING_DONTKNOW)
652 : 0 : eEnc = GetCodeSet();
653 : :
654 [ # # ]: 0 : if (!aParserStates.empty())
655 : 0 : aParserStates.top().eCodeSet = eEnc;
656 : 0 : SetSrcEncoding(eEnc);
657 : 0 : }
658 : :
659 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|