Browse Source

add usefull JSON parsing methods

Kolja Strohm 2 years ago
parent
commit
5c9018e0eb
8 changed files with 982 additions and 768 deletions
  1. 22 22
      DX12PixelShader.h
  2. 18 18
      DX12VertexShader.h
  3. BIN
      Framework Tests/Framwork.dll
  4. 276 168
      Framework Tests/Json.cpp
  5. 423 403
      JSON.cpp
  6. 210 124
      JSON.h
  7. 19 19
      UIPixelShader.h
  8. 14 14
      UIVertexShader.h

+ 22 - 22
DX12PixelShader.h

@@ -92,10 +92,10 @@ ret
 
 const BYTE DX12PixelShaderBytes[] =
 {
-     68,  88,  66,  67,  43, 143, 
-    103, 203,  52, 109,  44, 247, 
-     85,  59, 253, 111,  96,  69, 
-    202,  69,   1,   0,   0,   0, 
+     68,  88,  66,  67,  45, 240, 
+     40, 192,  58,  36, 164, 115, 
+    240,  63,  98, 190, 172,  93, 
+     98, 164,   1,   0,   0,   0, 
     184,  91,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      36,   2,   0,   0, 188,   2, 
@@ -763,11 +763,11 @@ const BYTE DX12PixelShaderBytes[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0, 148,  46, 
-     49,   1, 106, 171,   7,  98, 
-      1,   0,   0,   0, 244, 199, 
-    241, 140, 163,  64, 165,  77, 
-    143,  33, 238,  36, 249,  16, 
-     93, 159,   0,   0,   0,   0, 
+     49,   1, 229, 111,  72,  98, 
+      1,   0,   0,   0,  95, 185, 
+    137, 251,  87,   1,  66,  66, 
+    156,  18, 237, 181, 102, 228, 
+    237, 103,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -938,10 +938,10 @@ const BYTE DX12PixelShaderBytes[] =
       3,   0, 242,  56,   1,   0, 
      43, 236,   3,   0,  28,  19, 
       2,   0,  65,  36,   1,   0, 
-    236, 179,   1,   0,  34,  36, 
-      0,   0, 125,  10,   2,   0, 
-    125, 181,   2,   0, 111,  77, 
-      2,   0, 193,  33,   3,   0, 
+    236, 179,   1,   0,  51, 246, 
+      1,   0, 125,  10,   2,   0, 
+    125, 181,   2,   0,  45,  24, 
+      0,   0, 193,  33,   3,   0, 
      65, 185,   2,   0, 140, 239, 
       1,   0, 246,  49,   0,   0, 
     213, 255,   0,   0,  46, 248, 
@@ -1788,7 +1788,7 @@ const BYTE DX12PixelShaderBytes[] =
     117, 114, 101,  50,  68,  32, 
     115, 104,  97, 100,  27, 226, 
      48,   1, 128,   0,   0,   0, 
-     16, 155, 222,  30,  14,  32, 
+    191, 183,  31, 219, 168,  70, 
     216,   1,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2348,14 +2348,14 @@ const BYTE DX12PixelShaderBytes[] =
       0,   0,  23,   0,   1,   0, 
       5,  16,   0,   0,  14,   0, 
      23,  21,   0,  16,   0,   0, 
-      3,   2, 240, 142,   0,   0, 
+      3,   2,  64, 119,   0,   0, 
     242, 241,  10,   0,  24,  21, 
       8,  16,   0,   0,   1,   0, 
       1,   0,  10,   0,  24,  21, 
       9,  16,   0,   0,   1,   0, 
       0,   2,  14,   0,  23,  21, 
       0,   0,   0,   0,  10,   2, 
-    240, 142,   0,   0, 242, 241, 
+     64, 119,   0,   0, 242, 241, 
      10,   0,  24,  21,  11,  16, 
       0,   0,   1,   0,   1,   0, 
      10,   0,  24,  21,  12,  16, 
@@ -3408,11 +3408,11 @@ const BYTE DX12PixelShaderBytes[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-    148,  46,  49,   1, 106, 171, 
-      7,  98,   1,   0,   0,   0, 
-    244, 199, 241, 140, 163,  64, 
-    165,  77, 143,  33, 238,  36, 
-    249,  16,  93, 159, 128,   0, 
+    148,  46,  49,   1, 229, 111, 
+     72,  98,   1,   0,   0,   0, 
+     95, 185, 137, 251,  87,   1, 
+     66,  66, 156,  18, 237, 181, 
+    102, 228, 237, 103, 128,   0, 
       0,   0,  47,  76, 105, 110, 
     107,  73, 110, 102, 111,   0, 
      47, 110,  97, 109, 101, 115, 
@@ -3512,7 +3512,7 @@ const BYTE DX12PixelShaderBytes[] =
       0,   0,   2,   0,   9,   0, 
     220,   4,   0,   0,   0,   0, 
       0,   0, 156,   1,   0,   0, 
-      1,   0,  59,   0,   0,   0, 
+      1,   0,  20,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0, 109,  97, 
     105, 110,   0, 110, 111, 110, 

+ 18 - 18
DX12VertexShader.h

@@ -129,10 +129,10 @@ ret
 
 const BYTE DX12VertexShaderBytes[] =
 {
-     68,  88,  66,  67, 215, 202, 
-     62,  43,   2, 109,  23,  38, 
-    193, 162,   5, 122, 171,  74, 
-     94,  37,   1,   0,   0,   0, 
+     68,  88,  66,  67, 234,  46, 
+     38, 164, 122,  45,  63, 125, 
+     89,  69, 239,  14, 233, 147, 
+     80,  31,   1,   0,   0,   0, 
     108,  78,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     124,   2,   0,   0,  16,   3, 
@@ -915,11 +915,11 @@ const BYTE DX12VertexShaderBytes[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-    148,  46,  49,   1, 107, 171, 
-      7,  98,   1,   0,   0,   0, 
-    210,  20, 218, 223, 110,  14, 
-     29,  76, 150, 174, 148,   9, 
-    113,   0, 193, 196,   0,   0, 
+    148,  46,  49,   1, 229, 111, 
+     72,  98,   1,   0,   0,   0, 
+    235, 249,  93, 241,  19, 173, 
+    199,  64, 180,  38,   1, 253, 
+     72, 162,   5, 172,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -1095,7 +1095,7 @@ const BYTE DX12VertexShaderBytes[] =
       0,   0, 103, 159,   1,   0, 
     179, 120,   1,   0, 238,  97, 
       2,   0,  90,  28,   0,   0, 
-     61,  29,   0,   0,  53, 174, 
+     48, 242,   2,   0,  53, 174, 
       3,   0, 206,  21,   0,   0, 
     193, 205,   3,   0, 207, 193, 
       1,   0,  62,   3,   3,   0, 
@@ -1684,8 +1684,8 @@ const BYTE DX12VertexShaderBytes[] =
     112, 111, 115, 105, 116, 105, 
     111, 110,  32, 111, 102,  32, 
      27, 226,  48,   1, 128,   0, 
-      0,   0,  77,  87,  18,  31, 
-     14,  32, 216,   1,   1,   0, 
+      0,   0, 213, 223,  85, 219, 
+    168,  70, 216,   1,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2200,7 +2200,7 @@ const BYTE DX12VertexShaderBytes[] =
      12,  16,   0,   0,   1,   0, 
       1,   0,  14,   0,  23,  21, 
      13,  16,   0,   0,  36,   2, 
-    176,  49,   0,   0, 242, 241, 
+    128, 208,   0,   0, 242, 241, 
      10,   0,  24,  21,  14,  16, 
       0,   0,   1,   0,   0,   2, 
      18,   0,  22,  21,  10,  16, 
@@ -3134,11 +3134,11 @@ const BYTE DX12VertexShaderBytes[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0, 148,  46, 
-     49,   1, 107, 171,   7,  98, 
-      1,   0,   0,   0, 210,  20, 
-    218, 223, 110,  14,  29,  76, 
-    150, 174, 148,   9, 113,   0, 
-    193, 196, 129,   0,   0,   0, 
+     49,   1, 229, 111,  72,  98, 
+      1,   0,   0,   0, 235, 249, 
+     93, 241,  19, 173, 199,  64, 
+    180,  38,   1, 253,  72, 162, 
+      5, 172, 129,   0,   0,   0, 
      47,  76, 105, 110, 107,  73, 
     110, 102, 111,   0,  47, 110, 
      97, 109, 101, 115,   0,  47, 

BIN
Framework Tests/Framwork.dll


+ 276 - 168
Framework Tests/Json.cpp

@@ -6,172 +6,280 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
 
 namespace FrameworkTests
 {
-    TEST_CLASS( JSONParserTests )
-    {
-    public:
-        TEST_METHOD( NullTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "null" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('null') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NULL_, L"Framework::JSON::Parser::getValue('null') should return a json null value" );
-            value->release();
-        }
-
-        TEST_METHOD( BooleanTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "false" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('false') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('false') should return a boolean" );
-            Assert::IsTrue( ((Framework::JSON::JSONBool*)value)->getBool() == false, L"Framework::JSON::Parser::getValue('false') should return a boolean with value false" );
-            value->release();
-
-            value = Framework::JSON::Parser::getValue( "true" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('true') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('true') should return a boolean" );
-            Assert::IsTrue( ((Framework::JSON::JSONBool*)value)->getBool() == true, L"Framework::JSON::Parser::getValue('true') should return a boolean with value true" );
-            value->release();
-        }
-
-        TEST_METHOD( StringTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "\"test\"" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('\"test\"') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"test\"') should return a string" );
-            Assert::IsTrue( ((Framework::JSON::JSONString*)value)->getString().istGleich( "test" ), L"Framework::JSON::Parser::getValue('\"test\"') should return a string with value 'test'" );
-            value->release();
-
-            value = Framework::JSON::Parser::getValue( "\"\"" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('\"\"') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"\"') should return a string" );
-            Assert::IsTrue( ((Framework::JSON::JSONString*)value)->getString().istGleich( "" ), L"Framework::JSON::Parser::getValue('\"\"') should return a string with value ''" );
-            value->release();
-        }
-
-        TEST_METHOD( NumberTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "0" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('0') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('0') should return a number" );
-            Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == 0.0, L"Framework::JSON::Parser::getValue('0') should return a number with value '0'" );
-            value->release();
-
-            value = Framework::JSON::Parser::getValue( "1.5" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('1.5') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('1.5') should return a number" );
-            Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == 1.5, L"Framework::JSON::Parser::getValue('1.5') should return a number with value '1.5'" );
-            value->release();
-
-            value = Framework::JSON::Parser::getValue( "-1.5" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('-1.5') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-1.5') should return a number" );
-            Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == -1.5, L"Framework::JSON::Parser::getValue('-1.5') should return a number with value '-1.5'" );
-            value->release();
-
-            value = Framework::JSON::Parser::getValue( "-5.0" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('-5.0') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-5.0') should return a number" );
-            Assert::IsTrue( ((Framework::JSON::JSONNumber*)value)->getNumber() == -5.0, L"Framework::JSON::Parser::getValue('-5.0') should return a number with value '-5.0'" );
-            value->release();
-        }
-
-        TEST_METHOD( ArrayTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "[]" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('[]') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[]') should return an array" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->getLength() == 0, L"Framework::JSON::Parser::getValue('[]') should return an array with length 0" );
-            value->release();
-
-            value = Framework::JSON::Parser::getValue( "  \t[ \r\n\tnull   , \r\n\t  1,true , \"\"  ] " );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should return an array" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->getLength() == 4, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should return an array with length 4" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 0, Framework::JSON::JSONType::NULL_ ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain null at index 0" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 1, Framework::JSON::JSONType::NUMBER ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a number at index 1" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 2, Framework::JSON::JSONType::BOOLEAN ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a boolean at index 2" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 3, Framework::JSON::JSONType::STRING ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a boolean at index 3" );
-            value->release();
-        }
-
-        TEST_METHOD( MultipleArrayTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "[[1],2,[[]]]" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should return an array" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->getLength() == 3, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should return an array with length 3" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 0, Framework::JSON::JSONType::ARRAY ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain an array at index 0" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 1, Framework::JSON::JSONType::NUMBER ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a number at index 1" );
-            Assert::IsTrue( ((Framework::JSON::JSONArray*)value)->isValueOfType( 2, Framework::JSON::JSONType::ARRAY ), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain an array at index 2" );
-            value->release();
-        }
-
-        TEST_METHOD( ObjectTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "{\" \": []}" );
-            Assert::IsTrue( value != 0, L"Framework::JSON::Parser::getValue('{\"\": []}') should not return 0" );
-            Assert::IsTrue( value->getType() == Framework::JSON::JSONType::OBJECT, L"Framework::JSON::Parser::getValue('{\" \": []}') should return an object" );
-            Assert::IsTrue( ((Framework::JSON::JSONObject*)value)->getFieldCount() == 1, L"Framework::JSON::Parser::getValue('{\" \": []}') should return an object with one attribute" );
-            Assert::IsTrue( ((Framework::JSON::JSONObject*)value)->isValueOfType( " ", Framework::JSON::JSONType::ARRAY ), L"Framework::JSON::Parser::getValue('{\" \": []}') should contain an array at attribute ' '" );
-            value->release();
-        }
-
-        TEST_METHOD( ToStringTest )
-        {
-            Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue( "{\" \": [1, true, false, 0.0, {}], \"t\": null}" );
-            Framework::JSON::JSONValue* value2 = Framework::JSON::Parser::getValue( value->toString() );
-            Assert::IsTrue( isEqual( value, value2 ), L"Framework::JSON::Parser::getValue(value.toString()) should return a json value eqal to value" );
-            value->release();
-            value2->release();
-        }
-
-        bool isEqual( Framework::JSON::JSONValue* a, Framework::JSON::JSONValue* b )
-        {
-            if( a->getType() != b->getType() ) return 0;
-            switch( a->getType() )
-            {
-            case Framework::JSON::JSONType::NUMBER:
-                return ((Framework::JSON::JSONNumber*)a)->getNumber() == ((Framework::JSON::JSONNumber*)b)->getNumber();
-            case Framework::JSON::JSONType::BOOLEAN:
-                return ((Framework::JSON::JSONBool*)a)->getBool() == ((Framework::JSON::JSONBool*)b)->getBool();
-            case Framework::JSON::JSONType::STRING:
-                return ((Framework::JSON::JSONString*)a)->getString().istGleich( ((Framework::JSON::JSONString*)b)->getString() );
-            case Framework::JSON::JSONType::ARRAY:
-            {
-                Framework::JSON::JSONArray* arrayA = (Framework::JSON::JSONArray*)a;
-                Framework::JSON::JSONArray* arrayB = (Framework::JSON::JSONArray*)b;
-                if( arrayA->getLength() != arrayB->getLength() ) return 0;
-                for( int i = 0; i < arrayA->getLength(); i++ )
-                {
-                    Framework::JSON::JSONValue* entryA = arrayA->getValue( i );
-                    Framework::JSON::JSONValue* entryB = arrayB->getValue( i );
-                    bool eq = isEqual( entryA, entryB );
-                    entryA->release();
-                    entryB->release();
-                    if( !eq ) return 0;
-                }
-                return 1;
-            }
-            case Framework::JSON::JSONType::OBJECT:
-            {
-                Framework::JSON::JSONObject* objA = (Framework::JSON::JSONObject*)a;
-                Framework::JSON::JSONObject* objB = (Framework::JSON::JSONObject*)b;
-                if( objA->getFieldCount() != objB->getFieldCount() ) return 0;
-                auto oaf = objA->getFields();
-                while( oaf )
-                {
-                    if( !objB->hasValue( oaf ) ) return 0;
-                    Framework::JSON::JSONValue* entryA = objA->getValue( oaf );
-                    Framework::JSON::JSONValue* entryB = objB->getValue( oaf );
-                    bool eq = isEqual( entryA, entryB );
-                    entryA->release();
-                    entryB->release();
-                    if( !eq ) return 0;
-                    oaf++;
-                }
-                return 1;
-            }
-            }
-            return 1;
-        }
-    };
+	TEST_CLASS(JSONParserTests)
+	{
+	public:
+		TEST_METHOD(NullTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("null");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('null') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NULL_, L"Framework::JSON::Parser::getValue('null') should return a json null value");
+			value->release();
+		}
+
+		TEST_METHOD(BooleanTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("false");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('false') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('false') should return a boolean");
+			Assert::IsTrue(((Framework::JSON::JSONBool*)value)->getBool() == false, L"Framework::JSON::Parser::getValue('false') should return a boolean with value false");
+			value->release();
+
+			value = Framework::JSON::Parser::getValue("true");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('true') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::BOOLEAN, L"Framework::JSON::Parser::getValue('true') should return a boolean");
+			Assert::IsTrue(((Framework::JSON::JSONBool*)value)->getBool() == true, L"Framework::JSON::Parser::getValue('true') should return a boolean with value true");
+			value->release();
+		}
+
+		TEST_METHOD(StringTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("\"test\"");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('\"test\"') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"test\"') should return a string");
+			Assert::IsTrue(((Framework::JSON::JSONString*)value)->getString().istGleich("test"), L"Framework::JSON::Parser::getValue('\"test\"') should return a string with value 'test'");
+			value->release();
+
+			value = Framework::JSON::Parser::getValue("\"\"");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('\"\"') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::STRING, L"Framework::JSON::Parser::getValue('\"\"') should return a string");
+			Assert::IsTrue(((Framework::JSON::JSONString*)value)->getString().istGleich(""), L"Framework::JSON::Parser::getValue('\"\"') should return a string with value ''");
+			value->release();
+		}
+
+		TEST_METHOD(NumberTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("0");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('0') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('0') should return a number");
+			Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == 0.0, L"Framework::JSON::Parser::getValue('0') should return a number with value '0'");
+			value->release();
+
+			value = Framework::JSON::Parser::getValue("1.5");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('1.5') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('1.5') should return a number");
+			Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == 1.5, L"Framework::JSON::Parser::getValue('1.5') should return a number with value '1.5'");
+			value->release();
+
+			value = Framework::JSON::Parser::getValue("-1.5");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('-1.5') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-1.5') should return a number");
+			Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == -1.5, L"Framework::JSON::Parser::getValue('-1.5') should return a number with value '-1.5'");
+			value->release();
+
+			value = Framework::JSON::Parser::getValue("-5.0");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('-5.0') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::NUMBER, L"Framework::JSON::Parser::getValue('-5.0') should return a number");
+			Assert::IsTrue(((Framework::JSON::JSONNumber*)value)->getNumber() == -5.0, L"Framework::JSON::Parser::getValue('-5.0') should return a number with value '-5.0'");
+			value->release();
+		}
+
+		TEST_METHOD(ArrayTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("[]");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[]') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[]') should return an array");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->getLength() == 0, L"Framework::JSON::Parser::getValue('[]') should return an array with length 0");
+			value->release();
+
+			value = Framework::JSON::Parser::getValue("  \t[ \r\n\tnull   , \r\n\t  1,true , \"\"  ] ");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should return an array");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->getLength() == 4, L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should return an array with length 4");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(0, Framework::JSON::JSONType::NULL_), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain null at index 0");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(1, Framework::JSON::JSONType::NUMBER), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a number at index 1");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(2, Framework::JSON::JSONType::BOOLEAN), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a boolean at index 2");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(3, Framework::JSON::JSONType::STRING), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a boolean at index 3");
+			value->release();
+		}
+
+		TEST_METHOD(MultipleArrayTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("[[1],2,[[]]]");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::ARRAY, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should return an array");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->getLength() == 3, L"Framework::JSON::Parser::getValue('[[1],2,[[]]]') should return an array with length 3");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(0, Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain an array at index 0");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(1, Framework::JSON::JSONType::NUMBER), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain a number at index 1");
+			Assert::IsTrue(((Framework::JSON::JSONArray*)value)->isValueOfType(2, Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('[null, 1, true, \"\"]') should contain an array at index 2");
+			value->release();
+		}
+
+		TEST_METHOD(ObjectTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("{\" \": []}");
+			Assert::IsTrue(value != 0, L"Framework::JSON::Parser::getValue('{\"\": []}') should not return 0");
+			Assert::IsTrue(value->getType() == Framework::JSON::JSONType::OBJECT, L"Framework::JSON::Parser::getValue('{\" \": []}') should return an object");
+			Assert::IsTrue(((Framework::JSON::JSONObject*)value)->getFieldCount() == 1, L"Framework::JSON::Parser::getValue('{\" \": []}') should return an object with one attribute");
+			Assert::IsTrue(((Framework::JSON::JSONObject*)value)->isValueOfType(" ", Framework::JSON::JSONType::ARRAY), L"Framework::JSON::Parser::getValue('{\" \": []}') should contain an array at attribute ' '");
+			value->release();
+		}
+
+		TEST_METHOD(ToStringTest)
+		{
+			Framework::JSON::JSONValue* value = Framework::JSON::Parser::getValue("{\" \": [1, true, false, 0.0, {}], \"t\": null}");
+			Framework::JSON::JSONValue* value2 = Framework::JSON::Parser::getValue(value->toString());
+			Assert::IsTrue(isEqual(value, value2), L"Framework::JSON::Parser::getValue(value.toString()) should return a json value eqal to value");
+			value->release();
+			value2->release();
+		}
+
+		bool isEqual(Framework::JSON::JSONValue* a, Framework::JSON::JSONValue* b)
+		{
+			if (a->getType() != b->getType()) return 0;
+			switch (a->getType())
+			{
+			case Framework::JSON::JSONType::NUMBER:
+				return ((Framework::JSON::JSONNumber*)a)->getNumber() == ((Framework::JSON::JSONNumber*)b)->getNumber();
+			case Framework::JSON::JSONType::BOOLEAN:
+				return ((Framework::JSON::JSONBool*)a)->getBool() == ((Framework::JSON::JSONBool*)b)->getBool();
+			case Framework::JSON::JSONType::STRING:
+				return ((Framework::JSON::JSONString*)a)->getString().istGleich(((Framework::JSON::JSONString*)b)->getString());
+			case Framework::JSON::JSONType::ARRAY:
+			{
+				Framework::JSON::JSONArray* arrayA = (Framework::JSON::JSONArray*)a;
+				Framework::JSON::JSONArray* arrayB = (Framework::JSON::JSONArray*)b;
+				if (arrayA->getLength() != arrayB->getLength()) return 0;
+				for (int i = 0; i < arrayA->getLength(); i++)
+				{
+					Framework::JSON::JSONValue* entryA = arrayA->getValue(i);
+					Framework::JSON::JSONValue* entryB = arrayB->getValue(i);
+					bool eq = isEqual(entryA, entryB);
+					entryA->release();
+					entryB->release();
+					if (!eq) return 0;
+				}
+				return 1;
+			}
+			case Framework::JSON::JSONType::OBJECT:
+			{
+				Framework::JSON::JSONObject* objA = (Framework::JSON::JSONObject*)a;
+				Framework::JSON::JSONObject* objB = (Framework::JSON::JSONObject*)b;
+				if (objA->getFieldCount() != objB->getFieldCount()) return 0;
+				auto oaf = objA->getFields();
+				while (oaf)
+				{
+					if (!objB->hasValue(oaf)) return 0;
+					Framework::JSON::JSONValue* entryA = objA->getValue(oaf);
+					Framework::JSON::JSONValue* entryB = objB->getValue(oaf);
+					bool eq = isEqual(entryA, entryB);
+					entryA->release();
+					entryB->release();
+					if (!eq) return 0;
+					oaf++;
+				}
+				return 1;
+			}
+			}
+			return 1;
+		}
+
+		TEST_METHOD(ToArrayTest)
+		{
+			Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue("[1,2,3,4,5,6,7,8,9,10]")->asArray();
+			Framework::Array<int>* numberArray = jArray->toArray<int>([](Framework::JSON::JSONValue& v)
+				{
+					return (int)v.asNumber()->getNumber();
+				});
+			Assert::IsTrue(numberArray->getEintragAnzahl() == 10, L"Array hat die falsche Anzahl an elementen");
+			Assert::IsTrue(numberArray->get(2) == 3, L"Array hat mindestens ein falsches element");
+			Assert::IsTrue(numberArray->get(7) == 8, L"Array hat mindestens ein falsches element");
+			numberArray->release();
+			numberArray = jArray->toArray<int>([](Framework::JSON::JSONValue& v)
+				{
+					return (int)v.asNumber()->getNumber() % 2 == 0;
+				}, [](Framework::JSON::JSONValue& v)
+				{
+					return (int)v.asNumber()->getNumber();
+				});
+			Assert::IsTrue(numberArray->get(0) == 2, L"Array hat mindestens ein falsches element");
+			Assert::IsTrue(numberArray->get(3) == 8, L"Array hat mindestens ein falsches element");
+			jArray->release();
+		}
+
+		TEST_METHOD(ToRCArrayTest)
+		{
+			Framework::JSON::JSONArray* jArray = Framework::JSON::Parser::getValue("[\"1\",\"2\",\"3\",\"4\",\"5\"]")->asArray();
+			Framework::RCArray<Framework::Text>* numberArray = jArray->toRCArray<Framework::Text>([](Framework::JSON::JSONValue& v)
+				{
+					return new Framework::Text(v.asString()->getString());
+				});
+			Assert::IsTrue(numberArray->getEintragAnzahl() == 5, L"Array hat die falsche Anzahl an elementen");
+			Assert::IsTrue(numberArray->z(1)->istGleich("2"), L"Array hat mindestens ein falsches element");
+			Assert::IsTrue(numberArray->z(4)->istGleich("5"), L"Array hat mindestens ein falsches element");
+			numberArray->release();
+			numberArray = jArray->toRCArray<Framework::Text>([](Framework::JSON::JSONValue& v)
+				{
+					return (int)v.asString()->getString() % 2 == 0;
+				}, [](Framework::JSON::JSONValue& v)
+				{
+					return new Framework::Text(v.asString()->getString());
+				});
+			Assert::IsTrue(numberArray->z(0)->istGleich("2"), L"Array hat mindestens ein falsches element");
+			Assert::IsTrue(numberArray->z(1)->istGleich("4"), L"Array hat mindestens ein falsches element");
+			jArray->release();
+		}
+
+		class TestObject
+		{
+		public:
+			Framework::Text name;
+			Framework::Text value;
+		};
+
+		TEST_METHOD(ParseObjectTest)
+		{
+			Framework::JSON::JSONObject* jObj = Framework::JSON::Parser::getValue("{\"name\": \"test\", \"value\": \"1234\"}")->asObject();
+			TestObject* obj = jObj->parseTo<TestObject>(new TestObject(), [](TestObject* obj, Framework::Text attrName, Framework::JSON::JSONValue& v)
+				{
+					if (attrName.istGleich("name"))
+					{
+						obj->name = v.asString()->getString();
+					}
+					else
+					{
+						obj->value = v.asString()->getString();
+					}
+				});
+			Assert::IsTrue(obj->name.istGleich("test"), L"Feld hat falschen wert");
+			Assert::IsTrue(obj->value.istGleich("1234"), L"Feld hat falschen wert");
+			delete obj;
+			jObj->release();
+		}
+
+		TEST_METHOD(FromArrayTest)
+		{
+			Framework::Array<int> arr;
+			arr.add(1);
+			arr.add(2);
+			arr.add(3);
+			arr.add(4);
+
+			Framework::JSON::JSONArray* jArray = Framework::JSON::JSONArray::fromArray<int>(arr, [](int v)
+				{
+					return new Framework::JSON::JSONNumber(v);
+				});
+			Assert::IsTrue(jArray->getLength() == 4, L"Array hat falsche länge");
+			Framework::JSON::JSONNumber* n = jArray->getValue(1)->asNumber();
+			Assert::IsTrue(n->getNumber() == 2, L"Array hat mindestens einen falschen Wert");
+			n->release();
+			jArray->release();
+
+			Framework::RCArray<Framework::Text> rcArr;
+			rcArr.add(new Framework::Text("1"));
+			rcArr.add(new Framework::Text("2"));
+			rcArr.add(new Framework::Text("3"));
+			rcArr.add(new Framework::Text("4"));
+
+			jArray = Framework::JSON::JSONArray::fromRCArray<Framework::Text>(rcArr, [](Framework::Text& v)
+				{
+					return new Framework::JSON::JSONString(v);
+				});
+			Assert::IsTrue(jArray->getLength() == 4, L"Array hat falsche länge");
+			Framework::JSON::JSONString* s = jArray->getValue(2)->asString();
+			Assert::IsTrue(s->getString().istGleich("3"), L"Array hat mindestens einen falschen Wert");
+			s->release();
+			jArray->release();
+		}
+	};
 }

+ 423 - 403
JSON.cpp

@@ -5,537 +5,557 @@ using namespace Framework;
 using namespace JSON;
 
 JSONValue::JSONValue()
-    : ReferenceCounter()
+	: ReferenceCounter()
 {
-    this->type = JSONType::NULL_;
+	this->type = JSONType::NULL_;
 }
 
 JSONValue::~JSONValue()
 {}
 
-JSONValue::JSONValue( JSONType type )
-    : ReferenceCounter()
+JSONValue::JSONValue(JSONType type)
+	: ReferenceCounter()
 {
-    this->type = type;
+	this->type = type;
 }
 
 JSONType JSONValue::getType() const
 {
-    return type;
+	return type;
 }
 
 Text JSONValue::toString() const
 {
-    return Text( "null" );
+	return Text("null");
+}
+
+JSONBool* JSONValue::asBool() const {
+	return (JSONBool*)this;
+}
+
+JSONNumber* JSONValue::asNumber() const {
+	return (JSONNumber*)this;
+}
+
+JSONString* JSONValue::asString() const {
+	return (JSONString*)this;
+}
+
+JSONArray* JSONValue::asArray() const {
+	return (JSONArray*)this;
+}
+
+JSONObject* JSONValue::asObject() const {
+	return (JSONObject*)this;
 }
 
 
-JSONBool::JSONBool( bool b )
-    : JSONValue( JSONType::BOOLEAN )
+JSONBool::JSONBool(bool b)
+	: JSONValue(JSONType::BOOLEAN)
 {
-    this->b = b;
+	this->b = b;
 }
 
 bool JSONBool::getBool() const
 {
-    return b;
+	return b;
 }
 
 Text JSONBool::toString() const
 {
-    if( b )
-        return Text( "true" );
-    else
-        return Text( "false" );
+	if (b)
+		return Text("true");
+	else
+		return Text("false");
 }
 
 
-JSONNumber::JSONNumber( double num )
-    : JSONValue( JSONType::NUMBER )
+JSONNumber::JSONNumber(double num)
+	: JSONValue(JSONType::NUMBER)
 {
-    number = num;
+	number = num;
 }
 
 double JSONNumber::getNumber() const
 {
-    return number;
+	return number;
 }
 
 Text JSONNumber::toString() const
 {
-    return Text( number );
+	return Text(number);
 }
 
 
-JSONString::JSONString( Text string )
-    : JSONValue( JSONType::STRING )
+JSONString::JSONString(Text string)
+	: JSONValue(JSONType::STRING)
 {
-    this->string = string;
+	this->string = string;
 }
 
 Text JSONString::getString() const
 {
-    return string;
+	return string;
 }
 
 Text JSONString::toString() const
 {
-    return Text( Text( "\"" ) += string.getText() ) += "\"";
+	return Text(Text("\"") += string.getText()) += "\"";
 }
 
 
 JSONArray::JSONArray()
-    : JSONValue( JSONType::ARRAY )
+	: JSONValue(JSONType::ARRAY)
 {
-    array = new RCArray< JSONValue >();
+	array = new RCArray< JSONValue >();
 }
 
-JSONArray::JSONArray( Text string )
-    : JSONValue( JSONType::ARRAY )
+JSONArray::JSONArray(Text string)
+	: JSONValue(JSONType::ARRAY)
 {
-    array = new RCArray< 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();
-        }
-    }
+	array = new RCArray< 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( JSONType::ARRAY )
+JSONArray::JSONArray(const JSONArray& arr)
+	: JSONValue(JSONType::ARRAY)
 {
-    array = dynamic_cast<RCArray<JSONValue> *>(arr.array->getThis());
+	array = dynamic_cast<RCArray<JSONValue> *>(arr.array->getThis());
 }
 
 JSONArray::~JSONArray()
 {
-    array->release();
+	array->release();
 }
 
-JSONArray& JSONArray::operator=( const JSONArray& arr )
+JSONArray& JSONArray::operator=(const JSONArray& arr)
 {
-    array->release();
-    array = dynamic_cast<RCArray<JSONValue> *>(arr.array->getThis());
-    return *this;
+	array->release();
+	array = dynamic_cast<RCArray<JSONValue> *>(arr.array->getThis());
+	return *this;
 }
 
-void JSONArray::addValue( JSONValue* value )
+void JSONArray::addValue(JSONValue* value)
 {
-    array->add( value );
+	array->add(value);
 }
 
-JSONValue* JSONArray::getValue( int i ) const
+JSONValue* JSONArray::getValue(int i) const
 {
-    return array->get( i );
+	return array->get(i);
 }
 
 int JSONArray::getLength() const
 {
-    return array->getEintragAnzahl();
+	return array->getEintragAnzahl();
 }
 
-bool JSONArray::isValueOfType( int i, JSONType type ) const
+bool JSONArray::isValueOfType(int i, JSONType type) const
 {
-    return i >= 0 && i < array->getEintragAnzahl() && array->z( i )->getType() == type;
+	return i >= 0 && i < array->getEintragAnzahl() && array->z(i)->getType() == type;
 }
 
 Text JSONArray::toString() const
 {
-    Text str = "[";
-    for( auto i = array->begin(); i; i++ )
-    {
-        str += i->toString();
-        if( i.hasNext() )
-            str += ",";
-    }
-    str += "]";
-    return str;
+	Text str = "[";
+	for (auto i = array->begin(); i; i++)
+	{
+		str += i->toString();
+		if (i.hasNext())
+			str += ",";
+	}
+	str += "]";
+	return str;
 }
 
 
 JSONObject::JSONObject()
-    : JSONValue( JSONType::OBJECT )
-{
-    fields = new Array< Text >();
-    values = new RCArray< JSONValue >();
-}
-
-JSONObject::JSONObject( Text string )
-    : JSONValue( JSONType::OBJECT )
-{
-    fields = new Array< Text >();
-    values = new RCArray< 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( JSONType::OBJECT )
-{
-    fields = dynamic_cast<Array<Text> *>(obj.fields->getThis());
-    values = dynamic_cast<RCArray<JSONValue> *>(obj.values->getThis());
+	: JSONValue(JSONType::OBJECT)
+{
+	fields = new Array< Text >();
+	values = new RCArray< JSONValue >();
+}
+
+JSONObject::JSONObject(Text string)
+	: JSONValue(JSONType::OBJECT)
+{
+	fields = new Array< Text >();
+	values = new RCArray< 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(JSONType::OBJECT)
+{
+	fields = dynamic_cast<Array<Text> *>(obj.fields->getThis());
+	values = dynamic_cast<RCArray<JSONValue> *>(obj.values->getThis());
 }
 
 JSONObject::~JSONObject()
 {
-    fields->release();
-    values->release();
+	fields->release();
+	values->release();
 }
 
 
-JSONObject& JSONObject::operator=( const JSONObject& obj )
+JSONObject& JSONObject::operator=(const JSONObject& obj)
 {
-    fields->release();
-    values->release();
-    fields = dynamic_cast<Array<Text> *>(obj.fields->getThis());
-    values = dynamic_cast<RCArray<JSONValue> *>(obj.values->getThis());
-    return *this;
+	fields->release();
+	values->release();
+	fields = dynamic_cast<Array<Text> *>(obj.fields->getThis());
+	values = dynamic_cast<RCArray<JSONValue> *>(obj.values->getThis());
+	return *this;
 }
 
 
-bool JSONObject::addValue( Text field, JSONValue* value )
+bool JSONObject::addValue(Text field, JSONValue* value)
 {
-    if( hasValue( field ) )
-        return 0;
-    fields->add( field );
-    values->add( value );
-    return 1;
+	if (hasValue(field))
+		return 0;
+	fields->add(field);
+	values->add(value);
+	return 1;
 }
 
-bool JSONObject::removeValue( Text field )
+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;
+	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 )
+bool JSONObject::hasValue(Text field)
 {
-    for( int i = 0; i < fields->getEintragAnzahl(); i++ )
-    {
-        if( fields->get( i ).istGleich( field ) )
-            return 1;
-    }
-    return 0;
+	for (int i = 0; i < fields->getEintragAnzahl(); i++)
+	{
+		if (fields->get(i).istGleich(field))
+			return 1;
+	}
+	return 0;
 }
 
-JSONValue* JSONObject::getValue( Text field )
+JSONValue* JSONObject::getValue(Text field)
 {
-    for( int i = 0; i < fields->getEintragAnzahl(); i++ )
-    {
-        if( fields->get( i ).istGleich( field ) )
-            return values->get( i );
-    }
-    return new JSONValue();
+	for (int i = 0; i < fields->getEintragAnzahl(); i++)
+	{
+		if (fields->get(i).istGleich(field))
+			return values->get(i);
+	}
+	return new JSONValue();
 }
 
 Iterator< Text > JSONObject::getFields()
 {
-    return fields->begin();
+	return fields->begin();
 }
 
 Iterator< JSONValue* > JSONObject::getValues()
 {
-    return values->begin();
+	return values->begin();
 }
 
 int JSONObject::getFieldCount() const
 {
-    return fields->getEintragAnzahl();
+	return fields->getEintragAnzahl();
 }
 
-bool JSONObject::isValueOfType( Text field, JSONType type ) const
+bool JSONObject::isValueOfType(Text field, JSONType type) const
 {
-    for( int i = 0; i < fields->getEintragAnzahl(); i++ )
-    {
-        if( fields->get( i ).istGleich( field ) )
-            return values->z( i )->getType() == type;
-    }
-    return 0;
+	for (int i = 0; i < fields->getEintragAnzahl(); i++)
+	{
+		if (fields->get(i).istGleich(field))
+			return values->z(i)->getType() == type;
+	}
+	return 0;
 }
 
 Text JSONObject::toString() const
 {
-    Text str = "{";
-    Iterator< Text > k = fields->begin();
-    for( auto v = values->begin(); k && v; k++, v++ )
-    {
-        str += "\"";
-        str += k._.getText();
-        str += "\":";
-        str += v->toString().getText();
-        if( v.hasNext() )
-            str += ",";
-    }
-    str += "}";
-    return str;
-}
-
-JSONValue* JSON::loadJSONFromFile( Text path )
-{
-    Datei d;
-    d.setDatei( path );
-    d.open( Datei::Style::lesen );
-    int size = (int)d.getSize();
-    char* buffer = new char[ size + 1 ];
-    buffer[ size ] = 0;
-    d.lese( buffer, size );
-    d.close();
-    JSONValue* result = Parser::getValue( buffer );
-    delete[] buffer;
-    return result;
-}
-
-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':
-            if( strO )
-                ret.getText()[ index++ ] = str[ i ];
-            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 new JSONBool( 1 );
-    if( string.istGleich( "false" ) )
-        return new JSONBool( 0 );
-    if( string.getText()[ 0 ] == '"' )
-    {
-        string.remove( 0, 1 );
-        string.remove( string.getLength() - 1, string.getLength() );
-        return new JSONString( string );
-    }
-    if( string.getText()[ 0 ] == '[' )
-        return new JSONArray( string );
-    if( string.getText()[ 0 ] == '{' )
-        return new JSONObject( string );
-    if( Text( (int)string ).istGleich( string.getText() ) )
-        return new JSONNumber( string );
-    if( string.anzahlVon( '.' ) == 1 )
-    {
-        bool isNumber = 1;
-        for( char* c = (*string.getText() == '-') ? string.getText() + 1 : string.getText(); *c; c++ )
-            isNumber &= (*c >= '0' && *c <= '9') || *c == '.';
-        if( isNumber )
-            return new JSONNumber( string );
-    }
-    return new 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;
+	Text str = "{";
+	Iterator< Text > k = fields->begin();
+	for (auto v = values->begin(); k && v; k++, v++)
+	{
+		str += "\"";
+		str += k._.getText();
+		str += "\":";
+		str += v->toString().getText();
+		if (v.hasNext())
+			str += ",";
+	}
+	str += "}";
+	return str;
+}
+
+JSONValue* JSON::loadJSONFromFile(Text path)
+{
+	Datei d;
+	d.setDatei(path);
+	d.open(Datei::Style::lesen);
+	int size = (int)d.getSize();
+	char* buffer = new char[size + 1];
+	buffer[size] = 0;
+	d.lese(buffer, size);
+	d.close();
+	JSONValue* result = Parser::getValue(buffer);
+	delete[] buffer;
+	return result;
+}
+
+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':
+			if (strO)
+				ret.getText()[index++] = str[i];
+			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 new JSONBool(1);
+	if (string.istGleich("false"))
+		return new JSONBool(0);
+	if (string.getText()[0] == '"')
+	{
+		string.remove(0, 1);
+		string.remove(string.getLength() - 1, string.getLength());
+		return new JSONString(string);
+	}
+	if (string.getText()[0] == '[')
+		return new JSONArray(string);
+	if (string.getText()[0] == '{')
+		return new JSONObject(string);
+	if (Text((int)string).istGleich(string.getText()))
+		return new JSONNumber(string);
+	if (string.anzahlVon('.') == 1)
+	{
+		bool isNumber = 1;
+		for (char* c = (*string.getText() == '-') ? string.getText() + 1 : string.getText(); *c; c++)
+			isNumber &= (*c >= '0' && *c <= '9') || *c == '.';
+		if (isNumber)
+			return new JSONNumber(string);
+	}
+	return new 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;
 }

+ 210 - 124
JSON.h

@@ -3,131 +3,217 @@
 #include "Text.h"
 #include "Array.h"
 #include "ReferenceCounter.h"
+#include <functional>
 
 namespace Framework
 {
-    namespace JSON
-    {
-        enum class JSONType
-        {
-            NULL_,
-            BOOLEAN,
-            NUMBER,
-            STRING,
-            ARRAY,
-            OBJECT
-        };
-
-        class JSONArray;
-        class JSONObject;
-
-        class JSONValue : public virtual ReferenceCounter
-        {
-        private:
-            JSONType type;
-
-        protected:
-            __declspec(dllexport) JSONValue( JSONType type );
-
-        public:
-            __declspec(dllexport) JSONValue();
-            __declspec(dllexport) virtual ~JSONValue();
-            __declspec(dllexport) JSONType getType() const;
-            __declspec(dllexport) virtual Text toString() const;
-        };
-
-        class JSONBool : public JSONValue
-        {
-        private:
-            bool b;
-
-        public:
-            __declspec(dllexport) JSONBool( bool b );
-
-            __declspec(dllexport) bool getBool() const;
-            __declspec(dllexport) Text toString() const override;
-        };
-
-        class JSONNumber : public JSONValue
-        {
-        private:
-            double number;
-
-        public:
-            __declspec(dllexport) JSONNumber( double num );
-
-            __declspec(dllexport) double getNumber() const;
-            __declspec(dllexport) Text toString() const override;
-        };
-
-        class JSONString : public JSONValue
-        {
-        private:
-            Text string;
-
-        public:
-            __declspec(dllexport) JSONString( Text string );
-
-            __declspec(dllexport) Text getString() const;
-            __declspec(dllexport) Text toString() const override;
-        };
-
-        class JSONArray : public JSONValue
-        {
-        private:
-            RCArray< JSONValue >* array;
-
-        public:
-            __declspec(dllexport) JSONArray();
-            __declspec(dllexport) JSONArray( Text string );
-            __declspec(dllexport) JSONArray( const JSONArray& arr );
-            __declspec(dllexport) ~JSONArray();
-
-            __declspec(dllexport) JSONArray& operator=( const JSONArray& arr );
-
-            __declspec(dllexport) void addValue( JSONValue* value );
-            __declspec(dllexport) JSONValue* getValue( int i ) const;
-            __declspec(dllexport) int getLength() const;
-            __declspec(dllexport) bool isValueOfType( int i, JSONType type ) const;
-
-            __declspec(dllexport) Text toString() const override;
-        };
-
-        class JSONObject : public JSONValue
-        {
-        private:
-            Array< Text >* fields;
-            RCArray< JSONValue >* values;
-
-        public:
-            __declspec(dllexport) JSONObject();
-            __declspec(dllexport) JSONObject( Text string );
-            __declspec(dllexport) JSONObject( const JSONObject& obj );
-            __declspec(dllexport) ~JSONObject();
-
-            __declspec(dllexport) JSONObject& operator=( const JSONObject& obj );
-
-            __declspec(dllexport) bool addValue( Text field, JSONValue* value );
-            __declspec(dllexport) bool removeValue( Text field );
-            __declspec(dllexport) bool hasValue( Text field );
-            __declspec(dllexport) JSONValue* getValue( Text field );
-            __declspec(dllexport) Iterator< Text > getFields();
-            __declspec(dllexport) Iterator< JSONValue* > getValues();
-            __declspec(dllexport) int getFieldCount() const;
-            __declspec(dllexport) bool isValueOfType( Text field, JSONType type ) const;
-
-            __declspec(dllexport) Text toString() const override;
-        };
-
-        __declspec(dllexport) JSONValue* loadJSONFromFile( Text path );
-
-        namespace Parser
-        {
-            __declspec(dllexport) int findObjectEndInArray( const char* str );
-            __declspec(dllexport) Text removeWhitespace( const char* str );
-            __declspec(dllexport) JSONValue* getValue( const char* str );
-            __declspec(dllexport) int findFieldEndInObject( const char* str );
-            __declspec(dllexport) int findValueEndInObject( const char* str );
-        };
-    }
+	namespace JSON
+	{
+		enum class JSONType
+		{
+			NULL_,
+			BOOLEAN,
+			NUMBER,
+			STRING,
+			ARRAY,
+			OBJECT
+		};
+
+		class JSONArray;
+		class JSONObject;
+		class JSONBool;
+		class JSONNumber;
+		class JSONString;
+
+		class JSONValue : public virtual ReferenceCounter
+		{
+		private:
+			JSONType type;
+
+		protected:
+			__declspec(dllexport) JSONValue(JSONType type);
+
+		public:
+			__declspec(dllexport) JSONValue();
+			__declspec(dllexport) virtual ~JSONValue();
+			__declspec(dllexport) JSONType getType() const;
+			__declspec(dllexport) virtual Text toString() const;
+			__declspec(dllexport) JSONBool* asBool() const;
+			__declspec(dllexport) JSONNumber* asNumber() const;
+			__declspec(dllexport) JSONString* asString() const;
+			__declspec(dllexport) JSONArray* asArray() const;
+			__declspec(dllexport) JSONObject* asObject() const;
+		};
+
+		class JSONBool : public JSONValue
+		{
+		private:
+			bool b;
+
+		public:
+			__declspec(dllexport) JSONBool(bool b);
+
+			__declspec(dllexport) bool getBool() const;
+			__declspec(dllexport) Text toString() const override;
+		};
+
+		class JSONNumber : public JSONValue
+		{
+		private:
+			double number;
+
+		public:
+			__declspec(dllexport) JSONNumber(double num);
+
+			__declspec(dllexport) double getNumber() const;
+			__declspec(dllexport) Text toString() const override;
+		};
+
+		class JSONString : public JSONValue
+		{
+		private:
+			Text string;
+
+		public:
+			__declspec(dllexport) JSONString(Text string);
+
+			__declspec(dllexport) Text getString() const;
+			__declspec(dllexport) Text toString() const override;
+		};
+
+		class JSONArray : public JSONValue
+		{
+		private:
+			RCArray< JSONValue >* array;
+
+		public:
+			__declspec(dllexport) JSONArray();
+			__declspec(dllexport) JSONArray(Text string);
+			__declspec(dllexport) JSONArray(const JSONArray& arr);
+			__declspec(dllexport) ~JSONArray();
+
+			__declspec(dllexport) JSONArray& operator=(const JSONArray& arr);
+
+			__declspec(dllexport) void addValue(JSONValue* value);
+			__declspec(dllexport) JSONValue* getValue(int i) const;
+			__declspec(dllexport) int getLength() const;
+			__declspec(dllexport) bool isValueOfType(int i, JSONType type) const;
+
+			template<class T>
+			RCArray<T>* toRCArray(std::function<T* (JSONValue&)> map) const
+			{
+				return toRCArray([](JSONValue& v) { return 1; }, map);
+			}
+
+			template<class T>
+			RCArray<T>* toRCArray(std::function<bool(JSONValue&)> filter, std::function<T* (JSONValue&)> map) const
+			{
+				RCArray<T>* result = new RCArray<T>();
+				for (auto v : *array)
+				{
+					if (filter(*v))
+					{
+						result->add(map(*v));
+					}
+				}
+				return result;
+			}
+
+			template<class T>
+			Array<T>* toArray(std::function<T(JSONValue&)> map) const
+			{
+				return toArray([](JSONValue& v) { return 1; }, map);;
+			}
+
+			template<class T>
+			Array<T>* toArray(std::function<bool(JSONValue&)> filter, std::function<T(JSONValue&)> map) const
+			{
+				Array<T>* result = new Array<T>();
+				for (auto v : *array)
+				{
+					if (filter(*v))
+					{
+						result->add(map(*v));
+					}
+				}
+				return result;
+			}
+
+			__declspec(dllexport) Text toString() const override;
+
+
+			template<class T>
+			static JSONArray* fromRCArray(Framework::RCArray<T>& arr, std::function<JSONValue* (T&)> map)
+			{
+				JSONArray* array = new JSONArray();
+				for (T* v : arr)
+				{
+					array->addValue(map(*v));
+				}
+				return array;
+			}
+
+			template<class T>
+			static JSONArray* fromArray(Framework::Array<T>& arr, std::function<JSONValue* (T)> map)
+			{
+				JSONArray* array = new JSONArray();
+				for (T v : arr)
+				{
+					array->addValue(map(v));
+				}
+				return array;
+			}
+		};
+
+		class JSONObject : public JSONValue
+		{
+		private:
+			Array< Text >* fields;
+			RCArray< JSONValue >* values;
+
+		public:
+			__declspec(dllexport) JSONObject();
+			__declspec(dllexport) JSONObject(Text string);
+			__declspec(dllexport) JSONObject(const JSONObject& obj);
+			__declspec(dllexport) ~JSONObject();
+
+			__declspec(dllexport) JSONObject& operator=(const JSONObject& obj);
+
+			__declspec(dllexport) bool addValue(Text field, JSONValue* value);
+			__declspec(dllexport) bool removeValue(Text field);
+			__declspec(dllexport) bool hasValue(Text field);
+			__declspec(dllexport) JSONValue* getValue(Text field);
+			__declspec(dllexport) Iterator< Text > getFields();
+			__declspec(dllexport) Iterator< JSONValue* > getValues();
+			__declspec(dllexport) int getFieldCount() const;
+			__declspec(dllexport) bool isValueOfType(Text field, JSONType type) const;
+
+			template<class T>
+			T* parseTo(T* initialState, std::function<void(T* obj, Text fieldName, JSONValue& fieldValue)> parser) const
+			{
+				auto fieldsI = fields->begin();
+				auto valuesI = values->begin();
+				while (fieldsI && valuesI)
+				{
+					parser(initialState, fieldsI, *(JSONValue*)valuesI);
+					fieldsI++;
+					valuesI++;
+				}
+				return initialState;
+			}
+
+			__declspec(dllexport) Text toString() const override;
+		};
+
+		__declspec(dllexport) JSONValue* loadJSONFromFile(Text path);
+
+		namespace Parser
+		{
+			__declspec(dllexport) int findObjectEndInArray(const char* str);
+			__declspec(dllexport) Text removeWhitespace(const char* str);
+			__declspec(dllexport) JSONValue* getValue(const char* str);
+			__declspec(dllexport) int findFieldEndInObject(const char* str);
+			__declspec(dllexport) int findValueEndInObject(const char* str);
+		};
+	}
 }

+ 19 - 19
UIPixelShader.h

@@ -353,10 +353,10 @@ ret
 
 const BYTE UIPixelShader[] =
 {
-     68,  88,  66,  67, 154, 228, 
-     74, 173, 190, 146, 135, 121, 
-    250, 198, 149,  73,  55, 174, 
-    145,  91,   1,   0,   0,   0, 
+     68,  88,  66,  67, 225, 236, 
+     18, 150,  68, 156, 132,  61, 
+     69, 155, 244,  69, 113, 208, 
+     58, 245,   1,   0,   0,   0, 
      64, 134,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     192,   6,   0,   0,  80,   7, 
@@ -1815,10 +1815,10 @@ const BYTE UIPixelShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0, 148,  46,  49,   1, 
-    107, 171,   7,  98,   1,   0, 
-      0,   0, 144, 131, 223, 190, 
-     72,  44, 107,  65, 180, 134, 
-    158, 227,  77, 110, 132,  27, 
+    229, 111,  72,  98,   1,   0, 
+      0,   0, 213, 124, 118, 103, 
+     38,  53, 238,  73, 150, 118, 
+    133,  18, 143, 135, 162,  55, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
@@ -1990,9 +1990,9 @@ const BYTE UIPixelShader[] =
     242,  56,   1,   0,  43, 236, 
       3,   0,  28,  19,   2,   0, 
      65,  36,   1,   0, 236, 179, 
-      1,   0,  34,  36,   0,   0, 
+      1,   0,  51, 246,   1,   0, 
     125,  10,   2,   0, 125, 181, 
-      2,   0, 111,  77,   2,   0, 
+      2,   0,  45,  24,   0,   0, 
     193,  33,   3,   0,  65, 185, 
       2,   0,   9, 241,   2,   0, 
     146, 230,   3,   0, 125, 218, 
@@ -3010,8 +3010,8 @@ const BYTE UIPixelShader[] =
     120, 116, 117, 114, 101,  50, 
      68,  32, 115, 104,  97, 100, 
      27, 226,  48,   1, 128,   0, 
-      0,   0, 215,  80,  58,  31, 
-     14,  32, 216,   1,   1,   0, 
+      0,   0,  66, 246, 122, 219, 
+    168,  70, 216,   1,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4253,14 +4253,14 @@ const BYTE UIPixelShader[] =
       0,   0,  23,   0,   1,   0, 
       5,  16,   0,   0,  14,   0, 
      23,  21,   0,  16,   0,   0, 
-      3,   2, 240, 142,   0,   0, 
+      3,   2,  64, 119,   0,   0, 
     242, 241,  10,   0,  24,  21, 
       8,  16,   0,   0,   1,   0, 
       1,   0,  10,   0,  24,  21, 
       9,  16,   0,   0,   1,   0, 
       0,   2,  14,   0,  23,  21, 
       0,   0,   0,   0,  10,   2, 
-    240, 142,   0,   0, 242, 241, 
+     64, 119,   0,   0, 242, 241, 
      10,   0,  24,  21,  11,  16, 
       0,   0,   1,   0,   1,   0, 
      10,   0,  24,  21,  12,  16, 
@@ -5484,11 +5484,11 @@ const BYTE UIPixelShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0, 148,  46, 
-     49,   1, 107, 171,   7,  98, 
-      1,   0,   0,   0, 144, 131, 
-    223, 190,  72,  44, 107,  65, 
-    180, 134, 158, 227,  77, 110, 
-    132,  27, 128,   0,   0,   0, 
+     49,   1, 229, 111,  72,  98, 
+      1,   0,   0,   0, 213, 124, 
+    118, 103,  38,  53, 238,  73, 
+    150, 118, 133,  18, 143, 135, 
+    162,  55, 128,   0,   0,   0, 
      47,  76, 105, 110, 107,  73, 
     110, 102, 111,   0,  47, 110, 
      97, 109, 101, 115,   0,  47, 

+ 14 - 14
UIVertexShader.h

@@ -119,10 +119,10 @@ ret
 
 const BYTE UIVertexShader[] =
 {
-     68,  88,  66,  67, 104, 219, 
-    160, 104, 172,  13, 174, 193, 
-    254, 105,  77, 121, 137,  26, 
-    219, 133,   1,   0,   0,   0, 
+     68,  88,  66,  67, 222,  77, 
+     76, 107,  92, 142, 145, 170, 
+    144,  72, 184, 211, 248, 219, 
+     19,  34,   1,   0,   0,   0, 
     168,  77,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      20,   2,   0,   0, 168,   2, 
@@ -873,10 +873,10 @@ const BYTE UIVertexShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0, 148,  46,  49,   1, 
-    107, 171,   7,  98,   1,   0, 
-      0,   0, 207,  72,  92, 203, 
-     11, 233,  63,  73, 147, 211, 
-     74, 184,  17, 115, 139, 221, 
+    230, 111,  72,  98,   1,   0, 
+      0,   0, 126, 242, 225, 129, 
+    144, 227,  82,  79, 164,  52, 
+    208,  83, 125, 169,  42,  55, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
@@ -1556,8 +1556,8 @@ const BYTE UIVertexShader[] =
      32,  32,  32,  32,  32,  32, 
      32,  32,  32,  32,  32,  32, 
      27, 226,  48,   1, 128,   0, 
-      0,   0, 211, 182, 121,  31, 
-     14,  32, 216,   1,   1,   0, 
+      0,   0,  15, 246, 181, 219, 
+    168,  70, 216,   1,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2921,10 +2921,10 @@ const BYTE UIVertexShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0, 148,  46,  49,   1, 
-    107, 171,   7,  98,   1,   0, 
-      0,   0, 207,  72,  92, 203, 
-     11, 233,  63,  73, 147, 211, 
-     74, 184,  17, 115, 139, 221, 
+    230, 111,  72,  98,   1,   0, 
+      0,   0, 126, 242, 225, 129, 
+    144, 227,  82,  79, 164,  52, 
+    208,  83, 125, 169,  42,  55, 
     129,   0,   0,   0,  47,  76, 
     105, 110, 107,  73, 110, 102, 
     111,   0,  47, 110,  97, 109,