Parse long values

This commit is contained in:
Benoit Blanchon
2014-10-14 21:24:26 +02:00
parent 31c1a3d804
commit 5b6b38564f
6 changed files with 146 additions and 21 deletions

View File

@ -0,0 +1,92 @@
#include "JsonParser.h"
#include "../JsonBuffer.h"
#include <stdlib.h>
#include <ctype.h>
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;
}

View File

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

View File

@ -3,6 +3,7 @@
#include <new> #include <new>
#include "JsonValue.h" #include "JsonValue.h"
#include "Internals/JsonParser.h"
#include "Internals/JsonNode.h" #include "Internals/JsonNode.h"
JsonValue JsonBuffer::createValue() JsonValue JsonBuffer::createValue()
@ -18,21 +19,8 @@ JsonNode* JsonBuffer::createNode()
return new (node) JsonNode(); return new (node) JsonNode();
} }
JsonArray JsonBuffer::parseArray(const char* json) JsonArray JsonBuffer::parseArray(char* json)
{ {
JsonNode* root; JsonParser parser(this, json);
return JsonArray(parser.parseNode());
while(*json == ' ') json++;
if (json[0] == '[')
{
root = createNode();
root->setAsArray(this);
}
else
{
root = 0;
}
return JsonArray(root);
} }

View File

@ -3,10 +3,13 @@
#include "JsonArray.h" #include "JsonArray.h"
#include "JsonObject.h" #include "JsonObject.h"
class JsonParser;
class JsonBuffer class JsonBuffer
{ {
friend class JsonContainer; friend class JsonContainer;
friend class JsonNode; friend class JsonNode;
friend class JsonParser;
public: public:
virtual ~JsonBuffer() {}; virtual ~JsonBuffer() {};
@ -27,7 +30,7 @@ public:
JsonValue createValue(); JsonValue createValue();
JsonArray parseArray(char const *string); JsonArray parseArray(char* string);
protected: protected:
virtual void* allocateNode() = 0; virtual void* allocateNode() = 0;

View File

@ -92,11 +92,14 @@ TEST_F(JsonArray_Container_Tests, CanStoreBooleans)
TEST_F(JsonArray_Container_Tests, CanStoreStrings) TEST_F(JsonArray_Container_Tests, CanStoreStrings)
{ {
array.add("h3110"); const char* firstString = "h3110";
array.add("w0r1d"); const char* secondString = "w0r1d";
firstElementMustBe("h3110"); array.add(firstString);
secondElementMustBe("w0r1d"); array.add(secondString);
firstElementMustBe(firstString);
secondElementMustBe(secondString);
nodeCountMustBe(3); nodeCountMustBe(3);
} }

View File

@ -1,5 +1,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <StaticJsonBuffer.h> #include <StaticJsonBuffer.h>
#include <JsonValue.h>
class JsonArray_Parser_Tests : public testing::Test class JsonArray_Parser_Tests : public testing::Test
{ {
@ -30,3 +31,12 @@ TEST_F(JsonArray_Parser_Tests, Garbage)
EXPECT_FALSE(array.success()); EXPECT_FALSE(array.success());
EXPECT_EQ(0, array.size()); 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<int>(array[0]));
}