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