1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: parser.cxx,v $
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"
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 /*****************************************************************************/
54 bReplaceVariables( bReplace
),
66 /*****************************************************************************/
67 InformationParser::~InformationParser()
68 /*****************************************************************************/
72 /*****************************************************************************/
73 ByteString
&InformationParser::ReadLine()
74 /*****************************************************************************/
82 if ( !pActStream
->IsEof()) {
83 pActStream
->ReadLine( sLine
);
84 xub_StrLen nStart
= 0;
85 xub_StrLen nEnd
= sLine
.Len();
87 while ( nStart
< nEnd
&& ( sLine
.GetChar( nStart
) == ' ' || sLine
.GetChar( nStart
) == 0x09 ) )
93 while ( nStart
< nEnd
&& ( sLine
.GetChar( nEnd
-1 ) == ' ' || sLine
.GetChar( nEnd
-1 ) == 0x09 ) )
100 sLine
= sLine
.Copy( nStart
, nEnd
- nStart
);
102 if (( sLine
.GetChar( 0 ) == '#' ) || ( !sLine
.Len())) {
103 if ( sCurrentComment
.Len())
104 sCurrentComment
+= "\n";
105 sCurrentComment
+= sLine
;
109 if ( bReplaceVariables
) {
110 sLine
.SearchAndReplaceAll( "%UPD", sUPD
);
111 sLine
.SearchAndReplaceAll( "%VERSION", sVersion
);
118 fprintf( stdout
, "Reached EOF parsing %s. Suplying extra '}'\n",ByteString( sStreamName
, gsl_getSystemTextEncoding()).GetBuffer() );
119 // nErrorCode = IP_UNEXPECTED_EOF;
120 // nErrorLine = nActLine;
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
161 GenericInformation
*pInfo
= NULL
;
163 ByteString
sLine( ReadLine());
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 );
186 if ( bReplaceVariables
&& !nLevel
) {
187 sUPD
= sKey
.Copy( sKey
.Len() - 3 );
191 if ( ReadLine() == "{" ) {
193 GenericInformationList
*pSubList
= new GenericInformationList();
194 while ( ReadLine() != "}" ) {
199 pInfo
= new GenericInformation( sKey
, sValue
,
200 pExistingList
, pSubList
);
201 pInfo
->SetComment( sComment
);
205 if ( !sKey
.Equals( "}" ) && !sKey
.Equals( "{" ) )
207 pInfo
= new GenericInformation( sKey
, sValue
, pExistingList
);
208 pInfo
->SetComment( sComment
);
215 /*****************************************************************************/
216 void InformationParser::Recover()
217 /*****************************************************************************/
222 /*****************************************************************************/
223 BOOL
InformationParser::Save( SvStream
&rOutStream
,
224 const GenericInformationList
*pSaveList
,
225 USHORT level
, BOOL bStripped
)
226 /*****************************************************************************/
229 ULONG nInfoListCount
;
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
);
241 if ( !bStripped
&& level
)
242 sTmpStr
.Append( aKeyLevel
.GetBuffer(), level
);
245 for ( i
= 0; i
< pGenericInfo
->GetComment().GetTokenCount( '\n' ); i
++ ) {
246 sTmpStr
+= pGenericInfo
->GetComment().GetToken( i
, '\n' );
249 sTmpStr
.Append( aKeyLevel
.GetBuffer(), level
);
252 sTmpStr
+= pGenericInfo
->GetBuffer();
254 sTmpStr
+= pGenericInfo
->GetValue();
255 if ( !rOutStream
.WriteLine( sTmpStr
) )
258 // wenn vorhanden, bearbeite recursive die Sublisten
259 if (( pGenericInfoList
= pGenericInfo
->GetSubList() ) != NULL
) {
262 if ( !bStripped
&& level
)
263 sTmpStr
.Append( aKeyLevel
.GetBuffer(), level
);
265 if ( !rOutStream
.WriteLine( sTmpStr
) )
267 // recursiv die sublist abarbeiten
268 if ( !Save( rOutStream
, pGenericInfoList
, level
+1, bStripped
) )
270 // schliessende Klammer
272 if ( !bStripped
&& level
)
273 sTmpStr
.Append( aKeyLevel
.GetBuffer(), level
);
275 if ( !rOutStream
.WriteLine( sTmpStr
) )
282 /*****************************************************************************/
283 GenericInformationList
*InformationParser::Execute(
284 SvStream
&rSourceStream
,
285 GenericInformationList
*pExistingList
)
286 /*****************************************************************************/
288 GenericInformationList
*pList
;
290 pList
= pExistingList
;
292 pList
= new GenericInformationList();
294 pActStream
= &rSourceStream
;
296 // read all infos out of current file
297 while( !rSourceStream
.IsEof()) {
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())
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())
335 GenericInformationList
*pList
;
337 pList
= pExistingList
;
339 pList
= new GenericInformationList();
346 SvFileStream aActStream
;
347 aActStream
.Open( rSourceFile
, STREAM_READ
);
348 if( aActStream
.GetError())
351 pActStream
= &aActStream
;
352 if ( !Execute( aActStream
, pList
)) {
367 /*****************************************************************************/
368 GenericInformationList
*InformationParser::Execute( Dir
&rDir
,
369 GenericInformationList
*pExistingList
)
370 /*****************************************************************************/
372 GenericInformationList
*pList
;
375 pList
= pExistingList
;
377 pList
= new GenericInformationList();
379 for ( USHORT i
= 0; i
< rDir
.Count(); i
++ ) {
382 UniString
sNextFile( rDir
[i
].GetFull());
383 GenericInformationList
*pSubList
= Execute( sNextFile
);
391 // create new info and insert it into list
392 ByteString
sFileKey( rDir
[i
].GetName(), RTL_TEXTENCODING_UTF8
);
393 new GenericInformation(
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() );
416 /*****************************************************************************/
417 BOOL
InformationParser::Save( SvMemoryStream
&rSourceStream
,
418 const GenericInformationList
*pSaveList
)
419 /*****************************************************************************/
422 BOOL bRet
= Save( (SvStream
&)rSourceStream
, pSaveList
, 0, TRUE
);
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
)) {
443 /*****************************************************************************/
444 USHORT
InformationParser::GetErrorCode()
445 /*****************************************************************************/
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
) {
462 sErrorText
+= ByteString( "Keine Fehler aufgetereten" );
464 case IP_UNEXPECTED_EOF
:
465 sErrorText
+= ByteString( "Ungültiges Dateiende!" );