From 3144bd7deb950de0cb80e2215c1545bdf8fc81e9 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 6 Jun 2007 18:48:07 +0000 Subject: Except for storing the data somewhere, the TafReader is more or less done. Some more generalizations are in order, then we'll stuff the data somewhere. --- src/tests/taf.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/tests/taf.cpp (limited to 'src/tests/taf.cpp') diff --git a/src/tests/taf.cpp b/src/tests/taf.cpp new file mode 100644 index 0000000..12c653e --- /dev/null +++ b/src/tests/taf.cpp @@ -0,0 +1,9 @@ +#include "bu/tafreader.h" +#include "bu/file.h" + +int main() +{ + Bu::File f("test.taf", "rb"); + Bu::TafReader tr( f ); +} + -- cgit v1.2.3 From 8b598e8436a7110abbd0a7566138bcaa952bb527 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 7 Jun 2007 03:26:43 +0000 Subject: Except for an excessive amount of debug info, I finally got the delete code working. Now you can load Taf structures and clean up, you just can't access all of the data inside 100%. --- src/tafnode.cpp | 39 ++++++++++++++++++++++++++++++++++++++- src/tafnode.h | 5 +++++ src/tafreader.cpp | 32 +++++++++++++++++--------------- src/tafreader.h | 7 +++---- src/tests/taf.cpp | 11 +++++++++++ 5 files changed, 74 insertions(+), 20 deletions(-) (limited to 'src/tests/taf.cpp') diff --git a/src/tafnode.cpp b/src/tafnode.cpp index 01880d9..ed8adc0 100644 --- a/src/tafnode.cpp +++ b/src/tafnode.cpp @@ -6,11 +6,21 @@ Bu::TafNode::TafNode() Bu::TafNode::~TafNode() { + printf("Entering Bu::TafNode::~TafNode() \"%s\"\n", sName.getStr() ); + for( NodeHash::iterator i = hChildren.begin(); i != hChildren.end(); i++ ) + { + NodeList &l = i.getValue(); + for( NodeList::iterator k = l.begin(); k != l.end(); k++ ) + { + printf("deleting: [%08X] %s\n", *k, "" );//(*k)->getName().getStr() ); + delete (*k); + } + } } void Bu::TafNode::setProperty( Bu::FString sName, Bu::FString sValue ) { - if( hProp.has( sName ) ) + if( !hProp.has( sName ) ) { hProp.insert( sName, PropList() ); } @@ -18,8 +28,35 @@ void Bu::TafNode::setProperty( Bu::FString sName, Bu::FString sValue ) hProp.get( sName ).append( sValue ); } +void Bu::TafNode::addChild( TafNode *pNode ) +{ + if( !hChildren.has( pNode->getName() ) ) + { + hChildren.insert( pNode->getName(), NodeList() ); + } + + printf("Appending \"%s\"\n", pNode->getName().getStr() ); + hChildren.get( pNode->getName() ).append( pNode ); + printf("[%08X]\n", hChildren.get( pNode->getName() ).last() ); +} + const Bu::TafNode::PropList &Bu::TafNode::getProperty( const Bu::FString &sName ) { return hProp.get( sName ); } +const Bu::TafNode::NodeList &Bu::TafNode::getNode( const Bu::FString &sName ) +{ + return hChildren.get( sName ); +} + +void Bu::TafNode::setName( const Bu::FString &sName ) +{ + this->sName = sName; +} + +const Bu::FString &Bu::TafNode::getName() +{ + return sName; +} + diff --git a/src/tafnode.h b/src/tafnode.h index e962e88..a570d2d 100644 --- a/src/tafnode.h +++ b/src/tafnode.h @@ -23,8 +23,13 @@ namespace Bu TafNode(); virtual ~TafNode(); + void setName( const Bu::FString &sName ); + const Bu::FString &getName(); + void setProperty( Bu::FString sName, Bu::FString sValue ); const PropList &getProperty( const Bu::FString &sName ); + const NodeList &getNode( const Bu::FString &sName ); + void addChild( TafNode *pNode ); private: Bu::FString sName; diff --git a/src/tafreader.cpp b/src/tafreader.cpp index 5fe303b..1187176 100644 --- a/src/tafreader.cpp +++ b/src/tafreader.cpp @@ -5,10 +5,9 @@ using namespace Bu; Bu::TafReader::TafReader( Bu::Stream &sIn ) : + c( 0 ), sIn( sIn ) { - next(); - node(); } Bu::TafReader::~TafReader() @@ -16,55 +15,58 @@ Bu::TafReader::~TafReader() } -Bu::TafNode *Bu::TafReader::readNode() -{ -} - -void Bu::TafReader::node() +Bu::TafNode *Bu::TafReader::getNode() { + if( c == 0 ) next(); + TafNode *pNode = new TafNode(); ws(); if( c != '{' ) throw TafException("Expected '{'"); next(); ws(); FString sName = readStr(); + pNode->setName( sName ); next(); - printf("Node[%s]:\n", sName.getStr() ); + //printf("Node[%s]:\n", sName.getStr() ); - nodeContent(); + nodeContent( pNode ); if( c != '}' ) throw TafException("Expected '}'"); next(); + + return pNode; } -void Bu::TafReader::nodeContent() +void Bu::TafReader::nodeContent( Bu::TafNode *pNode ) { for(;;) { ws(); if( c == '{' ) - node(); + pNode->addChild( getNode() ); else if( c == '}' ) return; else - nodeProperty(); + nodeProperty( pNode ); } } -void Bu::TafReader::nodeProperty() +void Bu::TafReader::nodeProperty( Bu::TafNode *pNode ) { FString sName = readStr(); ws(); if( c != '=' ) { - printf(" %s (true)\n", sName.getStr() ); + //printf(" %s (true)\n", sName.getStr() ); + pNode->setProperty( sName, "" ); return; } next(); FString sValue = readStr(); - printf(" %s = %s\n", sName.getStr(), sValue.getStr() ); + pNode->setProperty( sName, sValue ); + //printf(" %s = %s\n", sName.getStr(), sValue.getStr() ); } Bu::FString Bu::TafReader::readStr() diff --git a/src/tafreader.h b/src/tafreader.h index 4da800c..47ae187 100644 --- a/src/tafreader.h +++ b/src/tafreader.h @@ -17,12 +17,11 @@ namespace Bu TafReader( Bu::Stream &sIn ); virtual ~TafReader(); - Bu::TafNode *readNode(); + Bu::TafNode *getNode(); private: - void node(); - void nodeContent(); - void nodeProperty(); + void nodeContent( Bu::TafNode *pNode ); + void nodeProperty( Bu::TafNode *pNode ); void ws(); bool isws(); void next(); diff --git a/src/tests/taf.cpp b/src/tests/taf.cpp index 12c653e..f7af2b2 100644 --- a/src/tests/taf.cpp +++ b/src/tests/taf.cpp @@ -5,5 +5,16 @@ int main() { Bu::File f("test.taf", "rb"); Bu::TafReader tr( f ); + + Bu::TafNode *pNode = tr.getNode(); + + const Bu::TafNode::NodeList &l = pNode->getNode("stats"); + for( Bu::TafNode::NodeList::const_iterator i = l.begin(); + i != l.end(); i++ ) + { + printf("%s\n", (*i)->getName().getStr() ); + } + + delete pNode; } -- cgit v1.2.3 From c2e3879b965d297604804f03271ac71c8c5c81f3 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 7 Jun 2007 04:55:29 +0000 Subject: The new taf interfaces seem to work just fine, except for saving and that loaded TafNode structures are immutable, it all looks really good. Saving should be a snap, and the immutable part I'm not sure is bad...we'll see what happens. Also, I'm contemplating looking into a way to add "named data structure" support to the Archive at a lower level, then allow it to use a nameing system to apply names to each data structure and then output to any backend that supports naming, like taf, xml, etc. --- src/hash.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/tafnode.cpp | 24 +++++++++++++++++------- src/tafnode.h | 8 +++++--- src/tests/taf.cpp | 9 +++------ 4 files changed, 77 insertions(+), 17 deletions(-) (limited to 'src/tests/taf.cpp') diff --git a/src/hash.h b/src/hash.h index a81c355..f6c207f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -358,6 +358,25 @@ namespace Bu ); } } + + virtual const value &get( key k ) const + { + uint32_t hash = __calcHashCode( k ); + bool bFill; + uint32_t nPos = probe( hash, k, bFill ); + + if( bFill ) + { + return aValues[nPos]; + } + else + { + throw HashException( + excodeNotFilled, + "No data assosiated with that key." + ); + } + } virtual bool has( key k ) { @@ -599,6 +618,38 @@ namespace Bu bFill = false; return nCur; } + + uint32_t probe( uint32_t hash, key k, bool &bFill, bool rehash=true ) const + { + uint32_t nCur = hash%nCapacity; + + // First we scan to see if the key is already there, abort if we + // run out of probing room, or we find a non-filled entry + for( int8_t j = 0; + isFilled( nCur ) && j < 32; + nCur = (nCur + (1<getName().getStr() ); + //printf("deleting: [%08X] %s\n", *k, "" );//(*k)->getName().getStr() ); delete (*k); } } @@ -35,27 +35,37 @@ void Bu::TafNode::addChild( TafNode *pNode ) hChildren.insert( pNode->getName(), NodeList() ); } - printf("Appending \"%s\"\n", pNode->getName().getStr() ); + //printf("Appending \"%s\"\n", pNode->getName().getStr() ); hChildren.get( pNode->getName() ).append( pNode ); - printf("[%08X]\n", hChildren.get( pNode->getName() ).last() ); + //printf("[%08X]\n", hChildren.get( pNode->getName() ).last() ); } -const Bu::TafNode::PropList &Bu::TafNode::getProperty( const Bu::FString &sName ) +const Bu::TafNode::PropList &Bu::TafNode::getProperties( const Bu::FString &sName ) const { return hProp.get( sName ); } -const Bu::TafNode::NodeList &Bu::TafNode::getNode( const Bu::FString &sName ) +const Bu::TafNode::NodeList &Bu::TafNode::getNodes( const Bu::FString &sName ) const { return hChildren.get( sName ); } +const Bu::FString &Bu::TafNode::getProperty( const Bu::FString &sName ) const +{ + return getProperties( sName ).first(); +} + +const Bu::TafNode *Bu::TafNode::getNode( const Bu::FString &sName ) const +{ + return getNodes( sName ).first(); +} + void Bu::TafNode::setName( const Bu::FString &sName ) { this->sName = sName; } -const Bu::FString &Bu::TafNode::getName() +const Bu::FString &Bu::TafNode::getName() const { return sName; } diff --git a/src/tafnode.h b/src/tafnode.h index a570d2d..10232d2 100644 --- a/src/tafnode.h +++ b/src/tafnode.h @@ -24,11 +24,13 @@ namespace Bu virtual ~TafNode(); void setName( const Bu::FString &sName ); - const Bu::FString &getName(); + const Bu::FString &getName() const; void setProperty( Bu::FString sName, Bu::FString sValue ); - const PropList &getProperty( const Bu::FString &sName ); - const NodeList &getNode( const Bu::FString &sName ); + const Bu::FString &getProperty( const Bu::FString &sName ) const; + const TafNode *getNode( const Bu::FString &sName ) const; + const PropList &getProperties( const Bu::FString &sName ) const; + const NodeList &getNodes( const Bu::FString &sName ) const; void addChild( TafNode *pNode ); private: diff --git a/src/tests/taf.cpp b/src/tests/taf.cpp index f7af2b2..e7bad52 100644 --- a/src/tests/taf.cpp +++ b/src/tests/taf.cpp @@ -8,12 +8,9 @@ int main() Bu::TafNode *pNode = tr.getNode(); - const Bu::TafNode::NodeList &l = pNode->getNode("stats"); - for( Bu::TafNode::NodeList::const_iterator i = l.begin(); - i != l.end(); i++ ) - { - printf("%s\n", (*i)->getName().getStr() ); - } + const Bu::TafNode *pStats = pNode->getNode("stats"); + printf("%s\n", pStats->getName().getStr() ); + printf(" str = %s\n", pStats->getProperty("str").getStr() ); delete pNode; } -- cgit v1.2.3 From 5f39066a4f561e9a94a6cc9293ab9b978ebf1f81 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 10 Jun 2007 21:28:14 +0000 Subject: Bunch of maintenence type things. Minor tweaks and the like. The file class has a lot more helper functions and the like, the filters give more info back to the caller, minor updates to taf. --- src/bzip2.cpp | 41 ++++++++++++++++++++++++++++++++++------- src/bzip2.h | 2 +- src/file.cpp | 31 +++++++++++++++++++++++++++++++ src/file.h | 17 ++++++++++++++++- src/filter.cpp | 7 ++++++- src/filter.h | 4 +++- src/socket.cpp | 4 ++++ src/socket.h | 2 ++ src/stream.h | 2 ++ src/tafnode.cpp | 6 +++--- src/tafnode.h | 4 ++-- src/tests/taf.cpp | 2 +- 12 files changed, 105 insertions(+), 17 deletions(-) (limited to 'src/tests/taf.cpp') diff --git a/src/bzip2.cpp b/src/bzip2.cpp index 433fc91..5423a10 100644 --- a/src/bzip2.cpp +++ b/src/bzip2.cpp @@ -26,16 +26,18 @@ void Bu::BZip2::start() pBuf = new char[nBufSize]; } -void Bu::BZip2::stop() +size_t Bu::BZip2::stop() { if( bzState.state ) { if( bReading ) { BZ2_bzDecompressEnd( &bzState ); + return 0; } else { + size_t sTotal = 0; for(;;) { bzState.next_in = NULL; @@ -45,14 +47,16 @@ void Bu::BZip2::stop() int res = BZ2_bzCompress( &bzState, BZ_FINISH ); if( bzState.avail_out < nBufSize ) { - rNext.write( pBuf, nBufSize-bzState.avail_out ); + sTotal += rNext.write( pBuf, nBufSize-bzState.avail_out ); } if( res == BZ_STREAM_END ) break; } BZ2_bzCompressEnd( &bzState ); + return sTotal; } } + return 0; } void Bu::BZip2::bzError( int code ) @@ -63,13 +67,35 @@ void Bu::BZip2::bzError( int code ) return; case BZ_CONFIG_ERROR: - throw ExceptionBase("The bzip2 library has been miscompiled."); + throw ExceptionBase("BZip2: Library configured improperly, reinstall."); + + case BZ_SEQUENCE_ERROR: + throw ExceptionBase("BZip2: Functions were called in an invalid sequence."); case BZ_PARAM_ERROR: - throw ExceptionBase("bzip2 parameter error."); + throw ExceptionBase("BZip2: Invalid parameter was passed into a function."); case BZ_MEM_ERROR: - throw ExceptionBase("Not enough memory available for bzip2."); + throw ExceptionBase("BZip2: Couldn't allocate sufficient memory."); + + case BZ_DATA_ERROR: + throw ExceptionBase("BZip2: Data was corrupted before decompression."); + + case BZ_DATA_ERROR_MAGIC: + throw ExceptionBase("BZip2: Stream does not appear to be bzip2 data."); + + case BZ_IO_ERROR: + throw ExceptionBase("BZip2: File couldn't be read from / written to."); + + case BZ_UNEXPECTED_EOF: + throw ExceptionBase("BZip2: End of file encountered before end of stream."); + + case BZ_OUTBUFF_FULL: + throw ExceptionBase("BZip2: Buffer not large enough to accomidate data."); + + default: + throw ExceptionBase("BZip2: Unknown error encountered."); + } } @@ -124,6 +150,7 @@ size_t Bu::BZip2::write( const void *pData, size_t nBytes ) if( bReading == true ) throw ExceptionBase("This bzip2 filter is in reading mode, you can't write."); + size_t sTotalOut = 0; bzState.next_in = (char *)pData; bzState.avail_in = nBytes; for(;;) @@ -135,12 +162,12 @@ size_t Bu::BZip2::write( const void *pData, size_t nBytes ) if( bzState.avail_out < nBufSize ) { - rNext.write( pBuf, nBufSize-bzState.avail_out ); + sTotalOut += rNext.write( pBuf, nBufSize-bzState.avail_out ); } if( bzState.avail_in == 0 ) break; } - return 0; + return sTotalOut; } diff --git a/src/bzip2.h b/src/bzip2.h index 056f336..a23f07a 100644 --- a/src/bzip2.h +++ b/src/bzip2.h @@ -18,7 +18,7 @@ namespace Bu virtual ~BZip2(); virtual void start(); - virtual void stop(); + virtual size_t stop(); virtual size_t read( void *pBuf, size_t nBytes ); virtual size_t write( const void *pBuf, size_t nBytes ); diff --git a/src/file.cpp b/src/file.cpp index 26986a5..14b6e54 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1,6 +1,8 @@ #include "file.h" #include "exceptions.h" #include +#include +#include Bu::File::File( const char *sName, const char *sFlags ) { @@ -11,6 +13,20 @@ Bu::File::File( const char *sName, const char *sFlags ) } } +Bu::File::File( const Bu::FString &sName, const char *sFlags ) +{ + fh = fopen( sName.getStr(), sFlags ); + if( fh == NULL ) + { + throw Bu::FileException( errno, strerror(errno) ); + } +} + +Bu::File::File( int fd, const char *sFlags ) +{ + fh = fdopen( fd, sFlags ); +} + Bu::File::~File() { close(); @@ -108,3 +124,18 @@ void Bu::File::setBlocking( bool bBlocking ) return; } +void Bu::File::truncate( long nSize ) +{ + ftruncate( fileno( fh ), nSize ); +} + +void Bu::File::flush() +{ + fflush( fh ); +} + +void Bu::File::chmod( mode_t t ) +{ + fchmod( fileno( fh ), t ); +} + diff --git a/src/file.h b/src/file.h index ee3fdb3..8107a1b 100644 --- a/src/file.h +++ b/src/file.h @@ -3,7 +3,8 @@ #include -#include "stream.h" +#include "bu/stream.h" +#include "bu/fstring.h" namespace Bu { @@ -11,6 +12,8 @@ namespace Bu { public: File( const char *sName, const char *sFlags ); + File( const Bu::FString &sName, const char *sFlags ); + File( int fd, const char *sFlags ); virtual ~File(); virtual void close(); @@ -23,6 +26,8 @@ namespace Bu virtual void setPosEnd( long pos ); virtual bool isEOS(); + virtual void flush(); + virtual bool canRead(); virtual bool canWrite(); virtual bool canSeek(); @@ -30,6 +35,16 @@ namespace Bu virtual bool isBlocking(); virtual void setBlocking( bool bBlocking=true ); + inline static Bu::File tempFile( Bu::FString &sName, const char *sFlags ) + { + int afh_d = mkstemp( sName.getStr() ); + + return Bu::File( afh_d, sFlags ); + } + + void truncate( long nSize ); + void chmod( mode_t t ); + private: FILE *fh; diff --git a/src/filter.cpp b/src/filter.cpp index d3faa00..693fb9f 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -7,7 +7,7 @@ Bu::Filter::Filter( Bu::Stream &rNext ) : Bu::Filter::~Filter() { - printf("-> Bu::Filter::~Filter()\n"); + //printf("-> Bu::Filter::~Filter()\n"); } /* void Bu::Filter::start() @@ -75,3 +75,8 @@ void Bu::Filter::setBlocking( bool bBlocking ) rNext.setBlocking( bBlocking ); } +void Bu::Filter::flush() +{ + rNext.flush(); +} + diff --git a/src/filter.h b/src/filter.h index b068206..088d46e 100644 --- a/src/filter.h +++ b/src/filter.h @@ -33,7 +33,7 @@ namespace Bu virtual ~Filter(); virtual void start()=0; - virtual void stop()=0; + virtual size_t stop()=0; virtual void close(); virtual long tell(); virtual void seek( long offset ); @@ -41,6 +41,8 @@ namespace Bu virtual void setPosEnd( long pos ); virtual bool isEOS(); + virtual void flush(); + virtual bool canRead(); virtual bool canWrite(); virtual bool canSeek(); diff --git a/src/socket.cpp b/src/socket.cpp index 441678a..1832898 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -240,3 +240,7 @@ void Bu::Socket::setBlocking( bool bBlocking ) { } +void Bu::Socket::flush() +{ +} + diff --git a/src/socket.h b/src/socket.h index e65eb74..30a43fb 100644 --- a/src/socket.h +++ b/src/socket.h @@ -29,6 +29,8 @@ namespace Bu virtual void setPosEnd( long pos ); virtual bool isEOS(); + virtual void flush(); + virtual bool canRead(); virtual bool canWrite(); virtual bool canSeek(); diff --git a/src/stream.h b/src/stream.h index fa0a606..a80586b 100644 --- a/src/stream.h +++ b/src/stream.h @@ -32,6 +32,8 @@ namespace Bu virtual void setPosEnd( long pos ) = 0; virtual bool isEOS() = 0; + virtual void flush() = 0; + virtual bool canRead() = 0; virtual bool canWrite() = 0; virtual bool canSeek() = 0; diff --git a/src/tafnode.cpp b/src/tafnode.cpp index 3060606..b9a4a24 100644 --- a/src/tafnode.cpp +++ b/src/tafnode.cpp @@ -45,7 +45,7 @@ const Bu::TafNode::PropList &Bu::TafNode::getProperties( const Bu::FString &sNam return hProp.get( sName ); } -const Bu::TafNode::NodeList &Bu::TafNode::getNodes( const Bu::FString &sName ) const +const Bu::TafNode::NodeList &Bu::TafNode::getChildren( const Bu::FString &sName ) const { return hChildren.get( sName ); } @@ -55,9 +55,9 @@ const Bu::FString &Bu::TafNode::getProperty( const Bu::FString &sName ) const return getProperties( sName ).first(); } -const Bu::TafNode *Bu::TafNode::getNode( const Bu::FString &sName ) const +const Bu::TafNode *Bu::TafNode::getChild( const Bu::FString &sName ) const { - return getNodes( sName ).first(); + return getChildren( sName ).first(); } void Bu::TafNode::setName( const Bu::FString &sName ) diff --git a/src/tafnode.h b/src/tafnode.h index 10232d2..08f78e8 100644 --- a/src/tafnode.h +++ b/src/tafnode.h @@ -28,9 +28,9 @@ namespace Bu void setProperty( Bu::FString sName, Bu::FString sValue ); const Bu::FString &getProperty( const Bu::FString &sName ) const; - const TafNode *getNode( const Bu::FString &sName ) const; const PropList &getProperties( const Bu::FString &sName ) const; - const NodeList &getNodes( const Bu::FString &sName ) const; + const TafNode *getChild( const Bu::FString &sName ) const; + const NodeList &getChildren( const Bu::FString &sName ) const; void addChild( TafNode *pNode ); private: diff --git a/src/tests/taf.cpp b/src/tests/taf.cpp index e7bad52..d135e78 100644 --- a/src/tests/taf.cpp +++ b/src/tests/taf.cpp @@ -8,7 +8,7 @@ int main() Bu::TafNode *pNode = tr.getNode(); - const Bu::TafNode *pStats = pNode->getNode("stats"); + const Bu::TafNode *pStats = pNode->getChild("stats"); printf("%s\n", pStats->getName().getStr() ); printf(" str = %s\n", pStats->getProperty("str").getStr() ); -- cgit v1.2.3 From c86c0cf088492e02431dffb1f860ff2f6faa492d Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 27 Jun 2007 18:11:13 +0000 Subject: The taf system is new and improved. The writer works, we added C++ style comment blocks, and it retains the order of all nodes. --- src/tafnode.cpp | 138 ++++++++++++++++++++++++++++++++++++++++++------------ src/tafnode.h | 68 +++++++++++++++++++++++---- src/tafreader.cpp | 44 +++++++++++------ src/tafreader.h | 9 ++-- src/tafwriter.cpp | 42 ++++++++++++++++- src/tafwriter.h | 4 +- src/tests/taf.cpp | 13 +++-- src/unit/taf.cpp | 2 +- test.taf | 31 +++--------- 9 files changed, 260 insertions(+), 91 deletions(-) (limited to 'src/tests/taf.cpp') diff --git a/src/tafnode.cpp b/src/tafnode.cpp index b9a4a24..b7cf211 100644 --- a/src/tafnode.cpp +++ b/src/tafnode.cpp @@ -1,72 +1,148 @@ #include "tafnode.h" -Bu::TafNode::TafNode() +Bu::TafNode::TafNode( NodeType eType ) : + eType( eType ) { } Bu::TafNode::~TafNode() +{ +} + +const Bu::TafNode::NodeType Bu::TafNode::getType() const +{ + return eType; +} + +/* +const Bu::TafNode::PropList &Bu::TafNode::getProperties( const Bu::FString &sName ) const +{ + return hProp.get( sName ); +} + +const Bu::TafNode::NodeList &Bu::TafNode::getChildren( const Bu::FString &sName ) const +{ + return hChildren.get( sName ); +} + +const Bu::FString &Bu::TafNode::getProperty( const Bu::FString &sName ) const +{ + return getProperties( sName ).first(); +} + +const Bu::TafNode *Bu::TafNode::getChild( const Bu::FString &sName ) const +{ + return getChildren( sName ).first(); +} +*/ + +Bu::TafGroup::TafGroup( const Bu::FString &sName ) : + TafNode( typeGroup ), + sName( sName ) +{ +} + +Bu::TafGroup::~TafGroup() { //printf("Entering Bu::TafNode::~TafNode() \"%s\"\n", sName.getStr() ); - for( NodeHash::iterator i = hChildren.begin(); i != hChildren.end(); i++ ) + for( NodeList::iterator i = lChildren.begin(); i != lChildren.end(); i++ ) { - NodeList &l = i.getValue(); - for( NodeList::iterator k = l.begin(); k != l.end(); k++ ) - { - //printf("deleting: [%08X] %s\n", *k, "" );//(*k)->getName().getStr() ); - delete (*k); - } + delete (*i); } } -void Bu::TafNode::setProperty( Bu::FString sName, Bu::FString sValue ) +const Bu::FString &Bu::TafGroup::getName() const { - if( !hProp.has( sName ) ) + return sName; +} + +void Bu::TafGroup::addChild( Bu::TafNode *pNode ) +{ + switch( pNode->getType() ) { - hProp.insert( sName, PropList() ); + case typeGroup: + { + TafGroup *pGroup = (TafGroup *)pNode; + if( !hChildren.has( pGroup->getName() ) ) + hChildren.insert( pGroup->getName(), GroupList() ); + hChildren.get( pGroup->getName() ).append( pGroup ); + } + break; + + case typeProperty: + { + TafProperty *pProperty = (TafProperty *)pNode; + if( !hProp.has( pProperty->getName() ) ) + hProp.insert( pProperty->getName(), PropList() ); + hProp.get( pProperty->getName() ).append( pProperty->getValue() ); + } + break; + + case typeComment: + break; } - hProp.get( sName ).append( sValue ); + lChildren.append( pNode ); } -void Bu::TafNode::addChild( TafNode *pNode ) +const Bu::TafGroup::GroupList &Bu::TafGroup::getChildren( const Bu::FString &sName ) const { - if( !hChildren.has( pNode->getName() ) ) - { - hChildren.insert( pNode->getName(), NodeList() ); - } + return hChildren.get( sName ); +} - //printf("Appending \"%s\"\n", pNode->getName().getStr() ); - hChildren.get( pNode->getName() ).append( pNode ); - //printf("[%08X]\n", hChildren.get( pNode->getName() ).last() ); +const Bu::TafGroup::NodeList &Bu::TafGroup::getChildren() const +{ + return lChildren; } -const Bu::TafNode::PropList &Bu::TafNode::getProperties( const Bu::FString &sName ) const +const Bu::TafGroup *Bu::TafGroup::getChild( const Bu::FString &sName ) const { - return hProp.get( sName ); + return hChildren.get( sName ).first(); } -const Bu::TafNode::NodeList &Bu::TafNode::getChildren( const Bu::FString &sName ) const +const Bu::TafGroup::PropList &Bu::TafGroup::getProperties( const Bu::FString &sName ) const { - return hChildren.get( sName ); + return hProp.get( sName ); } -const Bu::FString &Bu::TafNode::getProperty( const Bu::FString &sName ) const +const Bu::FString &Bu::TafGroup::getProperty( const Bu::FString &sName ) const { - return getProperties( sName ).first(); + return hProp.get( sName ).first(); } -const Bu::TafNode *Bu::TafNode::getChild( const Bu::FString &sName ) const +Bu::TafProperty::TafProperty( const Bu::FString &sName, const Bu::FString &sValue ) : + TafNode( typeProperty ), + sName( sName ), + sValue( sValue ) { - return getChildren( sName ).first(); } -void Bu::TafNode::setName( const Bu::FString &sName ) +Bu::TafProperty::~TafProperty() { - this->sName = sName; } -const Bu::FString &Bu::TafNode::getName() const +const Bu::FString &Bu::TafProperty::getName() const { return sName; } +const Bu::FString &Bu::TafProperty::getValue() const +{ + return sValue; +} + +Bu::TafComment::TafComment( const Bu::FString &sText ) : + TafNode( typeComment ), + sText( sText ) +{ +} + +Bu::TafComment::~TafComment() +{ +} + +const Bu::FString &Bu::TafComment::getText() const +{ + return sText; +} + diff --git a/src/tafnode.h b/src/tafnode.h index 08f78e8..55a5123 100644 --- a/src/tafnode.h +++ b/src/tafnode.h @@ -14,29 +14,77 @@ namespace Bu class TafNode { public: - typedef Bu::List PropList; - typedef Bu::Hash PropHash; - typedef Bu::List NodeList; - typedef Bu::Hash NodeHash; + enum NodeType + { + typeGroup, + typeProperty, + typeComment + }; public: - TafNode(); + TafNode( NodeType eType ); virtual ~TafNode(); - void setName( const Bu::FString &sName ); + const NodeType getType() const; + + private: + NodeType eType; + }; + + class TafProperty; + class TafComment; + class TafGroup : public TafNode + { + public: + typedef Bu::List PropList; + typedef Bu::Hash PropHash; + typedef Bu::List GroupList; + typedef Bu::Hash GroupHash; + typedef Bu::List NodeList; + + TafGroup( const Bu::FString &sName ); + virtual ~TafGroup(); + const Bu::FString &getName() const; - void setProperty( Bu::FString sName, Bu::FString sValue ); const Bu::FString &getProperty( const Bu::FString &sName ) const; const PropList &getProperties( const Bu::FString &sName ) const; - const TafNode *getChild( const Bu::FString &sName ) const; - const NodeList &getChildren( const Bu::FString &sName ) const; + const TafGroup *getChild( const Bu::FString &sName ) const; + const GroupList &getChildren( const Bu::FString &sName ) const; void addChild( TafNode *pNode ); + const NodeList &getChildren() const; private: Bu::FString sName; PropHash hProp; - NodeHash hChildren; + GroupHash hChildren; + NodeList lChildren; + }; + + class TafProperty : public TafNode + { + public: + TafProperty( const Bu::FString &sName, const Bu::FString &sValue ); + virtual ~TafProperty(); + + const Bu::FString &getName() const; + const Bu::FString &getValue() const; + + private: + Bu::FString sName; + Bu::FString sValue; + }; + + class TafComment : public TafNode + { + public: + TafComment( const Bu::FString &sText ); + virtual ~TafComment(); + + const Bu::FString &getText() const; + + private: + Bu::FString sText; }; } diff --git a/src/tafreader.cpp b/src/tafreader.cpp index 1187176..db465e9 100644 --- a/src/tafreader.cpp +++ b/src/tafreader.cpp @@ -8,6 +8,7 @@ Bu::TafReader::TafReader( Bu::Stream &sIn ) : c( 0 ), sIn( sIn ) { + next(); next(); } Bu::TafReader::~TafReader() @@ -15,60 +16,74 @@ Bu::TafReader::~TafReader() } -Bu::TafNode *Bu::TafReader::getNode() +Bu::TafGroup *Bu::TafReader::readGroup() { - if( c == 0 ) next(); - TafNode *pNode = new TafNode(); ws(); if( c != '{' ) throw TafException("Expected '{'"); next(); ws(); FString sName = readStr(); - pNode->setName( sName ); + TafGroup *pGroup = new TafGroup( sName ); next(); //printf("Node[%s]:\n", sName.getStr() ); - nodeContent( pNode ); + groupContent( pGroup ); if( c != '}' ) throw TafException("Expected '}'"); next(); - return pNode; + return pGroup; } -void Bu::TafReader::nodeContent( Bu::TafNode *pNode ) +void Bu::TafReader::groupContent( Bu::TafGroup *pGroup ) { for(;;) { ws(); if( c == '{' ) - pNode->addChild( getNode() ); + pGroup->addChild( readGroup() ); else if( c == '}' ) return; + else if( c == '/' && la == '*' ) + pGroup->addChild( readComment() ); else - nodeProperty( pNode ); + pGroup->addChild( readProperty() ); } } -void Bu::TafReader::nodeProperty( Bu::TafNode *pNode ) +Bu::TafProperty *Bu::TafReader::readProperty() { FString sName = readStr(); ws(); if( c != '=' ) { //printf(" %s (true)\n", sName.getStr() ); - pNode->setProperty( sName, "" ); - return; + return new Bu::TafProperty( sName, "" ); } next(); FString sValue = readStr(); - pNode->setProperty( sName, sValue ); + return new Bu::TafProperty( sName, sValue ); //printf(" %s = %s\n", sName.getStr(), sValue.getStr() ); } +Bu::TafComment *Bu::TafReader::readComment() +{ + next(); + FString sCmnt; + for(;;) + { + next(); + if( c == '*' && la == '/' ) + break; + sCmnt += c; + } + + return new TafComment( sCmnt ); +} + Bu::FString Bu::TafReader::readStr() { ws(); @@ -134,6 +149,7 @@ bool Bu::TafReader::isws() void Bu::TafReader::next() { - sIn.read( &c, 1 ); + c = la; + sIn.read( &la, 1 ); } diff --git a/src/tafreader.h b/src/tafreader.h index 47ae187..eeaafb3 100644 --- a/src/tafreader.h +++ b/src/tafreader.h @@ -17,16 +17,17 @@ namespace Bu TafReader( Bu::Stream &sIn ); virtual ~TafReader(); - Bu::TafNode *getNode(); + Bu::TafGroup *readGroup(); private: - void nodeContent( Bu::TafNode *pNode ); - void nodeProperty( Bu::TafNode *pNode ); + void groupContent( Bu::TafGroup *pNode ); + Bu::TafProperty *readProperty(); + Bu::TafComment *readComment(); void ws(); bool isws(); void next(); Bu::FString readStr(); - char c; + char c, la; Bu::Stream &sIn; }; } diff --git a/src/tafwriter.cpp b/src/tafwriter.cpp index ac42d3d..6b505ef 100644 --- a/src/tafwriter.cpp +++ b/src/tafwriter.cpp @@ -9,16 +9,54 @@ Bu::TafWriter::~TafWriter() { } -void Bu::TafWriter::writeNode( Bu::TafNode *pRoot ) +void Bu::TafWriter::writeGroup( const Bu::TafGroup *pRoot ) { sOut.write("{", 1 ); - writeString( pRoot->getName().getStr() ); + writeString( pRoot->getName() ); sOut.write(": ", 2 ); + const Bu::TafGroup::NodeList &nl = pRoot->getChildren(); + for( Bu::TafGroup::NodeList::const_iterator i = nl.begin(); i != nl.end(); i++ ) + { + switch( (*i)->getType() ) + { + case Bu::TafNode::typeGroup: + writeGroup( (Bu::TafGroup *)(*i) ); + break; + + case Bu::TafNode::typeProperty: + writeProperty( (Bu::TafProperty *)(*i) ); + break; + + case Bu::TafNode::typeComment: + writeComment( (Bu::TafComment *)(*i) ); + break; + } + } sOut.write("}", 1 ); } +void Bu::TafWriter::writeProperty( const Bu::TafProperty *pProp ) +{ + writeString( pProp->getName() ); + if( pProp->getValue().getStr() != NULL ) + { + sOut.write("=", 1 ); + writeString( pProp->getValue() ); + } + sOut.write(" ", 1 ); +} + +void Bu::TafWriter::writeComment( const Bu::TafComment *pComment ) +{ + sOut.write("/*", 2 ); + sOut.write( pComment->getText().getStr(), pComment->getText().getSize() ); + sOut.write("*/ ", 3 ); +} + void Bu::TafWriter::writeString( const Bu::FString &str ) { + if( str.getStr() == NULL ) + return; sOut.write("\"", 1 ); for( const char *s = str.getStr(); *s; s++ ) { diff --git a/src/tafwriter.h b/src/tafwriter.h index 4310e62..5f80504 100644 --- a/src/tafwriter.h +++ b/src/tafwriter.h @@ -17,9 +17,11 @@ namespace Bu TafWriter( Bu::Stream &sOut ); virtual ~TafWriter(); - void writeNode( Bu::TafNode *pRoot ); + void writeGroup( const Bu::TafGroup *pRoot ); private: + void writeProperty( const Bu::TafProperty *pProp ); + void writeComment( const Bu::TafComment *pComment ); void writeString( const Bu::FString &str ); Bu::Stream &sOut; }; diff --git a/src/tests/taf.cpp b/src/tests/taf.cpp index d135e78..e3da120 100644 --- a/src/tests/taf.cpp +++ b/src/tests/taf.cpp @@ -1,4 +1,5 @@ #include "bu/tafreader.h" +#include "bu/tafwriter.h" #include "bu/file.h" int main() @@ -6,12 +7,18 @@ int main() Bu::File f("test.taf", "rb"); Bu::TafReader tr( f ); - Bu::TafNode *pNode = tr.getNode(); + Bu::TafGroup *pGroup = tr.readGroup(); - const Bu::TafNode *pStats = pNode->getChild("stats"); + const Bu::TafGroup *pStats = pGroup->getChild("stats"); printf("%s\n", pStats->getName().getStr() ); printf(" str = %s\n", pStats->getProperty("str").getStr() ); - delete pNode; + { + Bu::File fo("out.taf", "wb"); + Bu::TafWriter tw( fo ); + tw.writeGroup( pGroup ); + } + + delete pGroup; } diff --git a/src/unit/taf.cpp b/src/unit/taf.cpp index ab485d0..5e0e914 100644 --- a/src/unit/taf.cpp +++ b/src/unit/taf.cpp @@ -32,7 +32,7 @@ public: Bu::File fIn(sFnTmp.c_str(), "rb"); Bu::TafReader tr(fIn); - Bu::TafNode *tn = tr.getNode(); + Bu::TafGroup *tn = tr.readGroup(); unitTest( !strcmp("Bob", tn->getProperty("name").c_str()) ); delete tn; diff --git a/test.taf b/test.taf index 045b042..1d4e7d1 100644 --- a/test.taf +++ b/test.taf @@ -1,26 +1,7 @@ -{player: - password = "aoeuaoeuao" - userclass = "implementor" - species = "human" - sex = "male" - active - startroom = "Salourn::Xagafinelle's Room" - {stats: str=14 dex=12 spd=12 enr=7 rea=12 wil=10 int=13 cha=14} - {hp: cur = 100 max = 100} - {en: cur = 100 max = 100} - attackrate = 30 - gold = 0 - {inventory: - {: count=1 id="Salourn::Dark Blade"} - {: count=1 id="Salourn::Dark Suit"} - {: count=3 id="Salourn::Small Fig"} - } - {aliases: - {: key="." value="say"} - {: key="," value="yell"} - {: key="li" value="lightning"} - } - description = "They appear to be rather average looking, not particularly +{"player": "password"="aoeuaoeuao" "userclass"="implementor" "species"="human" "sex"="male" "active" "startroom"="Salourn::Xagafinelle's Room" {"stats": "str"="14" "dex"="12" "spd"="12" "enr"="7" "rea"="12" "wil"="10" "int"="13" "cha"="14" }{"hp": "cur"="100" "max"="100" }{"en": "cur"="100" "max"="100" }"attackrate"="30" "gold"="0" + + /* Hey, the inventory is next...isn't that cool? Oooooh yeah! */ + +{"inventory": {: "count"="1" "id"="Salourn::Dark Blade" }{: "count"="1" "id"="Salourn::Dark Suit" }{: "count"="3" "id"="Salourn::Small Fig" }}{"aliases": {: "key"="." "value"="say" }{: "key"="," "value"="yell" }{: "key"="li" "value"="lightning" }}"description"="They appear to be rather average looking, not particularly tall or short, with facial features that are difficult to remember even - seconds after witnessing them." -} + seconds after witnessing them." } -- cgit v1.2.3