From 74dd68ad611d15abf16a65c36a7cfd3f4492930a Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 9 Nov 2012 16:25:22 +0000 Subject: Made the repo less libbu++-centric. --- c++-libbu++/src/boolean.cpp | 53 +++++ c++-libbu++/src/boolean.h | 30 +++ c++-libbu++/src/dictionary.cpp | 380 ++++++++++++++++++++++++++++++ c++-libbu++/src/dictionary.h | 74 ++++++ c++-libbu++/src/float.cpp | 130 ++++++++++ c++-libbu++/src/float.h | 33 +++ c++-libbu++/src/gatsc/main.cpp | 73 ++++++ c++-libbu++/src/gatscon/clientthread.cpp | 38 +++ c++-libbu++/src/gatscon/clientthread.h | 37 +++ c++-libbu++/src/gatscon/clientwidget.cpp | 82 +++++++ c++-libbu++/src/gatscon/clientwidget.h | 30 +++ c++-libbu++/src/gatscon/clientwidget.ui | 87 +++++++ c++-libbu++/src/gatscon/connectdlg.cpp | 22 ++ c++-libbu++/src/gatscon/connectdlg.h | 17 ++ c++-libbu++/src/gatscon/connectdlg.ui | 99 ++++++++ c++-libbu++/src/gatscon/filewidget.cpp | 72 ++++++ c++-libbu++/src/gatscon/filewidget.h | 29 +++ c++-libbu++/src/gatscon/filewidget.ui | 95 ++++++++ c++-libbu++/src/gatscon/gatstotree.cpp | 91 +++++++ c++-libbu++/src/gatscon/gatstotree.h | 28 +++ c++-libbu++/src/gatscon/iobase.cpp | 1 + c++-libbu++/src/gatscon/iobase.h | 10 + c++-libbu++/src/gatscon/main.cpp | 13 + c++-libbu++/src/gatscon/mainwnd.cpp | 119 ++++++++++ c++-libbu++/src/gatscon/mainwnd.h | 26 ++ c++-libbu++/src/gatscon/mainwnd.ui | 207 ++++++++++++++++ c++-libbu++/src/gatscon/proxythread.cpp | 108 +++++++++ c++-libbu++/src/gatscon/proxythread.h | 60 +++++ c++-libbu++/src/gatscon/proxywidget.cpp | 131 ++++++++++ c++-libbu++/src/gatscon/proxywidget.h | 33 +++ c++-libbu++/src/gatscon/proxywidget.ui | 181 ++++++++++++++ c++-libbu++/src/gatscon/setupproxydlg.cpp | 27 +++ c++-libbu++/src/gatscon/setupproxydlg.h | 18 ++ c++-libbu++/src/gatscon/setupproxydlg.ui | 112 +++++++++ c++-libbu++/src/gatscon/treetogats.cpp | 52 ++++ c++-libbu++/src/gatscon/treetogats.h | 13 + c++-libbu++/src/gatsstream.cpp | 108 +++++++++ c++-libbu++/src/gatsstream.h | 56 +++++ c++-libbu++/src/integer.cpp | 39 +++ c++-libbu++/src/integer.h | 86 +++++++ c++-libbu++/src/list.cpp | 205 ++++++++++++++++ c++-libbu++/src/list.h | 58 +++++ c++-libbu++/src/null.cpp | 33 +++ c++-libbu++/src/null.h | 24 ++ c++-libbu++/src/object.cpp | 339 ++++++++++++++++++++++++++ c++-libbu++/src/object.h | 55 +++++ c++-libbu++/src/protocolgats.cpp | 56 +++++ c++-libbu++/src/protocolgats.h | 30 +++ c++-libbu++/src/string.cpp | 70 ++++++ c++-libbu++/src/string.h | 32 +++ c++-libbu++/src/tests/clone.cpp | 22 ++ c++-libbu++/src/tests/dump.cpp | 30 +++ c++-libbu++/src/tests/int.cpp | 47 ++++ c++-libbu++/src/types.h | 8 + c++-libbu++/src/unit/basic.unit | 191 +++++++++++++++ c++-libbu++/src/unit/float.unit | 84 +++++++ c++-libbu++/src/unit/io.unit | 128 ++++++++++ 57 files changed, 4312 insertions(+) create mode 100644 c++-libbu++/src/boolean.cpp create mode 100644 c++-libbu++/src/boolean.h create mode 100644 c++-libbu++/src/dictionary.cpp create mode 100644 c++-libbu++/src/dictionary.h create mode 100644 c++-libbu++/src/float.cpp create mode 100644 c++-libbu++/src/float.h create mode 100644 c++-libbu++/src/gatsc/main.cpp create mode 100644 c++-libbu++/src/gatscon/clientthread.cpp create mode 100644 c++-libbu++/src/gatscon/clientthread.h create mode 100644 c++-libbu++/src/gatscon/clientwidget.cpp create mode 100644 c++-libbu++/src/gatscon/clientwidget.h create mode 100644 c++-libbu++/src/gatscon/clientwidget.ui create mode 100644 c++-libbu++/src/gatscon/connectdlg.cpp create mode 100644 c++-libbu++/src/gatscon/connectdlg.h create mode 100644 c++-libbu++/src/gatscon/connectdlg.ui create mode 100644 c++-libbu++/src/gatscon/filewidget.cpp create mode 100644 c++-libbu++/src/gatscon/filewidget.h create mode 100644 c++-libbu++/src/gatscon/filewidget.ui create mode 100644 c++-libbu++/src/gatscon/gatstotree.cpp create mode 100644 c++-libbu++/src/gatscon/gatstotree.h create mode 100644 c++-libbu++/src/gatscon/iobase.cpp create mode 100644 c++-libbu++/src/gatscon/iobase.h create mode 100644 c++-libbu++/src/gatscon/main.cpp create mode 100644 c++-libbu++/src/gatscon/mainwnd.cpp create mode 100644 c++-libbu++/src/gatscon/mainwnd.h create mode 100644 c++-libbu++/src/gatscon/mainwnd.ui create mode 100644 c++-libbu++/src/gatscon/proxythread.cpp create mode 100644 c++-libbu++/src/gatscon/proxythread.h create mode 100644 c++-libbu++/src/gatscon/proxywidget.cpp create mode 100644 c++-libbu++/src/gatscon/proxywidget.h create mode 100644 c++-libbu++/src/gatscon/proxywidget.ui create mode 100644 c++-libbu++/src/gatscon/setupproxydlg.cpp create mode 100644 c++-libbu++/src/gatscon/setupproxydlg.h create mode 100644 c++-libbu++/src/gatscon/setupproxydlg.ui create mode 100644 c++-libbu++/src/gatscon/treetogats.cpp create mode 100644 c++-libbu++/src/gatscon/treetogats.h create mode 100644 c++-libbu++/src/gatsstream.cpp create mode 100644 c++-libbu++/src/gatsstream.h create mode 100644 c++-libbu++/src/integer.cpp create mode 100644 c++-libbu++/src/integer.h create mode 100644 c++-libbu++/src/list.cpp create mode 100644 c++-libbu++/src/list.h create mode 100644 c++-libbu++/src/null.cpp create mode 100644 c++-libbu++/src/null.h create mode 100644 c++-libbu++/src/object.cpp create mode 100644 c++-libbu++/src/object.h create mode 100644 c++-libbu++/src/protocolgats.cpp create mode 100644 c++-libbu++/src/protocolgats.h create mode 100644 c++-libbu++/src/string.cpp create mode 100644 c++-libbu++/src/string.h create mode 100644 c++-libbu++/src/tests/clone.cpp create mode 100644 c++-libbu++/src/tests/dump.cpp create mode 100644 c++-libbu++/src/tests/int.cpp create mode 100644 c++-libbu++/src/types.h create mode 100644 c++-libbu++/src/unit/basic.unit create mode 100644 c++-libbu++/src/unit/float.unit create mode 100644 c++-libbu++/src/unit/io.unit (limited to 'c++-libbu++/src') diff --git a/c++-libbu++/src/boolean.cpp b/c++-libbu++/src/boolean.cpp new file mode 100644 index 0000000..729e644 --- /dev/null +++ b/c++-libbu++/src/boolean.cpp @@ -0,0 +1,53 @@ +#include "gats/boolean.h" + +#include +#include + +Gats::Boolean::Boolean() : + bVal( false ) +{ +} + +Gats::Boolean::Boolean( bool bVal ) : + bVal( bVal ) +{ +} + +Gats::Boolean::~Boolean() +{ +} + +Gats::Object *Gats::Boolean::clone() const +{ + return new Gats::Boolean( bVal ); +} + +void Gats::Boolean::write( Bu::Stream &rOut ) const +{ + if( bVal ) + { + rOut.write("1", 1 ); + } + else + { + rOut.write("0", 1 ); + } +} + +void Gats::Boolean::read( Bu::Stream &rIn, char cType ) +{ + if( cType == '1' ) + { + bVal = true; + } + else + { + bVal = false; + } +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Boolean &b ) +{ + return f << "(bool) " << b.getValue(); +} + diff --git a/c++-libbu++/src/boolean.h b/c++-libbu++/src/boolean.h new file mode 100644 index 0000000..6b256c5 --- /dev/null +++ b/c++-libbu++/src/boolean.h @@ -0,0 +1,30 @@ +#ifndef GATS_BOOLEAN_H +#define GATS_BOOLEAN_H + +#include "gats/object.h" + +namespace Gats +{ + class Boolean : public Gats::Object + { + public: + Boolean(); + Boolean( bool bVal ); + virtual ~Boolean(); + + virtual Type getType() const { return typeBoolean; } + bool getValue() const { return bVal; } + void setValue( bool b ) { bVal = b; } + virtual Object *clone() const; + + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + + private: + bool bVal; + }; +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Boolean &b ); + +#endif diff --git a/c++-libbu++/src/dictionary.cpp b/c++-libbu++/src/dictionary.cpp new file mode 100644 index 0000000..b59d652 --- /dev/null +++ b/c++-libbu++/src/dictionary.cpp @@ -0,0 +1,380 @@ +#include "gats/dictionary.h" + +#include "gats/boolean.h" +#include "gats/integer.h" +#include "gats/float.h" +#include "gats/string.h" +#include "gats/list.h" + +#include + +template<> +uint32_t Bu::__calcHashCode( const Gats::String &s ) +{ + return __calcHashCode( dynamic_cast(s) ); +} + +Gats::Dictionary::Dictionary() +{ +} + +Gats::Dictionary::~Dictionary() +{ + for( iterator i = begin(); i; i++ ) + { + delete *i; + } +} + +Gats::Object *Gats::Dictionary::clone() const +{ + Gats::Dictionary *pClone = new Gats::Dictionary; + for( const_iterator i = begin(); i; i++ ) + { + Bu::String s(i.getKey()); + pClone->insert( s.clone(), (*i)->clone() ); + } + + return pClone; +} + +void Gats::Dictionary::write( Bu::Stream &rOut ) const +{ + rOut.write("d", 1 ); + for( const_iterator i= begin(); i; i++ ) + { + i.getKey().write( rOut ); + (*i)->write( rOut ); + } + rOut.write("e", 1 ); +} + +void Gats::Dictionary::read( Bu::Stream &rIn, char cType ) +{ + for(;;) + { + char cNext; + rIn.read( &cNext, 1 ); + if( cNext == 'e' ) + break; + if( cNext != 's' ) + throw Bu::ExceptionBase("You can only use strings as keys."); + Gats::String sKey; + sKey.read( rIn, cNext ); + + ((Bu::Hash *)this)->insert( + sKey, Gats::Object::read( rIn ) + ); + } +} + +void Gats::Dictionary::insert( const Bu::String &sKey, char i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, unsigned char i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, signed char i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, unsigned short i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, signed short i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, unsigned int i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, signed int i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, unsigned long i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, signed long i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, unsigned long long i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, signed long long i ) +{ + ((Bu::Hash *)this)->insert( + sKey, new Gats::Integer( i ) + ); +} +/* +void Gats::Dictionary::insert( const Bu::String &sKey, bool b ) +{ + Bu::Hash::insert( + sKey, new Gats::Boolean( b ) + ); +}*/ + +void Gats::Dictionary::insert( const Bu::String &sKey, float d ) +{ + Bu::Hash::insert( + sKey, new Gats::Float( d ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, double d ) +{ + Bu::Hash::insert( + sKey, new Gats::Float( d ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, const char *s ) +{ + Bu::Hash::insert( + sKey, new Gats::String( s ) + ); +} + +void Gats::Dictionary::insert( const Bu::String &sKey, const Bu::String &s ) +{ + Bu::Hash::insert( + sKey, new Gats::String( s ) + ); +} + +void Gats::Dictionary::insertBool( const Bu::String &sKey, bool b ) +{ + Bu::Hash::insert( + sKey, new Gats::Boolean( b ) + ); +} + +void Gats::Dictionary::insertInt( const Bu::String &sKey, int64_t i ) +{ + Bu::Hash::insert( + sKey, new Gats::Integer( i ) + ); +} + +void Gats::Dictionary::insertFloat( const Bu::String &sKey, double d ) +{ + Bu::Hash::insert( + sKey, new Gats::Float( d ) + ); +} + +void Gats::Dictionary::insertStr( const Bu::String &sKey, const Bu::String &s ) +{ + Bu::Hash::insert( + sKey, new Gats::String( s ) + ); +} + +void Gats::Dictionary::insertList( const Bu::String &sKey, Gats::List *pL ) +{ + Bu::Hash::insert( + sKey, pL + ); +} + +void Gats::Dictionary::insertDict( const Bu::String &sKey, + Gats::Dictionary *pD ) +{ + Bu::Hash::insert( + sKey, pD + ); +} + +Gats::List *Gats::Dictionary::insertList( const Bu::String &sKey ) +{ + Gats::List *pLst = new Gats::List(); + insertList( sKey, pLst ); + return pLst; +} + +Gats::Dictionary *Gats::Dictionary::insertDict( const Bu::String &sKey ) +{ + Gats::Dictionary *pDict = new Gats::Dictionary(); + insertDict( sKey, pDict ); + return pDict; +} + +bool Gats::Dictionary::getBool( const Bu::String &sKey ) +{ + Gats::Boolean *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as bool.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb->getValue(); +} + +int64_t Gats::Dictionary::getInt( const Bu::String &sKey ) +{ + Gats::Integer *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as int.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb->getValue(); +} + +double Gats::Dictionary::getFloat( const Bu::String &sKey ) +{ + Gats::Float *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as float.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb->getValue(); +} + +Bu::String Gats::Dictionary::getStr( const Bu::String &sKey ) +{ + Gats::String *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as string.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return *pOb; +} + +Gats::List *Gats::Dictionary::getList( const Bu::String &sKey ) +{ + Gats::List *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as list.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb; +} + +Gats::Dictionary *Gats::Dictionary::getDict( const Bu::String &sKey ) +{ + Gats::Dictionary *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as dictionary.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb; +} + +bool Gats::Dictionary::getBool( const Bu::String &sKey ) const +{ + Gats::Boolean *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as bool.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb->getValue(); +} + +int64_t Gats::Dictionary::getInt( const Bu::String &sKey ) const +{ + Gats::Integer *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as int.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb->getValue(); +} + +double Gats::Dictionary::getFloat( const Bu::String &sKey ) const +{ + Gats::Float *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as float.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb->getValue(); +} + +Bu::String Gats::Dictionary::getStr( const Bu::String &sKey ) const +{ + Gats::String *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as string.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return *pOb; +} + +Gats::List *Gats::Dictionary::getList( const Bu::String &sKey ) const +{ + Gats::List *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as list.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb; +} + +Gats::Dictionary *Gats::Dictionary::getDict( const Bu::String &sKey ) const +{ + Gats::Dictionary *pOb = dynamic_cast( get( sKey ) ); + if( !pOb ) + throw Bu::ExceptionBase("Cannot use %s item '%s' as dictionary.", + typeToStr( get( sKey )->getType() ), sKey.getStr() ); + + return pOb; +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Dictionary &d ) +{ + f << "(dict) {"; + f.incIndent(); + int iMax = 0; + for( Gats::Dictionary::const_iterator i = d.begin(); i; i++ ) + { + if( i.getKey().getSize() > iMax ) + iMax = i.getKey().getSize(); + } + iMax += 2; + for( Gats::Dictionary::const_iterator i = d.begin(); i; i++ ) + { + f << f.nl << Bu::Fmt( iMax ) << i.getKey() + ": " << *i.getValue(); + } + f.decIndent(); + f << f.nl << "}"; + + return f; +} + diff --git a/c++-libbu++/src/dictionary.h b/c++-libbu++/src/dictionary.h new file mode 100644 index 0000000..3dd1000 --- /dev/null +++ b/c++-libbu++/src/dictionary.h @@ -0,0 +1,74 @@ +#ifndef GATS_DICTIONARY_H +#define GATS_DICTIONARY_H + +#include "gats/object.h" +#include "gats/string.h" +#include + +namespace Gats +{ + class List; + + class Dictionary : public Gats::Object, + public Bu::Hash + { + public: + Dictionary(); + virtual ~Dictionary(); + + virtual Type getType() const { return typeDictionary; } + virtual Object *clone() const; + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + + void insert( const Bu::String &sKey, const char *s ); + void insert( const Bu::String &sKey, const Bu::String &s ); + void insert( const Bu::String &sKey, char i ); + void insert( const Bu::String &sKey, unsigned char i ); + void insert( const Bu::String &sKey, signed char i ); + void insert( const Bu::String &sKey, unsigned short i ); + void insert( const Bu::String &sKey, signed short i ); + void insert( const Bu::String &sKey, unsigned int i ); + void insert( const Bu::String &sKey, signed int i ); + void insert( const Bu::String &sKey, unsigned long i ); + void insert( const Bu::String &sKey, signed long i ); + void insert( const Bu::String &sKey, unsigned long long i ); + void insert( const Bu::String &sKey, signed long long i ); + //void insert( const Bu::String &sKey, bool b ); + void insert( const Bu::String &sKey, float d ); + void insert( const Bu::String &sKey, double d ); + using Bu::Hash::insert; + void insertBool( const Bu::String &sKey, bool b ); + void insertInt( const Bu::String &sKey, int64_t i ); + void insertFloat( const Bu::String &sKey, double d ); + void insertStr( const Bu::String &sKey, const Bu::String &s ); + void insertList( const Bu::String &sKey, Gats::List *pL ); + void insertDict( const Bu::String &sKey, Gats::Dictionary *pD ); + Gats::List *insertList( const Bu::String &sKey ); + Gats::Dictionary *insertDict( const Bu::String &sKey ); + + bool getBool( const Bu::String &sKey ); + int64_t getInt( const Bu::String &sKey ); + double getFloat( const Bu::String &sKey ); + Bu::String getStr( const Bu::String &sKey ); + Gats::List *getList( const Bu::String &sKey ); + Gats::Dictionary *getDict( const Bu::String &sKey ); + + bool getBool( const Bu::String &sKey ) const; + int64_t getInt( const Bu::String &sKey ) const; + double getFloat( const Bu::String &sKey ) const; + Bu::String getStr( const Bu::String &sKey ) const; + Gats::List *getList( const Bu::String &sKey ) const; + Gats::Dictionary *getDict( const Bu::String &sKey ) const; + }; +}; + +namespace Bu +{ +template<> +uint32_t __calcHashCode( const Gats::String &s ); +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Dictionary &d ); + +#endif diff --git a/c++-libbu++/src/float.cpp b/c++-libbu++/src/float.cpp new file mode 100644 index 0000000..c01d824 --- /dev/null +++ b/c++-libbu++/src/float.cpp @@ -0,0 +1,130 @@ +#include "gats/float.h" +#include "gats/integer.h" + +#include +#include + +#include +using namespace Bu; +Gats::Float::Float() : + fVal( 0.0 ) +{ +} + +Gats::Float::Float( double f ) : + fVal( f ) +{ +} + +Gats::Float::~Float() +{ +} + +Gats::Object *Gats::Float::clone() const +{ + return new Gats::Float( fVal ); +} + +void Gats::Float::write( Bu::Stream &rOut ) const +{ + if( fVal == 0.0 ) + { + if( signbit( fVal ) ) + rOut.write("FZ", 2 ); + else + rOut.write("Fz", 2 ); + } + else if( !isfinite( fVal ) ) + { + if( isnan( fVal ) ) + { + if( signbit( fVal ) ) + rOut.write("FN", 2 ); + else + rOut.write("Fn", 2 ); + } + else + { + if( signbit( fVal ) ) + rOut.write("FI", 2 ); + else + rOut.write("Fi", 2 ); + } + } + else + { + rOut.write("f", 1 ); + double d = fVal; + bool bNeg = false; + int64_t iScale=0; + if( signbit( d ) ) + { + bNeg = true; + d = -d; + } + + iScale = log( d ) / 0x1.62e42fefa39efp+2; // log( 256.0 ) + if( iScale < 0 ) iScale--; + d /= pow( 256.0, iScale ); + + Bu::String s; + s += (uint8_t)(d); + d -= (int)d; + for( int j = 0; j < 150 && d; j++ ) + { + d = d*256.0; + s += (uint8_t)d; + d -= (int)d; + } + Gats::Integer::writePackedInt( rOut, bNeg?-s.getSize():s.getSize() ); + rOut.write( s.getStr(), s.getSize() ); + Gats::Integer::writePackedInt( rOut, iScale ); + } +} + +void Gats::Float::read( Bu::Stream &rIn, char cType ) +{ + if( cType == 'F' ) + { + char buf; + rIn.read( &buf, 1 ); + switch( buf ) + { + case 'N': fVal = -NAN; break; + case 'n': fVal = NAN; break; + case 'I': fVal = -INFINITY; break; + case 'i': fVal = INFINITY; break; + case 'Z': fVal = -0.0; break; + case 'z': fVal = 0.0; break; + } + } + else if( cType == 'f' ) + { + int64_t iStr; + Gats::Integer::readPackedInt( rIn, iStr ); + bool bNeg = false; + if( iStr < 0 ) + { + bNeg = true; + iStr = -iStr; + } + Bu::String s( iStr ); + rIn.read( s.getStr(), iStr ); + fVal = 0.0; + for( int j = iStr-1; j > 0; j-- ) + { + fVal = (fVal+(uint8_t)s[j])*0x1p-8; + } + fVal += (uint8_t)s[0]; + int64_t iScale; + Gats::Integer::readPackedInt( rIn, iScale ); + fVal *= pow( 256.0, iScale ); + if( bNeg ) fVal = -fVal; + } +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ) +{ + return f << "(float) " << flt.getValue(); +} + diff --git a/c++-libbu++/src/float.h b/c++-libbu++/src/float.h new file mode 100644 index 0000000..ba38d6c --- /dev/null +++ b/c++-libbu++/src/float.h @@ -0,0 +1,33 @@ +#ifndef GATS_FLOAT_H +#define GATS_FLOAT_H + +#include "gats/object.h" + +#include + +namespace Gats +{ + class Float : public Gats::Object + { + public: + Float(); + Float( double f ); + virtual ~Float(); + + virtual Object *clone() const; + + virtual Type getType() const { return typeFloat; } + double getValue() const { return fVal; } + + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + + private: + double fVal; + mutable Bu::String sWriteCache; + }; +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt ); + +#endif diff --git a/c++-libbu++/src/gatsc/main.cpp b/c++-libbu++/src/gatsc/main.cpp new file mode 100644 index 0000000..2bac3fd --- /dev/null +++ b/c++-libbu++/src/gatsc/main.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include + +#include "gats/types.h" +#include "gats/gatsstream.h" + +using namespace Bu; + +class Options : public OptParser +{ +public: + Options( int argc, char *argv[] ) : + bCompile( true ) + { + addHelpBanner("Gats Compiler\nUsage: gatsc [options] [input]\n"); + + addOption( sInput, 'i', "input", "Specify input file."); + addOption( sOutput, 'o', "output", "Specify output file."); + + addOption( bCompile, 'd', "decompile", + "Convert binary gats to text gats."); + + addHelpOption('h', "help", "This Help"); + + setNonOption( slot( this, &Options::setInput ) ); + + setOverride("decompile", false ); + + parse( argc, argv ); + } + + int setInput( StrArray aParam ) + { + sInput = aParam[0]; + return 0; + } + + bool bCompile; + String sInput; + String sOutput; +}; + +int main( int argc, char *argv[] ) +{ + Options opt( argc, argv ); + + if( opt.sInput.isEmpty() ) + { + sio << "You must specify an input." << sio.nl << sio.nl; + return 1; + } + + if( opt.sOutput.isEmpty() ) + { + opt.sOutput.set( opt.sInput.begin(), opt.sInput.find('.') ); + opt.sOutput += ".gats"; + } + + if( opt.bCompile ) + { + File fIn( opt.sInput, File::Read ); + File fOut( opt.sOutput, File::WriteNew ); + Gats::GatsStream gs( fOut ); + Gats::Object *pObj = Gats::Object::strToGats( fIn.readAll() ); + gs.writeObject( pObj ); + delete pObj; + } + + return 0; +} + diff --git a/c++-libbu++/src/gatscon/clientthread.cpp b/c++-libbu++/src/gatscon/clientthread.cpp new file mode 100644 index 0000000..4c7b72a --- /dev/null +++ b/c++-libbu++/src/gatscon/clientthread.cpp @@ -0,0 +1,38 @@ +#include "clientthread.h" + +#include + +ClientThread::ClientThread( QObject *pParent, const QByteArray &baHost, + int iPort ) : + QThread( pParent ), + baHost( baHost ), + iPort( iPort ), + gsCli( ssCli ) +{ +} + +ClientThread::~ClientThread() +{ +} + +void ClientThread::send( Gats::Object *pObj ) +{ + gsCli.writeObject( pObj ); +} + +void ClientThread::run() +{ + ssCli.setStream( + new Bu::TcpSocket( baHost.constData(), iPort ) + ); + + while( !ssCli.isEos() ) + { + Gats::Object *pObj = gsCli.readObject(); + if( pObj == NULL ) + continue; + + emit recv( pObj ); + } +} + diff --git a/c++-libbu++/src/gatscon/clientthread.h b/c++-libbu++/src/gatscon/clientthread.h new file mode 100644 index 0000000..3182d37 --- /dev/null +++ b/c++-libbu++/src/gatscon/clientthread.h @@ -0,0 +1,37 @@ +#ifndef CLIENT_THREAD_H +#define CLIENT_THREAD_H + +#include +#include + +#include +#include + +namespace Gats +{ + class Object; +}; + +class ClientThread : public QThread +{ + Q_OBJECT; +public: + ClientThread( QObject *pParent, const QByteArray &baHost, int iPort ); + virtual ~ClientThread(); + + void send( Gats::Object *pObj ); + +signals: + void recv( Gats::Object *pObj ); + +protected: + virtual void run(); + +private: + QByteArray baHost; + int iPort; + Bu::StreamStack ssCli; + Gats::GatsStream gsCli; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/clientwidget.cpp b/c++-libbu++/src/gatscon/clientwidget.cpp new file mode 100644 index 0000000..941d9fa --- /dev/null +++ b/c++-libbu++/src/gatscon/clientwidget.cpp @@ -0,0 +1,82 @@ +#include "clientwidget.h" +#include "clientthread.h" + +#include "gatstotree.h" +#include "treetogats.h" + +#include + +#include +#include +#include +#include + +using namespace Bu; + +ClientWidget::ClientWidget( QWidget *pParent, const QByteArray &baHost, + int iPort ) : + QWidget( pParent ) +{ + setupUi( this ); + + pCli = new ClientThread( this, baHost, iPort ); + connect( pCli, SIGNAL(recv( Gats::Object *)), + this, SLOT(recv(Gats::Object *)), Qt::QueuedConnection ); + + pCli->start(); +} + +ClientWidget::~ClientWidget() +{ +} + +void ClientWidget::saveTo( const QString &sFile ) +{ + File fOut( sFile.toAscii().constData(), File::WriteNew ); + Gats::GatsStream gsOut( fOut ); + QTreeWidgetItem *pRoot = twHistory->invisibleRootItem(); + for( int j = 0; j < pRoot->childCount(); j++ ) + { + Gats::Object *pObj = treeToGats( pRoot->child( j ) ); + gsOut.writeObject( pObj ); + delete pObj; + } +} + +void ClientWidget::send() +{ + try + { + Gats::Object *pObj = Gats::Object::strToGats( + leGats->text().toAscii().constData() + ); + sio << "Send: " << *pObj << sio.nl; + QTreeWidgetItem *pIt = new QTreeWidgetItem( + twHistory->invisibleRootItem() + ); + pIt->setText( 0, "send" ); + gatsToTree( pIt, pObj ); + pCli->send( pObj ); + delete pObj; + + leGats->setText(""); + leGats->setFocus(); + } + catch( Bu::ExceptionBase &e ) + { + QMessageBox::critical( this, "Gats Console - Error", e.what() ); + } +} + +void ClientWidget::recv( Gats::Object *pObj ) +{ + sio << "Recv: " << *pObj << sio.nl; + + QTreeWidgetItem *pIt = new QTreeWidgetItem( + twHistory->invisibleRootItem() + ); + pIt->setText( 0, "recv" ); + gatsToTree( pIt, pObj ); + delete pObj; +} + diff --git a/c++-libbu++/src/gatscon/clientwidget.h b/c++-libbu++/src/gatscon/clientwidget.h new file mode 100644 index 0000000..06c154d --- /dev/null +++ b/c++-libbu++/src/gatscon/clientwidget.h @@ -0,0 +1,30 @@ +#ifndef CLIENT_WIDGET_H +#define CLIENT_WIDGET_H + +#include +#include "ui_clientwidget.h" +#include "iobase.h" + +namespace Gats +{ + class Object; +}; + +class ClientWidget : public QWidget, protected Ui::ClientWidget, public IoBase +{ + Q_OBJECT; +public: + ClientWidget( QWidget *pParent, const QByteArray &baHost, int iPort ); + virtual ~ClientWidget(); + + virtual void saveTo( const QString &sFile ); + +public slots: + void send(); + void recv( Gats::Object *pObj ); + +private: + class ClientThread *pCli; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/clientwidget.ui b/c++-libbu++/src/gatscon/clientwidget.ui new file mode 100644 index 0000000..a0cb997 --- /dev/null +++ b/c++-libbu++/src/gatscon/clientwidget.ui @@ -0,0 +1,87 @@ + + + ClientWidget + + + + 0 + 0 + 363 + 291 + + + + Form + + + + + + + Name + + + + + Type + + + + + Value + + + + + + + + + + Gats: + + + + + + + + + + Send + + + true + + + true + + + + + + + + + + + pushButton + clicked() + ClientWidget + send() + + + 332 + 276 + + + 322 + 367 + + + + + + send() + + diff --git a/c++-libbu++/src/gatscon/connectdlg.cpp b/c++-libbu++/src/gatscon/connectdlg.cpp new file mode 100644 index 0000000..589ae97 --- /dev/null +++ b/c++-libbu++/src/gatscon/connectdlg.cpp @@ -0,0 +1,22 @@ +#include "connectdlg.h" + +ConnectDlg::ConnectDlg( QWidget *pParent ) : + QDialog( pParent ) +{ + setupUi( this ); +} + +ConnectDlg::~ConnectDlg() +{ +} + +QByteArray ConnectDlg::getHostname() const +{ + return leHost->text().toAscii(); +} + +int ConnectDlg::getPort() const +{ + return sbPort->value(); +} + diff --git a/c++-libbu++/src/gatscon/connectdlg.h b/c++-libbu++/src/gatscon/connectdlg.h new file mode 100644 index 0000000..57ea6cd --- /dev/null +++ b/c++-libbu++/src/gatscon/connectdlg.h @@ -0,0 +1,17 @@ +#ifndef CONNECT_DLG_H +#define CONNECT_DLG_H + +#include "ui_connectdlg.h" + +class ConnectDlg : public QDialog, protected Ui::ConnectDlg +{ + Q_OBJECT; +public: + ConnectDlg( QWidget *pParent ); + virtual ~ConnectDlg(); + + QByteArray getHostname() const; + int getPort() const; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/connectdlg.ui b/c++-libbu++/src/gatscon/connectdlg.ui new file mode 100644 index 0000000..6875e27 --- /dev/null +++ b/c++-libbu++/src/gatscon/connectdlg.ui @@ -0,0 +1,99 @@ + + + ConnectDlg + + + + 0 + 0 + 300 + 93 + + + + Gats Console - Connect + + + + + + + + Hostname: + + + + + + + Port: + + + + + + + localhost + + + + + + + 1 + + + 32767 + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + ConnectDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ConnectDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/c++-libbu++/src/gatscon/filewidget.cpp b/c++-libbu++/src/gatscon/filewidget.cpp new file mode 100644 index 0000000..dbd70fd --- /dev/null +++ b/c++-libbu++/src/gatscon/filewidget.cpp @@ -0,0 +1,72 @@ +#include "filewidget.h" + +#include "gatstotree.h" +#include "treetogats.h" + +#include +#include +#include + +#include + +using namespace Bu; + +FileWidget::FileWidget( QWidget *pParent ) : + QWidget( pParent ) +{ + setupUi( this ); +} + +FileWidget::FileWidget( QWidget *pParent, QString sFile ) : + QWidget( pParent ) +{ + setupUi( this ); + + File fIn( sFile.toAscii().constData(), File::Read ); + Gats::GatsStream gsIn( fIn ); + Gats::Object *pObj; + while( (pObj = gsIn.readObject()) ) + { + QTreeWidgetItem *pNew = new QTreeWidgetItem( + twGats->invisibleRootItem() + ); + pNew->setText( 0, "" ); + gatsToTree( pNew, pObj ); + delete pObj; + } +} + +FileWidget::~FileWidget() +{ +} + +void FileWidget::saveTo( const QString &sFile ) +{ + File fOut( sFile.toAscii().constData(), File::WriteNew ); + Gats::GatsStream gsOut( fOut ); + QTreeWidgetItem *pRoot = twGats->invisibleRootItem(); + for( int j = 0; j < pRoot->childCount(); j++ ) + { + Gats::Object *pObj = treeToGats( pRoot->child( j ) ); + gsOut.writeObject( pObj ); + delete pObj; + } +} + +void FileWidget::addRootItem() +{ + QString sText = QInputDialog::getText( this, "Gats Console - Add Root Item", + "Gats:"); + Gats::Object *pObj = Gats::Object::strToGats( sText.toAscii().constData() ); + QTreeWidgetItem *pNew = new QTreeWidgetItem( + twGats->invisibleRootItem() + ); + pNew->setText( 0, "" ); + gatsToTree( pNew, pObj ); + delete pObj; +} + +void FileWidget::delRootItem() +{ +} + diff --git a/c++-libbu++/src/gatscon/filewidget.h b/c++-libbu++/src/gatscon/filewidget.h new file mode 100644 index 0000000..9993bfe --- /dev/null +++ b/c++-libbu++/src/gatscon/filewidget.h @@ -0,0 +1,29 @@ +#ifndef FILE_WIDGET_H +#define FILE_WIDGET_H + +#include "ui_filewidget.h" +#include "iobase.h" + +namespace Gats +{ + class Object; +}; + +class FileWidget : public QWidget, protected Ui::FileWidget, public IoBase +{ + Q_OBJECT; +public: + FileWidget( QWidget *pParent=NULL ); + FileWidget( QWidget *pParent, QString sFile ); + virtual ~FileWidget(); + + virtual void saveTo( const QString &sFile ); + +public slots: + void addRootItem(); + void delRootItem(); + +private: +}; + +#endif diff --git a/c++-libbu++/src/gatscon/filewidget.ui b/c++-libbu++/src/gatscon/filewidget.ui new file mode 100644 index 0000000..d0e6ec3 --- /dev/null +++ b/c++-libbu++/src/gatscon/filewidget.ui @@ -0,0 +1,95 @@ + + + FileWidget + + + + 0 + 0 + 316 + 300 + + + + Form + + + + + + + Name + + + + + Type + + + + + Value + + + + + + + + + + Add Root Item + + + + + + + Del Root Item + + + + + + + + + + + pushButton_2 + clicked() + FileWidget + addRootItem() + + + 60 + 283 + + + 10 + 343 + + + + + pushButton + clicked() + FileWidget + delRootItem() + + + 252 + 283 + + + 258 + 324 + + + + + + addRootItem() + delRootItem() + + diff --git a/c++-libbu++/src/gatscon/gatstotree.cpp b/c++-libbu++/src/gatscon/gatstotree.cpp new file mode 100644 index 0000000..e388d5e --- /dev/null +++ b/c++-libbu++/src/gatscon/gatstotree.cpp @@ -0,0 +1,91 @@ +#include "gatstotree.h" + +#include + +#include + +void gatsToTree( QTreeWidgetItem *p, Gats::Object *pObj ) +{ + switch( pObj->getType() ) + { + case Gats::typeInteger: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + + case Gats::typeString: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + + case Gats::typeFloat: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + + case Gats::typeBoolean: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + + case Gats::typeList: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + + case Gats::typeDictionary: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + + case Gats::typeNull: + gatsToTree( p, dynamic_cast( pObj ) ); + break; + } +} + +void gatsToTree( QTreeWidgetItem *p, Gats::Integer *pObj ) +{ + p->setText( 1, "int"); + p->setText( 2, QString("%1").arg( pObj->getValue() ) ); +} + +void gatsToTree( QTreeWidgetItem *p, Gats::String *pObj ) +{ + p->setText( 1, "str"); + p->setText( 2, QString("%1").arg( pObj->getStr() ) ); +} + +void gatsToTree( QTreeWidgetItem *p, Gats::Float *pObj ) +{ + p->setText( 1, "float"); + p->setText( 2, QString("%1").arg( pObj->getValue() ) ); +} + +void gatsToTree( QTreeWidgetItem *p, Gats::Boolean *pObj ) +{ + p->setText( 1, "bool"); + p->setText( 2, pObj->getValue()?"true":"false" ); +} + +void gatsToTree( QTreeWidgetItem *p, Gats::List *pObj ) +{ + p->setText( 1, "list"); + int j = 0; + for( Gats::List::iterator i = pObj->begin(); i; i++ ) + { + QTreeWidgetItem *pIt = new QTreeWidgetItem( p ); + pIt->setText( 0, QString("%1").arg( j++ ) ); + gatsToTree( pIt, *i ); + } +} + +void gatsToTree( QTreeWidgetItem *p, Gats::Dictionary *pObj ) +{ + p->setText( 1, "dict"); + for( Gats::Dictionary::iterator i = pObj->begin(); i; i++ ) + { + QTreeWidgetItem *pIt = new QTreeWidgetItem( p ); + pIt->setText( 0, QString( i.getKey().getStr() ) ); + gatsToTree( pIt, *i ); + } +} + +void gatsToTree( QTreeWidgetItem *p, Gats::Null *pObj ) +{ + p->setText( 1, "null"); +} diff --git a/c++-libbu++/src/gatscon/gatstotree.h b/c++-libbu++/src/gatscon/gatstotree.h new file mode 100644 index 0000000..a803017 --- /dev/null +++ b/c++-libbu++/src/gatscon/gatstotree.h @@ -0,0 +1,28 @@ +#ifndef GATS_TO_TREE_H +#define GATS_TO_TREE_H + +class QTreeWidgetItem; + +namespace Gats +{ + class Integer; + class String; + class Float; + class Boolean; + class List; + class Dictionary; + class Object; +}; + +#include + +void gatsToTree( QTreeWidgetItem *p, Gats::Object *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::Integer *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::String *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::Float *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::Boolean *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::List *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::Dictionary *pObj ); +void gatsToTree( QTreeWidgetItem *p, Gats::Null *pObj ); + +#endif diff --git a/c++-libbu++/src/gatscon/iobase.cpp b/c++-libbu++/src/gatscon/iobase.cpp new file mode 100644 index 0000000..309444c --- /dev/null +++ b/c++-libbu++/src/gatscon/iobase.cpp @@ -0,0 +1 @@ +#include "iobase.h" diff --git a/c++-libbu++/src/gatscon/iobase.h b/c++-libbu++/src/gatscon/iobase.h new file mode 100644 index 0000000..5bd3843 --- /dev/null +++ b/c++-libbu++/src/gatscon/iobase.h @@ -0,0 +1,10 @@ +#ifndef IO_BASE_H +#define IO_BASE_H + +class IoBase +{ +public: + virtual void saveTo( const class QString &sFile )=0; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/main.cpp b/c++-libbu++/src/gatscon/main.cpp new file mode 100644 index 0000000..b9b2327 --- /dev/null +++ b/c++-libbu++/src/gatscon/main.cpp @@ -0,0 +1,13 @@ +#include "mainwnd.h" +#include + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + MainWnd wnd; + wnd.show(); + + return app.exec(); +} + diff --git a/c++-libbu++/src/gatscon/mainwnd.cpp b/c++-libbu++/src/gatscon/mainwnd.cpp new file mode 100644 index 0000000..5d31019 --- /dev/null +++ b/c++-libbu++/src/gatscon/mainwnd.cpp @@ -0,0 +1,119 @@ +#include "mainwnd.h" + +#include "clientwidget.h" +#include "proxywidget.h" +#include "filewidget.h" + +#include "connectdlg.h" +#include "setupproxydlg.h" + +#include +#include + +MainWnd::MainWnd() +{ + setupUi( this ); + + pMode = new QLabel( "Idle", this ); + statusBar()->addPermanentWidget( pMode ); +} + +MainWnd::~MainWnd() +{ +} + +void MainWnd::connect() +{ + ConnectDlg dlg( this ); + if( dlg.exec() == QDialog::Accepted ) + { + sCurFile.clear(); + setCentralWidget( + new ClientWidget( + this, dlg.getHostname(), dlg.getPort() + ) + ); + pMode->setText( + QString("Client Mode: %1:%2").arg( QString(dlg.getHostname()) ). + arg( dlg.getPort() ) + ); + } +} + +void MainWnd::proxy() +{ + SetupProxyDlg dlg( this ); + + if( dlg.exec() == QDialog::Accepted ) + { + sCurFile.clear(); + setCentralWidget( + new ProxyWidget( + this, dlg.getPortIn(), dlg.getHostOut(), dlg.getPortOut() + ) + ); + pMode->setText( + QString("Proxy Mode: :%1 -> %2:%3").arg( dlg.getPortIn() ). + arg( QString(dlg.getHostOut()) ). + arg( dlg.getPortOut() ) + ); + } +} + +void MainWnd::open() +{ + QString sFile = QFileDialog::getOpenFileName( + this, "Gats Console - open gats file" + ); + if( sFile.isEmpty() ) + return; + + sCurFile = sFile; + setCentralWidget( + new FileWidget( this, sFile ) + ); + pMode->setText( QString("File mode: %1").arg( sCurFile ) ); +} + +void MainWnd::newFile() +{ + sCurFile.clear(); + setCentralWidget( + new FileWidget( this ) + ); + pMode->setText( QString("File mode: ") ); +} + +void MainWnd::save() +{ + if( sCurFile.isEmpty() ) + { + saveAs(); + } + else + { + IoBase *pIo = dynamic_cast(centralWidget()); + if( !pIo ) + return; + + pIo->saveTo( sCurFile ); + } +} + +void MainWnd::saveAs() +{ + IoBase *pIo = dynamic_cast(centralWidget()); + if( !pIo ) + return; + + QString sFile = QFileDialog::getSaveFileName( + this, "Gats Console - save gats file" + ); + if( sFile.isEmpty() ) + return; + + pIo->saveTo( sFile ); + + sCurFile = sFile; +} + diff --git a/c++-libbu++/src/gatscon/mainwnd.h b/c++-libbu++/src/gatscon/mainwnd.h new file mode 100644 index 0000000..d1ae080 --- /dev/null +++ b/c++-libbu++/src/gatscon/mainwnd.h @@ -0,0 +1,26 @@ +#ifndef MAIN_WND_H +#define MAIN_WND_H + +#include "ui_mainwnd.h" + +class MainWnd : public QMainWindow, protected Ui::MainWnd +{ + Q_OBJECT; +public: + MainWnd(); + virtual ~MainWnd(); + +public slots: + void connect(); + void proxy(); + void open(); + void newFile(); + void save(); + void saveAs(); + +private: + QString sCurFile; + class QLabel *pMode; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/mainwnd.ui b/c++-libbu++/src/gatscon/mainwnd.ui new file mode 100644 index 0000000..01f534a --- /dev/null +++ b/c++-libbu++/src/gatscon/mainwnd.ui @@ -0,0 +1,207 @@ + + + MainWnd + + + + 0 + 0 + 431 + 319 + + + + Gats Console + + + + + + 0 + 0 + 431 + 21 + + + + + &File + + + + + + + + + + + &Network + + + + + + + + + + + &Open connection... + + + + + &Start proxy... + + + + + &Open Gats File... + + + + + &New Gats File + + + + + &Save + + + + + &Save As... + + + + + E&xit + + + + + + + action_Open_connection + triggered() + MainWnd + connect() + + + -1 + -1 + + + 215 + 159 + + + + + action_Open_proxy_connection + triggered() + MainWnd + proxy() + + + -1 + -1 + + + 215 + 159 + + + + + action_Open_gats_file + triggered() + MainWnd + open() + + + -1 + -1 + + + 215 + 159 + + + + + actionE_xit + triggered() + MainWnd + close() + + + -1 + -1 + + + 215 + 159 + + + + + action_New_Gats_File + triggered() + MainWnd + newFile() + + + -1 + -1 + + + 215 + 159 + + + + + action_Save + triggered() + MainWnd + save() + + + -1 + -1 + + + 215 + 159 + + + + + action_Save_As + triggered() + MainWnd + saveAs() + + + -1 + -1 + + + 215 + 159 + + + + + + connect() + proxy() + open() + save() + saveAs() + newFile() + + diff --git a/c++-libbu++/src/gatscon/proxythread.cpp b/c++-libbu++/src/gatscon/proxythread.cpp new file mode 100644 index 0000000..574b56b --- /dev/null +++ b/c++-libbu++/src/gatscon/proxythread.cpp @@ -0,0 +1,108 @@ +#include "proxythread.h" + +#include + +#include +#include +#include +#include + +using namespace Bu; + +ProxyThread::ProxyThread( QObject *pParent, int iPortIn, + const QByteArray &baHostOut, int iPortOut ) : + QThread( pParent ), + pHost( NULL ), + iPortIn( iPortIn ), + baHostOut( baHostOut ), + iPortOut( iPortOut ), + gsCli( ssCli ) +{ + pHost = new ProxyHostThread( pParent, this ); +} + +ProxyThread::~ProxyThread() +{ +} + +void ProxyThread::send( Gats::Object *pObj ) +{ + MemBuf bg; + Gats::GatsStream gs( bg ); + gs.writeObject( pObj ); + ssCli.write( bg.getString().getStr(), bg.getString().getSize() ); +} + +void ProxyThread::run() +{ + int iSockIn; + + { + TcpServerSocket tsIn( iPortIn ); + do + { + iSockIn = tsIn.accept( 5 ); + } while( iSockIn < 0 ); + } + + emit gotConnection(); + + ssCli.setStream( new TcpSocket( iSockIn ) ); + ssCli.setBlocking( true ); + + pHost->setStream( + new TcpSocket( baHostOut.constData(), iPortOut ) + ); + + pHost->start(); + + while( !ssCli.isEos() ) + { + Gats::Object *pObj = gsCli.readObject(); + if( pObj == NULL ) + continue; + + pHost->send( pObj ); + emit recv( pObj ); + } + +} + +ProxyHostThread::ProxyHostThread( QObject *pParent, ProxyThread *pClient ) : + QThread( pParent ), + pClient( pClient ), + ssHst(), + gsHst( ssHst ) +{ +} + +ProxyHostThread::~ProxyHostThread() +{ +} + +void ProxyHostThread::send( Gats::Object *pObj ) +{ + MemBuf bg; + Gats::GatsStream gs( bg ); + gs.writeObject( pObj ); + ssHst.write( bg.getString().getStr(), bg.getString().getSize() ); +} + +void ProxyHostThread::setStream( Bu::Stream *pStr ) +{ + ssHst.setStream( pStr ); +} + +void ProxyHostThread::run() +{ + while( !ssHst.isEos() ) + { + Gats::Object *pObj = gsHst.readObject(); + if( pObj == NULL ) + continue; + + pClient->send( pObj ); + emit recv( pObj ); + } +} + diff --git a/c++-libbu++/src/gatscon/proxythread.h b/c++-libbu++/src/gatscon/proxythread.h new file mode 100644 index 0000000..df75046 --- /dev/null +++ b/c++-libbu++/src/gatscon/proxythread.h @@ -0,0 +1,60 @@ +#ifndef PROXY_THREAD_H +#define PROXY_THREAD_H + +#include + +#include +#include + +class ProxyThread : public QThread +{ + Q_OBJECT; +public: + ProxyThread( QObject *pParent, int iPortIn, const QByteArray &baHostOut, + int iPortOut ); + virtual ~ProxyThread(); + + class ProxyHostThread *pHost; + + void send( Gats::Object *pObj ); + +signals: + void recv( Gats::Object *pObj ); + void gotConnection(); + +protected: + virtual void run(); + +private: + int iPortIn; + QByteArray baHostOut; + int iPortOut; + + Bu::StreamStack ssCli; + Gats::GatsStream gsCli; +}; + +class ProxyHostThread : public QThread +{ + Q_OBJECT; +public: + ProxyHostThread( QObject *pParent, ProxyThread *pClient ); + virtual ~ProxyHostThread(); + + void send( Gats::Object *pObj ); + + void setStream( Bu::Stream *pStr ); + +signals: + void recv( Gats::Object *pObj ); + +protected: + virtual void run(); + +private: + ProxyThread *pClient; + Bu::StreamStack ssHst; + Gats::GatsStream gsHst; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/proxywidget.cpp b/c++-libbu++/src/gatscon/proxywidget.cpp new file mode 100644 index 0000000..215f95f --- /dev/null +++ b/c++-libbu++/src/gatscon/proxywidget.cpp @@ -0,0 +1,131 @@ +#include "proxywidget.h" +#include "proxythread.h" + +#include "gatstotree.h" +#include "treetogats.h" + +#include + +#include +#include +#include +#include + +using namespace Bu; + +ProxyWidget::ProxyWidget( QWidget *pParent, int iPortIn, + const QByteArray baHost, int iPortOut ) : + QWidget( pParent ), + pPrx( NULL ) +{ + setupUi( this ); + + pPrx = new ProxyThread( this, iPortIn, baHost, iPortOut ); + + connect( pPrx, SIGNAL(gotConnection()), + this, SLOT(gotConnection()), Qt::QueuedConnection ); + connect( pPrx, SIGNAL(recv( Gats::Object *)), + this, SLOT(clientRecv(Gats::Object *)), Qt::QueuedConnection ); + connect( pPrx->pHost, SIGNAL(recv( Gats::Object *)), + this, SLOT(hostRecv(Gats::Object *)), Qt::QueuedConnection ); + + pPrx->start(); +} + +ProxyWidget::~ProxyWidget() +{ +} + +void ProxyWidget::saveTo( const QString &sFile ) +{ + File fOut( sFile.toAscii().constData(), File::WriteNew ); + Gats::GatsStream gsOut( fOut ); + QTreeWidgetItem *pRoot = twHistory->invisibleRootItem(); + for( int j = 0; j < pRoot->childCount(); j++ ) + { + Gats::Object *pObj = treeToGats( pRoot->child( j ) ); + gsOut.writeObject( pObj ); + delete pObj; + } +} + +void ProxyWidget::sendToClient() +{ + try + { + Gats::Object *pObj = Gats::Object::strToGats( + leGats->text().toAscii().constData() + ); + sio << "Send: " << *pObj << sio.nl; + QTreeWidgetItem *pIt = new QTreeWidgetItem( + twHistory->invisibleRootItem() + ); + pIt->setText( 0, "proxy -> client" ); + gatsToTree( pIt, pObj ); + pPrx->send( pObj ); + delete pObj; + + leGats->setText(""); + leGats->setFocus(); + } + catch( Bu::ExceptionBase &e ) + { + QMessageBox::critical( this, "Gats Console - Error", e.what() ); + } +} + +void ProxyWidget::sendToServer() +{ + try + { + Gats::Object *pObj = Gats::Object::strToGats( + leGats->text().toAscii().constData() + ); + sio << "Send: " << *pObj << sio.nl; + QTreeWidgetItem *pIt = new QTreeWidgetItem( + twHistory->invisibleRootItem() + ); + pIt->setText( 0, "proxy -> host" ); + gatsToTree( pIt, pObj ); + pPrx->pHost->send( pObj ); + delete pObj; + + leGats->setText(""); + leGats->setFocus(); + } + catch( Bu::ExceptionBase &e ) + { + QMessageBox::critical( this, "Gats Console - Error", e.what() ); + } +} + +void ProxyWidget::clientRecv( Gats::Object *pObj ) +{ + sio << "Recv: " << *pObj << sio.nl; + + QTreeWidgetItem *pIt = new QTreeWidgetItem( + twHistory->invisibleRootItem() + ); + pIt->setText( 0, "client -> host" ); + gatsToTree( pIt, pObj ); + delete pObj; +} + +void ProxyWidget::hostRecv( Gats::Object *pObj ) +{ + sio << "Recv: " << *pObj << sio.nl; + + QTreeWidgetItem *pIt = new QTreeWidgetItem( + twHistory->invisibleRootItem() + ); + pIt->setText( 0, "host -> client" ); + gatsToTree( pIt, pObj ); + delete pObj; +} + +void ProxyWidget::gotConnection() +{ + lwConnect->stop(); + swRoot->setCurrentIndex( 1 ); +} + diff --git a/c++-libbu++/src/gatscon/proxywidget.h b/c++-libbu++/src/gatscon/proxywidget.h new file mode 100644 index 0000000..d6ebf4d --- /dev/null +++ b/c++-libbu++/src/gatscon/proxywidget.h @@ -0,0 +1,33 @@ +#ifndef PROXY_WIDGET_H +#define PROXY_WIDGET_H + +#include "ui_proxywidget.h" +#include "iobase.h" + +namespace Gats +{ + class Object; +}; + +class ProxyWidget : public QWidget, protected Ui::ProxyWidget, public IoBase +{ + Q_OBJECT; +public: + ProxyWidget( QWidget *pParent, int iPortIn, const QByteArray baHost, + int iPortOut ); + virtual ~ProxyWidget(); + + virtual void saveTo( const QString &sFile ); + +public slots: + void sendToClient(); + void sendToServer(); + void clientRecv( Gats::Object *pObj ); + void hostRecv( Gats::Object *pObj ); + void gotConnection(); + +private: + class ProxyThread *pPrx; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/proxywidget.ui b/c++-libbu++/src/gatscon/proxywidget.ui new file mode 100644 index 0000000..995fc73 --- /dev/null +++ b/c++-libbu++/src/gatscon/proxywidget.ui @@ -0,0 +1,181 @@ + + + ProxyWidget + + + + 0 + 0 + 338 + 300 + + + + Form + + + + 0 + + + + + 0 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Listening for connections... + + + Qt::AlignCenter + + + + + + + + 0 + 50 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Name + + + + + Type + + + + + Value + + + + + + + + + + Gats: + + + + + + + + + + + + Send to Client + + + + + + + Send to Server + + + + + + + + + + + + + + + + LoadingWidget + QWidget +
loadingwidget.h
+ 1 +
+
+ + + + pushButton + clicked() + ProxyWidget + sendToClient() + + + 280 + 258 + + + 392 + 223 + + + + + pushButton_2 + clicked() + ProxyWidget + sendToServer() + + + 306 + 284 + + + 199 + 340 + + + + + + sendToClient() + sendToServer() + +
diff --git a/c++-libbu++/src/gatscon/setupproxydlg.cpp b/c++-libbu++/src/gatscon/setupproxydlg.cpp new file mode 100644 index 0000000..7c7a873 --- /dev/null +++ b/c++-libbu++/src/gatscon/setupproxydlg.cpp @@ -0,0 +1,27 @@ +#include "setupproxydlg.h" + +SetupProxyDlg::SetupProxyDlg( QWidget *pParent ) : + QDialog( pParent ) +{ + setupUi( this ); +} + +SetupProxyDlg::~SetupProxyDlg() +{ +} + +int SetupProxyDlg::getPortIn() const +{ + return sbPortIn->value(); +} + +QByteArray SetupProxyDlg::getHostOut() const +{ + return leHostOut->text().toAscii(); +} + +int SetupProxyDlg::getPortOut() const +{ + return sbPortOut->value(); +} + diff --git a/c++-libbu++/src/gatscon/setupproxydlg.h b/c++-libbu++/src/gatscon/setupproxydlg.h new file mode 100644 index 0000000..6cc31bd --- /dev/null +++ b/c++-libbu++/src/gatscon/setupproxydlg.h @@ -0,0 +1,18 @@ +#ifndef SETUP_PROXY_DLG_H +#define SETUP_PROXY_DLG_H + +#include "ui_setupproxydlg.h" + +class SetupProxyDlg : public QDialog, protected Ui::SetupProxyDlg +{ + Q_OBJECT; +public: + SetupProxyDlg( QWidget *pParent=NULL ); + virtual ~SetupProxyDlg(); + + int getPortIn() const; + QByteArray getHostOut() const; + int getPortOut() const; +}; + +#endif diff --git a/c++-libbu++/src/gatscon/setupproxydlg.ui b/c++-libbu++/src/gatscon/setupproxydlg.ui new file mode 100644 index 0000000..c713baf --- /dev/null +++ b/c++-libbu++/src/gatscon/setupproxydlg.ui @@ -0,0 +1,112 @@ + + + SetupProxyDlg + + + + 0 + 0 + 359 + 122 + + + + Gats Console - Setup Proxy + + + + + + + + Listening port: + + + + + + + 1 + + + 32767 + + + + + + + Target host: + + + + + + + + + + Target port: + + + + + + + 1 + + + 32767 + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SetupProxyDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SetupProxyDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/c++-libbu++/src/gatscon/treetogats.cpp b/c++-libbu++/src/gatscon/treetogats.cpp new file mode 100644 index 0000000..a1571d1 --- /dev/null +++ b/c++-libbu++/src/gatscon/treetogats.cpp @@ -0,0 +1,52 @@ +#include "treetogats.h" + +#include + +#include + +Gats::Object *treeToGats( QTreeWidgetItem *pRoot ) +{ + QString sType = pRoot->text( 1 ); + QByteArray baDat = pRoot->text( 2 ).toAscii(); + if( sType == "int" ) + { + return new Gats::Integer( strtoll( baDat.constData(), NULL, 10 ) ); + } + else if( sType == "str" ) + { + return new Gats::String( baDat.constData(), baDat.size() ); + } + else if( sType == "float" ) + { + return new Gats::Float( strtod( baDat.constData(), NULL ) ); + } + else if( sType == "bool" ) + { + return new Gats::Boolean( baDat == "true" ); + } + else if( sType == "list" ) + { + Gats::List *pRet = new Gats::List(); + for( int j = 0; j < pRoot->childCount(); j++ ) + { + pRet->append( treeToGats( pRoot->child( j ) ) ); + } + return pRet; + } + else if( sType == "dict" ) + { + Gats::Dictionary *pRet = new Gats::Dictionary(); + for( int j = 0; j < pRoot->childCount(); j++ ) + { + QTreeWidgetItem *pChild = pRoot->child( j ); + pRet->insert( + pChild->text( 0 ).toAscii().constData(), + treeToGats( pChild ) + ); + } + return pRet; + } + + throw Bu::ExceptionBase("Unhandled type found."); +} + diff --git a/c++-libbu++/src/gatscon/treetogats.h b/c++-libbu++/src/gatscon/treetogats.h new file mode 100644 index 0000000..931623d --- /dev/null +++ b/c++-libbu++/src/gatscon/treetogats.h @@ -0,0 +1,13 @@ +#ifndef TREE_TO_GATS_H +#define TREE_TO_GATS_H + +class QTreeWidgetItem; + +namespace Gats +{ + class Object; +}; + +Gats::Object *treeToGats( QTreeWidgetItem *pRoot ); + +#endif diff --git a/c++-libbu++/src/gatsstream.cpp b/c++-libbu++/src/gatsstream.cpp new file mode 100644 index 0000000..d5e3f82 --- /dev/null +++ b/c++-libbu++/src/gatsstream.cpp @@ -0,0 +1,108 @@ +#include "gats/gatsstream.h" +#include "gats/object.h" + +// #include +#include +// using namespace Bu; + +Gats::GatsStream::GatsStream( Bu::Stream &rStream ) : + rStream( rStream ) +{ +} + +Gats::GatsStream::~GatsStream() +{ +} + +Gats::Object *Gats::GatsStream::readObject() +{ + char buf[1500]; + + // sio << "Gats::GatsStream::readObject(): Scanning for object header." << sio.nl; + do + { + if( qbRead.getSize() < 5 ) + { + // sio << "Gats::GatsStream::readObject(): reading header data, need 5b, have " << qbRead.getSize() << "b." << sio.nl; + int iRead = rStream.read( buf, 5-qbRead.getSize() ); + qbRead.write( buf, iRead ); + + if( qbRead.getSize() < 5 ) + return NULL; + } + } while( !skipReadNulls() ); + + uint8_t uVer; + qbRead.peek( &uVer, 1 ); + // sio << "Gats::GatsStream::readObject(): Packet version: " << (int)uVer << sio.nl; + + int32_t iSize; + qbRead.peek( &iSize, 4, 1 ); + iSize = be32toh( iSize ); + // sio << "Gats::GatsStream::readObject(): Header read, looking for " << iSize << "b, we have " << qbRead.getSize() << "b." << sio.nl; + while( qbRead.getSize() < iSize ) + { + int32_t iRead = iSize - qbRead.getSize(); + if( iRead > 1500 ) + iRead = 1500; + // sio << "Gats::GatsStream::readObject(): Attempting to read " << iRead << "b." << sio.nl; + int32_t iReal = rStream.read( buf, iRead ); + // sio << "Gats::GatsStream::readObject(): Read " << iReal << "b." << sio.nl; + qbRead.write( buf, iReal ); + if( iReal < iRead ) + { + // sio << "Gats::GatsStream::readObject(): Insufficient data read in block, bailing on read." << sio.nl; + return NULL; + } + } + + if( qbRead.getSize() < iSize ) + { + // sio << "Gats::GatsStream::readObject(): Somehow, we still don't have enough data, bailing." << sio.nl; + return NULL; + } + + // sio << "Gats::GatsStream::readObject(): We have " << qbRead.getSize() << "b of " << iSize << "b, time to read the object." << sio.nl; + + qbRead.seek( 5 ); + Gats::Object *pObj = Gats::Object::read( qbRead ); + + // sio << "Gats::GatsStream::readObject(): Read completed, there are " << qbRead.getSize() << "b left in the buffer." << sio.nl; + return pObj; +} + +void Gats::GatsStream::writeObject( Gats::Object *pObject ) +{ + Bu::NullStream ns; + pObject->write( ns ); + + uint8_t uBuf = 1; + int32_t iSize = htobe32( ns.tell()+5 ); + rStream.write( &uBuf, 1 ); + rStream.write( &iSize, 4 ); + pObject->write( rStream ); + + // sio << "Object consumed " << ns.tell() << "b." << sio.nl; +} + +bool Gats::GatsStream::skipReadNulls() +{ + char buf; + + // sio << "Gats::GatsStream::skipReadNulls(): Scanning for nulls, " << qbRead.getSize() << "b." << sio.nl; + bool bHaveSeeked = false; + for(;;) + { + if( qbRead.peek( &buf, 1 ) == 0 ) + return false; + if( buf != 0 ) + return !bHaveSeeked; //true; + else + { + // sio << "Gats::GatsStream::skipReadNulls(): Null byte read, not header yet..." << sio.nl; + qbRead.seek( 1 ); + bHaveSeeked = true; + } + } +} + diff --git a/c++-libbu++/src/gatsstream.h b/c++-libbu++/src/gatsstream.h new file mode 100644 index 0000000..39719cf --- /dev/null +++ b/c++-libbu++/src/gatsstream.h @@ -0,0 +1,56 @@ +#ifndef GATS_STREAM_H +#define GATS_STREAM_H + +#include +#include + +namespace Gats +{ + class Object; + + class GatsStream + { + public: + GatsStream( Bu::Stream &rStream ); + virtual ~GatsStream(); + + /** + * Read an object packet from the assosiated stream. This will make + * every effort to only read exactly enough data to describe one packet, + * in case you want to do other things with your stream. It will + * automatically skip NULL byte spacing between packets, which makes + * a convinient padding method for encrypted data streams. Since + * sizing information is available in the packet header exact amounts + * of data can be read, however this function doesn't assume that it + * can read the entire object in one operation. If it fails to read + * a complete packet in one call, it will keep the data it's read so + * far buffered and return NULL, ready for another attempt. You can + * use the function hasReadBuffer() to deterimne if readObject() + * has read part of an object packet or not. If readObject returns + * non-null then hasReadBuffer should return false on it's next call. + */ + Gats::Object *readObject(); + + /** + * Write an object + */ + void writeObject( Gats::Object *pObject ); + + /** + * Tells you if there is data still in the read buffer, i.e. that a + * packet is part way through being read. If readObject has returned + * non-null in the most recent call, this should always be false. + */ + bool hasReadBuffer() { return qbRead.getSize() > 0; } + int getReadBufferSize() { return qbRead.getSize(); } + + private: + bool skipReadNulls(); + + private: + Bu::Stream &rStream; + Bu::QueueBuf qbRead; + }; +}; + +#endif diff --git a/c++-libbu++/src/integer.cpp b/c++-libbu++/src/integer.cpp new file mode 100644 index 0000000..e89ac1d --- /dev/null +++ b/c++-libbu++/src/integer.cpp @@ -0,0 +1,39 @@ +#include "gats/integer.h" + +#include + +Gats::Integer::Integer() : + iVal( 0 ) +{ +} + +Gats::Integer::Integer( int64_t iVal ) : + iVal( iVal ) +{ +} + +Gats::Integer::~Integer() +{ +} + +Gats::Object *Gats::Integer::clone() const +{ + return new Gats::Integer( iVal ); +} + +void Gats::Integer::write( Bu::Stream &rOut ) const +{ + rOut.write("i", 1 ); + writePackedInt( rOut, iVal ); +} + +void Gats::Integer::read( Bu::Stream &rIn, char cType ) +{ + readPackedInt( rIn, iVal ); +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Integer &i ) +{ + return f << "(int) " << i.getValue(); +} + diff --git a/c++-libbu++/src/integer.h b/c++-libbu++/src/integer.h new file mode 100644 index 0000000..a5e0d58 --- /dev/null +++ b/c++-libbu++/src/integer.h @@ -0,0 +1,86 @@ +#ifndef GATS_INTEGER_H +#define GATS_INTEGER_H + +#include "gats/object.h" + +#include + +#include + +namespace Gats +{ + class Integer : public Gats::Object + { + public: + Integer(); + Integer( int64_t iVal ); + virtual ~Integer(); + + virtual Object *clone() const; + + virtual Type getType() const { return typeInteger; } + int64_t getValue() const { return iVal; } + + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + + template + static void readPackedInt( Bu::Stream &rStream, itype &rOut ) + { + int8_t b; + rOut = 0; + bool bNeg; + + rStream.read( &b, 1 ); + bNeg = ( b&0x40 ); + rOut |= (itype(b&0x3F)); + int c = 0; + while( (b&0x80) ) + { + rStream.read( &b, 1 ); + rOut |= (itype(b&0x7F)) << (6+7*(c++)); + } + if( bNeg ) rOut = -rOut; + } + + template + static void writePackedInt( Bu::Stream &rStream, itype iIn ) + { + uint8_t b; + + if( iIn < 0 ) + { + iIn = -iIn; + b = (iIn&0x3F); + if( iIn > b ) + b |= 0x80 | 0x40; + else + b |= 0x40; + } + else + { + b = (iIn&0x3F); + if( iIn > b ) + b |= 0x80; + } + rStream.write( &b, 1 ); + iIn = iIn >> 6; + + while( iIn ) + { + b = (iIn&0x7F); + if( iIn > b ) + b |= 0x80; + rStream.write( &b, 1 ); + iIn = iIn >> 7; + } + } + + private: + int64_t iVal; + }; +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Integer &i ); + +#endif diff --git a/c++-libbu++/src/list.cpp b/c++-libbu++/src/list.cpp new file mode 100644 index 0000000..d081a22 --- /dev/null +++ b/c++-libbu++/src/list.cpp @@ -0,0 +1,205 @@ +#include "gats/list.h" + +#include "gats/string.h" +#include "gats/integer.h" +#include "gats/float.h" +#include "gats/boolean.h" +#include "gats/dictionary.h" + +#include +#include + +Gats::List::List() +{ +} + +Gats::List::~List() +{ + for( iterator i = begin(); i; i++ ) + { + delete *i; + } +} + +Gats::Object *Gats::List::clone() const +{ + Gats::List *pClone = new Gats::List; + for( const_iterator i = begin(); i; i++ ) + { + pClone->append( (*i)->clone() ); + } + return pClone; +} + +void Gats::List::write( Bu::Stream &rOut ) const +{ + rOut.write("l", 1 ); + for( const_iterator i = begin(); i; i++ ) + { + (*i)->write( rOut ); + } + rOut.write("e", 1 ); +} + +void Gats::List::read( Bu::Stream &rIn, char cType ) +{ + for(;;) + { + Gats::Object *pObj = Gats::Object::read( rIn ); + if( pObj == NULL ) + break; + append( pObj ); + } +} + +void Gats::List::append( const char *s ) +{ + Bu::List::append( new Gats::String( s ) ); +} + +void Gats::List::append( const Bu::String &s ) +{ + Bu::List::append( new Gats::String( s ) ); +} + +void Gats::List::append( int32_t i ) +{ + Bu::List::append( new Gats::Integer( i ) ); +} + +void Gats::List::append( int64_t i ) +{ + Bu::List::append( new Gats::Integer( i ) ); +} + +void Gats::List::append( double d ) +{ + Bu::List::append( new Gats::Float( d ) ); +} + +void Gats::List::appendStr( const Bu::String &s ) +{ + Bu::List::append( new Gats::String( s ) ); +} + +void Gats::List::appendInt( int64_t i ) +{ + Bu::List::append( new Gats::Integer( i ) ); +} + +void Gats::List::appendFloat( double d ) +{ + Bu::List::append( new Gats::Float( d ) ); +} + +void Gats::List::appendBool( bool b ) +{ + Bu::List::append( new Gats::Boolean( b ) ); +} + +void Gats::List::appendList( Gats::List *pL ) +{ + Bu::List::append( pL ); +} + +void Gats::List::appendDict( Gats::Dictionary *pD ) +{ + Bu::List::append( pD ); +} + +Gats::List *Gats::List::appendList() +{ + Gats::List *pLst = new Gats::List(); + appendList( pLst ); + return pLst; +} + +Gats::Dictionary *Gats::List::appendDict() +{ + Gats::Dictionary *pDict = new Gats::Dictionary(); + appendDict( pDict ); + return pDict; +} + +void Gats::List::prepend( const char *s ) +{ + Bu::List::prepend( new Gats::String( s ) ); +} + +void Gats::List::prepend( const Bu::String &s ) +{ + Bu::List::prepend( new Gats::String( s ) ); +} + +void Gats::List::prepend( int32_t i ) +{ + Bu::List::prepend( new Gats::Integer( i ) ); +} + +void Gats::List::prepend( int64_t i ) +{ + Bu::List::prepend( new Gats::Integer( i ) ); +} + +void Gats::List::prepend( double d ) +{ + Bu::List::prepend( new Gats::Float( d ) ); +} + +void Gats::List::prependStr( const Bu::String &s ) +{ + Bu::List::prepend( new Gats::String( s ) ); +} + +void Gats::List::prependInt( int64_t i ) +{ + Bu::List::prepend( new Gats::Integer( i ) ); +} + +void Gats::List::prependFloat( double d ) +{ + Bu::List::prepend( new Gats::Float( d ) ); +} + +void Gats::List::prependBool( bool b ) +{ + Bu::List::prepend( new Gats::Boolean( b ) ); +} + +void Gats::List::prependList( Gats::List *pL ) +{ + Bu::List::prepend( pL ); +} + +void Gats::List::prependDict( Gats::Dictionary *pD ) +{ + Bu::List::prepend( pD ); +} + +Gats::List *Gats::List::prependList() +{ + Gats::List *pLst = new Gats::List(); + prependList( pLst ); + return pLst; +} + +Gats::Dictionary *Gats::List::prependDict() +{ + Gats::Dictionary *pDict = new Gats::Dictionary(); + prependDict( pDict ); + return pDict; +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::List &l ) +{ + f << "(list) ["; + f.incIndent(); + for( Gats::List::const_iterator i = l.begin(); i; i++ ) + { + f << f.nl << **i; + } + f.decIndent(); + f << f.nl << "]"; + return f; +} + diff --git a/c++-libbu++/src/list.h b/c++-libbu++/src/list.h new file mode 100644 index 0000000..5c1cd6e --- /dev/null +++ b/c++-libbu++/src/list.h @@ -0,0 +1,58 @@ +#ifndef GATS_LIST_H +#define GATS_LIST_H + +#include "gats/object.h" +#include +#include + +namespace Gats +{ + class Dictionary; + + class List : public Gats::Object, public Bu::List + { + public: + List(); + virtual ~List(); + + virtual Object *clone() const; + virtual Type getType() const { return typeList; } + + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + + void append( const char *s ); + void append( const Bu::String &s ); + void append( int32_t i ); + void append( int64_t i ); + void append( double d ); + using Bu::List::append; + void appendStr( const Bu::String &s ); + void appendInt( int64_t i ); + void appendFloat( double d ); + void appendBool( bool b ); + void appendList( Gats::List *pL ); + void appendDict( Gats::Dictionary *pD ); + Gats::List *appendList(); + Gats::Dictionary *appendDict(); + + void prepend( const char *s ); + void prepend( const Bu::String &s ); + void prepend( int32_t i ); + void prepend( int64_t i ); + void prepend( double d ); + using Bu::List::prepend; + void prependStr( const Bu::String &s ); + void prependInt( int64_t i ); + void prependFloat( double d ); + void prependBool( bool b ); + void prependList( Gats::List *pL ); + void prependDict( Gats::Dictionary *pD ); + Gats::List *prependList(); + Gats::Dictionary *prependDict(); + }; +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::List &l ); + +#endif diff --git a/c++-libbu++/src/null.cpp b/c++-libbu++/src/null.cpp new file mode 100644 index 0000000..13a61ed --- /dev/null +++ b/c++-libbu++/src/null.cpp @@ -0,0 +1,33 @@ +#include "gats/null.h" + +#include +#include + +Gats::Null::Null() +{ +} + +Gats::Null::~Null() +{ +} + +Gats::Object *Gats::Null::clone() const +{ + return new Gats::Null(); +} + +void Gats::Null::write( Bu::Stream &rOut ) const +{ + rOut.write("n", 1 ); +} + +void Gats::Null::read( Bu::Stream &rIn, char cType ) +{ + // Nothing to do... +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Null &b ) +{ + return f << "(null)"; +} + diff --git a/c++-libbu++/src/null.h b/c++-libbu++/src/null.h new file mode 100644 index 0000000..afa2d0a --- /dev/null +++ b/c++-libbu++/src/null.h @@ -0,0 +1,24 @@ +#ifndef GATS_NULL_H +#define GATS_NULL_H + +#include "gats/object.h" + +namespace Gats +{ + class Null : public Gats::Object + { + public: + Null(); + virtual ~Null(); + + virtual Type getType() const { return typeNull; } + virtual Object *clone() const; + + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + }; +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Null &b ); + +#endif diff --git a/c++-libbu++/src/object.cpp b/c++-libbu++/src/object.cpp new file mode 100644 index 0000000..15d7cb5 --- /dev/null +++ b/c++-libbu++/src/object.cpp @@ -0,0 +1,339 @@ +#include "gats/object.h" + +#include "gats/integer.h" +#include "gats/float.h" +#include "gats/boolean.h" +#include "gats/string.h" +#include "gats/list.h" +#include "gats/dictionary.h" +#include "gats/null.h" + +#include + +#include +#include + +#include +using namespace Bu; + +Gats::Object::Object() +{ +} + +Gats::Object::~Object() +{ +} + +Gats::Object *Gats::Object::read( Bu::Stream &rIn ) +{ + char buf; + rIn.read( &buf, 1 ); + Object *pObj = NULL; + switch( buf ) + { + case 'i': + pObj = new Gats::Integer(); + break; + + case 's': + pObj = new Gats::String(); + break; + + case '0': + case '1': + pObj = new Gats::Boolean(); + break; + + case 'l': + pObj = new Gats::List(); + break; + + case 'd': + pObj = new Gats::Dictionary(); + break; + + case 'f': // Normal floats + case 'F': // Special float values + pObj = new Gats::Float(); + break; + + case 'n': + pObj = new Gats::Null(); + break; + + case 'e': + return NULL; + + default: + throw Bu::ExceptionBase("Invalid Gats type discovered: %c.", buf ); + } + + pObj->read( rIn, buf ); + + return pObj; +} + +void Gats::Object::skipWs( Bu::String::const_iterator &i ) +{ + for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { } +} + +Bu::String Gats::Object::token( Bu::String::const_iterator &i ) +{ + Bu::String sRet; + if( *i == '\"' ) + { + for( i++; i && *i != '\"' ; i++ ) + { + if( *i == '\\' ) + i++; + sRet += i; + } + i++; + } + else + { + for(; i && *i != ' ' && *i != '\t' && *i != '\r' && *i != '\n' && + *i != ',' && *i != ']' && *i != '}' && *i != '[' && + *i != '{'; i++ ) + { + sRet += i; + } + } + + return sRet; +} + +Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) +{ + skipWs( i ); + + switch( *i ) + { + case '[': + { + Gats::List *pLst = new Gats::List(); + i++; + for(;;) + { + skipWs( i ); + if( *i == ']' ) + { + i++; + return pLst; + } + Gats::Object *pObj = strToGats( i ); + if( !pObj ) + break; + pLst->append( pObj ); + skipWs( i ); + switch( *i ) + { + case ',': + i++; + break; + + case ']': + i++; + return pLst; + + default: + throw Bu::ExceptionBase("Invalid character found."); + } + } + } + break; + + case '{': + { + Gats::Dictionary *pDict = new Gats::Dictionary(); + i++; + for(;;) + { + skipWs( i ); + if( *i == '}' ) + { + i++; + return pDict; + } + if( *i != '\"' ) + throw Bu::ExceptionBase("Keys must be quoted strings."); + Bu::String sKey = token( i ); + skipWs( i ); + if( *i != ':' ) + throw Bu::ExceptionBase("Keys and values must be " + "seperated with colons."); + i++; + Gats::Object *pObj = strToGats( i ); + if( !pObj ) + throw Bu::ExceptionBase("No value object found."); + pDict->insert( sKey, pObj ); + skipWs( i ); + switch( *i ) + { + case ',': + i++; + break; + + case '}': + i++; + return pDict; + + default: + throw Bu::ExceptionBase("Invalid character found."); + } + } + } + break; + + case '\"': + return new Gats::String( token( i ) ); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + case '+': + case '-': + { + Bu::String s = token( i ); + int iSize = s.getSize(); + if( s[iSize-1] == 'i' ) + { + return new Gats::Integer( + strtoll( s.getStr(), NULL, 10 ) + ); + } + else if( s[iSize-1] == 'f' ) + { + return new Gats::Float( + strtod( s.getStr(), NULL ) + ); + } + else + { + for( Bu::String::iterator i = s.begin(); i; i++ ) + { + if( *i == '.' ) + return new Gats::Float( + strtod( s.getStr(), NULL ) + ); + } + return new Gats::Integer( + strtoll( s.getStr(), NULL, 10 ) + ); + } + } + break; + + default: + { + Bu::String s = token( i ); + int iSize = s.getSize(); + // Test for explicit types first + if( iSize > 2 ) + { + if( (s[0] >= '0' && s[0] <= '9') || s[0] == '+' || s[0] == '-' ) + { + } + else + { + Bu::String st = s.toLower(); + if( st == "true" ) + { + return new Gats::Boolean( true ); + } + else if( st == "false" ) + { + return new Gats::Boolean( false ); + } + else if( st == "null" ) + { + return new Gats::Null(); + } + } + } + } + break; + } + + return NULL; +} + +Gats::Object *Gats::Object::strToGats( const Bu::String &sStr ) +{ + Bu::String::const_iterator i = sStr.begin(); + + return strToGats( i ); +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Object &obj ) +{ + switch( obj.getType() ) + { + case Gats::typeDictionary: + return f << dynamic_cast(obj); + + case Gats::typeList: + return f << dynamic_cast(obj); + + case Gats::typeString: + return f << dynamic_cast(obj); + + case Gats::typeInteger: + return f << dynamic_cast(obj); + + case Gats::typeFloat: + return f << dynamic_cast(obj); + + case Gats::typeBoolean: + return f << dynamic_cast(obj); + + case Gats::typeNull: + return f << dynamic_cast(obj); + + default: + return f << "***ERROR: Bad Gats type***"; + } +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Type &t ) +{ + switch( t ) + { + case Gats::typeDictionary: return f << "dictionary"; + case Gats::typeList: return f << "list"; + case Gats::typeString: return f << "string"; + case Gats::typeInteger: return f << "integer"; + case Gats::typeFloat: return f << "float"; + case Gats::typeBoolean: return f << "boolean"; + case Gats::typeNull: return f << "null"; + } + + return f << "***unknown***"; +} + +const char *Gats::typeToStr( Gats::Type t ) +{ + switch( t ) + { + case Gats::typeDictionary: return "dictionary"; + case Gats::typeList: return "list"; + case Gats::typeString: return "string"; + case Gats::typeInteger: return "integer"; + case Gats::typeFloat: return "float"; + case Gats::typeBoolean: return "boolean"; + case Gats::typeNull: return "null"; + } + + return "***unknown***"; +} + diff --git a/c++-libbu++/src/object.h b/c++-libbu++/src/object.h new file mode 100644 index 0000000..2724189 --- /dev/null +++ b/c++-libbu++/src/object.h @@ -0,0 +1,55 @@ +#ifndef GATS_OBJECT_H +#define GATS_OBJECT_H + +#include + +namespace Bu +{ + class Stream; + class Formatter; +}; + +namespace Gats +{ + enum Type + { + typeDictionary, + typeList, + typeString, + typeInteger, + typeFloat, + typeBoolean, + typeNull + }; + + /** + * The baseclass for every type that can be stored in a packet. + */ + class Object + { + public: + Object(); + virtual ~Object(); + + virtual Type getType() const =0; + + virtual void write( Bu::Stream &rOut ) const=0; + virtual void read( Bu::Stream &rIn, char cType )=0; + virtual Object *clone() const=0; + + static Object *read( Bu::Stream &rIn ); + static Object *strToGats( const Bu::String &sStr ); + + private: + static Object *strToGats( Bu::String::const_iterator &i ); + static Bu::String token( Bu::String::const_iterator &i ); + static void skipWs( Bu::String::const_iterator &i ); + }; + + const char *typeToStr( Type t ); +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Object &obj ); +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Type &t ); + +#endif diff --git a/c++-libbu++/src/protocolgats.cpp b/c++-libbu++/src/protocolgats.cpp new file mode 100644 index 0000000..827eb65 --- /dev/null +++ b/c++-libbu++/src/protocolgats.cpp @@ -0,0 +1,56 @@ +#include "gats/protocolgats.h" +#include "gats/gatsstream.h" + +#include + +#include +using namespace Bu; + +Gats::ProtocolGats::ProtocolGats() : + pStream( NULL ), + pUsedClient( NULL ) +{ +} + +Gats::ProtocolGats::~ProtocolGats() +{ + delete pStream; + pStream = NULL; +} + +void Gats::ProtocolGats::onNewConnection( Bu::Client *pClient ) +{ + if( pStream == NULL ) + { + pStream = new Gats::GatsStream( *pClient ); + pUsedClient = pClient; + } +} + +void Gats::ProtocolGats::onNewData( Bu::Client *pClient ) +{ + if( pStream == NULL ) + { + pStream = new Gats::GatsStream( *pClient ); + pUsedClient = pClient; + } + else if( pClient != pUsedClient ) + { + throw Bu::ExceptionBase("ProtocolGats requires that you maintain a " + "1:1 relationship between client and protocol objects."); + } + + for(;;) + { + Gats::Object *pObj = pStream->readObject(); + if( pObj == NULL ) + break; + onNewObject( pClient, pObj ); + } +} + +void Gats::ProtocolGats::writeObject( Gats::Object *pObj ) +{ + pStream->writeObject( pObj ); +} + diff --git a/c++-libbu++/src/protocolgats.h b/c++-libbu++/src/protocolgats.h new file mode 100644 index 0000000..7ed58d4 --- /dev/null +++ b/c++-libbu++/src/protocolgats.h @@ -0,0 +1,30 @@ +#ifndef GATS_PROTOCOL_GATS_H +#define GATS_PROTOCOL_GATS_H + +#include + +namespace Gats +{ + class Object; + class GatsStream; + + class ProtocolGats : public Bu::Protocol + { + public: + ProtocolGats(); + virtual ~ProtocolGats(); + + virtual void onNewConnection( Bu::Client *pClient ); + virtual void onNewData( Bu::Client *pClient ); + + virtual void onNewObject( Bu::Client *pClient, Gats::Object *pObj )=0; + + void writeObject( Gats::Object *pObj ); + + private: + Gats::GatsStream *pStream; + Bu::Client *pUsedClient; + }; +}; + +#endif diff --git a/c++-libbu++/src/string.cpp b/c++-libbu++/src/string.cpp new file mode 100644 index 0000000..de66d5d --- /dev/null +++ b/c++-libbu++/src/string.cpp @@ -0,0 +1,70 @@ +#include "gats/string.h" + +#include "gats/integer.h" + +#include + +Gats::String::String() +{ +} + +Gats::String::String( const char *s ) : + Bu::String( s ) +{ +} + +Gats::String::String( const char *s, long iLength ) : + Bu::String( s, iLength ) +{ +} + +Gats::String::String( long iLength ) : + Bu::String( iLength ) +{ +} + +Gats::String::String( const String &s ) : + Bu::String( s ) +{ +} + +Gats::String::String( const Bu::String &s ) : + Bu::String( s ) +{ +} + +Gats::String::~String() +{ +} + +Gats::Object *Gats::String::clone() const +{ + return new Gats::String( Bu::String::clone() ); +} + +void Gats::String::write( Bu::Stream &rOut ) const +{ + rOut.write("s", 1 ); + uint32_t iSize = getSize(); + Gats::Integer::writePackedInt( rOut, iSize ); + rOut.write( getStr(), iSize ); +} + +void Gats::String::read( Bu::Stream &rIn, char cType ) +{ + uint32_t iSize; + Gats::Integer::readPackedInt( rIn, iSize ); + setSize( iSize ); + rIn.read( getStr(), iSize ); +} + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::String &s ) +{ + for( Gats::String::const_iterator i = s.begin(); i; i++ ) + { + if( *i >= 127 || *i <= 31 ) + return f << "(binary str) " << s.getSize() << " bytes"; + } + return f << "(str) \"" << dynamic_cast(s) << "\""; +} + diff --git a/c++-libbu++/src/string.h b/c++-libbu++/src/string.h new file mode 100644 index 0000000..de8eedd --- /dev/null +++ b/c++-libbu++/src/string.h @@ -0,0 +1,32 @@ +#ifndef GATS_STRING_H +#define GATS_STRING_H + +#include "gats/object.h" +#include + +namespace Gats +{ + class String : public Gats::Object, public Bu::String + { + public: + String(); + String( const char *s ); + String( const char *s, long iLength ); + String( long iLength ); + String( const String &s ); + String( const Bu::String &s ); + virtual ~String(); + + virtual Object *clone() const; + virtual Type getType() const { return typeString; } + + virtual void write( Bu::Stream &rOut ) const; + virtual void read( Bu::Stream &rIn, char cType ); + + private: + }; +}; + +Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::String &s ); + +#endif diff --git a/c++-libbu++/src/tests/clone.cpp b/c++-libbu++/src/tests/clone.cpp new file mode 100644 index 0000000..8533376 --- /dev/null +++ b/c++-libbu++/src/tests/clone.cpp @@ -0,0 +1,22 @@ +#include "gats/types.h" + +#include + +using namespace Bu; + +int main( int argc, char *argv[] ) +{ + Gats::Object *pBase = Gats::Object::strToGats("{\"Thing\": 3.14159, \"bool\": true, \"list\":[\"string\",44,{\"Stuff\":{\"list\":[],\"what?\":false}}]}"); + + sio << *pBase << sio.nl; + + Gats::Object *pNew = pBase->clone(); + delete pBase; + + sio << *pNew << sio.nl; + + delete pNew; + + return 0; +} + diff --git a/c++-libbu++/src/tests/dump.cpp b/c++-libbu++/src/tests/dump.cpp new file mode 100644 index 0000000..e0dcb52 --- /dev/null +++ b/c++-libbu++/src/tests/dump.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +using namespace Bu; + +int main( int argc, char *argv[] ) +{ + File fIn( argv[1], File::Read ); + Gats::GatsStream gsIn( fIn ); + + for(;;) + { + sio << "Reading from file position: " << fIn.tell() << sio.nl; + Gats::Object *pObj = gsIn.readObject(); + if( !pObj ) + { + if( gsIn.hasReadBuffer() ) + { + sio << "Premature end of stream detected, have " + << gsIn.getReadBufferSize() << "b." << sio.nl; + } + return 0; + } + + sio << *pObj << sio.nl; + } +} + diff --git a/c++-libbu++/src/tests/int.cpp b/c++-libbu++/src/tests/int.cpp new file mode 100644 index 0000000..c19df9c --- /dev/null +++ b/c++-libbu++/src/tests/int.cpp @@ -0,0 +1,47 @@ +#include "gats/integer.h" + +#include +#include +#include + +using namespace Bu; + +void hexdump( char *dat, int iSize ) +{ + static const char *hex="0123456789ABCDEF"; + printf("----\n"); + for( int j = 0; j < iSize; j += 8 ) + { + for( int k = j; /*k < iSize &&*/ k < j+8; k++ ) + printf((k>4)&0x0F], hex[dat[k]&0x0F] ); + printf("| "); + for( int k = j; k < iSize && k < j+8; k++ ) + printf("%c ", (dat[k]>13&&dat[k]<127)?(dat[k]):('.') ); + printf("\n"); + } + printf("----\n"); +} + +int main( int argc, char *argv[] ) +{ + for( int j = 1; j < argc; j++ ) + { + int64_t i = strtoll( argv[j], NULL, 10 ); + MemBuf mb; + Gats::Integer::writePackedInt( mb, i ); + hexdump( mb.getString().getStr(), mb.getString().getSize() ); + } +/* + sio << "Before: " << i << sio.nl; + Gats::Integer::writePackedInt( mb, i ); + mb.write("aaa", 3 ); + mb.setPos( 0 ); + Gats::Integer::readPackedInt( mb, i ); + sio << "After: " << i << sio.nl; + char buf[4]; + buf[mb.read( buf, 3 )] = '\0'; + sio << "Extra: \"" << buf << "\"" << sio.nl; +*/ + return 0; +} + diff --git a/c++-libbu++/src/types.h b/c++-libbu++/src/types.h new file mode 100644 index 0000000..81240e8 --- /dev/null +++ b/c++-libbu++/src/types.h @@ -0,0 +1,8 @@ +#include "gats/object.h" +#include "gats/boolean.h" +#include "gats/dictionary.h" +#include "gats/float.h" +#include "gats/integer.h" +#include "gats/list.h" +#include "gats/string.h" +#include "gats/null.h" diff --git a/c++-libbu++/src/unit/basic.unit b/c++-libbu++/src/unit/basic.unit new file mode 100644 index 0000000..2c2c31a --- /dev/null +++ b/c++-libbu++/src/unit/basic.unit @@ -0,0 +1,191 @@ +// vim: syntax=cpp +/* + * Copyright (C) 2007-2010 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "gats/dictionary.h" +#include "gats/integer.h" +#include "gats/float.h" +#include "gats/list.h" +#include "gats/boolean.h" +#include "gats/string.h" +#include "gats/null.h" +#include "gats/gatsstream.h" + +#include "bu/membuf.h" +#include "bu/list.h" +#include "bu/sio.h" + +#include +#include + +using namespace Bu; + +suite Basic +{ + test integer + { + Bu::List lInts; + Bu::MemBuf mb; + + int64_t i = 1; + for( int x = 0; x < 256; x++ ) + { + lInts.append( i ); + Gats::Integer( i ).write( mb ); + i = -(i<<1)-i; + } + + mb.setPos( 0 ); + + for( Bu::List::iterator j = lInts.begin(); j; j++ ) + { + Gats::Object *pObj = Gats::Object::read( mb ); + if( pObj->getType() != Gats::typeInteger ) + unitFailed("Bad type read."); + + if( dynamic_cast(pObj)->getValue() != *j ) + unitFailed("Bad number."); + } + } + + test string + { + Bu::List lStrs; + Bu::MemBuf mb; + + lStrs.append( Bu::String() ); + Gats::String("").write( mb ); + + { + int iMax = 0; + for( int j = 1; j <= (1<<16); j=j<<1 ) + iMax += j; + setStepCount( iMax ); + } + for( int j = 1; j <= (1<<16); j=j<<1 ) + { + Bu::String s( j ); + for( int x = 0; x < j; x++ ) + { + s[x] = (unsigned char)(random()%256); + } + incProgress( j ); + Gats::String( s ).write( mb ); + lStrs.append( s ); + } + + mb.setPos( 0 ); + + for( Bu::List::iterator i = lStrs.begin(); i; i++ ) + { + Gats::Object *pObj = Gats::Object::read( mb ); + if( pObj->getType() != Gats::typeString ) + unitFailed("Bad type read."); + + if( *dynamic_cast(pObj) != *i ) + unitFailed("Bad string."); + } + } + + test boolean + { + Bu::List lBs; + Bu::MemBuf mb; + + for( int j = 0; j < 1024; j++ ) + { + if( random()%2 == 0 ) + { + lBs.append( true ); + Gats::Boolean( true ).write( mb ); + } + else + { + lBs.append( false ); + Gats::Boolean( false ).write( mb ); + } + } + + mb.setPos( 0 ); + + for( Bu::List::iterator i = lBs.begin(); i; i++ ) + { + Gats::Object *pObj = Gats::Object::read( mb ); + if( pObj->getType() != Gats::typeBoolean ) + unitFailed("Bad type read."); + + if( dynamic_cast(pObj)->getValue() != *i ) + unitFailed("Bad string."); + } + } + + test floats + { + Bu::MemBuf mb; + + Gats::Float( M_PI ).write( mb ); + + mb.setPos( 0 ); + + Gats::Object *pObj = Gats::Object::read( mb ); + unitTest( pObj != NULL ); + unitTest( pObj->getType() == Gats::typeFloat ); + Gats::Float *pFlt = dynamic_cast(pObj); + // sio << "old = " << M_PI << ", new = " << pFlt->getValue() << sio.nl; + unitTest( pFlt->getValue() == M_PI ); + + delete pObj; + } + + test dictionary + { + MemBuf mb; + + { + Gats::Dictionary dict; + dict.insert("bool", new Gats::Boolean(true) ); + dict.insert("int", 33403055 ); + dict.insert("str", "Hey there" ); + dict.write( mb ); + } + + mb.setPos( 0 ); + + { + Gats::Object *pRead = Gats::Object::read( mb ); + unitTest( pRead != NULL ); + Gats::Dictionary *pDict = dynamic_cast(pRead); + unitTest( pDict != NULL ); + + unitTest( pDict->getBool("bool") == true ); + unitTest( pDict->getInt("int") == 33403055 ); + unitTest( pDict->getStr("str") == "Hey there" ); + unitTest( pDict->getSize() == 3 ); + + delete pDict; + } + } + + test null + { + MemBuf mb; + { + Gats::Null n; + Gats::GatsStream gs( mb ); + gs.writeObject( &n ); + } + + mb.setPos( 0 ); + + { + Gats::GatsStream gs( mb ); + Gats::Object *pObj = gs.readObject(); + unitTest( pObj->getType() == Gats::typeNull ); + delete pObj; + } + } +} diff --git a/c++-libbu++/src/unit/float.unit b/c++-libbu++/src/unit/float.unit new file mode 100644 index 0000000..b1eb063 --- /dev/null +++ b/c++-libbu++/src/unit/float.unit @@ -0,0 +1,84 @@ +// vim: syntax=cpp +/* + * Copyright (C) 2007-2010 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "gats/dictionary.h" +#include "gats/float.h" +#include "gats/string.h" + +#include "bu/membuf.h" +#include "bu/list.h" +#include "bu/sio.h" + +#include +#include + +using namespace Bu; + +suite Basic +{ + void rw( double dVal ) + { + Bu::MemBuf mb; + + Gats::Float( dVal ).write( mb ); + + mb.setPos( 0 ); + + Gats::Object *pObj = Gats::Object::read( mb ); + unitTest( pObj != NULL ); + unitTest( pObj->getType() == Gats::typeFloat ); + Gats::Float *pFlt = dynamic_cast(pObj); + Bu::String sHex; + for( Bu::String::iterator i = mb.getString().begin(); i; i++ ) + { + sHex += "0123456789abcdef"[(((uint8_t)*i)>>4)&0x0f]; + sHex += "0123456789abcdef"[(*i)&0x0f]; + sHex += ' '; + } + printf("In: %a\nOut: %a\nRaw: %s\n", dVal, pFlt->getValue(), sHex.getStr() ); + if( isnan( dVal ) ) + unitTest( isnan(pFlt->getValue()) == isnan(dVal) ); + else + unitTest( pFlt->getValue() == dVal ); + unitTest( signbit(pFlt->getValue()) == signbit(dVal) ); + + delete pObj; + } + + test positive + { + rw( 8485738457.0 ); + rw( 63723.0 ); + rw( 0.000000000000001928173 ); + rw( 1.0 ); + rw( 0.0 ); + rw( M_PI ); + } + + test negitave + { + rw( -8485738457.0 ); + rw( -63723.0 ); + rw( -0.000000000000001928173 ); + rw( -1.0 ); + rw( -0.0 ); + rw( -M_PI ); + } + + test inf + { + rw( INFINITY ); + rw( -INFINITY ); + } + + test nan + { + rw( NAN ); + rw( -NAN ); + } +} diff --git a/c++-libbu++/src/unit/io.unit b/c++-libbu++/src/unit/io.unit new file mode 100644 index 0000000..1a9747f --- /dev/null +++ b/c++-libbu++/src/unit/io.unit @@ -0,0 +1,128 @@ +// vim: syntax=cpp +/* + * Copyright (C) 2007-2010 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "gats/dictionary.h" +#include "gats/integer.h" +#include "gats/float.h" +#include "gats/list.h" +#include "gats/boolean.h" +#include "gats/string.h" +#include "gats/gatsstream.h" + +#include "bu/membuf.h" +#include "bu/list.h" +#include "bu/sio.h" + +#include + +using namespace Bu; + +suite Basic +{ + test basic + { + Bu::String sTmpFileName("temp-XXXXXXXXX"); + Bu::File fIo = tempFile( sTmpFileName ); + + { + Gats::Dictionary dTest; + dTest.insert("age", 27 ); + dTest.insert("firstName", "Mike"); + dTest.insert("lastName", "Buland"); + dTest.insert("awake", true ); + + Gats::GatsStream sGats( fIo ); + sGats.writeObject( &dTest ); + } + + fIo.setPos( 0 ); + + { + Gats::GatsStream sGats( fIo ); + Gats::Object *pObj = sGats.readObject(); + unitTest( pObj != NULL ); + unitTest( pObj->getType() == Gats::typeDictionary ); + Gats::Dictionary *pDic = dynamic_cast(pObj); + unitTest( pDic->getSize() == 4 ); + unitTest( pDic->getInt("age") == 27 ); + unitTest( pDic->getStr("firstName") == "Mike" ); + unitTest( pDic->getStr("lastName") == "Buland" ); + unitTest( pDic->getBool("awake") == true ); + + delete pDic; + } + } + + test spacers + { + Bu::String sTmpFileName("temp-XXXXXXXXX"); + Bu::File fIo = tempFile( sTmpFileName ); + + { + Gats::GatsStream sGats( fIo ); + Gats::Integer i( -157 ); + sGats.writeObject( &i ); + fIo.write( "\x00\x00\x00", 3 ); + Gats::String s("negative one hundred and fifty seven"); + sGats.writeObject( &s ); + } + + fIo.setPos( 0 ); + + { + Gats::GatsStream sGats( fIo ); + Gats::Object *pObj1 = sGats.readObject(); + unitTest( pObj1 != NULL ); + unitTest( pObj1->getType() == Gats::typeInteger ); + unitTest( dynamic_cast(pObj1)->getValue() == -157 ); + + Gats::Object *pObj2 = sGats.readObject(); + unitTest( pObj2 != NULL ); + unitTest( pObj2->getType() == Gats::typeString ); + unitTest( *dynamic_cast(pObj2) == + "negative one hundred and fifty seven" ); + + delete pObj1; + delete pObj2; + } + } + + test biggerSpacers + { + Bu::String sTmpFileName("temp-XXXXXXXXX"); + Bu::File fIo = tempFile( sTmpFileName ); + + { + Gats::GatsStream sGats( fIo ); + Gats::Integer i( -157 ); + sGats.writeObject( &i ); + fIo.write( "\x00\x00\x00\x00\x00\x00\x00\x00\x00", 9 ); + Gats::String s("negative one hundred and fifty seven"); + sGats.writeObject( &s ); + } + + fIo.setPos( 0 ); + + { + Gats::GatsStream sGats( fIo ); + Gats::Object *pObj1 = sGats.readObject(); + unitTest( pObj1 != NULL ); + unitTest( pObj1->getType() == Gats::typeInteger ); + unitTest( dynamic_cast(pObj1)->getValue() == -157 ); + + Gats::Object *pObj2 = sGats.readObject(); + unitTest( pObj2 != NULL ); + unitTest( pObj2->getType() == Gats::typeString ); + unitTest( *dynamic_cast(pObj2) == + "negative one hundred and fifty seven" ); + + delete pObj1; + delete pObj2; + } + } +} -- cgit v1.2.3