mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-14 19:16:35 +02:00
Fixed negative number parsing
This commit is contained in:
@ -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();
|
||||
};
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
Reference in New Issue
Block a user