Store parsed token as string and allow conversion between various types (issues #64, #69, #90, #93)

This commit is contained in:
Benoit Blanchon
2015-08-10 17:22:22 +02:00
parent bce101578d
commit ef2641b49b
29 changed files with 686 additions and 274 deletions

View File

@ -9,22 +9,111 @@
#include "../include/ArduinoJson/JsonArray.hpp"
#include "../include/ArduinoJson/JsonObject.hpp"
using namespace ArduinoJson;
#include <errno.h> // for errno
#include <stdlib.h> // for strtol, strtod
using namespace ArduinoJson::Internals;
void JsonVariant::writeTo(JsonWriter &writer) const {
if (is<const JsonArray &>())
as<const JsonArray &>().writeTo(writer);
else if (is<const JsonObject &>())
as<const JsonObject &>().writeTo(writer);
else if (is<const char *>())
writer.writeString(as<const char *>());
else if (is<long>())
writer.writeLong(as<long>());
else if (is<bool>())
writer.writeBoolean(as<bool>());
else if (is<double>()) {
namespace ArduinoJson {
template <>
const char *JsonVariant::as<const char *>() const {
if (_type == JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString))
return NULL;
if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
return NULL;
}
template <>
double JsonVariant::as<double>() const {
if (_type >= JSON_DOUBLE_0_DECIMALS) return _content.asDouble;
if (_type == JSON_LONG || _type == JSON_BOOLEAN)
return static_cast<double>(_content.asLong);
if ((_type == JSON_STRING || _type == JSON_UNPARSED) && _content.asString)
return strtod(_content.asString, NULL);
return 0.0;
}
template <>
long JsonVariant::as<long>() const {
if (_type == JSON_LONG || _type == JSON_BOOLEAN) return _content.asLong;
if (_type >= JSON_DOUBLE_0_DECIMALS)
return static_cast<long>(_content.asDouble);
if ((_type == JSON_STRING || _type == JSON_UNPARSED) && _content.asString) {
if (!strcmp("true", _content.asString)) return 1;
return strtol(_content.asString, NULL, 10);
}
return 0L;
}
template <>
String JsonVariant::as<String>() const {
if ((_type == JSON_STRING || _type == JSON_UNPARSED) &&
_content.asString != NULL)
return String(_content.asString);
if (_type == JSON_LONG || _type == JSON_BOOLEAN)
return String(_content.asLong);
if (_type >= JSON_DOUBLE_0_DECIMALS) {
uint8_t decimals = static_cast<uint8_t>(_type - JSON_DOUBLE_0_DECIMALS);
writer.writeDouble(as<double>(), decimals);
return String(_content.asDouble, decimals);
}
String s;
printTo(s);
return s;
}
template <>
bool JsonVariant::is<signed long>() const {
if (_type == JSON_LONG) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtol(_content.asString, &end, 10);
return *end == '\0' && errno == 0;
}
template <>
bool JsonVariant::is<double>() const {
if (_type >= JSON_DOUBLE_0_DECIMALS) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtod(_content.asString, &end);
return *end == '\0' && errno == 0 && !is<long>();
}
void JsonVariant::writeTo(JsonWriter &writer) const {
if (_type == JSON_ARRAY) _content.asArray->writeTo(writer);
if (_type == JSON_OBJECT) _content.asObject->writeTo(writer);
if (_type == JSON_STRING) writer.writeString(_content.asString);
if (_type == JSON_UNPARSED) writer.writeRaw(_content.asString);
if (_type == JSON_LONG) writer.writeLong(_content.asLong);
if (_type == JSON_BOOLEAN) writer.writeBoolean(_content.asLong);
if (_type >= JSON_DOUBLE_0_DECIMALS) {
uint8_t decimals = static_cast<uint8_t>(_type - JSON_DOUBLE_0_DECIMALS);
writer.writeDouble(_content.asDouble, decimals);
}
}
}