JsonVariantImpl.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright Benoit Blanchon 2014-2017
  2. // MIT License
  3. //
  4. // Arduino JSON library
  5. // https://github.com/bblanchon/ArduinoJson
  6. // If you like this project, please add a star!
  7. #pragma once
  8. #include "Configuration.hpp"
  9. #include "JsonArray.hpp"
  10. #include "JsonObject.hpp"
  11. #include "JsonVariant.hpp"
  12. #include "Polyfills/isFloat.hpp"
  13. #include "Polyfills/isInteger.hpp"
  14. #include "Polyfills/parseFloat.hpp"
  15. #include "Polyfills/parseInteger.hpp"
  16. #include <string.h> // for strcmp
  17. namespace ArduinoJson {
  18. inline JsonVariant::JsonVariant(const JsonArray &array) {
  19. if (array.success()) {
  20. _type = Internals::JSON_ARRAY;
  21. _content.asArray = const_cast<JsonArray *>(&array);
  22. } else {
  23. _type = Internals::JSON_UNDEFINED;
  24. }
  25. }
  26. inline JsonVariant::JsonVariant(const JsonObject &object) {
  27. if (object.success()) {
  28. _type = Internals::JSON_OBJECT;
  29. _content.asObject = const_cast<JsonObject *>(&object);
  30. } else {
  31. _type = Internals::JSON_UNDEFINED;
  32. }
  33. }
  34. inline JsonArray &JsonVariant::variantAsArray() const {
  35. if (_type == Internals::JSON_ARRAY) return *_content.asArray;
  36. return JsonArray::invalid();
  37. }
  38. inline JsonObject &JsonVariant::variantAsObject() const {
  39. if (_type == Internals::JSON_OBJECT) return *_content.asObject;
  40. return JsonObject::invalid();
  41. }
  42. template <typename T>
  43. inline T JsonVariant::variantAsInteger() const {
  44. using namespace Internals;
  45. switch (_type) {
  46. case JSON_UNDEFINED:
  47. return 0;
  48. case JSON_POSITIVE_INTEGER:
  49. case JSON_BOOLEAN:
  50. return static_cast<T>(_content.asInteger);
  51. case JSON_NEGATIVE_INTEGER:
  52. return static_cast<T>(_content.asInteger * -1);
  53. case JSON_STRING:
  54. case JSON_UNPARSED:
  55. if (!_content.asString) return 0;
  56. if (!strcmp("true", _content.asString)) return 1;
  57. return Polyfills::parseInteger<T>(_content.asString);
  58. default:
  59. return static_cast<T>(_content.asFloat);
  60. }
  61. }
  62. inline const char *JsonVariant::variantAsString() const {
  63. using namespace Internals;
  64. if (_type == JSON_UNPARSED && _content.asString &&
  65. !strcmp("null", _content.asString))
  66. return NULL;
  67. if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
  68. return NULL;
  69. }
  70. template <typename T>
  71. inline T JsonVariant::variantAsFloat() const {
  72. using namespace Internals;
  73. switch (_type) {
  74. case JSON_UNDEFINED:
  75. return 0;
  76. case JSON_POSITIVE_INTEGER:
  77. case JSON_BOOLEAN:
  78. return static_cast<T>(_content.asInteger);
  79. case JSON_NEGATIVE_INTEGER:
  80. return -static_cast<T>(_content.asInteger);
  81. case JSON_STRING:
  82. case JSON_UNPARSED:
  83. return Polyfills::parseFloat<T>(_content.asString);
  84. default:
  85. return static_cast<T>(_content.asFloat);
  86. }
  87. }
  88. inline bool JsonVariant::variantIsBoolean() const {
  89. using namespace Internals;
  90. if (_type == JSON_BOOLEAN) return true;
  91. if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
  92. return !strcmp(_content.asString, "true") ||
  93. !strcmp(_content.asString, "false");
  94. }
  95. inline bool JsonVariant::variantIsInteger() const {
  96. using namespace Internals;
  97. return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER ||
  98. (_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString));
  99. }
  100. inline bool JsonVariant::variantIsFloat() const {
  101. using namespace Internals;
  102. return _type >= JSON_FLOAT_0_DECIMALS ||
  103. (_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString));
  104. }
  105. #if ARDUINOJSON_ENABLE_STD_STREAM
  106. inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
  107. return source.printTo(os);
  108. }
  109. #endif
  110. } // namespace ArduinoJson