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 : : #include <stdio.h>
30 : : #include <svtools/svparser.hxx>
31 : : #include <tools/stream.hxx>
32 : : #include <tools/debug.hxx>
33 : : #include <rtl/textcvt.h>
34 : : #include <rtl/tencinfo.h>
35 : :
36 : : // Struktur, um sich die akt. Daten zumerken
37 : 7 : struct SvParser_Impl
38 : : {
39 : : String aToken; // gescanntes Token
40 : : sal_uLong nFilePos; // akt. Position im Stream
41 : : sal_uLong nlLineNr; // akt. Zeilen Nummer
42 : : sal_uLong nlLinePos; // akt. Spalten Nummer
43 : : long nTokenValue; // zusaetzlicher Wert (RTF)
44 : : sal_Bool bTokenHasValue; // indicates whether nTokenValue is valid
45 : : int nToken; // akt. Token
46 : : sal_Unicode nNextCh; // akt. Zeichen
47 : :
48 : : int nSaveToken; // das Token vom Continue
49 : :
50 : : rtl_TextToUnicodeConverter hConv;
51 : : rtl_TextToUnicodeContext hContext;
52 : :
53 : 7 : SvParser_Impl() :
54 : 7 : nSaveToken(0), hConv( 0 ), hContext( (rtl_TextToUnicodeContext)1 )
55 : : {
56 : 7 : }
57 : :
58 : : };
59 : :
60 : :
61 : :
62 : : // Konstruktor
63 : 7 : SvParser::SvParser( SvStream& rIn, sal_uInt8 nStackSize )
64 : : : rInput( rIn )
65 : : , nlLineNr( 1 )
66 : : , nlLinePos( 1 )
67 : : , pImplData( 0 )
68 : : , nTokenValue( 0 )
69 : : , bTokenHasValue( false )
70 : : , eState( SVPAR_NOTSTARTED )
71 : : , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
72 : : , bDownloadingFile( sal_False )
73 : : , nTokenStackSize( nStackSize )
74 [ + - ]: 7 : , nTokenStackPos( 0 )
75 : : {
76 : 7 : bUCS2BSrcEnc = bSwitchToUCS2 = sal_False;
77 : 7 : eState = SVPAR_NOTSTARTED;
78 [ - + ]: 7 : if( nTokenStackSize < 3 )
79 : 0 : nTokenStackSize = 3;
80 [ + - ][ + - ]: 28 : pTokenStack = new TokenStackType[ nTokenStackSize ];
[ + + # #
# # ]
81 : 7 : pTokenStackPos = pTokenStack;
82 : 7 : }
83 : :
84 [ + - ]: 7 : SvParser::~SvParser()
85 : : {
86 [ + - ][ + - ]: 7 : if( pImplData && pImplData->hConv )
87 : : {
88 : : rtl_destroyTextToUnicodeContext( pImplData->hConv,
89 [ + - ]: 7 : pImplData->hContext );
90 [ + - ]: 7 : rtl_destroyTextToUnicodeConverter( pImplData->hConv );
91 : : }
92 : :
93 [ + - ][ + - ]: 7 : delete pImplData;
94 : :
95 [ + - ][ + + ]: 28 : delete [] pTokenStack;
[ + - ]
96 [ - + ]: 7 : }
97 : :
98 : 0 : void SvParser::ClearTxtConvContext()
99 : : {
100 [ # # ][ # # ]: 0 : if( pImplData && pImplData->hConv )
101 : 0 : rtl_resetTextToUnicodeContext( pImplData->hConv, pImplData->hContext );
102 : 0 : }
103 : :
104 : 14 : void SvParser::SetSrcEncoding( rtl_TextEncoding eEnc )
105 : : {
106 : :
107 [ + + ]: 14 : if( eEnc != eSrcEnc )
108 : : {
109 [ + + ][ + - ]: 12 : if( pImplData && pImplData->hConv )
110 : : {
111 : : rtl_destroyTextToUnicodeContext( pImplData->hConv,
112 : 5 : pImplData->hContext );
113 : 5 : rtl_destroyTextToUnicodeConverter( pImplData->hConv );
114 : 5 : pImplData->hConv = 0;
115 : 5 : pImplData->hContext = (rtl_TextToUnicodeContext )1;
116 : : }
117 : :
118 [ - + ][ # # ]: 12 : if( rtl_isOctetTextEncoding(eEnc) ||
[ + - ]
119 : : RTL_TEXTENCODING_UCS2 == eEnc )
120 : : {
121 : 12 : eSrcEnc = eEnc;
122 [ + + ]: 12 : if( !pImplData )
123 [ + - ]: 7 : pImplData = new SvParser_Impl;
124 : 12 : pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
125 : : DBG_ASSERT( pImplData->hConv,
126 : : "SvParser::SetSrcEncoding: no converter for source encoding" );
127 [ - + ]: 12 : if( !pImplData->hConv )
128 : 0 : eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
129 : : else
130 : : pImplData->hContext =
131 : 12 : rtl_createTextToUnicodeContext( pImplData->hConv );
132 : : }
133 : : else
134 : : {
135 : : DBG_ASSERT( !this,
136 : : "SvParser::SetSrcEncoding: invalid source encoding" );
137 : 0 : eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
138 : : }
139 : : }
140 : 14 : }
141 : :
142 : 0 : void SvParser::RereadLookahead()
143 : : {
144 : 0 : rInput.Seek(nNextChPos);
145 : 0 : nNextCh = GetNextChar();
146 : 0 : }
147 : :
148 : 1909 : sal_Unicode SvParser::GetNextChar()
149 : : {
150 : 1909 : sal_Unicode c = 0U;
151 : :
152 : : // When reading muliple bytes, we don't have to care about the file
153 : : // position when we run inti the pending state. The file position is
154 : : // maintained by SaveState/RestoreState.
155 : : sal_Bool bErr;
156 [ + + ][ + - ]: 1909 : if( bSwitchToUCS2 && 0 == rInput.Tell() )
[ + + ]
157 : : {
158 : : sal_uChar c1, c2;
159 : 7 : sal_Bool bSeekBack = sal_True;
160 : :
161 [ + - ]: 7 : rInput >> c1;
162 [ + - ][ - + ]: 7 : bErr = rInput.IsEof() || rInput.GetError();
163 [ + - ]: 7 : if( !bErr )
164 : : {
165 [ + - ][ - + ]: 7 : if( 0xff == c1 || 0xfe == c1 )
166 : : {
167 [ # # ]: 0 : rInput >> c2;
168 [ # # ][ # # ]: 0 : bErr = rInput.IsEof() || rInput.GetError();
169 [ # # ]: 0 : if( !bErr )
170 : : {
171 [ # # ][ # # ]: 0 : if( 0xfe == c1 && 0xff == c2 )
172 : : {
173 : 0 : eSrcEnc = RTL_TEXTENCODING_UCS2;
174 : 0 : bUCS2BSrcEnc = sal_True;
175 : 0 : bSeekBack = sal_False;
176 : : }
177 [ # # ][ # # ]: 0 : else if( 0xff == c1 && 0xfe == c2 )
178 : : {
179 : 0 : eSrcEnc = RTL_TEXTENCODING_UCS2;
180 : 0 : bUCS2BSrcEnc = sal_False;
181 : 0 : bSeekBack = sal_False;
182 : : }
183 : : }
184 : : }
185 : : }
186 [ + - ]: 7 : if( bSeekBack )
187 [ + - ]: 7 : rInput.Seek( 0 );
188 : :
189 : 7 : bSwitchToUCS2 = sal_False;
190 : : }
191 : :
192 : 1909 : nNextChPos = rInput.Tell();
193 : :
194 [ - + ]: 1909 : if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
195 : : {
196 : 0 : sal_Unicode cUC = USHRT_MAX;
197 : : sal_uChar c1, c2;
198 : :
199 [ # # ][ # # ]: 0 : rInput >> c1 >> c2;
200 [ # # # # ]: 0 : if( 2 == rInput.Tell() &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
201 [ # # ]: 0 : !(rInput.IsEof() || rInput.GetError()) &&
202 : : ( (bUCS2BSrcEnc && 0xfe == c1 && 0xff == c2) ||
203 : 0 : (!bUCS2BSrcEnc && 0xff == c1 && 0xfe == c2) ) )
204 [ # # ][ # # ]: 0 : rInput >> c1 >> c2;
205 : :
206 [ # # ][ # # ]: 0 : bErr = rInput.IsEof() || rInput.GetError();
207 [ # # ]: 0 : if( !bErr )
208 : : {
209 [ # # ]: 0 : if( bUCS2BSrcEnc )
210 : 0 : cUC = (sal_Unicode(c1) << 8) | c2;
211 : : else
212 : 0 : cUC = (sal_Unicode(c2) << 8) | c1;
213 : : }
214 : :
215 [ # # ]: 0 : if( !bErr )
216 : : {
217 : 0 : c = cUC;
218 : : }
219 : : }
220 : : else
221 : : {
222 : 1909 : sal_Size nChars = 0;
223 [ + + ][ - + ]: 1909 : do
[ - + ]
224 : : {
225 : : sal_Char c1; // signed, that's the text converter expects
226 [ + - ]: 1909 : rInput >> c1;
227 [ + + ][ - + ]: 1909 : bErr = rInput.IsEof() || rInput.GetError();
228 [ + + ]: 1909 : if( !bErr )
229 : : {
230 [ + - ][ - + ]: 1897 : if (
231 : : RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
232 : : RTL_TEXTENCODING_SYMBOL == eSrcEnc
233 : : )
234 : : {
235 : : // no convserion shall take place
236 : 0 : c = (sal_Unicode)c1;
237 : 0 : nChars = 1;
238 : : }
239 : : else
240 : : {
241 : : DBG_ASSERT( pImplData && pImplData->hConv,
242 : : "no text converter!" );
243 : :
244 : : sal_Unicode cUC;
245 : 1897 : sal_uInt32 nInfo = 0;
246 : : sal_Size nCvtBytes;
247 : : nChars = rtl_convertTextToUnicode(
248 : : pImplData->hConv, pImplData->hContext,
249 : : &c1, 1, &cUC, 1,
250 : : RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
251 : : RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
252 : : RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
253 [ + - ]: 1897 : &nInfo, &nCvtBytes);
254 [ - + ]: 1897 : if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
255 : : {
256 : : // The conversion wasn't successfull because we haven't
257 : : // read enough characters.
258 [ # # ]: 0 : if( pImplData->hContext != (rtl_TextToUnicodeContext)1 )
259 : : {
260 [ # # ]: 0 : while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
261 : : {
262 [ # # ]: 0 : rInput >> c1;
263 [ # # ][ # # ]: 0 : bErr = rInput.IsEof() || rInput.GetError();
264 [ # # ]: 0 : if( bErr )
265 : 0 : break;
266 : :
267 : : nChars = rtl_convertTextToUnicode(
268 : : pImplData->hConv, pImplData->hContext,
269 : : &c1, 1, &cUC, 1,
270 : : RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
271 : : RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
272 : : RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
273 [ # # ]: 0 : &nInfo, &nCvtBytes);
274 : : }
275 [ # # ]: 0 : if( !bErr )
276 : : {
277 [ # # ][ # # ]: 0 : if( 1 == nChars && 0 == nInfo )
278 : : {
279 : 0 : c = cUC;
280 : : }
281 [ # # ][ # # ]: 0 : else if( 0 != nChars || 0 != nInfo )
282 : : {
283 : : DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
284 : : "source buffer is to small" );
285 : : DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
286 : : "there is a conversion error" );
287 : : DBG_ASSERT( 0 == nChars,
288 : : "there is a converted character, but an error" );
289 : : // There are still errors, but nothing we can
290 : : // do
291 : 0 : c = (sal_Unicode)'?';
292 : 0 : nChars = 1;
293 : : }
294 : : }
295 : : }
296 : : else
297 : : {
298 : : sal_Char sBuffer[10];
299 : 0 : sBuffer[0] = c1;
300 : 0 : sal_uInt16 nLen = 1;
301 [ # # ][ # # ]: 0 : while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 &&
[ # # ]
302 : : nLen < 10 )
303 : : {
304 [ # # ]: 0 : rInput >> c1;
305 [ # # ][ # # ]: 0 : bErr = rInput.IsEof() || rInput.GetError();
306 [ # # ]: 0 : if( bErr )
307 : 0 : break;
308 : :
309 : 0 : sBuffer[nLen++] = c1;
310 : : nChars = rtl_convertTextToUnicode(
311 : : pImplData->hConv, 0, sBuffer, nLen, &cUC, 1,
312 : : RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
313 : : RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
314 : : RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
315 [ # # ]: 0 : &nInfo, &nCvtBytes);
316 : : }
317 [ # # ]: 0 : if( !bErr )
318 : : {
319 [ # # ][ # # ]: 0 : if( 1 == nChars && 0 == nInfo )
320 : : {
321 : : DBG_ASSERT( nCvtBytes == nLen,
322 : : "no all bytes have been converted!" );
323 : 0 : c = cUC;
324 : : }
325 : : else
326 : : {
327 : : DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
328 : : "source buffer is to small" );
329 : : DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
330 : : "there is a conversion error" );
331 : : DBG_ASSERT( 0 == nChars,
332 : : "there is a converted character, but an error" );
333 : :
334 : : // There are still errors, so we use the first
335 : : // character and restart after that.
336 : 0 : c = (sal_Unicode)sBuffer[0];
337 [ # # ]: 0 : rInput.SeekRel( -(nLen-1) );
338 : 0 : nChars = 1;
339 : : }
340 : : }
341 : : }
342 : : }
343 [ + - ][ + - ]: 1897 : else if( 1 == nChars && 0 == nInfo )
344 : : {
345 : : // The conversion was successfull
346 : : DBG_ASSERT( nCvtBytes == 1,
347 : : "no all bytes have been converted!" );
348 : 1897 : c = cUC;
349 : : }
350 [ # # ][ # # ]: 0 : else if( 0 != nChars || 0 != nInfo )
351 : : {
352 : : DBG_ASSERT( 0 == nChars,
353 : : "there is a converted character, but an error" );
354 : : DBG_ASSERT( 0 != nInfo,
355 : : "there is no converted character and no error" );
356 : : // #73398#: If the character could not be converted,
357 : : // because a conversion is not available, do no conversion at all.
358 : 0 : c = (sal_Unicode)c1;
359 : 1897 : nChars = 1;
360 : :
361 : : }
362 : : }
363 : : }
364 : : }
365 : : while( 0 == nChars && !bErr );
366 : : }
367 [ + + ]: 1909 : if( bErr )
368 : : {
369 [ - + ]: 12 : if( ERRCODE_IO_PENDING == rInput.GetError() )
370 : : {
371 : 0 : eState = SVPAR_PENDING;
372 : 0 : return c;
373 : : }
374 : : else
375 : 12 : return sal_Unicode(EOF);
376 : : }
377 : :
378 [ + + ]: 1897 : if( c == '\n' )
379 : : {
380 : 66 : IncLineNr();
381 : 66 : SetLinePos( 1L );
382 : : }
383 : : else
384 : 1831 : IncLinePos();
385 : 1909 : return c;
386 : : }
387 : :
388 : 242 : int SvParser::GetNextToken()
389 : : {
390 : 242 : int nRet = 0;
391 : :
392 [ + - ]: 242 : if( !nTokenStackPos )
393 : : {
394 : 242 : aToken.Erase(); // Token-Buffer loeschen
395 : 242 : nTokenValue = -1; // Kennzeichen fuer kein Value gelesen
396 : 242 : bTokenHasValue = false;
397 : :
398 : 242 : nRet = _GetNextToken();
399 [ - + ]: 242 : if( SVPAR_PENDING == eState )
400 : 0 : return nRet;
401 : : }
402 : :
403 : 242 : ++pTokenStackPos;
404 [ + + ]: 242 : if( pTokenStackPos == pTokenStack + nTokenStackSize )
405 : 80 : pTokenStackPos = pTokenStack;
406 : :
407 : : // vom Stack holen ??
408 [ - + ]: 242 : if( nTokenStackPos )
409 : : {
410 : 0 : --nTokenStackPos;
411 : 0 : nTokenValue = pTokenStackPos->nTokenValue;
412 : 0 : bTokenHasValue = pTokenStackPos->bTokenHasValue;
413 : 0 : aToken = pTokenStackPos->sToken;
414 : 0 : nRet = pTokenStackPos->nTokenId;
415 : : }
416 : : // nein, dann das aktuelle auf den Stack
417 [ + + ]: 242 : else if( SVPAR_WORKING == eState )
418 : : {
419 : 235 : pTokenStackPos->sToken = aToken;
420 : 235 : pTokenStackPos->nTokenValue = nTokenValue;
421 : 235 : pTokenStackPos->bTokenHasValue = bTokenHasValue;
422 : 235 : pTokenStackPos->nTokenId = nRet;
423 : : }
424 [ - + ][ # # ]: 7 : else if( SVPAR_ACCEPTED != eState && SVPAR_PENDING != eState )
425 : 0 : eState = SVPAR_ERROR; // irgend ein Fehler
426 : :
427 : 242 : return nRet;
428 : : }
429 : :
430 : 0 : int SvParser::SkipToken( short nCnt ) // n Tokens zurueck "skippen"
431 : : {
432 : 0 : pTokenStackPos = GetStackPtr( nCnt );
433 : 0 : short nTmp = nTokenStackPos - nCnt;
434 [ # # ]: 0 : if( nTmp < 0 )
435 : 0 : nTmp = 0;
436 [ # # ]: 0 : else if( nTmp > nTokenStackSize )
437 : 0 : nTmp = nTokenStackSize;
438 : 0 : nTokenStackPos = sal_uInt8(nTmp);
439 : :
440 : : // und die Werte zurueck
441 : 0 : aToken = pTokenStackPos->sToken;
442 : 0 : nTokenValue = pTokenStackPos->nTokenValue;
443 : 0 : bTokenHasValue = pTokenStackPos->bTokenHasValue;
444 : :
445 : 0 : return pTokenStackPos->nTokenId;
446 : : }
447 : :
448 : 0 : SvParser::TokenStackType* SvParser::GetStackPtr( short nCnt )
449 : : {
450 : 0 : sal_uInt8 nAktPos = sal_uInt8(pTokenStackPos - pTokenStack );
451 [ # # ]: 0 : if( nCnt > 0 )
452 : : {
453 [ # # ]: 0 : if( nCnt >= nTokenStackSize )
454 : 0 : nCnt = (nTokenStackSize-1);
455 [ # # ]: 0 : if( nAktPos + nCnt < nTokenStackSize )
456 : 0 : nAktPos = sal::static_int_cast< sal_uInt8 >(nAktPos + nCnt);
457 : : else
458 : : nAktPos = sal::static_int_cast< sal_uInt8 >(
459 : 0 : nAktPos + (nCnt - nTokenStackSize));
460 : : }
461 [ # # ]: 0 : else if( nCnt < 0 )
462 : : {
463 [ # # ]: 0 : if( -nCnt >= nTokenStackSize )
464 : 0 : nCnt = -nTokenStackSize+1;
465 [ # # ]: 0 : if( -nCnt <= nAktPos )
466 : 0 : nAktPos = sal::static_int_cast< sal_uInt8 >(nAktPos + nCnt);
467 : : else
468 : : nAktPos = sal::static_int_cast< sal_uInt8 >(
469 : 0 : nAktPos + (nCnt + nTokenStackSize));
470 : : }
471 : 0 : return pTokenStack + nAktPos;
472 : : }
473 : :
474 : : // wird fuer jedes Token gerufen, das in CallParser erkannt wird
475 : 0 : void SvParser::NextToken( int )
476 : : {
477 : 0 : }
478 : :
479 : :
480 : : // fuers asynchrone lesen aus dem SvStream
481 : :
482 : 0 : int SvParser::GetSaveToken() const
483 : : {
484 [ # # ]: 0 : return pImplData ? pImplData->nSaveToken : 0;
485 : : }
486 : :
487 : 477 : void SvParser::SaveState( int nToken )
488 : : {
489 : : // aktuellen Status merken
490 [ - + ]: 477 : if( !pImplData )
491 : : {
492 [ # # ]: 0 : pImplData = new SvParser_Impl;
493 : 0 : pImplData->nSaveToken = 0;
494 : : }
495 : :
496 : 477 : pImplData->nFilePos = rInput.Tell();
497 : 477 : pImplData->nToken = nToken;
498 : :
499 : 477 : pImplData->aToken = aToken;
500 : 477 : pImplData->nlLineNr = nlLineNr;
501 : 477 : pImplData->nlLinePos = nlLinePos;
502 : 477 : pImplData->nTokenValue= nTokenValue;
503 : 477 : pImplData->bTokenHasValue = bTokenHasValue;
504 : 477 : pImplData->nNextCh = nNextCh;
505 : 477 : }
506 : :
507 : 0 : void SvParser::RestoreState()
508 : : {
509 : : // alten Status wieder zurueck setzen
510 [ # # ]: 0 : if( pImplData )
511 : : {
512 [ # # ]: 0 : if( ERRCODE_IO_PENDING == rInput.GetError() )
513 : 0 : rInput.ResetError();
514 : 0 : aToken = pImplData->aToken;
515 : 0 : nlLineNr = pImplData->nlLineNr;
516 : 0 : nlLinePos = pImplData->nlLinePos;
517 : 0 : nTokenValue= pImplData->nTokenValue;
518 : 0 : bTokenHasValue=pImplData->bTokenHasValue;
519 : 0 : nNextCh = pImplData->nNextCh;
520 : :
521 : 0 : pImplData->nSaveToken = pImplData->nToken;
522 : :
523 : 0 : rInput.Seek( pImplData->nFilePos );
524 : : }
525 : 0 : }
526 : :
527 : 0 : void SvParser::Continue( int )
528 : : {
529 : 0 : }
530 : :
531 : 4 : void SvParser::BuildWhichTbl( std::vector<sal_uInt16> &rWhichMap,
532 : : sal_uInt16 *pWhichIds,
533 : : sal_uInt16 nWhichIds )
534 : : {
535 : : sal_uInt16 aNewRange[2];
536 : :
537 [ + + ]: 74 : for( sal_uInt16 nCnt = 0; nCnt < nWhichIds; ++nCnt, ++pWhichIds )
538 [ + - ]: 70 : if( *pWhichIds )
539 : : {
540 : 70 : aNewRange[0] = aNewRange[1] = *pWhichIds;
541 : 70 : sal_Bool bIns = sal_True;
542 : :
543 : : // Position suchen
544 [ + - ][ + + ]: 488 : for ( sal_uInt16 nOfs = 0; rWhichMap[nOfs]; nOfs += 2 )
545 : : {
546 [ + - ][ + + ]: 468 : if( *pWhichIds < rWhichMap[nOfs] - 1 )
547 : : {
548 : : // neuen Range davor
549 [ + - ][ + - ]: 18 : rWhichMap.insert( rWhichMap.begin() + nOfs, aNewRange, aNewRange + 2 );
550 : 18 : bIns = sal_False;
551 : 18 : break;
552 : : }
553 [ + - ][ + + ]: 450 : else if( *pWhichIds == rWhichMap[nOfs] - 1 )
554 : : {
555 : : // diesen Range nach unten erweitern
556 [ + - ]: 6 : rWhichMap[nOfs] = *pWhichIds;
557 : 6 : bIns = sal_False;
558 : 6 : break;
559 : : }
560 [ + - ][ + + ]: 444 : else if( *pWhichIds == rWhichMap[nOfs+1] + 1 )
561 : : {
562 [ + - ][ + + ]: 26 : if( rWhichMap[nOfs+2] != 0 && rWhichMap[nOfs+2] == *pWhichIds + 1 )
[ + - ][ + + ]
[ + + ]
563 : : {
564 : : // mit dem naechsten Bereich mergen
565 [ + - ][ + - ]: 12 : rWhichMap[nOfs+1] = rWhichMap[nOfs+3];
566 : 12 : rWhichMap.erase( rWhichMap.begin() + nOfs + 2,
567 [ + - ]: 24 : rWhichMap.begin() + nOfs + 4 );
[ + - + - ]
[ + - ][ + - ]
568 : : }
569 : : else
570 : : // diesen Range nach oben erweitern
571 [ + - ]: 14 : rWhichMap[nOfs+1] = *pWhichIds;
572 : 26 : bIns = sal_False;
573 : 26 : break;
574 : : }
575 : : }
576 : :
577 : : // einen Range hinten anhaengen
578 [ + + ]: 70 : if( bIns )
579 : : {
580 : 20 : rWhichMap.insert( rWhichMap.begin() + rWhichMap.size() - 1,
581 [ + - ][ + - ]: 20 : aNewRange, aNewRange + 2 );
[ + - ]
582 : : }
583 : : }
584 : 4 : }
585 : :
586 : :
587 : 0 : IMPL_STATIC_LINK( SvParser, NewDataRead, void*, EMPTYARG )
588 : : {
589 [ # # # # ]: 0 : switch( pThis->eState )
590 : : {
591 : : case SVPAR_PENDING:
592 : : // Wenn gerade ein File geladen wird duerfen wir nicht weiterlaufen,
593 : : // sondern muessen den Aufruf ignorieren.
594 [ # # ]: 0 : if( pThis->IsDownloadingFile() )
595 : 0 : break;
596 : :
597 : 0 : pThis->eState = SVPAR_WORKING;
598 : 0 : pThis->RestoreState();
599 : :
600 : 0 : pThis->Continue( pThis->pImplData->nToken );
601 : :
602 [ # # ]: 0 : if( ERRCODE_IO_PENDING == pThis->rInput.GetError() )
603 : 0 : pThis->rInput.ResetError();
604 : :
605 [ # # ]: 0 : if( SVPAR_PENDING != pThis->eState )
606 : 0 : pThis->ReleaseRef(); // ansonsten sind wir fertig!
607 : 0 : break;
608 : :
609 : : case SVPAR_WAITFORDATA:
610 : 0 : pThis->eState = SVPAR_WORKING;
611 : 0 : break;
612 : :
613 : : case SVPAR_NOTSTARTED:
614 : : case SVPAR_WORKING:
615 : 0 : break;
616 : :
617 : : default:
618 : 0 : pThis->ReleaseRef(); // ansonsten sind wir fertig!
619 : 0 : break;
620 : : }
621 : :
622 : 0 : return 0;
623 : : }
624 : :
625 : : /*========================================================================
626 : : *
627 : : * SvKeyValueIterator.
628 : : *
629 : : *======================================================================*/
630 : :
631 : : /*
632 : : * SvKeyValueIterator.
633 : : */
634 : 2734 : SvKeyValueIterator::SvKeyValueIterator (void)
635 [ + - ]: 2734 : : m_pList (new SvKeyValueList_Impl),
636 [ + - ]: 2734 : m_nPos (0)
637 : : {
638 : 2734 : }
639 : :
640 : : /*
641 : : * ~SvKeyValueIterator.
642 : : */
643 : 2396 : SvKeyValueIterator::~SvKeyValueIterator (void)
644 : : {
645 [ + - ][ + - ]: 2396 : delete m_pList;
646 [ - + ]: 3594 : }
647 : :
648 : : /*
649 : : * GetFirst.
650 : : */
651 : 1376 : sal_Bool SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal)
652 : : {
653 : 1376 : m_nPos = m_pList->size();
654 : 1376 : return GetNext (rKeyVal);
655 : : }
656 : :
657 : : /*
658 : : * GetNext.
659 : : */
660 : 2756 : sal_Bool SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal)
661 : : {
662 [ + + ]: 2756 : if (m_nPos > 0)
663 : : {
664 : 1380 : rKeyVal = (*m_pList)[--m_nPos];
665 : 1380 : return sal_True;
666 : : }
667 : : else
668 : : {
669 : : // Nothing to do.
670 : 2756 : return sal_False;
671 : : }
672 : : }
673 : :
674 : : /*
675 : : * Append.
676 : : */
677 : 1369 : void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal)
678 : : {
679 [ + - ]: 1369 : m_pList->push_back(new SvKeyValue(rKeyVal));
680 : 1369 : }
681 : :
682 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|