Browse Source

Reafctor interface and parser internal

- Migrate to common template function for parsing
- Hide parser internals
- Fix few issues in parser
- Implement tests
Alexey Edelev 4 years ago
parent
commit
d6c4dae445
5 changed files with 526 additions and 256 deletions
  1. 16 1
      CMakeLists.txt
  2. 270 150
      microjson.cpp
  3. 6 37
      microjson.h
  4. 1 2
      tests/CMakeLists.txt
  5. 233 66
      tests/main.cpp

+ 16 - 1
CMakeLists.txt

@@ -39,4 +39,19 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_CONFIG}.cmake" DESTINATION "
 export(TARGETS ${TARGET} FILE ${TARGET_EXPORT}.cmake)
 
 set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_PREFIX_PATH})
-add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tests")
+
+if(DEFINED $ENV{MICROJSON_MAKE_TESTS})
+    set(MICROJSON_MAKE_TESTS $ENV{MICROJSON_MAKE_TESTS})
+elseif(NOT DEFINED MICROJSON_MAKE_TESTS)
+    set(MICROJSON_MAKE_TESTS ON)
+endif()
+
+if(MICROJSON_MAKE_TESTS)
+    find_package(GTest)
+    if(GTest_FOUND)
+        enable_testing()
+        add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/tests")
+    else()
+        message(STATUS "Force disable test")
+    endif()
+endif()

+ 270 - 150
microjson.cpp

@@ -26,86 +26,158 @@
 #include "microjson.h"
 
 #include <iostream>
-#include <functional>
 
 #ifdef MICROJSON_DEBUG
-    #define micorJsonDebug std::cout
+    #define microjsonDebug std::cout
 #else
-    struct micorJsonNull : public std::ostream {
-    };
-    static micorJsonNull nullout;
-    #define micorJsonDebug nullout
+    struct microjsonNull : public std::ostream {};
+    static microjsonNull nullout;
+    #define microjsonDebug nullout
 #endif
 
-namespace  {
-enum ParsingState {
-    LookingForNameBegin,
-    LookingForNameEnd,
-    LookingForSeparator,
-    LookingForValueBegin,
-    LookingForValueEnd
+namespace {
+struct JsonProperty {
+    JsonProperty() : nameBegin(SIZE_MAX)
+      , nameEnd(SIZE_MAX)
+      , valueBegin(SIZE_MAX)
+      , valueEnd(SIZE_MAX)
+      , type(microjson::JsonInvalidType){}
+
+    size_t nameBegin;
+    size_t nameEnd;
+    size_t valueBegin;
+    size_t valueEnd;
+    microjson::JsonType type;
+
+    size_t nameSize() const {
+        return nameEnd - nameBegin;
+    }
+
+    size_t valueSize() const {
+        return valueEnd - valueBegin + 1;
+    }
+
+    bool checkValue() const {
+        return type != microjson::JsonInvalidType && valueBegin != SIZE_MAX && valueEnd != SIZE_MAX &&
+                valueBegin <= valueEnd;
+    }
+
+    bool checkEof() const {
+        return (type == microjson::JsonNumberType || type == microjson::JsonBoolType) &&
+                valueBegin != SIZE_MAX && valueEnd == SIZE_MAX;
+    }
+
+    bool check() const {
+        return checkValue() && nameBegin != SIZE_MAX && nameEnd != SIZE_MAX &&
+                nameBegin < nameEnd && nameEnd < valueBegin;
+    }
 };
+
+inline bool skipWhiteSpace(const char byte) {
+    return byte == '\n' || byte == ' ' || byte == '\r' || byte == '\t' || byte == '\f' || byte == '\v';
 }
-size_t microjson::extractNextProperty(const char *buffer, size_t size, JsonProperty &property) {
-    if (buffer == nullptr || size == 0 || size == SIZE_MAX) {
-        return SIZE_MAX;
+
+template<const char expectedBeginByte>
+void lookForBoundaries(const char *buffer, size_t size, size_t &begin, size_t &end) {
+    const char expectedEndByte = expectedBeginByte + 2;
+    begin = SIZE_MAX;
+    end = SIZE_MAX;
+    for (size_t i = 0; i < size; i++) {
+        const char beginByte = buffer[i];
+        const char endByte = buffer[size - i - 1];
+        if (begin == SIZE_MAX) {
+            if (beginByte == expectedBeginByte) {
+                begin = i;
+            } else if (beginByte != '\n' && beginByte != ' ' && beginByte != '\r' && beginByte != '\t') {
+                std::cerr << "Unexpected begin byte" << beginByte << std::endl;
+                break;
+            }
+        }
+
+        if (end == SIZE_MAX) {
+            if (endByte == expectedEndByte) {
+                end = size - i - 1;
+            } else if (endByte != '\n' && endByte != ' ' && endByte != '\r' && endByte != '\t') {
+                std::cerr << "Unexpected end byte" << endByte << std::endl;
+                break;
+            }
+        }
+
+        if (begin != SIZE_MAX && end != SIZE_MAX) {
+            break;
+        }
     }
+}
 
+void lookForName(const char *buffer, size_t size, size_t &i, JsonProperty &property) {
     property.nameBegin = SIZE_MAX;
     property.nameEnd = SIZE_MAX;
-    property.valueBegin = SIZE_MAX;
-    property.valueEnd = SIZE_MAX;
-    property.type = JsonInvalidType;
-
-    int valueBracesCounter = -1;
-    int valueBracketsCounter = -1;
-    int trueCounter = 3;
-    int falseCounter = 4;
-
-    std::function<bool(void)> valueEndMarker;
-    ParsingState state = LookingForNameBegin;
-    size_t i = 0;
-    for (; i < size; i++) {
+    bool beginFound = false;
+    for(; i < size; ++i) {
         const char byte = buffer[i];
-        if (state == LookingForNameBegin) {
-            if (byte == '\n' || byte == ' ' || byte == '\r' || byte == '\t') {
-                micorJsonDebug << "Skip space" << std::endl;
-                continue;
-            }
+        if (skipWhiteSpace(byte)) {
+            microjsonDebug << "Skip space" << std::endl;
+            continue;
+        }
+
+        if(!beginFound) {
             if (byte == '"') {
-                micorJsonDebug << "Found name begin" << std::endl;
+                microjsonDebug << "Found name begin" << std::endl;
                 property.nameBegin = i + 1;
-                state = LookingForNameEnd;
+                beginFound = true;
             } else {
                 std::cerr << "Not found name begin, unexpected" << std::endl;
                 break;
             }
-        } else if (state == LookingForNameEnd && byte == '"') {
-            if (byte == '\n' || byte == ' ' || byte == '\r' || byte == '\t') {
-                micorJsonDebug << "Skip space" << std::endl;
-                continue;
-            }
+        } else if(byte == '"') {
             if (i > 0 && buffer[i - 1] == '\\') {
-                micorJsonDebug << "'\"' found in name" << std::endl;
+                microjsonDebug << "'\"' found in name" << std::endl;
                 continue;
             }
-            micorJsonDebug << "Found name end" << std::endl;
+            microjsonDebug << "Found name end" << std::endl;
             property.nameEnd = i;
-            state = LookingForSeparator;
-        } else if (state == LookingForSeparator) {
-            if (byte == '\n' || byte == ' ' || byte == '\r' || byte == '\t') {
-                micorJsonDebug << "Skip space" << std::endl;
-                continue;
-            }
-            if (byte == ':') {
-                micorJsonDebug << "Found Separator" << std::endl;
-                state = LookingForValueBegin;
-            } else {
-                break;
-            }
-        } else if (state == LookingForValueBegin) {
-            if (byte == '\n' || byte == ' ' || byte == '\r' || byte == '\t') {
-                micorJsonDebug << "Skip space" << std::endl;
+            break;
+        }
+    }
+    ++i;
+}
+
+bool lookForSeparator(const char* buffer, size_t size, size_t &i) {
+    bool found = false;
+    for(; i < size; ++i) {
+        const char byte = buffer[i];
+        if (skipWhiteSpace(byte)) {
+            microjsonDebug << "Skip space" << std::endl;
+            continue;
+        }
+        if (byte == ':') {
+            microjsonDebug << "Found Separator" << std::endl;
+            found = true;
+        }
+        break;
+    }
+    ++i;
+    return found;
+}
+
+void lookForValue(const char *buffer, size_t size, size_t &i, JsonProperty &property) {
+    int valueBracesCounter = -1;
+    int valueBracketsCounter = -1;
+    int trueCounter = 3;
+    int falseCounter = 4;
+
+    std::function<bool(void)> valueEndMarker;
+    bool beginFound = false;
+    bool stringScope = false;
+
+    property.valueBegin = SIZE_MAX;
+    property.valueEnd = SIZE_MAX;
+    for(; i < size; i++) {
+        const char byte = buffer[i];
+        if (!beginFound) {
+            microjsonDebug << "lookForValue at: " << i << " byte: " << byte << std::endl;
+            if (skipWhiteSpace(byte)) {
+                microjsonDebug << "Skip space" << std::endl;
                 continue;
             }
             switch (byte) {
@@ -113,7 +185,7 @@ size_t microjson::extractNextProperty(const char *buffer, size_t size, JsonPrope
                 valueEndMarker = [&](){
                     return buffer[i] == '"' && buffer[i - 1] != '\\';
                 };
-                property.type = JsonStringType;
+                property.type = microjson::JsonStringType;
                 break;
             case '-':
             case '0':
@@ -146,157 +218,205 @@ size_t microjson::extractNextProperty(const char *buffer, size_t size, JsonPrope
                     }
                     return false;
                 };
-                property.type = JsonNumberType;
+                property.type = microjson::JsonNumberType;
                 break;
             case '{':
                 valueBracesCounter++;
-                valueEndMarker = [&valueBracesCounter](){
+                valueEndMarker = [&stringScope, &byte, &valueBracesCounter](){
+                    if (!stringScope) {
+                        switch (byte) {
+                        case '}':
+                            --valueBracesCounter;
+                            break;
+                        case '{':
+                            ++valueBracesCounter;
+                            break;
+                        default:
+                            break;
+                        }
+                    }
                     return valueBracesCounter < 0;
                 };
-                property.type = JsonObjectType;
+                property.type = microjson::JsonObjectType;
                 break;
             case 't':
                 valueEndMarker = [&trueCounter](){
+                    --trueCounter;
                     return trueCounter == 0;
                 };
-                property.type = JsonBoolType;
+                property.type = microjson::JsonBoolType;
                 break;
             case 'f':
                 valueEndMarker = [&falseCounter](){
+                    --falseCounter;
                     return falseCounter == 0;
                 };
-                property.type = JsonBoolType;
+                property.type = microjson::JsonBoolType;
                 break;
             case '[':
                 valueBracketsCounter++;
-                valueEndMarker = [&valueBracketsCounter](){
+                valueEndMarker = [&stringScope, &byte, &valueBracketsCounter](){
+                    if(!stringScope) {
+                        switch(byte) {
+                        case ']':
+                            --valueBracketsCounter;
+                            break;
+                        case '[':
+                            ++valueBracketsCounter;
+                            break;
+                        default:
+                            break;
+                        }
+                    }
                     return valueBracketsCounter < 0;
                 };
-                property.type = JsonArrayType;
+                property.type = microjson::JsonArrayType;
                 break;
             }
 
             if (valueEndMarker) {
-                micorJsonDebug << "Found value begin" << std::endl;
+                microjsonDebug << "Found value begin" << std::endl;
                 property.valueBegin = i;
-                state = LookingForValueEnd;
+                beginFound = true;
             } else {
                 break;
             }
-        } else if (state == LookingForValueEnd) {
-            switch (byte) {
-            case '}':
-                --valueBracesCounter;
-                break;
-            case '{':
-                ++valueBracesCounter;
-                break;
-            case ']':
-                --valueBracketsCounter;
-                break;
-            case '[':
-                ++valueBracketsCounter;
-                break;
-            default:
-                --trueCounter;
-                --falseCounter;
-                break;
+        } else {
+            if (byte == '"' && (i == 0 || buffer[i - 1] != '\\')) {
+                stringScope = !stringScope;
             }
 
             if (valueEndMarker()) {
-                micorJsonDebug << "Found value end" << std::endl;
+                microjsonDebug << "Found value end" << std::endl;
                 property.valueEnd = i;
                 break;
             }
         }
     }
+}
 
-    if (property.eofCheck()) {
-        property.valueEnd = size - 1; //EOF case
-        micorJsonDebug << "Found value end at EOF" << std::endl;
+bool extractProperty(const char *buffer, size_t size, size_t &i, JsonProperty &property) {
+    lookForName(buffer, size, i, property);
+    if(property.nameBegin == SIZE_MAX && property.nameEnd == SIZE_MAX) {
+        std::cerr << "Name not found" << std::endl;
+        return false;
     }
 
-    micorJsonDebug << property.nameBegin << " " << property.nameEnd << " " << property.valueBegin << " " << property.valueEnd << " " << property.type << std::endl;
-    if (property.check()) {
-        if (property.type == JsonStringType
-                || property.type == JsonArrayType
-                || property.type == JsonObjectType) {
-            ++property.valueBegin;
-            --property.valueEnd;
-        }
-        for (size_t j = i + 1; j < size; j++) {
-            const char &byte = buffer[j];
-            if (byte == ',') {
-                return j + 1;
-            } else if (byte != '\n' && byte != ' ' && byte != '\r' && byte != '\t') {
-                micorJsonDebug << "Unexpected: " << byte;
-                return SIZE_MAX;
-            }
-        }
-        return size;
-    } else {
-        micorJsonDebug << "Property check failed" << std::endl;
+    if(!lookForSeparator(buffer, size, i)) {
+        std::cerr << "Separator not found" << std::endl;
+        return false;
     }
-    return SIZE_MAX;
+
+    lookForValue(buffer, size, i, property);
+    if (property.checkEof()) {
+        property.valueEnd = size - 1; //EOF case
+        microjsonDebug << "Found value end at EOF" << std::endl;
+    }
+
+    return property.check();
 }
 
-microjson::JsonObject microjson::parseObject(const char *buffer, size_t size) {
-    JsonObject obj;
+bool extractValue(const char *buffer, size_t size, size_t &i, JsonProperty &property) {
+    lookForValue(buffer, size, i, property);
+    if (property.checkEof()) {
+        property.valueEnd = size - 1; //EOF case
+        microjsonDebug << "Found value end at EOF" << std::endl;
+    }
+
+    return property.checkValue();
+}
 
+using Extractor = bool(*)(const char *, size_t, size_t &, JsonProperty &);
+template <Extractor extract>
+size_t extractNext(const char *buffer, size_t size, JsonProperty &property) {
     if (buffer == nullptr || size == 0 || size == SIZE_MAX) {
-        return obj;
+        return SIZE_MAX;
     }
 
-    size_t objectBeginPosition = SIZE_MAX;
-    size_t objectEndPosition = SIZE_MAX;
-    for (size_t i = 0; i < size; i++) {
-        const char beginByte = buffer[i];
-        const char endByte = buffer[size - i - 1];
-        if (objectBeginPosition == SIZE_MAX) {
-            if (beginByte == '{') {
-                objectBeginPosition = i;
-            } else if (beginByte != '\n' && beginByte != ' ' && beginByte != '\r' && beginByte != '\t') {
-                std::cerr << "Unexpected begin byte" << beginByte << std::endl;
-                break;
-            }
-        }
+    property.nameBegin = SIZE_MAX;
+    property.nameEnd = SIZE_MAX;
+    property.valueBegin = SIZE_MAX;
+    property.valueEnd = SIZE_MAX;
+    property.type = microjson::JsonInvalidType;
 
-        if (objectEndPosition == SIZE_MAX) {
-            if (endByte == '}') {
-                objectEndPosition = size - i - 1;
-            } else if (endByte != '\n' && endByte != ' ' && endByte != '\r' && endByte != '\t') {
-                std::cerr << "Unexpected end byte" << endByte << std::endl;
-                break;
-            }
-        }
+    size_t i = 0;
+    if(!extract(buffer, size, i, property)) {
+        return SIZE_MAX;
+    }
 
-        if (objectBeginPosition != SIZE_MAX && objectEndPosition != SIZE_MAX) {
-            break;
+    if (property.type == microjson::JsonStringType) {
+        ++property.valueBegin;
+        --property.valueEnd;
+    }
+
+    for (size_t j = i + 1; j < size; j++) {
+        const char &byte = buffer[j];
+        if (byte == ',') {
+            return j + 1;
+        } else if (!skipWhiteSpace(byte)) {
+            microjsonDebug << "Unexpected: " << byte;
+            return SIZE_MAX;
         }
+    }
+    return size;
+}
+
+template<typename R,
+         const char expectedBeginByte,
+         Extractor extract,
+         void(* collect)(const char *, R &, const JsonProperty &property)>
+R parseJsonCommon(const char *buffer, size_t size) {
+    R returnValue;
 
+    if (buffer == nullptr || size == 0 || size == SIZE_MAX) {
+        return returnValue;
     }
 
+    size_t objectBeginPosition = SIZE_MAX;
+    size_t objectEndPosition = SIZE_MAX;
+
+    lookForBoundaries<expectedBeginByte>(buffer, size, objectBeginPosition, objectEndPosition);
     if (objectBeginPosition == SIZE_MAX || objectEndPosition == SIZE_MAX) {
-        return obj;
+        return returnValue;
     }
 
     JsonProperty property;
     buffer += objectBeginPosition + 1;//Skip '{'
     size = objectEndPosition - objectBeginPosition - 1;//Skip '}'
 
-    micorJsonDebug << "Object buffer size: " << size << " buffer: " << std::string(buffer, size) << std::endl;
+    microjsonDebug << "Object buffer size: " << size << " buffer: " << std::string(buffer, size) << std::endl;
 
-    for (size_t nextPropertyPosition = microjson::extractNextProperty(buffer, size, property); nextPropertyPosition != SIZE_MAX; ) {
-        micorJsonDebug << "nextPropertyPosition: " << nextPropertyPosition << "size: " << size << std::endl;
-        if (nextPropertyPosition != SIZE_MAX) {
-            std::string name((buffer + property.nameBegin), property.nameSize());
-            std::string value((buffer + property.valueBegin), property.valueSize());
-            micorJsonDebug << "name: " << name << " value: " << value << std::endl;
-            obj[name] = { value, property.type };
+    for (size_t nextPosition = extractNext<extract>(buffer, size, property); nextPosition != SIZE_MAX; ) {
+        microjsonDebug << "nextPropertyPosition: " << nextPosition << "size: " << size << std::endl;
+        if (nextPosition != SIZE_MAX) {
+            collect(buffer, returnValue, property);
         }
-        buffer += nextPropertyPosition;
-        size = size - nextPropertyPosition;
-        nextPropertyPosition = microjson::extractNextProperty(buffer, size, property);
+        buffer += nextPosition;
+        size = size - nextPosition;
+        nextPosition = extractNext<extract>(buffer, size, property);
     }
-    return obj;
+    return returnValue;
+}
+
+void appendProperty(const char* buffer, microjson::JsonObject &obj, const JsonProperty &property){
+    std::string name((buffer + property.nameBegin), property.nameSize());
+    std::string value((buffer + property.valueBegin), property.valueSize());
+    microjsonDebug << "name: " << name << " value: " << value << std::endl;
+    obj[name] = { value, property.type };
+};
+
+void appendValue(const char* buffer, microjson::JsonArray &values, const JsonProperty &property){
+    std::string value = std::string((buffer + property.valueBegin), property.valueSize());
+    microjsonDebug << "value: " << value << std::endl;
+    values.push_back({value, property.type});
+};
+
+}
+
+microjson::JsonObject microjson::parseJsonObject(const char *buffer, size_t size) {
+    return parseJsonCommon<JsonObject, '{', extractProperty, appendProperty>(buffer, size);
+}
+
+microjson::JsonArray microjson::parseJsonArray(const char *buffer, size_t size) {
+    return parseJsonCommon<JsonArray, '[', extractValue, appendValue>(buffer, size);
 }

+ 6 - 37
microjson.h

@@ -26,7 +26,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <functional>
+
 #include <string>
+#include <vector>
 #include <unordered_map>
 
 namespace microjson {
@@ -49,42 +52,8 @@ struct JsonValue {
 };
 
 using JsonObject = std::unordered_map<std::string, JsonValue>;
+using JsonArray = std::vector<JsonValue>;
 
-struct JsonProperty {
-    JsonProperty() : nameBegin(SIZE_MAX)
-      , nameEnd(SIZE_MAX)
-      , valueBegin(SIZE_MAX)
-      , valueEnd(SIZE_MAX)
-      , type(JsonInvalidType){}
-
-    size_t nameBegin;
-    size_t nameEnd;
-    size_t valueBegin;
-    size_t valueEnd;
-    JsonType type;
-
-    size_t nameSize() const {
-        return nameEnd - nameBegin;
-    }
-
-    size_t valueSize() const {
-        return valueEnd - valueBegin + 1;
-    }
-
-    bool check() const {
-        return type != JsonInvalidType && nameBegin != SIZE_MAX && nameEnd != SIZE_MAX &&
-                valueBegin != SIZE_MAX && valueEnd != SIZE_MAX &&
-                nameBegin < nameEnd && nameEnd < valueBegin &&
-                valueBegin <= valueEnd;
-    }
-
-    bool eofCheck() const {
-        return (type == JsonNumberType || type == JsonBoolType) && nameBegin != SIZE_MAX && nameEnd != SIZE_MAX &&
-                valueBegin != SIZE_MAX && valueEnd == SIZE_MAX &&
-                nameBegin < nameEnd && nameEnd < valueBegin;
-    }
-};
-
-extern JsonObject parseObject(const char *buffer, size_t size);
-extern size_t extractNextProperty(const char *buffer, size_t size, JsonProperty &property);
+extern JsonArray parseJsonArray(const char *buffer, size_t size);
+extern JsonObject parseJsonObject(const char *buffer, size_t size);
 }

+ 1 - 2
tests/CMakeLists.txt

@@ -1,5 +1,4 @@
 find_package(microjson CONFIG REQUIRED)
-find_package(GTest REQUIRED)
-
 add_executable(microjson_test main.cpp)
 target_link_libraries(microjson_test microjson gtest_main gtest)
+add_test(NAME microjson_test COMMAND microjson_test)

+ 233 - 66
tests/main.cpp

@@ -14,7 +14,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
 {
     const char *buffer1 = "{\"testField\":\"test\"}";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -24,7 +24,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
     obj.clear();
     const char *buffer2 = "{\"testField\":\"\"}";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -34,7 +34,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
     obj.clear();
     const char *buffer3 = "{\"testField\":\"t\"}";
     size = strlen(buffer3);
-    obj = microjson::parseObject(buffer3, size);
+    obj = microjson::parseJsonObject(buffer3, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -44,7 +44,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
     obj.clear();
     const char *buffer4 = "{\"testField\":\"\\\"test\\\"\"}";
     size = strlen(buffer4);
-    obj = microjson::parseObject(buffer4, size);
+    obj = microjson::parseJsonObject(buffer4, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -54,7 +54,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
     obj.clear();
     const char *buffer5 = "{\"testField\":\"\\\"test\"}";
     size = strlen(buffer5);
-    obj = microjson::parseObject(buffer5, size);
+    obj = microjson::parseJsonObject(buffer5, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -64,7 +64,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
     obj.clear();
     const char *buffer6 = "{\"testField\":\"\\\"\"}";
     size = strlen(buffer6);
-    obj = microjson::parseObject(buffer6, size);
+    obj = microjson::parseJsonObject(buffer6, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -74,7 +74,7 @@ TEST_F(MicrojsonDeserializationTest, StringValue)
     obj.clear();
     const char *buffer7 = "{\"testField\":\"test\",\"testField1\":\"\",\"testField2\":\"t\",\"testField3\":\"\\\"test\\\"\",\"testField4\":\"\\\"test\",\"testField5\":\"\\\"\"}";
     size = strlen(buffer7);
-    obj = microjson::parseObject(buffer7, size);
+    obj = microjson::parseJsonObject(buffer7, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -116,7 +116,7 @@ TEST_F(MicrojsonDeserializationTest, NumberValue)
 {
     const char *buffer1 = "{\"testField\":5}";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -126,7 +126,7 @@ TEST_F(MicrojsonDeserializationTest, NumberValue)
     obj.clear();
     const char *buffer2 = "{\"testField\":56}";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -136,7 +136,7 @@ TEST_F(MicrojsonDeserializationTest, NumberValue)
     obj.clear();
     const char *buffer3 = "{\"testField\":0}";
     size = strlen(buffer3);
-    obj = microjson::parseObject(buffer3, size);
+    obj = microjson::parseJsonObject(buffer3, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -146,7 +146,7 @@ TEST_F(MicrojsonDeserializationTest, NumberValue)
     obj.clear();
     const char *buffer4 = "{\"testField\":-5}";
     size = strlen(buffer4);
-    obj = microjson::parseObject(buffer4, size);
+    obj = microjson::parseJsonObject(buffer4, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -156,7 +156,7 @@ TEST_F(MicrojsonDeserializationTest, NumberValue)
     obj.clear();
     const char *buffer5 = "{\"testField\":-131}";
     size = strlen(buffer5);
-    obj = microjson::parseObject(buffer5, size);
+    obj = microjson::parseJsonObject(buffer5, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -166,7 +166,7 @@ TEST_F(MicrojsonDeserializationTest, NumberValue)
     obj.clear();
     const char *buffer6 = "{\"testField\":5,\"testField1\":56,\"testField2\":0,\"testField3\":-8,\"testField4\":-124}";
     size = strlen(buffer6);
-    obj = microjson::parseObject(buffer6, size);
+    obj = microjson::parseJsonObject(buffer6, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -202,7 +202,7 @@ TEST_F(MicrojsonDeserializationTest, TextSpacesCutting)
 {
     const char *buffer1 = "\n\r\t  {\n\r\t \"testField\"\n\r\t :   5\n\t \r}\n\t \r";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -211,7 +211,7 @@ TEST_F(MicrojsonDeserializationTest, TextSpacesCutting)
 
     const char *buffer2 = "\n\r\t  {\n\r\t \"testField\"\n\r\t :   5\n\t \r, \n\r\t \"testField2\"\n\r\t :   -0.932e+10\n\t \r}\n\t \r";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_EQ(it->second.type, microjson::JsonNumberType);
@@ -223,15 +223,15 @@ TEST_F(MicrojsonDeserializationTest, TextSpacesCutting)
     EXPECT_STREQ(it->second.value.c_str(), "-0.932e+10");
 
 
-    const char *buffer3 = "\n\r\t  {\n\r\t \"testField\"\n\r\t :   \"5\"\n\t \r, \n\r\t \"testField2\"\n\r\t :   \"\\\"qwerty\t\t\t\t\"\n\t \r}\n\t \r";
+    const char *buffer3 = "\n\r\t  {\n\r\t \"testField\"\n\r\t :   \"5\"\n\t \r, \n\r\t \"test\n\rField2\"\n\r\t :   \"\\\"qwerty\t\t\t\t\"\n\t \r}\n\t \r";
     size = strlen(buffer3);
-    obj = microjson::parseObject(buffer3, size);
+    obj = microjson::parseJsonObject(buffer3, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_EQ(it->second.type, microjson::JsonStringType);
     EXPECT_STREQ(it->second.value.c_str(), "5");
 
-    it = obj.find("testField2");
+    it = obj.find("test\n\rField2");
     ASSERT_TRUE(it != obj.end());
     EXPECT_EQ(it->second.type, microjson::JsonStringType);
     EXPECT_STREQ(it->second.value.c_str(), "\\\"qwerty\t\t\t\t");
@@ -241,7 +241,7 @@ TEST_F(MicrojsonDeserializationTest, BooleanValue)
 {
     const char *buffer1 = "{\"testField\":true}";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -251,7 +251,7 @@ TEST_F(MicrojsonDeserializationTest, BooleanValue)
     obj.clear();
     const char *buffer2 = "{\"testField\":false}";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -260,7 +260,7 @@ TEST_F(MicrojsonDeserializationTest, BooleanValue)
     obj.clear();
     const char *buffer7 = "{\"testField\":true,\"testField1\":false}";
     size = strlen(buffer7);
-    obj = microjson::parseObject(buffer7, size);
+    obj = microjson::parseJsonObject(buffer7, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -278,7 +278,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
 {
     const char *buffer1 = "{\"testField\":0.0}";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -288,7 +288,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer2 = "{\"testField\":1.0}";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -298,7 +298,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer3 = "{\"testField\":20.0}";
     size = strlen(buffer3);
-    obj = microjson::parseObject(buffer3, size);
+    obj = microjson::parseJsonObject(buffer3, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -308,7 +308,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer4 = "{\"testField\":20.01}";
     size = strlen(buffer4);
-    obj = microjson::parseObject(buffer4, size);
+    obj = microjson::parseJsonObject(buffer4, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -318,7 +318,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer5 = "{\"testField\":-1.0}";
     size = strlen(buffer5);
-    obj = microjson::parseObject(buffer5, size);
+    obj = microjson::parseJsonObject(buffer5, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -328,7 +328,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer6 = "{\"testField\":-87.0}";
     size = strlen(buffer6);
-    obj = microjson::parseObject(buffer6, size);
+    obj = microjson::parseJsonObject(buffer6, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -338,7 +338,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer7 = "{\"testField\":-11.21}";
     size = strlen(buffer7);
-    obj = microjson::parseObject(buffer7, size);
+    obj = microjson::parseJsonObject(buffer7, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -348,7 +348,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer8 = "{\"testField\":1.1234+e10}";
     size = strlen(buffer8);
-    obj = microjson::parseObject(buffer8, size);
+    obj = microjson::parseJsonObject(buffer8, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -358,7 +358,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer9 = "{\"testField\":1.1234-e10}";
     size = strlen(buffer9);
-    obj = microjson::parseObject(buffer9, size);
+    obj = microjson::parseJsonObject(buffer9, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -368,7 +368,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer10 = "{\"testField\":-1.1234-e10}";
     size = strlen(buffer10);
-    obj = microjson::parseObject(buffer10, size);
+    obj = microjson::parseJsonObject(buffer10, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -378,7 +378,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer11 = "{\"testField\":-1.1234+e10}";
     size = strlen(buffer11);
-    obj = microjson::parseObject(buffer11, size);
+    obj = microjson::parseJsonObject(buffer11, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -388,7 +388,7 @@ TEST_F(MicrojsonDeserializationTest, FloatingPointValue)
     obj.clear();
     const char *buffer12 = "{\"testField\":0.0,\"testField1\":1.0,\"testField2\":20.0,\"testField3\":20.01,\"testField4\":-1.0,\"testField5\":-87.0,\"testField6\":-11.21,\"testField7\":1.1234+e10,\"testField8\":1.1234-e10,\"testField9\":-1.1234-e10,\"testField10\":-1.1234+e10}";
     size = strlen(buffer12);
-    obj = microjson::parseObject(buffer12, size);
+    obj = microjson::parseJsonObject(buffer12, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
@@ -460,168 +460,335 @@ TEST_F(MicrojsonDeserializationTest, ArrayValue)
 {
     const char *buffer1 = "{\"testField\":[\"test1\"]}";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"test1\"");
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\"]");
 
     obj.clear();
     const char *buffer2 = "{\"testField\":[\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"]}";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"");
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"]");
 
     obj.clear();
     const char *buffer3 = "{\"testField\":[],\"testField1\":[\"test1\",\"test2\"]}";
     size = strlen(buffer3);
-    obj = microjson::parseObject(buffer3, size);
+    obj = microjson::parseJsonObject(buffer3, size);
+
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "");
+    EXPECT_STREQ(it->second.value.c_str(), "[]");
+
     it = obj.find("testField1");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField1");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"test1\",\"test2\"");
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\",\"test2\"]");
 
     obj.clear();
     const char *buffer4 = "{\"testField\":[1,1.0,-10,\"test1\",{\"test2\":15}]}";
     size = strlen(buffer4);
-    obj = microjson::parseObject(buffer4, size);
+    obj = microjson::parseJsonObject(buffer4, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "1,1.0,-10,\"test1\",{\"test2\":15}");
+    EXPECT_STREQ(it->second.value.c_str(), "[1,1.0,-10,\"test1\",{\"test2\":15}]");
 
     obj.clear();
     const char *buffer5 = "{\"testField\":[[1,2,3,4,5,6],[7,8,9,10,\"test1\"]]}";
     size = strlen(buffer5);
-    obj = microjson::parseObject(buffer5, size);
+    obj = microjson::parseJsonObject(buffer5, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "[1,2,3,4,5,6],[7,8,9,10,\"test1\"]");
+    EXPECT_STREQ(it->second.value.c_str(), "[[1,2,3,4,5,6],[7,8,9,10,\"test1\"]]");
 
     obj.clear();
     const char *buffer6 = "{\"testField\":[{\"test1\":[1,2,3,4,5,{\"test2\":[\"test3\",\"test4\",[1,2,3,4]]}]}]}";
     size = strlen(buffer6);
-    obj = microjson::parseObject(buffer6, size);
+    obj = microjson::parseJsonObject(buffer6, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "{\"test1\":[1,2,3,4,5,{\"test2\":[\"test3\",\"test4\",[1,2,3,4]]}]}");
+    EXPECT_STREQ(it->second.value.c_str(), "[{\"test1\":[1,2,3,4,5,{\"test2\":[\"test3\",\"test4\",[1,2,3,4]]}]}]");
 
     const char *buffer7 = "{\"testField\":[\"test1\"],\"testField1\":[\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"],\"testField2\":[],\"testField3\":[\"test1\",\"test2\"],\"testField4\":[1,1.0,-10,\"test1\",{\"test2\":15}],\"testField5\":[[1,2,3,4,5,6],[7,8,9,10,\"test1\"]],\"testField6\":[{\"test1\":[1,2,3,4,5,{\"test2\":[\"test3\",\"test4\",[1,2,3,4]]}]}]}";
     size = strlen(buffer7);
-    obj = microjson::parseObject(buffer7, size);
+    obj = microjson::parseJsonObject(buffer7, size);
 
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"test1\"");
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\"]");
 
     it = obj.find("testField1");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField1");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"");
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"]");
 
     it = obj.find("testField2");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField2");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "");
+    EXPECT_STREQ(it->second.value.c_str(), "[]");
 
     it = obj.find("testField3");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField3");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"test1\",\"test2\"");
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\",\"test2\"]");
 
     it = obj.find("testField4");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField4");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "1,1.0,-10,\"test1\",{\"test2\":15}");
+    EXPECT_STREQ(it->second.value.c_str(), "[1,1.0,-10,\"test1\",{\"test2\":15}]");
 
     it = obj.find("testField5");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField5");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "[1,2,3,4,5,6],[7,8,9,10,\"test1\"]");
+    EXPECT_STREQ(it->second.value.c_str(), "[[1,2,3,4,5,6],[7,8,9,10,\"test1\"]]");
 
     it = obj.find("testField6");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField6");
     EXPECT_EQ(it->second.type, microjson::JsonArrayType);
-    EXPECT_STREQ(it->second.value.c_str(), "{\"test1\":[1,2,3,4,5,{\"test2\":[\"test3\",\"test4\",[1,2,3,4]]}]}");
+    EXPECT_STREQ(it->second.value.c_str(), "[{\"test1\":[1,2,3,4,5,{\"test2\":[\"test3\",\"test4\",[1,2,3,4]]}]}]");
 }
 
 TEST_F(MicrojsonDeserializationTest, ObjectValue)
 {
     const char *buffer1 = "{\"testField\":{\"testField1\":1}}";
     size_t size = strlen(buffer1);
-    microjson::JsonObject obj = microjson::parseObject(buffer1, size);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
     auto it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonObjectType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"testField1\":1");
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField1\":1}");
 
     const char *buffer2 = "{\"testField\":{\"testField1\":1,\"testField2\":2}}";
     size = strlen(buffer2);
-    obj = microjson::parseObject(buffer2, size);
+    obj = microjson::parseJsonObject(buffer2, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonObjectType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"testField1\":1,\"testField2\":2");
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField1\":1,\"testField2\":2}");
 
     const char *buffer3 = "{\"testField\":{\"testField1\":1.0,\"testField2\":\"2\"}}";
     size = strlen(buffer3);
-    obj = microjson::parseObject(buffer3, size);
+    obj = microjson::parseJsonObject(buffer3, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonObjectType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"testField1\":1.0,\"testField2\":\"2\"");
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField1\":1.0,\"testField2\":\"2\"}");
 
     const char *buffer4 = "{\"testField\":{}}";
     size = strlen(buffer4);
-    obj = microjson::parseObject(buffer4, size);
+    obj = microjson::parseJsonObject(buffer4, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonObjectType);
-    EXPECT_STREQ(it->second.value.c_str(), "");
+    EXPECT_STREQ(it->second.value.c_str(), "{}");
 
     const char *buffer5 = "{\"testField\":{\"testField1\":{},\"testField2\":{\"testField3\":\"2\"}}}";
     size = strlen(buffer5);
-    obj = microjson::parseObject(buffer5, size);
+    obj = microjson::parseJsonObject(buffer5, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonObjectType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"testField1\":{},\"testField2\":{\"testField3\":\"2\"}");
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField1\":{},\"testField2\":{\"testField3\":\"2\"}}");
 
     const char *buffer6 = "{\"testField\":{\"testField1\":{},\"testField2\":{\"testField3\":[\"2\",0,1,2,{\"testField4\":9}]}}}";
     size = strlen(buffer6);
-    obj = microjson::parseObject(buffer6, size);
+    obj = microjson::parseJsonObject(buffer6, size);
     it = obj.find("testField");
     ASSERT_TRUE(it != obj.end());
     EXPECT_STREQ(it->first.c_str(), "testField");
     EXPECT_EQ(it->second.type, microjson::JsonObjectType);
-    EXPECT_STREQ(it->second.value.c_str(), "\"testField1\":{},\"testField2\":{\"testField3\":[\"2\",0,1,2,{\"testField4\":9}]}");
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField1\":{},\"testField2\":{\"testField3\":[\"2\",0,1,2,{\"testField4\":9}]}}");
+}
+
+TEST_F(MicrojsonDeserializationTest, ArrayValues)
+{
+    const char *buffer1 = "[\"test1\",\"test2\",\"test3\",\"test5\",\"test6\"]";
+    size_t size = strlen(buffer1);
+    microjson::JsonArray arr = microjson::parseJsonArray(buffer1, size);
+    ASSERT_EQ(arr.size(), 5);
+    EXPECT_STREQ(arr[0].value.c_str(), "test1");
+    EXPECT_STREQ(arr[1].value.c_str(), "test2");
+    EXPECT_STREQ(arr[2].value.c_str(), "test3");
+    EXPECT_STREQ(arr[3].value.c_str(), "test5");
+    EXPECT_STREQ(arr[4].value.c_str(), "test6");
+
+    const char *buffer2 = "[\"test1\"]";
+    size = strlen(buffer2);
+    arr = microjson::parseJsonArray(buffer2, size);
+    ASSERT_EQ(arr.size(), 1);
+    EXPECT_STREQ(arr[0].value.c_str(), "test1");
+
+    const char *buffer3 = "[]";
+    size = strlen(buffer3);
+    arr = microjson::parseJsonArray(buffer3, size);
+    ASSERT_EQ(arr.size(), 0);
+
+    const char *buffer4 = "[[\"test1\"]]";
+    size = strlen(buffer4);
+    arr = microjson::parseJsonArray(buffer4, size);
+    ASSERT_EQ(arr.size(), 1);
+    EXPECT_STREQ(arr[0].value.c_str(), "[\"test1\"]");
+
+    const char *buffer5 = "[[],[],[]]";
+    size = strlen(buffer5);
+    arr = microjson::parseJsonArray(buffer5, size);
+    ASSERT_EQ(arr.size(), 3);
+    EXPECT_STREQ(arr[0].value.c_str(), "[]");
+    EXPECT_EQ(arr[0].type, microjson::JsonArrayType);
+    EXPECT_STREQ(arr[1].value.c_str(), "[]");
+    EXPECT_EQ(arr[1].type, microjson::JsonArrayType);
+    EXPECT_STREQ(arr[2].value.c_str(), "[]");
+    EXPECT_EQ(arr[2].type, microjson::JsonArrayType);
+
+    const char *buffer6 = "[[],\"\",0,0.0,false]";
+    size = strlen(buffer6);
+    arr = microjson::parseJsonArray(buffer6, size);
+    ASSERT_EQ(arr.size(), 5);
+    EXPECT_STREQ(arr[0].value.c_str(), "[]");
+    EXPECT_EQ(arr[0].type, microjson::JsonArrayType);
+    EXPECT_STREQ(arr[1].value.c_str(), "");
+    EXPECT_EQ(arr[1].type, microjson::JsonStringType);
+    EXPECT_STREQ(arr[2].value.c_str(), "0");
+    EXPECT_EQ(arr[2].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[3].value.c_str(), "0.0");
+    EXPECT_EQ(arr[3].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[4].value.c_str(), "false");
+    EXPECT_EQ(arr[4].type, microjson::JsonBoolType);
+
+    const char *buffer7 = "[[[1111,2222,3333],[4444,5555,6666]],\"testString\",787,-123,0.0,0.99,1.0,1.2345+e10,false,[false,true],{\"testField1\":[\"testArrayValue1\", 2, 3, 4],\"testField2\":0.1212+e14}]";
+    size = strlen(buffer7);
+    arr = microjson::parseJsonArray(buffer7, size);
+    ASSERT_EQ(arr.size(), 11);
+    EXPECT_STREQ(arr[0].value.c_str(), "[[1111,2222,3333],[4444,5555,6666]]");
+    EXPECT_EQ(arr[0].type, microjson::JsonArrayType);
+    EXPECT_STREQ(arr[1].value.c_str(), "testString");
+    EXPECT_EQ(arr[1].type, microjson::JsonStringType);
+    EXPECT_STREQ(arr[2].value.c_str(), "787");
+    EXPECT_EQ(arr[2].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[3].value.c_str(), "-123");
+    EXPECT_EQ(arr[3].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[4].value.c_str(), "0.0");
+    EXPECT_EQ(arr[4].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[5].value.c_str(), "0.99");
+    EXPECT_EQ(arr[5].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[6].value.c_str(), "1.0");
+    EXPECT_EQ(arr[6].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[7].value.c_str(), "1.2345+e10");
+    EXPECT_EQ(arr[7].type, microjson::JsonNumberType);
+    EXPECT_STREQ(arr[8].value.c_str(), "false");
+    EXPECT_EQ(arr[8].type, microjson::JsonBoolType);
+    EXPECT_STREQ(arr[9].value.c_str(), "[false,true]");
+    EXPECT_EQ(arr[9].type, microjson::JsonArrayType);
+    EXPECT_STREQ(arr[10].value.c_str(), "{\"testField1\":[\"testArrayValue1\", 2, 3, 4],\"testField2\":0.1212+e14}");
+    EXPECT_EQ(arr[10].type, microjson::JsonObjectType);
+}
+
+TEST_F(MicrojsonDeserializationTest, PropertyName) {
+    const char *buffer1 = "{\"testField1\":\"test2\"}";
+    size_t size = strlen(buffer1);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
+    auto it = obj.find("testField1");
+    ASSERT_TRUE(it != obj.end());
+
+    obj.clear();
+    const char *buffer2 = "{\"t\":\"test2\"}";
+    size = strlen(buffer2);
+    obj = microjson::parseJsonObject(buffer2, size);
+    it = obj.find("t");
+    ASSERT_TRUE(it != obj.end());
+
+    obj.clear();
+    const char *buffer3 = "{\"\":\"test2\"}";
+    size = strlen(buffer3);
+    obj = microjson::parseJsonObject(buffer3, size);
+    ASSERT_EQ(obj.size(), 0);
+
+    obj.clear();
+    const char *buffer4 = "{\"\\\"\":\"test2\"}";
+    size = strlen(buffer4);
+    obj = microjson::parseJsonObject(buffer4, size);
+    it = obj.find("\\\"");
+    ASSERT_TRUE(it != obj.end());
+
+    obj.clear();
+    const char *buffer5 = "{\"testField1{\":{\"testField2\":\"test2\"}}";
+    size = strlen(buffer5);
+    obj = microjson::parseJsonObject(buffer5, size);
+    it = obj.find("testField1{");
+    ASSERT_TRUE(it != obj.end());
+    EXPECT_EQ(it->second.type, microjson::JsonObjectType);
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField2\":\"test2\"}");
+
+    obj.clear();
+    const char *buffer6 = "{\"test}Field1}\":{\"testField2\":\"test2\"}}";
+    size = strlen(buffer6);
+    obj = microjson::parseJsonObject(buffer6, size);
+    it = obj.find("test}Field1}");
+    ASSERT_TRUE(it != obj.end());
+    EXPECT_EQ(it->second.type, microjson::JsonObjectType);
+    EXPECT_STREQ(it->second.value.c_str(), "{\"testField2\":\"test2\"}");
+
+    obj.clear();
+    const char *buffer7 = "{\"test[Fiel[d1}\":[\"test1\",\"test2\"]}";
+    size = strlen(buffer7);
+    obj = microjson::parseJsonObject(buffer7, size);
+    it = obj.find("test[Fiel[d1}");
+    ASSERT_TRUE(it != obj.end());
+    EXPECT_EQ(it->second.type, microjson::JsonArrayType);
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\",\"test2\"]");
+
+    obj.clear();
+    const char *buffer8 = "{\"test]Fiel]d1}\":[\"test1\",\"test2\"]}";
+    size = strlen(buffer8);
+    obj = microjson::parseJsonObject(buffer8, size);
+    it = obj.find("test]Fiel]d1}");
+    ASSERT_TRUE(it != obj.end());
+    EXPECT_EQ(it->second.type, microjson::JsonArrayType);
+    EXPECT_STREQ(it->second.value.c_str(), "[\"test1\",\"test2\"]");
+}
+
+TEST_F(MicrojsonDeserializationTest, MixedStringValue) {
+    const char *buffer1 = "{\"testField1\":[\"[[test2\",\"[test2\"]}";
+    size_t size = strlen(buffer1);
+    microjson::JsonObject obj = microjson::parseJsonObject(buffer1, size);
+    auto it = obj.find("testField1");
+    ASSERT_TRUE(it != obj.end());
+    EXPECT_EQ(it->second.type, microjson::JsonArrayType);
+    EXPECT_STREQ(it->second.value.c_str(), "[\"[[test2\",\"[test2\"]");
+
+    const char *buffer2 = "{\"testField1\":{\"test]Fiel]d1}\":[\"[[test2\",\"}test{{2\"]}}";
+    size = strlen(buffer2);
+    obj = microjson::parseJsonObject(buffer2, size);
+    it = obj.find("testField1");
+    ASSERT_TRUE(it != obj.end());
+    EXPECT_EQ(it->second.type, microjson::JsonObjectType);
+    EXPECT_STREQ(it->second.value.c_str(), "{\"test]Fiel]d1}\":[\"[[test2\",\"}test{{2\"]}");
 }