From 3d92531ad36db9ad05a1cd84967289a49995a897 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 15 Oct 2014 23:27:38 +0200 Subject: [PATCH] Parse 'null' --- srcs/Internals/JsonParser.cpp | 102 ++++++++++++++++++------------- srcs/Internals/JsonParser.h | 36 +++++------ srcs/JsonBuffer.cpp | 42 ++++++++----- srcs/JsonBuffer.h | 8 +-- tests/JsonArray_Parser_Tests.cpp | 12 ++++ 5 files changed, 120 insertions(+), 80 deletions(-) diff --git a/srcs/Internals/JsonParser.cpp b/srcs/Internals/JsonParser.cpp index 9949a73a..039807c0 100644 --- a/srcs/Internals/JsonParser.cpp +++ b/srcs/Internals/JsonParser.cpp @@ -3,11 +3,6 @@ #include // for strtol, strtod #include -bool JsonParser::isEnd() -{ - return *_ptr == 0; -} - bool JsonParser::isArrayStart() { return *_ptr == '['; @@ -18,20 +13,14 @@ bool JsonParser::isArrayStop() return *_ptr == ']'; } -bool JsonParser::isLong() +bool JsonParser::isBoolean() { - char* ptr = _ptr; + return *_ptr == 't' || *_ptr == 'f'; +} - // skip all digits - while (isdigit(*ptr)) - ptr++; - - // same position => 0 digits => not a number - if (ptr == _ptr) - return false; - - // stopped on a decimal separator => not a long but a double - return *ptr != '.'; +bool JsonParser::isComma() +{ + return *_ptr == ','; } bool JsonParser::isDouble() @@ -50,21 +39,37 @@ bool JsonParser::isDouble() return *ptr == '.'; } +bool JsonParser::isEnd() +{ + return *_ptr == 0; +} + +bool JsonParser::isLong() +{ + char* ptr = _ptr; + + // skip all digits + while (isdigit(*ptr)) + ptr++; + + // same position => 0 digits => not a number + if (ptr == _ptr) + return false; + + // stopped on a decimal separator => not a long but a double + return *ptr != '.'; +} + +bool JsonParser::isNull() +{ + return *_ptr == 'n'; +} + bool JsonParser::isSpace() { return *_ptr == ' ' || *_ptr == '\t' || *_ptr == '\n' || *_ptr == '\r'; } -bool JsonParser::isComma() -{ - return *_ptr == ','; -} - -bool JsonParser::isBoolean() -{ - return *_ptr == 't' || *_ptr == 'f'; -} - void JsonParser::skipOneChar() { _ptr++; @@ -81,15 +86,18 @@ JsonNode* JsonParser::parseAnything() if (isArrayStart()) return parseArray(); - - if (isLong()) - return parseLong(); - - if (isDouble()) - return parseDouble(); if (isBoolean()) return parseBoolean(); + + if (isDouble()) + return parseDouble(); + + if (isLong()) + return parseLong(); + + if (isNull()) + return parseNull(); return 0; } @@ -124,11 +132,15 @@ JsonNode* JsonParser::parseArray() } } -JsonNode* JsonParser::parseLong() +JsonNode *JsonParser::parseBoolean() { - long value = strtol(_ptr, &_ptr, 10); + bool value = *_ptr == 't'; - return _buffer->createLongNode(value); + _ptr += value ? 4 : 5; + // 4 = strlen("true") + // 5 = strlen("false"); + + return _buffer->createBoolNode(value); } JsonNode *JsonParser::parseDouble() @@ -142,13 +154,17 @@ JsonNode *JsonParser::parseDouble() return _buffer->createDoubleNode(value, decimals); } -JsonNode *JsonParser::parseBoolean() +JsonNode* JsonParser::parseLong() { - bool value = *_ptr == 't'; + long value = strtol(_ptr, &_ptr, 10); - _ptr += value ? 4 : 5; - // 4 = strlen("true") - // 5 = strlen("false"); - - return _buffer->createBoolNode(value); + return _buffer->createLongNode(value); +} + +JsonNode* JsonParser::parseNull() +{ + _ptr += 4; + // 4 = strlen("null") + + return _buffer->createStringNode(0); } diff --git a/srcs/Internals/JsonParser.h b/srcs/Internals/JsonParser.h index 340ffc76..bf40d861 100644 --- a/srcs/Internals/JsonParser.h +++ b/srcs/Internals/JsonParser.h @@ -8,33 +8,35 @@ class JsonBuffer; class JsonParser { public: - JsonParser(JsonBuffer* buffer, char* json) - : _buffer(buffer), _ptr(json) - { + JsonParser(JsonBuffer* buffer, char* json) + : _buffer(buffer), _ptr(json) + { - } + } - JsonNode* parseAnything(); + JsonNode* parseAnything(); private: - JsonBuffer* _buffer; - char* _ptr; + JsonBuffer* _buffer; + char* _ptr; - inline bool isEnd(); - inline bool isArrayStart(); - inline bool isArrayStop(); - inline bool isLong(); - inline bool isDouble(); - inline bool isSpace(); - inline bool isComma(); + inline bool isArrayStart(); + inline bool isArrayStop(); inline bool isBoolean(); + inline bool isComma(); + inline bool isDouble(); + inline bool isEnd(); + inline bool isLong(); + inline bool isNull(); + inline bool isSpace(); - inline void skipOneChar(); - inline void skipSpaces(); + inline void skipOneChar(); + inline void skipSpaces(); inline JsonNode* parseArray(); - inline JsonNode* parseLong(); inline JsonNode* parseBoolean(); + inline JsonNode* parseLong(); + inline JsonNode* parseNull(); JsonNode *parseDouble(); }; \ No newline at end of file diff --git a/srcs/JsonBuffer.cpp b/srcs/JsonBuffer.cpp index 0daf34ae..bc964c6f 100644 --- a/srcs/JsonBuffer.cpp +++ b/srcs/JsonBuffer.cpp @@ -25,7 +25,7 @@ JsonArray JsonBuffer::parseArray(char* json) return JsonArray(parser.parseAnything()); } -JsonNode *JsonBuffer::createArrayNode() +JsonNode* JsonBuffer::createArrayNode() { JsonNode* node = createNode(); @@ -35,27 +35,17 @@ JsonNode *JsonBuffer::createArrayNode() return node; } -JsonNode *JsonBuffer::createObjectNode() +JsonNode* JsonBuffer::createBoolNode(bool value) { JsonNode* node = createNode(); if (node) - node->setAsObject(this); + node->setAsBoolean(value); return node; } -JsonNode *JsonBuffer::createLongNode(long value) -{ - JsonNode* node = createNode(); - - if (node) - node->setAsLong(value); - - return node; -} - -JsonNode *JsonBuffer::createDoubleNode(double value, int decimals) +JsonNode* JsonBuffer::createDoubleNode(double value, int decimals) { JsonNode* node = createNode(); @@ -65,12 +55,32 @@ JsonNode *JsonBuffer::createDoubleNode(double value, int decimals) return node; } -JsonNode *JsonBuffer::createBoolNode(bool value) +JsonNode* JsonBuffer::createLongNode(long value) { JsonNode* node = createNode(); if (node) - node->setAsBoolean(value); + node->setAsLong(value); return node; } + +JsonNode* JsonBuffer::createObjectNode() +{ + JsonNode* node = createNode(); + + if (node) + node->setAsObject(this); + + return node; +} + +JsonNode* JsonBuffer::createStringNode(const char* value) +{ + JsonNode* node = createNode(); + + if (node) + node->setAsString(value); + + return node; +} \ No newline at end of file diff --git a/srcs/JsonBuffer.h b/srcs/JsonBuffer.h index e619d033..092fbc5b 100644 --- a/srcs/JsonBuffer.h +++ b/srcs/JsonBuffer.h @@ -35,10 +35,10 @@ private: JsonNode* createNode(); JsonNode* createArrayNode(); - JsonNode* createObjectNode(); + JsonNode* createBoolNode(bool value); + JsonNode* createDoubleNode(double value, int decimals); JsonNode* createLongNode(long value); - JsonNode *createDoubleNode(double value, int decimals); - - JsonNode *createBoolNode(bool value); + JsonNode* createObjectNode(); + JsonNode* createStringNode(const char* value); }; diff --git a/tests/JsonArray_Parser_Tests.cpp b/tests/JsonArray_Parser_Tests.cpp index b5dc30b8..698fc07a 100644 --- a/tests/JsonArray_Parser_Tests.cpp +++ b/tests/JsonArray_Parser_Tests.cpp @@ -135,4 +135,16 @@ TEST_F(JsonArray_Parser_Tests, TwoBooleans) sizeMustBe(2); firstElementMustBe(true); secondElementMustBe(false); +} + +TEST_F(JsonArray_Parser_Tests, TwoNulls) +{ + const char* const nullCharPtr = 0; + + whenInputIs("[null,null]"); + + parseMustSucceed(); + sizeMustBe(2); + firstElementMustBe(nullCharPtr); + secondElementMustBe(nullCharPtr); } \ No newline at end of file