mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-15 03:26:39 +02:00
Fixed negative number parsing
This commit is contained in:
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
return parseArray();
|
{
|
||||||
|
case '[':
|
||||||
|
return parseArray();
|
||||||
|
|
||||||
if (isBoolean())
|
case 't':
|
||||||
return parseBoolean();
|
case 'f':
|
||||||
|
return parseBoolean();
|
||||||
if (isDouble())
|
|
||||||
return parseDouble();
|
|
||||||
|
|
||||||
if (isLong())
|
case '-':
|
||||||
return parseLong();
|
case '.':
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
return parseNumber();
|
||||||
|
|
||||||
if (isNull())
|
case 'n':
|
||||||
return parseNull();
|
return parseNull();
|
||||||
|
|
||||||
if (isObjectStart())
|
case '{':
|
||||||
return parseObject();
|
return parseObject();
|
||||||
|
|
||||||
return parseString();
|
case '\'':
|
||||||
|
case '\"':
|
||||||
|
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()
|
||||||
{
|
{
|
||||||
double value = strtod(_ptr, &_ptr);
|
char* endOfLong;
|
||||||
|
long longValue = strtol(_ptr, &endOfLong, 10);
|
||||||
|
|
||||||
int decimals = 0;
|
if (*endOfLong == '.') // stopped on a decimal separator
|
||||||
while(_ptr[1-decimals] != '.')
|
{
|
||||||
decimals++;
|
double value = strtod(_ptr, &_ptr);
|
||||||
|
int decimals = _ptr - endOfLong - 1;
|
||||||
return _buffer->createDoubleNode(value, decimals);
|
return _buffer->createDoubleNode(value, decimals);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
JsonNode* JsonParser::parseLong()
|
{
|
||||||
{
|
_ptr = endOfLong;
|
||||||
long value = strtol(_ptr, &_ptr, 10);
|
return _buffer->createLongNode(longValue);
|
||||||
|
}
|
||||||
return _buffer->createLongNode(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode* JsonParser::parseNull()
|
JsonNode* JsonParser::parseNull()
|
||||||
|
@ -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;
|
||||||
@ -148,4 +154,22 @@ TEST_F(JsonParser_Object_Test, EndingWithAComma)
|
|||||||
whenInputIs("{\"key1\":\"value1\",}");
|
whenInputIs("{\"key1\":\"value1\",}");
|
||||||
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);
|
||||||
}
|
}
|
Reference in New Issue
Block a user