From 086d07151f171bd363288454b26bcb10a524ad1c Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 15 Oct 2014 14:54:31 +0200 Subject: [PATCH] Parse doubles --- srcs/Internals/JsonParser.cpp | 45 ++++++++++++++++++++++++-------- srcs/Internals/JsonParser.h | 5 ++++ srcs/JsonBuffer.cpp | 42 ++++++++++++++++++++++++++++- srcs/JsonBuffer.h | 13 ++++----- tests/JsonArray_Parser_Tests.cpp | 19 ++++++++++++++ 5 files changed, 106 insertions(+), 18 deletions(-) diff --git a/srcs/Internals/JsonParser.cpp b/srcs/Internals/JsonParser.cpp index bf145371..abdefdfb 100644 --- a/srcs/Internals/JsonParser.cpp +++ b/srcs/Internals/JsonParser.cpp @@ -1,6 +1,6 @@ #include "JsonParser.h" #include "../JsonBuffer.h" -#include +#include // for strtol, strtod #include bool JsonParser::isEnd() @@ -26,15 +26,28 @@ bool JsonParser::isLong() while (isdigit(*ptr)) ptr++; - // same position => 0 digits => not a long + // same position => 0 digits => not a number if (ptr == _ptr) return false; // stopped on a decimal separator => not a long but a double - if (*ptr == '.') + return *ptr != '.'; +} + +bool JsonParser::isDouble() +{ + char* ptr = _ptr; + + // skip all digits + while (isdigit(*ptr)) + ptr++; + + // same position => 0 digits => not a number + if (ptr == _ptr) return false; - return true; + // stopped on a decimal separator => ok it's a double + return *ptr == '.'; } bool JsonParser::isSpace() @@ -65,7 +78,10 @@ JsonNode* JsonParser::parseAnything() return parseArray(); if (isLong()) - return parseLong(); + return parseLong(); + + if (isDouble()) + return parseDouble(); return 0; } @@ -98,15 +114,22 @@ JsonNode* JsonParser::parseArray() skipOneChar(); // skip the ',' } - - 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 + return _buffer->createLongNode(value); +} + +JsonNode *JsonParser::parseDouble() +{ + double value = strtod(_ptr, &_ptr); + + int decimals = 0; + while(_ptr[1-decimals] != '.') + decimals++; + + return _buffer->createDoubleNode(value, decimals); +} diff --git a/srcs/Internals/JsonParser.h b/srcs/Internals/JsonParser.h index 395f9846..acab613f 100644 --- a/srcs/Internals/JsonParser.h +++ b/srcs/Internals/JsonParser.h @@ -1,3 +1,5 @@ +#include "JsonNode.h" + #pragma once class JsonNode; @@ -22,6 +24,7 @@ private: inline bool isArrayStart(); inline bool isArrayStop(); inline bool isLong(); + inline bool isDouble(); inline bool isSpace(); inline bool isComma(); @@ -30,4 +33,6 @@ private: inline JsonNode* parseArray(); inline JsonNode* parseLong(); + + JsonNode *parseDouble(); }; \ No newline at end of file diff --git a/srcs/JsonBuffer.cpp b/srcs/JsonBuffer.cpp index 292c9d66..b3f93869 100644 --- a/srcs/JsonBuffer.cpp +++ b/srcs/JsonBuffer.cpp @@ -23,4 +23,44 @@ JsonArray JsonBuffer::parseArray(char* json) { JsonParser parser(this, json); return JsonArray(parser.parseAnything()); -} \ No newline at end of file +} + +JsonNode *JsonBuffer::createArrayNode() +{ + JsonNode* node = createNode(); + + if (node) + node->setAsArray(this); + + return node; +} + +JsonNode *JsonBuffer::createObjectNode() +{ + JsonNode* node = createNode(); + + if (node) + node->setAsObject(this); + + 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* node = createNode(); + + if (node) + node->setAsDouble(value, decimals); + + return node; +} diff --git a/srcs/JsonBuffer.h b/srcs/JsonBuffer.h index dd3edd5f..9041b539 100644 --- a/srcs/JsonBuffer.h +++ b/srcs/JsonBuffer.h @@ -16,16 +16,12 @@ public: JsonArray createArray() { - JsonNode* node = createNode(); - if (node) node->setAsArray(this); - return JsonArray(node); + return JsonArray(createArrayNode()); } JsonObject createObject() { - JsonNode* node = createNode(); - if (node) node->setAsObject(this); - return JsonObject(node); + return JsonObject(createObjectNode()); } JsonValue createValue(); @@ -37,5 +33,10 @@ protected: private: JsonNode* createNode(); + + JsonNode* createArrayNode(); + JsonNode* createObjectNode(); + JsonNode* createLongNode(long value); + JsonNode *createDoubleNode(double value, int decimals); }; diff --git a/tests/JsonArray_Parser_Tests.cpp b/tests/JsonArray_Parser_Tests.cpp index ce355c0c..e0c5e7f0 100644 --- a/tests/JsonArray_Parser_Tests.cpp +++ b/tests/JsonArray_Parser_Tests.cpp @@ -115,4 +115,23 @@ TEST_F(JsonArray_Parser_Tests, TwoIntegers) sizeMustBe(2); firstElementMustBe(42); secondElementMustBe(84); +} + +TEST_F(JsonArray_Parser_Tests, OneDouble) +{ + whenInputIs("[4.2]"); + + parseMustSucceed(); + sizeMustBe(1); + firstElementMustBe(4.2); +} + +TEST_F(JsonArray_Parser_Tests, TwoDoubles) +{ + whenInputIs("[4.2,8.4]"); + + parseMustSucceed(); + sizeMustBe(2); + firstElementMustBe(4.2); + secondElementMustBe(8.4); } \ No newline at end of file