Update ooo320-m1
[ooovba.git] / tools / source / communi / parser.cxx
blob961c25c4595cb5d17ec7bcf0b944ad6f6244553e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: parser.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
34 #include <stdio.h>
35 #include <tools/stream.hxx>
36 #include <tools/fsys.hxx>
38 #include "tools/iparser.hxx"
39 #include "tools/geninfo.hxx"
44 // class InformationParser
47 #define cKeyLevelChar '\t'
49 /*****************************************************************************/
50 InformationParser::InformationParser( BOOL bReplace )
51 /*****************************************************************************/
52 : bRecover( FALSE ),
53 sOldLine( "" ),
54 bReplaceVariables( bReplace ),
55 nLevel( 0 ),
56 sUPD( "" ),
57 sVersion( "" ),
58 pActStream( NULL ),
59 nErrorCode( 0 ),
60 nErrorLine( 0 ),
61 sErrorText( "" ),
62 nActLine( 0 )
66 /*****************************************************************************/
67 InformationParser::~InformationParser()
68 /*****************************************************************************/
72 /*****************************************************************************/
73 ByteString &InformationParser::ReadLine()
74 /*****************************************************************************/
76 ByteString sLine;
78 if ( bRecover ) {
79 bRecover = FALSE;
81 else {
82 if ( !pActStream->IsEof()) {
83 pActStream->ReadLine( sLine );
84 xub_StrLen nStart = 0;
85 xub_StrLen nEnd = sLine.Len();
86 BOOL bCopy = FALSE;
87 while ( nStart < nEnd && ( sLine.GetChar( nStart ) == ' ' || sLine.GetChar( nStart ) == 0x09 ) )
89 nStart++;
90 bCopy = TRUE;
93 while ( nStart < nEnd && ( sLine.GetChar( nEnd-1 ) == ' ' || sLine.GetChar( nEnd-1 ) == 0x09 ) )
95 nEnd--;
96 bCopy = TRUE;
99 if ( bCopy )
100 sLine = sLine.Copy( nStart, nEnd - nStart );
102 if (( sLine.GetChar( 0 ) == '#' ) || ( !sLine.Len())) {
103 if ( sCurrentComment.Len())
104 sCurrentComment += "\n";
105 sCurrentComment += sLine;
106 return ReadLine();
108 else {
109 if ( bReplaceVariables ) {
110 sLine.SearchAndReplaceAll( "%UPD", sUPD );
111 sLine.SearchAndReplaceAll( "%VERSION", sVersion );
115 else {
116 if ( nLevel ) {
117 sLine = "}";
118 fprintf( stdout, "Reached EOF parsing %s. Suplying extra '}'\n",ByteString( sStreamName, gsl_getSystemTextEncoding()).GetBuffer() );
119 // nErrorCode = IP_UNEXPECTED_EOF;
120 // nErrorLine = nActLine;
122 else
123 sLine = "";
126 sOldLine = sLine;
127 nActLine++;
130 return sOldLine;
133 /*****************************************************************************/
134 GenericInformation *InformationParser::ReadKey(
135 GenericInformationList *pExistingList )
136 /*****************************************************************************/
138 // this method has no error handling yet, but it works very fast.
139 // it is used to create whole informations and sub informations in
140 // a simple data format in memory, readed in a configuration file with
141 // following format:
145 key [value]
147 key [value]
148 key [value]
150 key [value]
155 key [value]
161 GenericInformation *pInfo = NULL;
163 ByteString sLine( ReadLine());
164 ByteString sKey;
165 ByteString sValue;
166 ByteString sComment( sCurrentComment );
167 sCurrentComment = "";
169 // key separated from value by tab?
170 USHORT nWSPos = sLine.Search( ' ' );
171 if ( sLine.Search( '\t' ) < nWSPos ) {
172 nWSPos = sLine.Search( '\t' );
173 sLine.SearchAndReplace( "\t", " " );
176 if ( sLine.GetTokenCount( ' ' ) > 1 ) {
177 sKey = sLine.GetToken( 0, ' ' );
178 sValue = sLine.Copy( sKey.Len() + 1 );
179 while (( sValue.Search( ' ' ) == 0 ) || ( sValue.Search( '\t' ) == 0 )) {
180 sValue.Erase( 0, 1 );
183 else
184 sKey=sLine;
186 if ( bReplaceVariables && !nLevel ) {
187 sUPD = sKey.Copy( sKey.Len() - 3 );
188 sVersion = sKey;
191 if ( ReadLine() == "{" ) {
192 nLevel++;
193 GenericInformationList *pSubList = new GenericInformationList();
194 while ( ReadLine() != "}" ) {
195 Recover();
196 ReadKey( pSubList );
198 nLevel--;
199 pInfo = new GenericInformation( sKey, sValue,
200 pExistingList, pSubList );
201 pInfo->SetComment( sComment );
203 else {
204 Recover();
205 if ( !sKey.Equals( "}" ) && !sKey.Equals( "{" ) )
207 pInfo = new GenericInformation( sKey, sValue, pExistingList );
208 pInfo->SetComment( sComment );
212 return pInfo;
215 /*****************************************************************************/
216 void InformationParser::Recover()
217 /*****************************************************************************/
219 bRecover = TRUE;
222 /*****************************************************************************/
223 BOOL InformationParser::Save( SvStream &rOutStream,
224 const GenericInformationList *pSaveList,
225 USHORT level, BOOL bStripped )
226 /*****************************************************************************/
228 USHORT i;
229 ULONG nInfoListCount;
230 ByteString sTmpStr;
231 GenericInformation *pGenericInfo;
232 GenericInformationList *pGenericInfoList;
234 static ByteString aKeyLevel;
235 aKeyLevel.Expand( level, cKeyLevelChar );
237 for ( nInfoListCount = 0; nInfoListCount < pSaveList->Count(); nInfoListCount++) {
238 // Key-Value Paare schreiben
239 pGenericInfo = pSaveList->GetObject( nInfoListCount );
240 sTmpStr = "";
241 if ( !bStripped && level )
242 sTmpStr.Append( aKeyLevel.GetBuffer(), level );
244 if ( !bStripped )
245 for ( i = 0; i < pGenericInfo->GetComment().GetTokenCount( '\n' ); i++ ) {
246 sTmpStr += pGenericInfo->GetComment().GetToken( i, '\n' );
247 sTmpStr += "\n";
248 if ( level )
249 sTmpStr.Append( aKeyLevel.GetBuffer(), level );
252 sTmpStr += pGenericInfo->GetBuffer();
253 sTmpStr += ' ';
254 sTmpStr += pGenericInfo->GetValue();
255 if ( !rOutStream.WriteLine( sTmpStr ) )
256 return FALSE;
258 // wenn vorhanden, bearbeite recursive die Sublisten
259 if (( pGenericInfoList = pGenericInfo->GetSubList() ) != NULL ) {
260 // oeffnende Klammer
261 sTmpStr = "";
262 if ( !bStripped && level )
263 sTmpStr.Append( aKeyLevel.GetBuffer(), level );
264 sTmpStr += '{';
265 if ( !rOutStream.WriteLine( sTmpStr ) )
266 return FALSE;
267 // recursiv die sublist abarbeiten
268 if ( !Save( rOutStream, pGenericInfoList, level+1, bStripped ) )
269 return FALSE;
270 // schliessende Klammer
271 sTmpStr = "";
272 if ( !bStripped && level )
273 sTmpStr.Append( aKeyLevel.GetBuffer(), level );
274 sTmpStr += '}';
275 if ( !rOutStream.WriteLine( sTmpStr ) )
276 return FALSE;
279 return TRUE;
282 /*****************************************************************************/
283 GenericInformationList *InformationParser::Execute(
284 SvStream &rSourceStream,
285 GenericInformationList *pExistingList )
286 /*****************************************************************************/
288 GenericInformationList *pList;
289 if ( pExistingList )
290 pList = pExistingList;
291 else
292 pList = new GenericInformationList();
294 pActStream = &rSourceStream;
296 // read all infos out of current file
297 while( !rSourceStream.IsEof()) {
298 nLevel = 0;
299 ReadKey( pList );
302 return pList;
305 /*****************************************************************************/
306 GenericInformationList *InformationParser::Execute( SvMemoryStream &rSourceStream,
307 GenericInformationList *pExistingList )
308 /*****************************************************************************/
310 sStreamName = UniString( "Memory", gsl_getSystemTextEncoding());
311 return Execute( (SvStream &)rSourceStream, pExistingList );
314 /*****************************************************************************/
315 GenericInformationList *InformationParser::Execute(
316 SvFileStream &rSourceStream,
317 GenericInformationList *pExistingList )
318 /*****************************************************************************/
320 if ( !rSourceStream.IsOpen())
321 return NULL;
322 sStreamName = rSourceStream.GetFileName();
323 return Execute( (SvStream &)rSourceStream, pExistingList );
326 /*****************************************************************************/
327 GenericInformationList *InformationParser::Execute( UniString &rSourceFile,
328 GenericInformationList *pExistingList )
329 /*****************************************************************************/
331 DirEntry aDirEntry( rSourceFile );
332 if ( !aDirEntry.Exists())
333 return NULL;
335 GenericInformationList *pList;
336 if ( pExistingList )
337 pList = pExistingList;
338 else
339 pList = new GenericInformationList();
341 // reset status
342 nErrorCode = 0;
343 nErrorLine = 0;
344 nActLine = 0;
346 SvFileStream aActStream;
347 aActStream.Open( rSourceFile, STREAM_READ );
348 if( aActStream.GetError())
349 return NULL;
351 pActStream = &aActStream;
352 if ( !Execute( aActStream, pList )) {
353 delete pList;
354 pList = NULL;
357 // close the stream
358 aActStream.Close();
359 pActStream = NULL;
361 if ( !nErrorCode )
362 return pList;
364 return NULL;
367 /*****************************************************************************/
368 GenericInformationList *InformationParser::Execute( Dir &rDir,
369 GenericInformationList *pExistingList )
370 /*****************************************************************************/
372 GenericInformationList *pList;
374 if ( pExistingList )
375 pList = pExistingList;
376 else
377 pList = new GenericInformationList();
379 for ( USHORT i = 0; i < rDir.Count(); i++ ) {
381 // execute this dir
382 UniString sNextFile( rDir[i].GetFull());
383 GenericInformationList *pSubList = Execute( sNextFile );
385 if ( !pSubList ) {
386 // any errors ?
387 delete pList;
388 return NULL;
391 // create new info and insert it into list
392 ByteString sFileKey( rDir[i].GetName(), RTL_TEXTENCODING_UTF8 );
393 new GenericInformation(
394 sFileKey,
395 ByteString( "" ),
396 pList, pSubList );
399 return pList;
402 /*****************************************************************************/
403 BOOL InformationParser::Save( SvFileStream &rSourceStream,
404 const GenericInformationList *pSaveList )
405 /*****************************************************************************/
407 if ( !rSourceStream.IsOpen() || !Save( (SvStream &)rSourceStream, pSaveList, 0, FALSE ))
409 printf( "ERROR saving file \"%s\"\n",ByteString( rSourceStream.GetFileName(), gsl_getSystemTextEncoding()).GetBuffer() );
410 return FALSE;
413 return TRUE;
416 /*****************************************************************************/
417 BOOL InformationParser::Save( SvMemoryStream &rSourceStream,
418 const GenericInformationList *pSaveList )
419 /*****************************************************************************/
421 Time a;
422 BOOL bRet = Save( (SvStream &)rSourceStream, pSaveList, 0, TRUE );
423 Time b;
424 b = b - a;
425 return bRet;
428 /*****************************************************************************/
429 BOOL InformationParser::Save( const UniString &rSourceFile,
430 const GenericInformationList *pSaveList )
431 /*****************************************************************************/
433 SvFileStream *pOutFile = new SvFileStream( rSourceFile, STREAM_STD_WRITE | STREAM_TRUNC );
435 if ( !Save( *pOutFile, pSaveList )) {
436 delete pOutFile;
437 return FALSE;
439 delete pOutFile;
440 return TRUE;
443 /*****************************************************************************/
444 USHORT InformationParser::GetErrorCode()
445 /*****************************************************************************/
447 return nErrorCode;
450 /*****************************************************************************/
451 ByteString &InformationParser::GetErrorText()
452 /*****************************************************************************/
454 // sErrorText = pActStream->GetFileName();
455 sErrorText = ByteString( sStreamName, gsl_getSystemTextEncoding());
456 sErrorText += ByteString( " (" );
457 sErrorText += ByteString::CreateFromInt64(nErrorLine);
458 sErrorText += ByteString( "): " );
460 switch ( nErrorCode ) {
461 case IP_NO_ERROR:
462 sErrorText += ByteString( "Keine Fehler aufgetereten" );
463 break;
464 case IP_UNEXPECTED_EOF:
465 sErrorText += ByteString( "Ungültiges Dateiende!" );
466 break;
469 return sErrorText;