#include "JSON.h" using namespace Framework; using namespace JSON; JSONValue::JSONValue() { this->type = NULL_; } JSONValue::JSONValue( JSONType type ) { this->type = type; } JSONType JSONValue::getType() const { return type; } Text JSONValue::toString() const { return Text( "null" ); } JSONBool::JSONBool( bool b ) : JSONValue( BOOLEAN ) { this->b = b; } bool JSONBool::getBool() const { return b; } Text JSONBool::toString() const { if( b ) return Text( "true" ); else return Text( "false" ); } JSONNumber::JSONNumber( double num ) : JSONValue( NUMBER ) { number = num; } double JSONNumber::getNumber() const { return number; } Text JSONNumber::toString() const { return Text( number ); } JSONString::JSONString( Text string ) : JSONValue( STRING ) { this->string = string; } Text JSONString::getString() const { return string; } Text JSONString::toString() const { return Text( Text( "\"" ) += string.getText() ) += "\""; } JSONArray::JSONArray() : JSONValue( ARRAY ) { array = new Array< JSONValue >(); } JSONArray::JSONArray( Text string ) : JSONValue( ARRAY ) { array = new Array< JSONValue >(); string = Parser::removeWhitespace( string ); if( string.getText()[ 0 ] == '[' && string.getText()[ string.getLength() - 1 ] == ']' ) { string.remove( 0, 1 ); string.remove( string.getLength() - 1, string.getLength() ); while( string.getLength() ) { int end = Parser::findObjectEndInArray( string ); Text *objStr = string.getTeilText( 0, end ); string.remove( 0, end + 1 ); array->add( Parser::getValue( *objStr ) ); objStr->release(); } } } JSONArray::JSONArray( const JSONArray &arr ) : JSONValue( ARRAY ) { array = arr.array->getThis(); } JSONArray::~JSONArray() { array->release(); } JSONArray &JSONArray::operator=( const JSONArray &arr ) { array->release(); array = arr.array->getThis(); return *this; } void JSONArray::addValue( JSONValue value ) { array->add( value ); } JSONValue JSONArray::getValue( int i ) const { return array->get( i ); } int JSONArray::getLength() const { return array->getEintragAnzahl(); } Text JSONArray::toString() const { Text str = "["; for( auto i = array->getIterator(); i; i++ ) { str += i._.toString(); if( i.hasNext() ) str += ","; } str += "]"; return str; } JSONObject::JSONObject() : JSONValue( OBJECT ) { fields = new Array< Text >(); values = new Array< JSONValue >(); } JSONObject::JSONObject( Text string ) : JSONValue( OBJECT ) { fields = new Array< Text >(); values = new Array< JSONValue >(); string = Parser::removeWhitespace( string ); if( string.getText()[ 0 ] == '{' && string.getText()[ string.getLength() - 1 ] == '}' ) { string.remove( 0, 1 ); string.remove( string.getLength() - 1, string.getLength() ); while( string.getLength() ) { int endField = Parser::findFieldEndInObject( string ); Text *fieldName = string.getTeilText( 0, endField ); string.remove( 0, endField + 1 ); fieldName->remove( 0, 1 ); fieldName->remove( fieldName->getLength() - 1, fieldName->getLength() ); int endValue = Parser::findValueEndInObject( string ); Text *value = string.getTeilText( 0, endValue ); string.remove( 0, endValue + 1 ); fields->add( Text( fieldName->getText() ) ); values->add( Parser::getValue( *value ) ); fieldName->release(); value->release(); } } } JSONObject::JSONObject( const JSONObject &obj ) : JSONValue( OBJECT ) { fields = obj.fields->getThis(); values = obj.values->getThis(); } JSONObject::~JSONObject() { fields->release(); values->release(); } JSONObject &JSONObject::operator=( const JSONObject &obj ) { fields->release(); values->release(); fields = obj.fields->getThis(); values = obj.values->getThis(); return *this; } bool JSONObject::addValue( Text field, JSONValue value ) { if( hasValue( field ) ) return 0; fields->add( field ); values->add( value ); return 1; } bool JSONObject::removeValue( Text field ) { for( int i = 0; i < fields->getEintragAnzahl(); i++ ) { if( fields->get( i ).istGleich( field ) ) { fields->remove( i ); values->remove( i ); return 1; } } return 0; } bool JSONObject::hasValue( Text field ) { for( int i = 0; i < fields->getEintragAnzahl(); i++ ) { if( fields->get( i ).istGleich( field ) ) return 1; } return 0; } JSONValue JSONObject::getValue( Text field ) { for( int i = 0; i < fields->getEintragAnzahl(); i++ ) { if( fields->get( i ).istGleich( field ) ) return values->get( i ); } return JSONValue(); } Iterator< Text > JSONObject::getFields() { return fields->getIterator(); } Iterator< JSONValue > JSONObject::getValues() { return values->getIterator(); } Text JSONObject::toString() const { Text str = "{"; Iterator< Text > k = fields->getIterator(); for( auto v = values->getIterator(); k && v; k++, v++ ) { str += "\""; str += k._.getText(); str += "\":"; str += v._.toString().getText(); if( v.hasNext() ) str += ","; } str += "}"; return str; } int Parser::findObjectEndInArray( const char *str ) { return findValueEndInObject( str ); } Text Parser::removeWhitespace( const char *str ) { int wsc = 0; int i = 0; bool esc = 0; bool strO = 0; for( ; str[ i ]; i++ ) { switch( str[ i ] ) { case '\\': if( strO ) esc = !esc; else esc = 0; break; case '"': if( !esc ) strO = !strO; esc = 0; break; case ' ': case '\n': case '\t': case '\r': if( !strO ) wsc++; esc = 0; break; default: esc = 0; break; } } Text ret; ret.fillText( ' ', i - wsc ); i = 0; esc = 0; strO = 0; int index = 0; for( ; str[ i ]; i++ ) { switch( str[ i ] ) { case '\\': if( strO ) esc = !esc; else esc = 0; ret.getText()[ index++ ] = str[ i ]; break; case '"': if( !esc ) strO = !strO; esc = 0; ret.getText()[ index++ ] = str[ i ]; break; case ' ': case '\n': case '\t': case '\r': esc = 0; break; default: ret.getText()[ index++ ] = str[ i ]; esc = 0; break; } } return ret; } JSONValue Parser::getValue( const char *str ) { Text string = Parser::removeWhitespace( str ); if( string.istGleich( "true" ) ) return JSONBool( 1 ); if( string.istGleich( "false" ) ) return JSONBool( 0 ); if( string.getText()[ 0 ] == '"' ) { string.remove( 0, 1 ); string.remove( string.getLength() - 1, string.getLength() ); return JSONString( string ); } if( string.getText()[ 0 ] == '[' ) return JSONArray( string ); if( string.getText()[ 0 ] == '{' ) return JSONObject( string ); if( Text( (double)string ).istGleich( string.getText() ) ) return JSONNumber( string ); return JSONValue(); } int Parser::findFieldEndInObject( const char *str ) { int i = 0; bool esc = 0; bool strO = 0; int objOc = 0; int arrayOc = 0; for( ; str[ i ]; i++ ) { switch( str[ i ] ) { case '\\': if( strO ) esc = !esc; else esc = 0; break; case '"': if( !esc ) strO = !strO; esc = 0; break; case '[': if( !strO ) arrayOc++; esc = 0; break; case ']': if( !strO ) arrayOc--; esc = 0; break; case '{': if( !strO ) objOc++; esc = 0; break; case '}': if( !strO ) objOc--; esc = 0; break; case ':': if( !strO && objOc == 0 && arrayOc == 0 ) return i; esc = 0; break; default: esc = 0; break; } } return i; } int Parser::findValueEndInObject( const char *str ) { int i = 0; bool esc = 0; bool strO = 0; int objOc = 0; int arrayOc = 0; for( ; str[ i ]; i++ ) { switch( str[ i ] ) { case '\\': if( strO ) esc = !esc; else esc = 0; break; case '"': if( !esc ) strO = !strO; esc = 0; break; case '[': if( !strO ) arrayOc++; esc = 0; break; case ']': if( !strO ) arrayOc--; esc = 0; break; case '{': if( !strO ) objOc++; esc = 0; break; case '}': if( !strO ) objOc--; esc = 0; break; case ',': if( !strO && objOc == 0 && arrayOc == 0 ) return i; esc = 0; break; default: esc = 0; break; } } return i; }