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; JsonBuffer* _buffer;
char* _ptr; char* _ptr;
inline bool isArrayStart(); bool isEnd()
inline bool isBoolean(); {
inline bool isDouble(); return *_ptr == 0;
inline bool isEnd(); }
inline bool isLong();
inline bool isNull();
inline bool isObjectStart();
bool skip(char charToSkip); bool skip(char charToSkip);
void skipSpaces(); void skipSpaces();
inline JsonNode* parseArray(); inline JsonNode* parseArray();
inline JsonNode* parseBoolean(); inline JsonNode* parseBoolean();
inline JsonNode *parseDouble();
inline JsonNode* parseObjectKeyValue();
inline JsonNode* parseLong();
inline JsonNode* parseNull(); inline JsonNode* parseNull();
inline JsonNode* parseNumber();
inline JsonNode* parseObject(); inline JsonNode* parseObject();
inline JsonNode* parseObjectKeyValue();
inline JsonNode* parseString(); inline JsonNode* parseString();
}; };
} }

View File

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

View File

@ -34,6 +34,12 @@ protected:
EXPECT_STREQ(expected, static_cast<const char*>(_object[key])); 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: private:
StaticJsonBuffer<10> _jsonBuffer; StaticJsonBuffer<10> _jsonBuffer;
JsonObject _object; JsonObject _object;
@ -149,3 +155,21 @@ TEST_F(JsonParser_Object_Test, EndingWithAComma)
parseMustFail(); parseMustFail();
sizeMustBe(0); 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);
}