summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2005-05-30 13:06:21 +0000
committerKurt Zenker <kz@openoffice.org>2005-05-30 13:06:21 +0000
commitd2bcf92b34a2d99440249368a9f29c06eb235841 (patch)
tree7ffb6537c73074d1bacca5c358f27eb043ad6297 /tools
parentf326c3896e732b65bb3ce1167f06b3155ecec97a (diff)
#i49990# back to previous version
Diffstat (limited to 'tools')
-rw-r--r--tools/source/communi/geninfo.cxx433
-rw-r--r--tools/source/communi/makefile.mk63
-rw-r--r--tools/source/communi/parser.cxx500
3 files changed, 962 insertions, 34 deletions
diff --git a/tools/source/communi/geninfo.cxx b/tools/source/communi/geninfo.cxx
new file mode 100644
index 000000000000..295e212a10f9
--- /dev/null
+++ b/tools/source/communi/geninfo.cxx
@@ -0,0 +1,433 @@
+/*************************************************************************
+ *
+ * $RCSfile: geninfo.cxx,v $
+ *
+ * $Revision: 1.7 $
+ *
+ * last change: $Author: kz $ $Date: 2005-05-30 14:06:17 $
+ *
+ * Copyright according the GNU Public License.
+ *
+ ************************************************************************/
+#include "geninfo.hxx"
+#include <stdio.h>
+
+//
+// class GenericInformation
+//
+
+/*****************************************************************************/
+GenericInformation::GenericInformation( const ByteString &rKey,
+ const ByteString &rValue,
+ GenericInformationList *pParentList,
+ GenericInformationList *pSubInfos )
+/*****************************************************************************/
+ : ByteString( rKey ),
+ sValue( rValue ),
+ pParent( pParentList ),
+ pInfoList( pSubInfos )
+{
+ // if a ParentList exists, insert this object into it
+ if ( pParent )
+ pParent->InsertInfo( this );
+ // make myself owner of pInfoList
+ if ( pInfoList )
+ pInfoList->SetOwner( this );
+}
+
+/*****************************************************************************/
+GenericInformation::GenericInformation( const GenericInformation& rInf,
+ BOOL bCopySubs)
+/*****************************************************************************/
+ : ByteString( rInf ),
+ sValue( rInf.sValue ),
+ pParent(NULL),
+ pInfoList( 0L )
+{
+ if(bCopySubs && rInf.pInfoList)
+ pInfoList = new GenericInformationList(*rInf.pInfoList, this);
+}
+
+/*****************************************************************************/
+GenericInformation::~GenericInformation()
+/*****************************************************************************/
+{
+ // remove pInfoList and all childs out of memory
+ delete pInfoList;
+ pInfoList = 0;
+
+ // remove this Info out of ParentList
+ if ( pParent )
+ pParent->RemoveInfo( this );
+}
+
+/*****************************************************************************/
+BOOL GenericInformation::InsertSubInfo( GenericInformation *pInfo )
+/*****************************************************************************/
+{
+ return ( pInfoList && pInfoList->InsertInfo( pInfo ));
+}
+
+/*****************************************************************************/
+BOOL GenericInformation::InsertSubInfo( const ByteString &rPathKey, const ByteString &rValue,
+ BOOL bSearchByPath, BOOL bNewPath )
+/*****************************************************************************/
+{
+ return (pInfoList && pInfoList->InsertInfo( rPathKey, rValue, bSearchByPath, bNewPath ));
+}
+
+/*****************************************************************************/
+void GenericInformation::RemoveSubInfo( GenericInformation *pInfo,
+ BOOL bDelete )
+/*****************************************************************************/
+{
+ pInfoList->RemoveInfo( pInfo, bDelete );
+}
+
+/*****************************************************************************/
+//void GenericInformation::RemoveSelf( BOOL bDelete )
+/*****************************************************************************/
+/*{
+ if ( pParent )
+ pParent->RemoveInfo( this, bDelete ); // loescht sich aus der Liste vom Parent und
+ // bei Bedarf auch mit obiger Methode alle Sublisten
+
+ // loescht sich bei Bedarf auch selbst
+ if ( bDelete )
+ delete this;
+}
+*/
+
+/*****************************************************************************/
+GenericInformation *GenericInformation::GetSubInfo( ByteString &rKey,
+ BOOL bSearchByPath,
+ BOOL bCreatePath )
+/*****************************************************************************/
+{
+ if ( !pInfoList && bCreatePath )
+ pInfoList = new GenericInformationList( this );
+ if ( pInfoList )
+ return pInfoList->GetInfo( rKey, bSearchByPath, bCreatePath );
+ return NULL;
+}
+
+
+//
+// class GenericInformationList
+//
+
+/*****************************************************************************/
+GenericInformationList::GenericInformationList( GenericInformation *pParent )
+/*****************************************************************************/
+ : pOwner( pParent )
+{
+}
+
+/*****************************************************************************/
+GenericInformationList::GenericInformationList(const GenericInformationList& rList,
+ GenericInformation *pParent)
+/*****************************************************************************/
+{
+ USHORT i;
+ GenericInformation* pTemp,*pWork;
+
+ pOwner = pParent;
+
+ for(i=0;i<rList.Count();i++)
+ {
+ pTemp = rList.GetObject(i);
+ pWork = new GenericInformation(*pTemp,TRUE);
+
+ Insert(pWork,LIST_APPEND);
+ }
+}
+
+/*****************************************************************************/
+GenericInformationList::~GenericInformationList()
+/*****************************************************************************/
+{
+ // delete all Informations stored in this List
+ // ### GH: Hier werden dann wohl etwa die Hlfte der Eintrge gelscht
+/* for ( ULONG i = 0; i < Count(); i++ ) {
+ GetObject( i )->ListDeleted();
+ delete GetObject( i );
+ Remove( i );*/
+ // Neue Variante:
+ while ( Count() ) {
+ GetObject( 0 )->ListDeleted();
+ delete GetObject( 0 );
+ Remove( (ULONG)0 );
+ }
+}
+
+/*****************************************************************************/
+GenericInformation *GenericInformationList::Search( ULONG &rPos, ByteString sKey,
+ ULONG nStart, ULONG nEnd )
+/*****************************************************************************/
+{
+ if ( Count() == 0 ) {
+ rPos = 0;
+ return NULL;
+ }
+
+ if ( nStart == nEnd ) {
+ rPos = nStart;
+ ByteString sCandidate = ByteString( *GetObject( nStart ));
+ if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii()) {
+ return GetObject( nStart ); // found !!!
+ }
+ else {
+ // requested key not found
+ return NULL;
+ }
+ }
+
+ // search binary in existing list
+ ULONG nActPos = nStart + (( nEnd - nStart ) / 2 );
+ rPos = nActPos;
+ ByteString sCandidate = ByteString( *GetObject( nActPos ));
+
+ if ( sCandidate.ToUpperAscii() == sKey.ToUpperAscii())
+ return GetObject( nActPos ); // found !!!
+
+ // split the list at ActPos
+ if ( sCandidate < sKey )
+ return Search( rPos, sKey, nActPos + 1, nEnd );
+ else
+ return Search( rPos, sKey, nStart, nActPos );
+}
+
+/*****************************************************************************/
+GenericInformation *GenericInformationList::GetInfo( ByteString &rKey,
+ BOOL bSearchByPath,
+ BOOL bCreatePath )
+/*****************************************************************************/
+{
+
+ rKey.EraseLeadingChars( '/' );
+ rKey.EraseTrailingChars( '/' );
+
+ ByteString sKey;
+ if ( bSearchByPath )
+ sKey = rKey.GetToken( 0, '/' );
+ else
+ sKey = rKey;
+
+ ULONG nPos = 0;
+ GenericInformation *pReturnInfo = Search( nPos, sKey, 0, Count() - 1 );
+ /* wenn kein Searchpath gesetzt und kein Returninfo vorhanden,
+ * gib NULL zurueck
+ * wenn Searchpath gesetzt und returninfo vorhanden,
+ * suche weiter nach unten
+ * wenn searchpath gesetzt kein returninfo vorhanden und newpath gesetzt,
+ * mache neues Verzeichniss
+ */
+ USHORT nTokenCount = rKey.GetTokenCount('/');
+ // search for next key of path in next level of tree
+ if ( bSearchByPath && (nTokenCount > 1)) {
+ ByteString sPath = ByteString(rKey.Copy( sKey.Len() + 1 ));
+ if ( !pReturnInfo ) { // wenn kein Return, dann muss man es anlegen
+ if ( !bCreatePath ) // wenn aber kein Create, dann nicht anlegen
+ return NULL;
+ USHORT nTmp = 0;
+ pReturnInfo = new GenericInformation( sKey, "", this, NULL);
+ pReturnInfo->SetSubList( new GenericInformationList( pReturnInfo ));
+ }
+ return pReturnInfo->GetSubInfo( sPath, TRUE, bCreatePath );
+ }
+ if ( !pReturnInfo && bCreatePath ) {
+ pReturnInfo = new GenericInformation ( sKey, "", this, NULL);
+ }
+
+ return pReturnInfo; // kann durchaus NULL sein.
+}
+
+/*****************************************************************************/
+ULONG GenericInformationList::InsertSorted( GenericInformation *pInfo,
+ BOOL bOverwrite,
+ ULONG nStart, ULONG nEnd )
+/*****************************************************************************/
+{
+ if ( Count() == 0 ) {
+ // empty list, so insert at first pos
+ Insert( pInfo, LIST_APPEND );
+ return 0;
+ }
+
+ ByteString sKey( pInfo->GetBuffer());
+ sKey.ToUpperAscii();
+
+ // Check to sppeed up reading a (partially) sorted list
+ if ( nStart == 0 && Count()-1 == nEnd )
+ {
+ ByteString sCandidate( *GetObject( nEnd ));
+ if ( sCandidate.ToUpperAscii() < sKey )
+ {
+ Insert( pInfo, LIST_APPEND );
+ return nEnd+1;
+ }
+ }
+
+// ### GH: dieser Block schein berflssig zu sein
+ if ( Count() == 1 ) {
+ ByteString sCandidate( *GetObject( 0 ));
+ if ( sCandidate.ToUpperAscii() == sKey ) {
+ // key allready exists in list
+ if ( bOverwrite )
+ Replace( pInfo, ULONG(0)); // ### Laut NF scheint hier ein Memory Leak zu sein
+ return 0;
+ }
+ else if ( sCandidate > sKey ) {
+ Insert( pInfo, ULONG(0));
+ return 0;
+ }
+ else {
+ Insert( pInfo, LIST_APPEND );
+ return 1;
+ }
+ }
+// ### GH: /ENDE/ dieser Block schein berflssig zu sein
+
+ ULONG nActPos = nStart + (( nEnd - nStart ) / 2 );
+ ByteString sCandidate = ByteString( *GetObject( nActPos ));
+
+ if ( sCandidate.ToUpperAscii() == sKey ) {
+ // key allready exists in list
+ if ( bOverwrite )
+ Replace( pInfo, nActPos ); // ### Laut NF scheint hier ein Memory Leak zu sein
+ return nActPos;
+ }
+
+ if ( nStart == nEnd ) {
+ // now more ways to search for key -> insert here
+ if ( sCandidate > sKey ) {
+ Insert( pInfo, nStart );
+ return nStart;
+ }
+ else {
+ Insert( pInfo, nStart + 1 );
+ return ( nStart + 1 );
+ }
+ }
+
+ if ( nActPos == Count() - 1 ) {
+ // reached end of list -> insert here
+ Insert( pInfo, LIST_APPEND );
+ return ( nActPos + 1 );
+ }
+
+ ByteString sSecondCand = ByteString( *GetObject( nActPos + 1 ));
+ if (( sCandidate < sKey ) && ( sSecondCand.ToUpperAscii() > sKey )) {
+ // optimal position to insert object
+ Insert( pInfo, nActPos + 1 );
+ return ( nActPos + 1 );
+ }
+
+ if ( sCandidate < sKey )
+ return InsertSorted( pInfo, bOverwrite, nActPos + 1, nEnd );
+ else
+ return InsertSorted( pInfo, bOverwrite, nStart, nActPos );
+}
+
+/*****************************************************************************/
+BOOL GenericInformationList::InsertInfo( GenericInformation *pInfo,
+ BOOL bOverwrite )
+/*****************************************************************************/
+{
+ if ( !pInfo->Len())
+ return FALSE;
+
+ InsertSorted( pInfo, bOverwrite, 0, Count() - 1 );
+ return TRUE;
+}
+
+
+/*****************************************************************************/
+BOOL GenericInformationList::InsertInfo( const ByteString &rPathKey, const ByteString &rValue,
+ BOOL bSearchByPath, BOOL bNewPath )
+/*****************************************************************************/
+{
+ GenericInformation *pInfo;
+ ByteString sPathKey ( rPathKey );
+ sPathKey.EraseLeadingChars( '/' );
+ sPathKey.EraseTrailingChars( '/' );
+
+ pInfo = GetInfo( sPathKey, bSearchByPath, bNewPath );
+
+ if ( pInfo ) {
+ pInfo->SetValue( rValue );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*****************************************************************************
+BOOL GenericInformationList::InsertInfo( const String &rPathKey,
+ const String &rValue,
+ BOOL bNewPath = FALSE)
+/*****************************************************************************
+{
+ GenericInformation *pInfo;
+
+ if ( !pPathKey || '\0'==pPathKey[0] )
+ return FALSE;
+
+ char *pNextItem = strchr( pPathKey, '/' );
+ if ( !pNextItem ) { // kein Token mehr gefunden
+ /* aus dem PathKey kann nun eine GenericInformation gebildet
+ * und eingefuegt werden *
+ pInfo = GetInfo( pPathKey, FALSE );
+ // Object besteht nicht und soll auch nicht nachgebildet werden
+ if ( !pInfo && !bNewPath )
+ return FALSE;
+ // erzeuge neue GI und stopfe sie in die Liste. Fertig !
+ pInfo = new GenericInformation( String( pPathKey ), String( pValue ), 0, 0 );
+ return InsertInfo( pInfo, TRUE );
+ }
+ else { // noch nicht fertig, muss noch tiefer in den Baum gehen
+ // SuchString anfertigen
+ String sSearch ( pPathKey );
+ sSearch.Erase ( USHORT(pNextItem - pPathKey));
+ // suchen..
+ pInfo = GetInfo( sSearch, FALSE );
+ if ( !pInfo && ! bNewPath) // subinfo nicht vorhanden und
+ return FALSE; // ich darf keinen neuen Pfad anlegen
+
+ if ( !pInfo )
+ // neue Subinfo machen und einfuegen
+ pInfo = new GenericInformation ( sSearch , "", this, 0 );
+
+ pNextItem++;
+ return pInfo->InsertSubInfo( pNextItem, pValue, bNewPath );
+ }
+ }
+}
+*/
+
+/*****************************************************************************/
+void GenericInformationList::RemoveInfo( GenericInformation *pInfo,
+ BOOL bDelete )
+/*****************************************************************************/
+{
+ Remove( pInfo );
+ if ( bDelete )
+ delete pInfo;
+/* if ( Count() == 0 && pOwner ) // Leere Listen entfernen;
+ {
+ SetOwner( NULL );
+ delete this;
+ } Rausgepatched by GH */
+}
+
+GenericInformation* GenericInformationList::SetOwner( GenericInformation *pNewOwner )
+{
+ GenericInformation *pOldOwner = pOwner;
+ if ( pOwner ) // bei parent austragen;
+ pOwner->SetSubList( NULL );
+ if ( pNewOwner )
+ pNewOwner->SetSubList( this );
+ pOwner = pNewOwner;
+ return pOldOwner;
+}
+
+
diff --git a/tools/source/communi/makefile.mk b/tools/source/communi/makefile.mk
index a8e6b8ac0d4a..0680606e88c5 100644
--- a/tools/source/communi/makefile.mk
+++ b/tools/source/communi/makefile.mk
@@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.9 $
+# $Revision: 1.10 $
#
-# last change: $Author: kz $ $Date: 2005-05-20 12:52:48 $
+# last change: $Author: kz $ $Date: 2005-05-30 14:06:19 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@@ -60,57 +60,52 @@
#
#*************************************************************************
-PRJ=..$/..$/..
-
-PRJNAME=devtools
-TARGET=btcommuni
-ENABLE_EXCEPTIONS=true
+PRJ=..$/..
+PRJNAME=TOOLS
+TARGET=communi
# --- Settings -----------------------------------------------------
.INCLUDE : svpre.mk
.INCLUDE : settings.mk
.INCLUDE : sv.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
# --- Files --------------------------------------------------------
-SLOFILES=\
+CXXFILES= simplecm.cxx bcst.cxx
+
+OBJFILES= \
+ $(OBJ)$/abthread.obj \
+ $(OBJ)$/tcpio.obj \
+ $(OBJ)$/packethandler.obj \
+ $(OBJ)$/simplecm.obj \
+ $(OBJ)$/bcst.obj \
+ $(OBJ)$/persbcst.obj \
+ $(OBJ)$/iiclient.obj \
+ $(OBJ)$/siclient.obj \
+ $(OBJ)$/infocom.obj \
+ $(OBJ)$/bsockcon.obj \
+ $(OBJ)$/ssockcon.obj \
+ $(OBJ)$/parser.obj \
+ $(OBJ)$/geninfo.obj \
+
+SLOFILES= \
$(SLO)$/abthread.obj \
$(SLO)$/tcpio.obj \
$(SLO)$/packethandler.obj \
+ $(SLO)$/simplecm.obj \
$(SLO)$/bcst.obj \
$(SLO)$/persbcst.obj \
$(SLO)$/iiclient.obj \
$(SLO)$/siclient.obj \
$(SLO)$/infocom.obj \
$(SLO)$/bsockcon.obj \
- $(SLO)$/ssockcon.obj
-
-SHL1TARGET =$(TARGET)$(UPD)$(DLLPOSTFIX)
-SHL1IMPLIB =i$(TARGET)
-SHL1LIBS =$(SLB)$/$(TARGET).lib
-SHL1DEF =$(MISC)$/$(SHL1TARGET).def
-SHL1DEPN =$(SHL1LIBS)
-SHL1STDLIBS=\
- $(TOOLSLIB) \
- $(SIMPLECMLIB) \
- $(VOSLIB) \
- $(SALLIB)
-
-DEF1NAME =$(SHL1TARGET)
-DEF1DEPN =$(MISC)$/$(SHL1TARGET).flt
-DEFLIB1NAME =$(TARGET)
+ $(SLO)$/ssockcon.obj \
+ $(SLO)$/parser.obj \
+ $(SLO)$/geninfo.obj \
# --- Targets ------------------------------------------------------
-.INCLUDE : target.mk
-
-$(MISC)$/$(SHL1TARGET).flt: makefile.mk
- @echo ------------------------------
- @echo Making: $@
- @echo WEP > $@
- @echo LIBMAIN >> $@
- @echo LibMain >> $@
- @echo __CT >> $@
-
+.INCLUDE : target.mk
diff --git a/tools/source/communi/parser.cxx b/tools/source/communi/parser.cxx
new file mode 100644
index 000000000000..c4772f370c71
--- /dev/null
+++ b/tools/source/communi/parser.cxx
@@ -0,0 +1,500 @@
+/*************************************************************************
+ *
+ * $RCSfile: parser.cxx,v $
+ *
+ * $Revision: 1.14 $
+ *
+ * last change: $Author: kz $ $Date: 2005-05-30 14:06:21 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <stream.hxx>
+#include <fsys.hxx>
+
+#include "iparser.hxx"
+#include "geninfo.hxx"
+
+
+
+//
+// class InformationParser
+//
+
+#define cKeyLevelChar '\t'
+
+/*****************************************************************************/
+InformationParser::InformationParser( BOOL bReplace )
+/*****************************************************************************/
+ : pActStream( NULL ),
+ nErrorCode( 0 ),
+ nErrorLine( 0 ),
+ nActLine( 0 ),
+ bRecover( FALSE ),
+ sOldLine( "" ),
+ sErrorText( "" ),
+ bReplaceVariables( bReplace ),
+ nLevel( 0 ),
+ sUPD( "" ),
+ sVersion( "" )
+{
+}
+
+/*****************************************************************************/
+InformationParser::~InformationParser()
+/*****************************************************************************/
+{
+}
+
+/*****************************************************************************/
+ByteString &InformationParser::ReadLine()
+/*****************************************************************************/
+{
+ ByteString sLine;
+
+ if ( bRecover ) {
+ bRecover = FALSE;
+ }
+ else {
+ if ( !pActStream->IsEof()) {
+ pActStream->ReadLine( sLine );
+ ULONG nStart = 0;
+ ULONG nEnd = sLine.Len();
+ BOOL bCopy = FALSE;
+ while ( nStart < nEnd && ( sLine.GetChar( nStart ) == ' ' || sLine.GetChar( nStart ) == 0x09 ) )
+ {
+ nStart++;
+ bCopy = TRUE;
+ }
+
+ while ( nStart < nEnd && ( sLine.GetChar( nEnd-1 ) == ' ' || sLine.GetChar( nEnd-1 ) == 0x09 ) )
+ {
+ nEnd--;
+ bCopy = TRUE;
+ }
+
+ if ( bCopy )
+ sLine = sLine.Copy( nStart, nEnd - nStart );
+
+ if (( sLine.GetChar( 0 ) == '#' ) || ( !sLine.Len())) {
+ if ( sCurrentComment.Len())
+ sCurrentComment += "\n";
+ sCurrentComment += sLine;
+ return ReadLine();
+ }
+ else {
+ if ( bReplaceVariables ) {
+ sLine.SearchAndReplaceAll( "%UPD", sUPD );
+ sLine.SearchAndReplaceAll( "%VERSION", sVersion );
+ }
+ }
+ }
+ else {
+ if ( nLevel ) {
+ sLine = "}";
+ fprintf( stdout, "Reached EOF parsing %s. Suplying extra '}'\n",ByteString( sStreamName, gsl_getSystemTextEncoding()).GetBuffer() );
+ // nErrorCode = IP_UNEXPECTED_EOF;
+ // nErrorLine = nActLine;
+ }
+ else
+ sLine = "";
+ }
+
+ sOldLine = sLine;
+ nActLine++;
+ }
+
+ return sOldLine;
+}
+
+/*****************************************************************************/
+GenericInformation *InformationParser::ReadKey(
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ // this method has no error handling yet, but it works very fast.
+ // it is used to create whole informations and sub informations in
+ // a simple data format in memory, readed in a configuration file with
+ // following format:
+
+ /*
+
+ key [value]
+ {
+ key [value]
+ key [value]
+ {
+ key [value]
+ ...
+ ...
+ }
+ }
+ key [value]
+ ...
+ ...
+
+ */
+
+ GenericInformation *pInfo = NULL;
+
+ ByteString sLine( ReadLine());
+ ByteString sKey;
+ ByteString sValue;
+ ByteString sComment( sCurrentComment );
+ sCurrentComment = "";
+
+ // key separated from value by tab?
+ USHORT nWSPos = sLine.Search( ' ' );
+ if ( sLine.Search( '\t' ) < nWSPos ) {
+ nWSPos = sLine.Search( '\t' );
+ sLine.SearchAndReplace( "\t", " " );
+ }
+
+ if ( sLine.GetTokenCount( ' ' ) > 1 ) {
+ sKey = sLine.GetToken( 0, ' ' );
+ sValue = sLine.Copy( sKey.Len() + 1 );
+ while (( sValue.Search( ' ' ) == 0 ) || ( sValue.Search( '\t' ) == 0 )) {
+ sValue.Erase( 0, 1 );
+ }
+ }
+ else
+ sKey=sLine;
+
+ if ( bReplaceVariables && !nLevel ) {
+ sUPD = sKey.Copy( sKey.Len() - 3 );
+ sVersion = sKey;
+ }
+
+ if ( ReadLine() == "{" ) {
+ nLevel++;
+ GenericInformationList *pSubList = new GenericInformationList();
+ while ( ReadLine() != "}" ) {
+ Recover();
+ ReadKey( pSubList );
+ }
+ nLevel--;
+ pInfo = new GenericInformation( sKey, sValue,
+ pExistingList, pSubList );
+ pInfo->SetComment( sComment );
+ }
+ else {
+ Recover();
+ if ( !sKey.Equals( "}" ) && !sKey.Equals( "{" ) )
+ {
+ pInfo = new GenericInformation( sKey, sValue, pExistingList );
+ pInfo->SetComment( sComment );
+ }
+ }
+
+ return pInfo;
+}
+
+/*****************************************************************************/
+void InformationParser::Recover()
+/*****************************************************************************/
+{
+ bRecover = TRUE;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( SvStream &rOutStream,
+ const GenericInformationList *pSaveList,
+ USHORT nLevel, BOOL bStripped )
+/*****************************************************************************/
+{
+ USHORT i;
+ ULONG nInfoListCount;
+ ByteString sTmpStr;
+ GenericInformation *pGenericInfo;
+ GenericInformationList *pGenericInfoList;
+
+ static ByteString aKeyLevel;
+ aKeyLevel.Expand( nLevel, cKeyLevelChar );
+
+ for ( nInfoListCount = 0; nInfoListCount < pSaveList->Count(); nInfoListCount++) {
+ // Key-Value Paare schreiben
+ pGenericInfo = pSaveList->GetObject( nInfoListCount );
+ sTmpStr = "";
+ if ( !bStripped && nLevel )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), nLevel );
+
+ if ( !bStripped )
+ for ( i = 0; i < pGenericInfo->GetComment().GetTokenCount( '\n' ); i++ ) {
+ sTmpStr += pGenericInfo->GetComment().GetToken( i, '\n' );
+ sTmpStr += "\n";
+ if ( nLevel )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), nLevel );
+ }
+
+ sTmpStr += pGenericInfo->GetBuffer();
+ sTmpStr += ' ';
+ sTmpStr += pGenericInfo->GetValue();
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return FALSE;
+
+ // wenn vorhanden, bearbeite recursive die Sublisten
+ if (( pGenericInfoList = pGenericInfo->GetSubList() ) != NULL ) {
+ // oeffnende Klammer
+ sTmpStr = "";
+ if ( !bStripped && nLevel )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), nLevel );
+ sTmpStr += '{';
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return FALSE;
+ // recursiv die sublist abarbeiten
+ if ( !Save( rOutStream, pGenericInfoList, nLevel+1, bStripped ) )
+ return FALSE;
+ // schliessende Klammer
+ sTmpStr = "";
+ if ( !bStripped && nLevel )
+ sTmpStr.Append( aKeyLevel.GetBuffer(), nLevel );
+ sTmpStr += '}';
+ if ( !rOutStream.WriteLine( sTmpStr ) )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute(
+ SvStream &rSourceStream,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ GenericInformationList *pList;
+ if ( pExistingList )
+ pList = pExistingList;
+ else
+ pList = new GenericInformationList();
+
+ pActStream = &rSourceStream;
+
+ // read all infos out of current file
+ while( !rSourceStream.IsEof()) {
+ nLevel = 0;
+ ReadKey( pList );
+ }
+
+ return pList;
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute( SvMemoryStream &rSourceStream,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ sStreamName = UniString( "Memory", gsl_getSystemTextEncoding());
+ return Execute( (SvStream &)rSourceStream, pExistingList );
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute(
+ SvFileStream &rSourceStream,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ if ( !rSourceStream.IsOpen())
+ return NULL;
+ sStreamName = rSourceStream.GetFileName();
+ return Execute( (SvStream &)rSourceStream, pExistingList );
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute( UniString &rSourceFile,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ DirEntry aDirEntry( rSourceFile );
+ if ( !aDirEntry.Exists())
+ return NULL;
+
+ GenericInformationList *pList;
+ if ( pExistingList )
+ pList = pExistingList;
+ else
+ pList = new GenericInformationList();
+
+ // reset status
+ nErrorCode = 0;
+ nErrorLine = 0;
+ nActLine = 0;
+
+ SvFileStream aActStream;
+ aActStream.Open( rSourceFile, STREAM_READ );
+ if( aActStream.GetError())
+ return NULL;
+
+ pActStream = &aActStream;
+ if ( !Execute( aActStream, pList )) {
+ delete pList;
+ pList = NULL;
+ }
+
+ // close the stream
+ aActStream.Close();
+ pActStream = NULL;
+
+ if ( !nErrorCode )
+ return pList;
+
+ return NULL;
+}
+
+/*****************************************************************************/
+GenericInformationList *InformationParser::Execute( Dir &rDir,
+ GenericInformationList *pExistingList )
+/*****************************************************************************/
+{
+ GenericInformationList *pList;
+
+ if ( pExistingList )
+ pList = pExistingList;
+ else
+ pList = new GenericInformationList();
+
+ for ( USHORT i = 0; i < rDir.Count(); i++ ) {
+
+ // execute this dir
+ UniString sNextFile( rDir[i].GetFull());
+ GenericInformationList *pSubList = Execute( sNextFile );
+
+ if ( !pSubList ) {
+ // any errors ?
+ delete pList;
+ return NULL;
+ }
+
+ // create new info and insert it into list
+ ByteString sFileKey( rDir[i].GetName(), RTL_TEXTENCODING_UTF8 );
+ GenericInformation *pInfo = new GenericInformation(
+ sFileKey,
+ ByteString( "" ),
+ pList, pSubList );
+ }
+
+ return pList;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( SvFileStream &rSourceStream,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ if ( !rSourceStream.IsOpen() || !Save( (SvStream &)rSourceStream, pSaveList, 0, FALSE ))
+ {
+ printf( "ERROR saving file \"%s\"\n",ByteString( rSourceStream.GetFileName(), gsl_getSystemTextEncoding()).GetBuffer() );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( SvMemoryStream &rSourceStream,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ Time a;
+ BOOL bRet = Save( (SvStream &)rSourceStream, pSaveList, 0, TRUE );
+ Time b;
+ b = b - a;
+ return bRet;
+}
+
+/*****************************************************************************/
+BOOL InformationParser::Save( const UniString &rSourceFile,
+ const GenericInformationList *pSaveList )
+/*****************************************************************************/
+{
+ SvFileStream *pOutFile = new SvFileStream( rSourceFile, STREAM_STD_WRITE | STREAM_TRUNC );
+
+ if ( !Save( *pOutFile, pSaveList )) {
+ delete pOutFile;
+ return FALSE;
+ }
+ delete pOutFile;
+ return TRUE;
+}
+
+/*****************************************************************************/
+USHORT InformationParser::GetErrorCode()
+/*****************************************************************************/
+{
+ return nErrorCode;
+}
+
+/*****************************************************************************/
+ByteString &InformationParser::GetErrorText()
+/*****************************************************************************/
+{
+ // sErrorText = pActStream->GetFileName();
+ sErrorText = ByteString( sStreamName, gsl_getSystemTextEncoding());
+ sErrorText += ByteString( " (" );
+ sErrorText += ByteString::CreateFromInt64(nErrorLine);
+ sErrorText += ByteString( "): " );
+
+ switch ( nErrorCode ) {
+ case IP_NO_ERROR:
+ sErrorText += ByteString( "Keine Fehler aufgetereten" );
+ break;
+ case IP_UNEXPECTED_EOF:
+ sErrorText += ByteString( "Ungltiges Dateiende!" );
+ break;
+ }
+
+ return sErrorText;
+}
+
+