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/object.cpp | 339 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 c++-libbu++/src/object.cpp (limited to 'c++-libbu++/src/object.cpp') 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***"; +} + -- cgit v1.2.3