Browse Source

JSON parser hinzugefügt

kolja 5 years ago
parent
commit
50d75c291b
6 changed files with 632 additions and 0 deletions
  1. 2 0
      Framework Linux.vcxproj
  2. 6 0
      Framework Linux.vcxproj.filters
  3. 2 0
      Framework.vcxproj
  4. 6 0
      Framework.vcxproj.filters
  5. 490 0
      JSON.cpp
  6. 126 0
      JSON.h

+ 2 - 0
Framework Linux.vcxproj

@@ -119,6 +119,7 @@
     <ClCompile Include="Fortschritt.cpp" />
     <ClCompile Include="Global.cpp" />
     <ClCompile Include="InitDatei.cpp" />
+    <ClCompile Include="JSON.cpp" />
     <ClCompile Include="Kamera2D.cpp" />
     <ClCompile Include="Key.cpp" />
     <ClCompile Include="Knopf.cpp" />
@@ -176,6 +177,7 @@
     <ClInclude Include="FrameworkMath.h" />
     <ClInclude Include="Globals.h" />
     <ClInclude Include="InitDatei.h" />
+    <ClInclude Include="JSON.h" />
     <ClInclude Include="Kamera2D.h" />
     <ClInclude Include="Key.h" />
     <ClInclude Include="Knopf.h" />

+ 6 - 0
Framework Linux.vcxproj.filters

@@ -261,6 +261,9 @@
     <ClInclude Include="Rect2.h">
       <Filter>Headerdateien\Framework\Grafik\2D</Filter>
     </ClInclude>
+    <ClInclude Include="JSON.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Prozess.cpp">
@@ -413,5 +416,8 @@
     <ClCompile Include="Kamera2D.cpp">
       <Filter>Quelldateien\Framework\Objekte2D</Filter>
     </ClCompile>
+    <ClCompile Include="JSON.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2 - 0
Framework.vcxproj

@@ -218,6 +218,7 @@ copy "x64\Release\Framework.dll" "..\..\Spiele Platform\SMP\Fertig\x64\framework
     <ClInclude Include="FrameworkMath.h" />
     <ClInclude Include="Globals.h" />
     <ClInclude Include="InitDatei.h" />
+    <ClInclude Include="JSON.h" />
     <ClInclude Include="Kam3D.h" />
     <ClInclude Include="Kamera2D.h" />
     <ClInclude Include="Knopf.h" />
@@ -287,6 +288,7 @@ copy "x64\Release\Framework.dll" "..\..\Spiele Platform\SMP\Fertig\x64\framework
     <ClCompile Include="Fortschritt.cpp" />
     <ClCompile Include="Global.cpp" />
     <ClCompile Include="InitDatei.cpp" />
+    <ClCompile Include="JSON.cpp" />
     <ClCompile Include="Kam3D.cpp" />
     <ClCompile Include="Kamera2D.cpp" />
     <ClCompile Include="Knopf.cpp" />

+ 6 - 0
Framework.vcxproj.filters

@@ -285,6 +285,9 @@
     <ClInclude Include="Rect2.h">
       <Filter>Headerdateien\Framework\Grafik\2D</Filter>
     </ClInclude>
+    <ClInclude Include="JSON.h">
+      <Filter>Headerdateien\Framework</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Maus.cpp">
@@ -455,5 +458,8 @@
     <ClCompile Include="Welt2D.cpp">
       <Filter>Quelldateien\Framework\Grafik\2D</Filter>
     </ClCompile>
+    <ClCompile Include="JSON.cpp">
+      <Filter>Quelldateien\Framework</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 490 - 0
JSON.cpp

@@ -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;
+}

+ 126 - 0
JSON.h

@@ -0,0 +1,126 @@
+#pragma once
+
+#include "Text.h"
+#include "Array.h"
+
+namespace Framework
+{
+    namespace JSON
+    {
+        enum JSONType
+        {
+            NULL_,
+            BOOLEAN,
+            NUMBER,
+            STRING,
+            ARRAY,
+            OBJECT
+        };
+
+        class JSONArray;
+        class JSONObject;
+
+        class JSONValue
+        {
+        private:
+            JSONType type;
+
+        protected:
+            JSONValue( JSONType type );
+
+        public:
+            JSONValue();
+            JSONType getType() const;
+            virtual Text toString() const;
+        };
+
+        class JSONBool : public JSONValue
+        {
+        private:
+            bool b;
+
+        public: 
+            JSONBool( bool b );
+
+            bool getBool() const;
+            Text toString() const override;
+        };
+
+        class JSONNumber : public JSONValue
+        {
+        private:
+            double number;
+
+        public:
+            JSONNumber( double num );
+
+            double getNumber() const;
+            Text toString() const override;
+        };
+
+        class JSONString : public JSONValue
+        {
+        private:
+            Text string;
+
+        public:
+            JSONString( Text string );
+
+            Text getString() const;
+            Text toString() const override;
+        };
+
+        class JSONArray : public JSONValue
+        {
+        private:
+            Array< JSONValue > *array;
+
+        public:
+            JSONArray();
+            JSONArray( Text string );
+            JSONArray( const JSONArray &arr );
+            ~JSONArray();
+
+            JSONArray &operator=( const JSONArray &arr );
+
+            void addValue( JSONValue value );
+            JSONValue getValue( int i ) const;
+            int getLength() const;
+
+            Text toString() const override;
+        };
+
+        class JSONObject : public JSONValue
+        {
+        private:
+            Array< Text > *fields;
+            Array< JSONValue > *values;
+
+        public:
+            JSONObject();
+            JSONObject( Text string );
+            JSONObject( const JSONObject &obj );
+            ~JSONObject();
+
+            JSONObject &operator=( const JSONObject &obj );
+
+            bool addValue( Text field, JSONValue value );
+            bool removeValue( Text field );
+            bool hasValue( Text field );
+            JSONValue getValue( Text field );
+            Iterator< Text > getFields();
+            Iterator< JSONValue > getValues();
+
+            Text toString() const override;
+        };
+
+        namespace Parser
+        {
+            int findObjectEndInArray( const char *str );
+            Text removeWhitespace( const char *str );
+            JSONValue getValue( const char *str );
+            int findFieldEndInObject( const char *str );
+            int findValueEndInObject( const char *str );
+        };
+    }
+}