diff --git a/srcs/Internals/JsonParser.cpp b/srcs/Internals/JsonParser.cpp new file mode 100644 index 00000000..fa245373 --- /dev/null +++ b/srcs/Internals/JsonParser.cpp @@ -0,0 +1,92 @@ +#include "JsonParser.h" +#include "../JsonBuffer.h" +#include +#include + +bool JsonParser::isEnd() +{ + return *_ptr == 0; +} + +bool JsonParser::isArrayStart() +{ + return *_ptr == '['; +} + +bool JsonParser::isArrayStop() +{ + return *_ptr == ']'; +} + +bool JsonParser::isLong() +{ + char* ptr = _ptr; + + // skip all digits + while (isdigit(*ptr)) + ptr++; + + // same position => 0 digits => not a long + if (ptr == _ptr) + return false; + + // stopped on a decimal separator => not a long but a double + if (*ptr == '.') + return false; + + return true; +} + +bool JsonParser::isSpace() +{ + return *_ptr == ' ' || *_ptr == '\t' || *_ptr == '\n' || *_ptr == '\r'; +} + +void JsonParser::skipOneChar() +{ + _ptr++; +} + +void JsonParser::skipSpaces() +{ + while(isSpace()) skipOneChar(); +} + +JsonNode* JsonParser::parseNode() +{ + skipSpaces(); + + if (isArrayStart()) + return parseArray(); + + if (isLong()) + return parseLong(); + + return 0; +} + +JsonNode* JsonParser::parseArray() +{ + skipOneChar(); + + JsonNode* node = _buffer->createNode(); + node->setAsArray(_buffer); + + skipSpaces(); + + if (isArrayStop()) + return node; + + node->addChild(parseNode()); + + return node; +} + +JsonNode* JsonParser::parseLong() +{ + long value = strtol(_ptr, &_ptr, 10); + + JsonNode* node = _buffer->createNode(); + node->setAsLong(value); + return node; +} \ No newline at end of file diff --git a/srcs/Internals/JsonParser.h b/srcs/Internals/JsonParser.h new file mode 100644 index 00000000..fa03369f --- /dev/null +++ b/srcs/Internals/JsonParser.h @@ -0,0 +1,29 @@ +#pragma once + +class JsonNode; +class JsonBuffer; + +class JsonParser +{ +public: + JsonParser(JsonBuffer* buffer, char* json) + : _buffer(buffer), _ptr(json) + { + + } + + JsonNode* parseNode(); + JsonNode* parseArray(); + JsonNode* parseLong(); +private: + JsonBuffer* _buffer; + char* _ptr; + + inline bool isEnd(); + inline bool isArrayStart(); + inline bool isArrayStop(); + inline bool isLong(); + inline bool isSpace(); + inline void skipOneChar(); + inline void skipSpaces(); +}; \ No newline at end of file diff --git a/srcs/JsonBuffer.cpp b/srcs/JsonBuffer.cpp index 5d1228f9..6eaec7a3 100644 --- a/srcs/JsonBuffer.cpp +++ b/srcs/JsonBuffer.cpp @@ -3,6 +3,7 @@ #include #include "JsonValue.h" +#include "Internals/JsonParser.h" #include "Internals/JsonNode.h" JsonValue JsonBuffer::createValue() @@ -18,21 +19,8 @@ JsonNode* JsonBuffer::createNode() return new (node) JsonNode(); } -JsonArray JsonBuffer::parseArray(const char* json) +JsonArray JsonBuffer::parseArray(char* json) { - JsonNode* root; - - while(*json == ' ') json++; - - if (json[0] == '[') - { - root = createNode(); - root->setAsArray(this); - } - else - { - root = 0; - } - - return JsonArray(root); + JsonParser parser(this, json); + return JsonArray(parser.parseNode()); } \ No newline at end of file diff --git a/srcs/JsonBuffer.h b/srcs/JsonBuffer.h index df6704a2..dd3edd5f 100644 --- a/srcs/JsonBuffer.h +++ b/srcs/JsonBuffer.h @@ -3,10 +3,13 @@ #include "JsonArray.h" #include "JsonObject.h" +class JsonParser; + class JsonBuffer { friend class JsonContainer; friend class JsonNode; + friend class JsonParser; public: virtual ~JsonBuffer() {}; @@ -27,7 +30,7 @@ public: JsonValue createValue(); - JsonArray parseArray(char const *string); + JsonArray parseArray(char* string); protected: virtual void* allocateNode() = 0; diff --git a/tests/JsonArray_Container_Tests.cpp b/tests/JsonArray_Container_Tests.cpp index e52defc6..2b9438c1 100644 --- a/tests/JsonArray_Container_Tests.cpp +++ b/tests/JsonArray_Container_Tests.cpp @@ -92,11 +92,14 @@ TEST_F(JsonArray_Container_Tests, CanStoreBooleans) TEST_F(JsonArray_Container_Tests, CanStoreStrings) { - array.add("h3110"); - array.add("w0r1d"); + const char* firstString = "h3110"; + const char* secondString = "w0r1d"; - firstElementMustBe("h3110"); - secondElementMustBe("w0r1d"); + array.add(firstString); + array.add(secondString); + + firstElementMustBe(firstString); + secondElementMustBe(secondString); nodeCountMustBe(3); } diff --git a/tests/JsonArray_Parser_Tests.cpp b/tests/JsonArray_Parser_Tests.cpp index e6baa36b..8f8ada61 100644 --- a/tests/JsonArray_Parser_Tests.cpp +++ b/tests/JsonArray_Parser_Tests.cpp @@ -1,5 +1,6 @@ #include #include +#include class JsonArray_Parser_Tests : public testing::Test { @@ -29,4 +30,13 @@ TEST_F(JsonArray_Parser_Tests, Garbage) EXPECT_FALSE(array.success()); EXPECT_EQ(0, array.size()); +} + +TEST_F(JsonArray_Parser_Tests, OneInteger) +{ + JsonArray array = json.parseArray("[42]"); + + EXPECT_TRUE(array.success()); + EXPECT_EQ(1, array.size()); + EXPECT_EQ(42, static_cast(array[0])); } \ No newline at end of file