xref: /AOO41X/main/tools/source/communi/parser.cxx (revision 89b56da77b74925c286b3e777681ba8dda16bf41)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_tools.hxx"
26 
27 #include <stdio.h>
28 #include <tools/stream.hxx>
29 #include <tools/fsys.hxx>
30 
31 #include "tools/iparser.hxx"
32 #include "tools/geninfo.hxx"
33 
34 
35 
36 //
37 // class InformationParser
38 //
39 
40 #define cKeyLevelChar '\t'
41 
42 /*****************************************************************************/
InformationParser(sal_Bool bReplace)43 InformationParser::InformationParser( sal_Bool bReplace )
44 /*****************************************************************************/
45                 : bRecover( sal_False ),
46                 sOldLine( "" ),
47                 bReplaceVariables( bReplace ),
48                 nLevel( 0 ),
49                 sUPD( "" ),
50                 sVersion( "" ),
51                 pActStream( NULL ),
52                 nErrorCode( 0 ),
53                 nErrorLine( 0 ),
54                 sErrorText( "" ),
55                 nActLine( 0 )
56 {
57 }
58 
59 /*****************************************************************************/
~InformationParser()60 InformationParser::~InformationParser()
61 /*****************************************************************************/
62 {
63 }
64 
65 /*****************************************************************************/
ReadLine()66 ByteString &InformationParser::ReadLine()
67 /*****************************************************************************/
68 {
69     ByteString sLine;
70 
71     if ( bRecover ) {
72         bRecover = sal_False;
73     }
74     else {
75          if ( !pActStream->IsEof()) {
76             pActStream->ReadLine( sLine );
77             xub_StrLen nStart = 0;
78             xub_StrLen nEnd = sLine.Len();
79             sal_Bool bCopy = sal_False;
80             while ( nStart < nEnd && ( sLine.GetChar( nStart ) == ' ' || sLine.GetChar( nStart ) == 0x09 ) )
81             {
82                 nStart++;
83                 bCopy = sal_True;
84             }
85 
86             while ( nStart < nEnd && ( sLine.GetChar( nEnd-1 ) == ' ' || sLine.GetChar( nEnd-1 ) == 0x09 ) )
87             {
88                 nEnd--;
89                 bCopy = sal_True;
90             }
91 
92             if ( bCopy )
93                 sLine = sLine.Copy( nStart, nEnd - nStart );
94 
95             if (( sLine.GetChar( 0 ) == '#' ) || ( !sLine.Len())) {
96                 if ( sCurrentComment.Len())
97                     sCurrentComment += "\n";
98                 sCurrentComment += sLine;
99                 return ReadLine();
100             }
101             else {
102                 if ( bReplaceVariables ) {
103                     sLine.SearchAndReplaceAll( "%UPD", sUPD );
104                     sLine.SearchAndReplaceAll( "%VERSION", sVersion );
105                 }
106             }
107         }
108         else {
109             if ( nLevel ) {
110                 sLine = "}";
111                 fprintf( stdout, "Reached EOF parsing %s. Suplying extra '}'\n",ByteString( sStreamName, gsl_getSystemTextEncoding()).GetBuffer() );
112     //          nErrorCode = IP_UNEXPECTED_EOF;
113     //          nErrorLine = nActLine;
114             }
115             else
116                 sLine = "";
117         }
118 
119         sOldLine = sLine;
120         nActLine++;
121     }
122 
123     return sOldLine;
124 }
125 
126 /*****************************************************************************/
ReadKey(GenericInformationList * pExistingList)127 GenericInformation *InformationParser::ReadKey(
128                                     GenericInformationList *pExistingList )
129 /*****************************************************************************/
130 {
131     // this method has no error handling yet, but it works very fast.
132     // it is used to create whole informations and sub informations in
133     // a simple data format in memory, readed in a configuration file with
134     // following format:
135 
136     /*
137 
138     key [value]
139     {
140         key [value]
141         key [value]
142         {
143             key [value]
144             ...
145             ...
146         }
147     }
148     key [value]
149     ...
150     ...
151 
152     */
153 
154     GenericInformation *pInfo = NULL;
155 
156     ByteString sLine( ReadLine());
157     ByteString sKey;
158     ByteString sValue;
159     ByteString sComment( sCurrentComment );
160     sCurrentComment = "";
161 
162     // key separated from value by tab?
163     sal_uInt16 nWSPos = sLine.Search( ' ' );
164     if ( sLine.Search( '\t' ) < nWSPos ) {
165         nWSPos = sLine.Search( '\t' );
166         sLine.SearchAndReplace( "\t", " " );
167     }
168 
169     if ( sLine.GetTokenCount( ' ' ) > 1 ) {
170         sKey = sLine.GetToken( 0, ' ' );
171         sValue = sLine.Copy( sKey.Len() + 1 );
172         while (( sValue.Search( ' ' ) == 0 ) || ( sValue.Search( '\t' ) == 0 )) {
173             sValue.Erase( 0, 1 );
174         }
175     }
176     else
177         sKey=sLine;
178 
179     if ( bReplaceVariables && !nLevel ) {
180         sUPD = sKey.Copy( sKey.Len() - 3 );
181         sVersion = sKey;
182     }
183 
184     if ( ReadLine() == "{" ) {
185         nLevel++;
186         GenericInformationList *pSubList = new GenericInformationList();
187         while ( ReadLine() != "}" ) {
188             Recover();
189             ReadKey( pSubList );
190         }
191         nLevel--;
192         pInfo = new GenericInformation( sKey, sValue,
193                         pExistingList, pSubList );
194         pInfo->SetComment( sComment );
195     }
196     else {
197         Recover();
198         if ( !sKey.Equals( "}" ) && !sKey.Equals( "{" ) )
199         {
200             pInfo = new GenericInformation( sKey, sValue, pExistingList );
201             pInfo->SetComment( sComment );
202         }
203     }
204 
205     return pInfo;
206 }
207 
208 /*****************************************************************************/
Recover()209 void InformationParser::Recover()
210 /*****************************************************************************/
211 {
212     bRecover = sal_True;
213 }
214 
215 /*****************************************************************************/
Save(SvStream & rOutStream,const GenericInformationList * pSaveList,sal_uInt16 level,sal_Bool bStripped)216 sal_Bool InformationParser::Save( SvStream &rOutStream,
217                   const GenericInformationList *pSaveList,
218                   sal_uInt16 level, sal_Bool bStripped )
219 /*****************************************************************************/
220 {
221     sal_uInt16 i;
222     sal_uIntPtr nInfoListCount;
223     ByteString sTmpStr;
224     GenericInformation *pGenericInfo;
225     GenericInformationList *pGenericInfoList;
226 
227     static ByteString aKeyLevel;
228     aKeyLevel.Expand( level, cKeyLevelChar );
229 
230     for ( nInfoListCount = 0; nInfoListCount < pSaveList->Count(); nInfoListCount++) {
231         // Key-Value Paare schreiben
232         pGenericInfo = pSaveList->GetObject( nInfoListCount );
233         sTmpStr = "";
234         if ( !bStripped && level )
235             sTmpStr.Append( aKeyLevel.GetBuffer(), level );
236 
237         if ( !bStripped )
238             for ( i = 0; i < pGenericInfo->GetComment().GetTokenCount( '\n' ); i++ ) {
239                 sTmpStr += pGenericInfo->GetComment().GetToken( i, '\n' );
240                 sTmpStr += "\n";
241                 if ( level )
242                     sTmpStr.Append( aKeyLevel.GetBuffer(), level );
243             }
244 
245         sTmpStr += pGenericInfo->GetBuffer();
246         sTmpStr += ' ';
247         sTmpStr += pGenericInfo->GetValue();
248         if ( !rOutStream.WriteLine( sTmpStr ) )
249             return sal_False;
250 
251         // wenn vorhanden, bearbeite recursive die Sublisten
252         if (( pGenericInfoList = pGenericInfo->GetSubList() ) != NULL ) {
253             // oeffnende Klammer
254             sTmpStr = "";
255             if ( !bStripped && level )
256                 sTmpStr.Append( aKeyLevel.GetBuffer(), level );
257             sTmpStr += '{';
258             if ( !rOutStream.WriteLine( sTmpStr ) )
259                 return sal_False;
260             // recursiv die sublist abarbeiten
261             if ( !Save( rOutStream, pGenericInfoList, level+1, bStripped ) )
262                 return sal_False;
263                 // schliessende Klammer
264             sTmpStr = "";
265             if ( !bStripped && level )
266                 sTmpStr.Append( aKeyLevel.GetBuffer(), level );
267             sTmpStr += '}';
268             if ( !rOutStream.WriteLine( sTmpStr ) )
269                 return sal_False;
270         }
271     }
272     return sal_True;
273 }
274 
275 /*****************************************************************************/
Execute(SvStream & rSourceStream,GenericInformationList * pExistingList)276 GenericInformationList *InformationParser::Execute(
277                                 SvStream &rSourceStream,
278                                 GenericInformationList *pExistingList )
279 /*****************************************************************************/
280 {
281     GenericInformationList *pList;
282     if ( pExistingList )
283         pList = pExistingList;
284     else
285         pList = new GenericInformationList();
286 
287     pActStream = &rSourceStream;
288 
289     // read all infos out of current file
290     while( !rSourceStream.IsEof()) {
291         nLevel = 0;
292         ReadKey( pList );
293     }
294 
295     return pList;
296 }
297 
298 /*****************************************************************************/
Execute(SvMemoryStream & rSourceStream,GenericInformationList * pExistingList)299 GenericInformationList *InformationParser::Execute( SvMemoryStream &rSourceStream,
300                             GenericInformationList *pExistingList )
301 /*****************************************************************************/
302 {
303     sStreamName = UniString( "Memory", gsl_getSystemTextEncoding());
304     return Execute( (SvStream &)rSourceStream, pExistingList );
305 }
306 
307 /*****************************************************************************/
Execute(SvFileStream & rSourceStream,GenericInformationList * pExistingList)308 GenericInformationList *InformationParser::Execute(
309                                 SvFileStream &rSourceStream,
310                                 GenericInformationList *pExistingList )
311 /*****************************************************************************/
312 {
313     if ( !rSourceStream.IsOpen())
314         return NULL;
315     sStreamName = rSourceStream.GetFileName();
316     return Execute( (SvStream &)rSourceStream, pExistingList );
317 }
318 
319 /*****************************************************************************/
Execute(UniString & rSourceFile,GenericInformationList * pExistingList)320 GenericInformationList *InformationParser::Execute( UniString &rSourceFile,
321                                 GenericInformationList *pExistingList )
322 /*****************************************************************************/
323 {
324     DirEntry aDirEntry( rSourceFile );
325     if ( !aDirEntry.Exists())
326         return NULL;
327 
328     GenericInformationList *pList;
329     if ( pExistingList )
330         pList = pExistingList;
331     else
332         pList = new GenericInformationList();
333 
334     // reset status
335     nErrorCode = 0;
336     nErrorLine = 0;
337     nActLine = 0;
338 
339     SvFileStream aActStream;
340     aActStream.Open( rSourceFile, STREAM_READ );
341     if( aActStream.GetError())
342         return NULL;
343 
344     pActStream = &aActStream;
345     if ( !Execute( aActStream, pList )) {
346         delete pList;
347         pList = NULL;
348     }
349 
350     // close the stream
351     aActStream.Close();
352     pActStream = NULL;
353 
354     if ( !nErrorCode )
355         return pList;
356 
357     return NULL;
358 }
359 
360 /*****************************************************************************/
Execute(Dir & rDir,GenericInformationList * pExistingList)361 GenericInformationList *InformationParser::Execute( Dir &rDir,
362                                 GenericInformationList *pExistingList )
363 /*****************************************************************************/
364 {
365     GenericInformationList *pList;
366 
367     if ( pExistingList )
368         pList = pExistingList;
369     else
370         pList = new GenericInformationList();
371 
372     for ( sal_uInt16 i = 0; i < rDir.Count(); i++ ) {
373 
374         // execute this dir
375         UniString sNextFile( rDir[i].GetFull());
376         GenericInformationList *pSubList = Execute( sNextFile );
377 
378         if ( !pSubList ) {
379             // any errors ?
380             delete pList;
381             return NULL;
382         }
383 
384         // create new info and insert it into list
385         ByteString sFileKey( rDir[i].GetName(), RTL_TEXTENCODING_UTF8 );
386         new GenericInformation(
387                                             sFileKey,
388                                             ByteString( "" ),
389                                             pList, pSubList );
390     }
391 
392     return pList;
393 }
394 
395 /*****************************************************************************/
Save(SvFileStream & rSourceStream,const GenericInformationList * pSaveList)396 sal_Bool InformationParser::Save( SvFileStream &rSourceStream,
397                   const GenericInformationList *pSaveList )
398 /*****************************************************************************/
399 {
400     if ( !rSourceStream.IsOpen() || !Save( (SvStream &)rSourceStream, pSaveList, 0, sal_False ))
401     {
402         printf( "ERROR saving file \"%s\"\n",ByteString( rSourceStream.GetFileName(), gsl_getSystemTextEncoding()).GetBuffer() );
403         return sal_False;
404     }
405 
406     return sal_True;
407 }
408 
409 /*****************************************************************************/
Save(SvMemoryStream & rSourceStream,const GenericInformationList * pSaveList)410 sal_Bool InformationParser::Save( SvMemoryStream &rSourceStream,
411                   const GenericInformationList *pSaveList )
412 /*****************************************************************************/
413 {
414     Time a;
415     sal_Bool bRet = Save( (SvStream &)rSourceStream, pSaveList, 0, sal_True );
416     Time b;
417     b = b - a;
418     return bRet;
419 }
420 
421 /*****************************************************************************/
Save(const UniString & rSourceFile,const GenericInformationList * pSaveList)422 sal_Bool InformationParser::Save( const UniString &rSourceFile,
423                   const GenericInformationList *pSaveList )
424 /*****************************************************************************/
425 {
426   SvFileStream *pOutFile = new SvFileStream( rSourceFile, STREAM_STD_WRITE | STREAM_TRUNC );
427 
428   if ( !Save( *pOutFile, pSaveList )) {
429     delete pOutFile;
430     return sal_False;
431   }
432   delete pOutFile;
433   return sal_True;
434 }
435 
436 /*****************************************************************************/
GetErrorCode()437 sal_uInt16 InformationParser::GetErrorCode()
438 /*****************************************************************************/
439 {
440     return nErrorCode;
441 }
442 
443 /*****************************************************************************/
GetErrorText()444 ByteString &InformationParser::GetErrorText()
445 /*****************************************************************************/
446 {
447   //    sErrorText = pActStream->GetFileName();
448     sErrorText = ByteString( sStreamName, gsl_getSystemTextEncoding());
449     sErrorText += ByteString( " (" );
450     sErrorText += ByteString::CreateFromInt64(nErrorLine);
451     sErrorText += ByteString( "): " );
452 
453     switch ( nErrorCode ) {
454     case IP_NO_ERROR:
455         sErrorText += ByteString( "Keine Fehler aufgetereten" );
456         break;
457     case IP_UNEXPECTED_EOF:
458         sErrorText += ByteString( "Ung�ltiges Dateiende!" );
459         break;
460     }
461 
462     return sErrorText;
463 }
464 
465 
466