Fixed negative number parsing

This commit is contained in:
Benoit Blanchon
2014-10-22 15:51:55 +02:00
parent 5aefc7d652
commit 1e0464f5b4
3 changed files with 75 additions and 95 deletions

View File

@ -25,24 +25,20 @@ namespace ArduinoJson
JsonBuffer* _buffer;
char* _ptr;
inline bool isArrayStart();
inline bool isBoolean();
inline bool isDouble();
inline bool isEnd();
inline bool isLong();
inline bool isNull();
inline bool isObjectStart();
bool isEnd()
{
return *_ptr == 0;
}
bool skip(char charToSkip);
void skipSpaces();
inline JsonNode* parseArray();
inline JsonNode* parseBoolean();
inline JsonNode *parseDouble();
inline JsonNode* parseObjectKeyValue();
inline JsonNode* parseLong();
inline JsonNode* parseNull();
inline JsonNode* parseNumber();
inline JsonNode* parseObject();
inline JsonNode* parseObjectKeyValue();
inline JsonNode* parseString();
};
}

View File

@ -8,63 +8,6 @@
using namespace ArduinoJson::Internals;
bool JsonParser::isArrayStart()
{
return *_ptr == '[';
}
bool JsonParser::isBoolean()
{
return *_ptr == 't' || *_ptr == 'f';
}
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;
// stopped on a decimal separator => ok it's a double
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::isObjectStart()
{
return *_ptr == '{';
}
void JsonParser::skipSpaces()
{
while(isspace(*_ptr)) _ptr++;
@ -83,25 +26,42 @@ JsonNode* JsonParser::parseAnything()
{
skipSpaces();
if (isArrayStart())
switch(*_ptr)
{
case '[':
return parseArray();
if (isBoolean())
case 't':
case 'f':
return parseBoolean();
if (isDouble())
return parseDouble();
case '-':
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return parseNumber();
if (isLong())
return parseLong();
if (isNull())
case 'n':
return parseNull();
if (isObjectStart())
case '{':
return parseObject();
case '\'':
case '\"':
return parseString();
default:
return NULL; // invalid JSON
}
}
JsonNode* JsonParser::parseArray()
@ -144,22 +104,22 @@ JsonNode *JsonParser::parseBoolean()
return _buffer->createBoolNode(value);
}
JsonNode *JsonParser::parseDouble()
JsonNode* JsonParser::parseNumber()
{
char* endOfLong;
long longValue = strtol(_ptr, &endOfLong, 10);
if (*endOfLong == '.') // stopped on a decimal separator
{
double value = strtod(_ptr, &_ptr);
int decimals = 0;
while(_ptr[1-decimals] != '.')
decimals++;
int decimals = _ptr - endOfLong - 1;
return _buffer->createDoubleNode(value, decimals);
}
JsonNode* JsonParser::parseLong()
else
{
long value = strtol(_ptr, &_ptr, 10);
return _buffer->createLongNode(value);
_ptr = endOfLong;
return _buffer->createLongNode(longValue);
}
}
JsonNode* JsonParser::parseNull()

View File

@ -34,6 +34,12 @@ protected:
EXPECT_STREQ(expected, static_cast<const char*>(_object[key]));
}
template<typename T>
void keyMustHaveValue(const char* key, T expected)
{
EXPECT_EQ(expected, static_cast<T>(_object[key]));
}
private:
StaticJsonBuffer<10> _jsonBuffer;
JsonObject _object;
@ -149,3 +155,21 @@ TEST_F(JsonParser_Object_Test, EndingWithAComma)
parseMustFail();
sizeMustBe(0);
}
TEST_F(JsonParser_Object_Test, TwoIntergers)
{
whenInputIs("{\"key1\":42,\"key2\":-42}");
parseMustSucceed();
sizeMustBe(2);
keyMustHaveValue("key1", 42);
keyMustHaveValue("key2", -42);
}
TEST_F(JsonParser_Object_Test, TwoDoubles)
{
whenInputIs("{\"key1\":12.345,\"key2\":-7.89}");
parseMustSucceed();
sizeMustBe(2);
keyMustHaveValue("key1", 12.345);
keyMustHaveValue("key2", -7.89);
}