Parse doubles

This commit is contained in:
Benoit Blanchon
2014-10-15 14:54:31 +02:00
parent a1cb9c9399
commit 086d07151f
5 changed files with 106 additions and 18 deletions

View File

@ -1,6 +1,6 @@
#include "JsonParser.h"
#include "../JsonBuffer.h"
#include <stdlib.h>
#include <stdlib.h> // for strtol, strtod
#include <ctype.h>
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()
@ -67,6 +80,9 @@ JsonNode* JsonParser::parseAnything()
if (isLong())
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;
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);
}

View File

@ -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();
};

View File

@ -24,3 +24,43 @@ JsonArray JsonBuffer::parseArray(char* json)
JsonParser parser(this, json);
return JsonArray(parser.parseAnything());
}
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;
}

View File

@ -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);
};

View File

@ -116,3 +116,22 @@ TEST_F(JsonArray_Parser_Tests, TwoIntegers)
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);
}