Skip to content

Commit

Permalink
Use float instead of double to reduce the size of JsonVariant (…
Browse files Browse the repository at this point in the history
…issue #134)
  • Loading branch information
bblanchon committed Oct 30, 2015
1 parent 9f3ce18 commit c0cf9c3
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 81 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ v5.0.5
------

* Add overload `JsonObjectSuscript::set(value, decimals)` (issue #143)
* Use `float` instead of `double` to reduce the size of `JsonVariant` (issue #134)

v5.0.4
------
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ data.add(2.302038, 6); // if not specified, 2 digits are printed
root.printTo(Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
``
```


Documentation
Expand Down
1 change: 1 addition & 0 deletions include/ArduinoJson/Arduino/Print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Print {

size_t print(const char[]);
size_t print(double, int = 2);
size_t print(int);
size_t print(long);
size_t println();
};
Expand Down
1 change: 1 addition & 0 deletions include/ArduinoJson/Arduino/String.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class String : public std::string {
String(const char *cstr = "") : std::string(cstr) {}
String(const String &str) : std::string(str) {}
explicit String(long);
explicit String(int);
explicit String(double, unsigned char decimalPlaces = 2);
};

Expand Down
20 changes: 20 additions & 0 deletions include/ArduinoJson/Internals/JsonFloat.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright Benoit Blanchon 2014-2015
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#pragma once

namespace ArduinoJson {
namespace Internals {

#ifdef ARDUINO
// On embedded platform, we with use float instead of double to keep JsonVariant
// small (issue #134)
typedef float JsonFloat;
#else
typedef double JsonFloat;
#endif
}
}
13 changes: 13 additions & 0 deletions include/ArduinoJson/Internals/JsonInteger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright Benoit Blanchon 2014-2015
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#pragma once

namespace ArduinoJson {
namespace Internals {
typedef long JsonInteger;
}
}
14 changes: 8 additions & 6 deletions include/ArduinoJson/Internals/JsonVariantContent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,24 @@

#pragma once

#include "JsonFloat.hpp"
#include "JsonInteger.hpp"

namespace ArduinoJson {

// Forward declarations
class JsonArray;
class JsonObject;

namespace Internals {

// A union that defines the actual content of a JsonVariant.
// The enum JsonVariantType determines which member is in use.
union JsonVariantContent {
double asDouble; // asDouble is also used for float
long asLong; // asLong is also used for bool, char, short and int
const char* asString; // asString can be null
JsonArray* asArray; // asArray cannot be null
JsonObject* asObject; // asObject cannot be null
JsonFloat asFloat; // used for double and float
JsonInteger asInteger; // used for bool, char, short, int and longs
const char* asString; // asString can be null
JsonArray* asArray; // asArray cannot be null
JsonObject* asObject; // asObject cannot be null
};
}
}
10 changes: 5 additions & 5 deletions include/ArduinoJson/Internals/JsonVariantType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ enum JsonVariantType {
JSON_UNPARSED, // the JsonVariant contains an unparsed string
JSON_STRING, // the JsonVariant stores a const char*
JSON_BOOLEAN, // the JsonVariant stores a bool
JSON_LONG, // the JsonVariant stores a long
JSON_INTEGER, // the JsonVariant stores an integer
JSON_ARRAY, // the JsonVariant stores a pointer to a JsonArray
JSON_OBJECT, // the JsonVariant stores a pointer to a JsonObject

// The following values are reserved for double values
// The following values are reserved for float values
// Multiple values are used for double, depending on the number of decimal
// digits that must be printed in the JSON output.
// This little trick allow to save one extra member in JsonVariant
JSON_DOUBLE_0_DECIMALS
// JSON_DOUBLE_1_DECIMAL
// JSON_DOUBLE_2_DECIMALS
JSON_FLOAT_0_DECIMALS
// JSON_FLOAT_1_DECIMAL
// JSON_FLOAT_2_DECIMALS
// ...
};
}
Expand Down
6 changes: 4 additions & 2 deletions include/ArduinoJson/Internals/JsonWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "../Arduino/Print.hpp"
#include "Encoding.hpp"
#include "ForceInline.hpp"
#include "JsonFloat.hpp"
#include "JsonInteger.hpp"

namespace ArduinoJson {
namespace Internals {
Expand Down Expand Up @@ -60,9 +62,9 @@ class JsonWriter {
}
}

void writeLong(long value) { _length += _sink.print(value); }
void writeInteger(JsonInteger value) { _length += _sink.print(value); }

void writeDouble(double value, uint8_t decimals) {
void writeFloat(JsonFloat value, uint8_t decimals) {
_length += _sink.print(value, decimals);
}

Expand Down
6 changes: 3 additions & 3 deletions include/ArduinoJson/Internals/StaticStringBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Internals {
// A Print implementation that allows to write in a char[]
class StaticStringBuilder : public Print {
public:
StaticStringBuilder(char *buf, int size)
StaticStringBuilder(char *buf, size_t size)
: buffer(buf), capacity(size - 1), length(0) {
buffer[0] = '\0';
}
Expand All @@ -23,8 +23,8 @@ class StaticStringBuilder : public Print {

private:
char *buffer;
int capacity;
int length;
size_t capacity;
size_t length;
};
}
}
3 changes: 3 additions & 0 deletions include/ArduinoJson/JsonVariant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
static T invalid();

private:
Internals::JsonFloat asFloat() const;
Internals::JsonInteger asInteger() const;

// The current type of the variant
Internals::JsonVariantType _type;

Expand Down
91 changes: 52 additions & 39 deletions include/ArduinoJson/JsonVariant.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
namespace ArduinoJson {

inline JsonVariant::JsonVariant(bool value) {
_type = Internals::JSON_BOOLEAN;
_content.asLong = value;
using namespace Internals;
_type = JSON_BOOLEAN;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(const char *value) {
Expand All @@ -26,15 +27,15 @@ inline JsonVariant::JsonVariant(Internals::Unparsed value) {
}

inline JsonVariant::JsonVariant(double value, uint8_t decimals) {
_type = static_cast<Internals::JsonVariantType>(
Internals::JSON_DOUBLE_0_DECIMALS + decimals);
_content.asDouble = value;
using namespace Internals;
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
_content.asFloat = static_cast<JsonFloat>(value);
}

inline JsonVariant::JsonVariant(float value, uint8_t decimals) {
_type = static_cast<Internals::JsonVariantType>(
Internals::JSON_DOUBLE_0_DECIMALS + decimals);
_content.asDouble = value;
using namespace Internals;
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
_content.asFloat = static_cast<JsonFloat>(value);
}

inline JsonVariant::JsonVariant(JsonArray &array) {
Expand All @@ -48,51 +49,53 @@ inline JsonVariant::JsonVariant(JsonObject &object) {
}

inline JsonVariant::JsonVariant(signed char value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(signed int value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(signed long value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(signed short value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(unsigned char value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(unsigned int value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(unsigned long value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

inline JsonVariant::JsonVariant(unsigned short value) {
_type = Internals::JSON_LONG;
_content.asLong = value;
using namespace Internals;
_type = JSON_INTEGER;
_content.asInteger = static_cast<JsonInteger>(value);
}

template <>
double JsonVariant::as<double>() const;

template <>
long JsonVariant::as<long>() const;

template <>
String JsonVariant::as<String>() const;

Expand All @@ -101,47 +104,57 @@ const char *JsonVariant::as<const char *>() const;

template <>
inline bool JsonVariant::as<bool>() const {
return as<long>() != 0;
return asInteger() != 0;
}

template <>
inline signed char JsonVariant::as<signed char>() const {
return static_cast<signed char>(as<long>());
return static_cast<signed char>(asInteger());
}

template <>
inline unsigned char JsonVariant::as<unsigned char>() const {
return static_cast<unsigned char>(as<long>());
return static_cast<unsigned char>(asInteger());
}

template <>
inline signed short JsonVariant::as<signed short>() const {
return static_cast<signed short>(as<long>());
return static_cast<signed short>(asInteger());
}

template <>
inline unsigned short JsonVariant::as<unsigned short>() const {
return static_cast<unsigned short>(as<long>());
return static_cast<unsigned short>(asInteger());
}

template <>
inline signed int JsonVariant::as<signed int>() const {
return static_cast<signed int>(as<long>());
return static_cast<signed int>(asInteger());
}

template <>
inline unsigned int JsonVariant::as<unsigned int>() const {
return static_cast<unsigned int>(as<long>());
return static_cast<unsigned int>(asInteger());
}

template <>
inline unsigned long JsonVariant::as<unsigned long>() const {
return static_cast<unsigned long>(as<long>());
return static_cast<unsigned long>(asInteger());
}

template <>
inline signed long JsonVariant::as<signed long>() const {
return static_cast<unsigned long>(asInteger());
}

template <>
inline double JsonVariant::as<double>() const {
return static_cast<double>(asFloat());
}

template <>
inline float JsonVariant::as<float>() const {
return static_cast<float>(as<double>());
return static_cast<float>(asFloat());
}

template <typename T>
Expand Down
6 changes: 6 additions & 0 deletions src/Arduino/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ size_t Print::print(long value) {
return print(tmp);
}

size_t Print::print(int value) {
char tmp[32];
sprintf(tmp, "%d", value);
return print(tmp);
}

size_t Print::println() { return write('\r') + write('\n'); }

#endif
6 changes: 6 additions & 0 deletions src/Arduino/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ String::String(long value) {
*this = tmp;
}

String::String(int value) {
char tmp[32];
sprintf(tmp, "%d", value);
*this = tmp;
}

#endif
Loading

0 comments on commit c0cf9c3

Please sign in to comment.