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