|
@@ -0,0 +1,490 @@
|
|
|
|
+#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( 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;
|
|
|
|
+}
|