mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-06-29 19:30:59 +02:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
2524a00a96 | |||
f5b83f9314 | |||
5e7b9ec688 | |||
08d05df00e | |||
c385862be1 | |||
0eff567910 | |||
94d38c0680 | |||
81285f49fe | |||
877096d49d | |||
bfe60243a4 | |||
ca9d606e72 | |||
24d21467dd | |||
41651136bf | |||
5e5f060fc0 | |||
29ab5fc9c2 | |||
80913b8044 | |||
02960f28e4 | |||
8db338ba14 | |||
dadd8986dc | |||
e2016cf65b | |||
1b214a60fa | |||
8560583ee7 | |||
2932c4ee43 | |||
e8c127a894 | |||
d7ac7ff9a3 | |||
aef7e43c48 | |||
d855b0f98c | |||
c726506b47 | |||
c32e306be9 | |||
13e907c894 | |||
d19a34152f | |||
19cce08b2b | |||
3cd6f66067 | |||
ada588c112 | |||
0d57fe5a7e | |||
5a74beb7e2 | |||
e2d591b9ff | |||
8082185ac4 | |||
85ebc8a1ec | |||
9ca32e664e | |||
566b76121a | |||
562080f22d | |||
bb8bddc758 | |||
9eb8842dda | |||
97558abc29 | |||
160ce092ff | |||
d6974127b4 | |||
092660db52 |
3
.clang-format
Normal file
3
.clang-format
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||||
|
|
||||||
|
BasedOnStyle: Google
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.sh text eol=lf
|
10
.travis.yml
10
.travis.yml
@ -2,5 +2,11 @@ language: c++
|
|||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang
|
||||||
before_script: cmake .
|
before_install:
|
||||||
script: make && make test
|
- sudo pip install cpp-coveralls
|
||||||
|
before_script:
|
||||||
|
- cmake -DCOVERAGE=true .
|
||||||
|
script:
|
||||||
|
- make && make test
|
||||||
|
after_success:
|
||||||
|
- coveralls --exclude test --exclude third-party --gcov-options '\-lp'
|
24
ArduinoJson.cpp
Normal file
24
ArduinoJson.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#ifdef ARDUINO
|
||||||
|
|
||||||
|
// This file is here to help the Arduino IDE find the other files.
|
||||||
|
|
||||||
|
#include "src/Arduino/Print.cpp"
|
||||||
|
#include "src/DynamicJsonBuffer.cpp"
|
||||||
|
#include "src/Internals/IndentedPrint.cpp"
|
||||||
|
#include "src/Internals/JsonParser.cpp"
|
||||||
|
#include "src/Internals/List.cpp"
|
||||||
|
#include "src/Internals/Prettyfier.cpp"
|
||||||
|
#include "src/Internals/QuotedString.cpp"
|
||||||
|
#include "src/Internals/StringBuilder.cpp"
|
||||||
|
#include "src/JsonArray.cpp"
|
||||||
|
#include "src/JsonBuffer.cpp"
|
||||||
|
#include "src/JsonObject.cpp"
|
||||||
|
#include "src/JsonVariant.cpp"
|
||||||
|
|
||||||
|
#endif
|
13
ArduinoJson.h
Normal file
13
ArduinoJson.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#ifdef ARDUINO
|
||||||
|
|
||||||
|
// This file is here to help the Arduino IDE find the other files.
|
||||||
|
|
||||||
|
#include "include/ArduinoJson.h"
|
||||||
|
|
||||||
|
#endif
|
40
CHANGELOG.md
40
CHANGELOG.md
@ -1,13 +1,51 @@
|
|||||||
Arduino JSON: change log
|
Arduino JSON: change log
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
v4.6
|
||||||
|
----
|
||||||
|
|
||||||
|
* Fixed segmentation fault in `DynamicJsonBuffer` when memory allocation fails (issue #92)
|
||||||
|
|
||||||
|
v4.5
|
||||||
|
----
|
||||||
|
|
||||||
|
* Fixed buffer overflow when input contains a backslash followed by a terminator (issue #81)
|
||||||
|
|
||||||
|
**Upgrading is recommended** since previous versions contain a potential security risk.
|
||||||
|
|
||||||
|
Special thanks to [Giancarlo Canales Barreto](https://github.com/gcanalesb) for finding this nasty bug.
|
||||||
|
|
||||||
|
v4.4
|
||||||
|
----
|
||||||
|
|
||||||
|
* Added `JsonArray::measureLength()` and `JsonObject::measureLength()` (issue #75)
|
||||||
|
|
||||||
|
v4.3
|
||||||
|
----
|
||||||
|
|
||||||
|
* Added `JsonArray::removeAt()` to remove an element of an array (issue #58)
|
||||||
|
* Fixed stack-overflow in `DynamicJsonBuffer` when parsing huge JSON files (issue #65)
|
||||||
|
* Fixed wrong return value of `parseArray()` and `parseObject()` when allocation fails (issue #68)
|
||||||
|
|
||||||
|
v4.2
|
||||||
|
----
|
||||||
|
|
||||||
|
* Switched back to old library layout (issues #39, #43 and #45)
|
||||||
|
* Removed global new operator overload (issue #40, #45 and #46)
|
||||||
|
* Added an example with EthernetServer
|
||||||
|
|
||||||
|
v4.1
|
||||||
|
----
|
||||||
|
|
||||||
|
* Added DynamicJsonBuffer (issue #19)
|
||||||
|
|
||||||
v4.0
|
v4.0
|
||||||
----
|
----
|
||||||
|
|
||||||
* Unified parser and generator API (issue #23)
|
* Unified parser and generator API (issue #23)
|
||||||
* Updated library layout, now requires Arduino 1.0.6 or newer
|
* Updated library layout, now requires Arduino 1.0.6 or newer
|
||||||
|
|
||||||
**BREAKING CHANGE**: API changed significantly, see `doc/Migrating to the new API.md`.
|
**BREAKING CHANGE**: API changed significantly, see [Migrating code to the new API](https://github.com/bblanchon/ArduinoJson/wiki/Migrating-code-to-the-new-API).
|
||||||
|
|
||||||
|
|
||||||
v3.4
|
v3.4
|
||||||
|
@ -11,5 +11,10 @@ if(MSVC)
|
|||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -W4)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS -W4)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${COVERAGE})
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -coverage")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
10
README.md
10
README.md
@ -1,7 +1,7 @@
|
|||||||
Arduino JSON library
|
Arduino JSON library
|
||||||
====================
|
====================
|
||||||
|
|
||||||
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
[](https://travis-ci.org/bblanchon/ArduinoJson) [](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master)
|
||||||
|
|
||||||
*An elegant and efficient JSON library for embedded systems.*
|
*An elegant and efficient JSON library for embedded systems.*
|
||||||
|
|
||||||
@ -35,8 +35,6 @@ Quick start
|
|||||||
double latitude = root["data"][0];
|
double latitude = root["data"][0];
|
||||||
double longitude = root["data"][1];
|
double longitude = root["data"][1];
|
||||||
|
|
||||||
[See complete guide](/doc/Decoding JSON.md)
|
|
||||||
|
|
||||||
#### Encoding / Generating
|
#### Encoding / Generating
|
||||||
|
|
||||||
StaticJsonBuffer<200> jsonBuffer;
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
@ -53,7 +51,11 @@ Quick start
|
|||||||
// This prints:
|
// This prints:
|
||||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||||
|
|
||||||
[See complete guide](/doc/Encoding JSON.md)
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
|
||||||
|
|
||||||
Testimonials
|
Testimonials
|
||||||
------------
|
------------
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
Avoiding common pitfalls in Arduino JSON
|
|
||||||
========================================
|
|
||||||
|
|
||||||
As `StaticJsonBuffer` is the corner stone of this library, you'll see that every pitfall listed here are related to a wrong understanding of the memory model.
|
|
||||||
|
|
||||||
Make sure you read [Arduino JSON memory model](Memory model.md) before going further.
|
|
||||||
|
|
||||||
## 1. Make `StaticJsonBuffer` big enough
|
|
||||||
|
|
||||||
By design, the library has no way to tell you why `parseArray()` or `parseObject()` failed.
|
|
||||||
|
|
||||||
There are basically two reasons why they may fail:
|
|
||||||
|
|
||||||
1. the JSON string is invalid,
|
|
||||||
2. the JSON string contains more values that the buffer can store.
|
|
||||||
|
|
||||||
So, if you are sure the JSON string is correct and you still can't parse it, you should try to increase the size of the `StaticJsonBuffer`.
|
|
||||||
|
|
||||||
## 2. Make sure everything fits in memory
|
|
||||||
|
|
||||||
You may go into unpredictable trouble if you allocate more memory than your processor really has.
|
|
||||||
It's a very common issue in embedded development.
|
|
||||||
|
|
||||||
To diagnose this, look at every big objects in you code and sum their size to check that they fit in RAM.
|
|
||||||
|
|
||||||
For example, don't do this:
|
|
||||||
|
|
||||||
char json[1024]; // 1 KB
|
|
||||||
StaticJsonBuffer<512> buffer; // 514 B
|
|
||||||
|
|
||||||
because it may be too big for a processor with only 2 KB: you need free memory to store other variables and the call stack.
|
|
||||||
|
|
||||||
That is why an 8-bit processor is not able to parse long and complex JSON strings.
|
|
||||||
|
|
||||||
## 3. Keep the `StaticJsonBuffer` in memory long enough
|
|
||||||
|
|
||||||
Remember that `StaticJsonBuffer`'s function return references.
|
|
||||||
References don't contain data, they are just pointer to the actual.
|
|
||||||
So they can only work if the actual data is in memory.
|
|
||||||
|
|
||||||
For example, don't do this:
|
|
||||||
|
|
||||||
JsonArray& getArray(char* json)
|
|
||||||
{
|
|
||||||
StaticJsonBuffer<200> buffer;
|
|
||||||
return buffer.parseArray(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
because the local variable `buffer` will be *removed* from memory when the function `parseArray()` returns, and the `JsonArray&` will point to an invalid location.
|
|
||||||
|
|
||||||
## 4. Don't reuse the same `StaticJsonBuffer`
|
|
||||||
|
|
||||||
During is lifetime a `StaticJsonBuffer` growth until it's discarded. If you try to reuse the same instance several time, it will rapidly get full.
|
|
||||||
|
|
||||||
For this reason, you should not use a global variable for your `StaticJsonBuffer`. I don't think there is any scenario in which a global `StaticJsonBuffer` would be a valid option.
|
|
||||||
|
|
||||||
The best practice is to declare it in a local scope, so that it's discarded as soon as possible. My advice it to declare it in a function which unique role is to handle the JSON serialization.
|
|
||||||
|
|
||||||
## 5. Keep the JSON string in memory long enough
|
|
||||||
|
|
||||||
The library never make memory duplication.
|
|
||||||
This has an important implication on string values, it means that the library will return pointer to chunks of the string.
|
|
||||||
|
|
||||||
For instance, let's imagine that you parse `["hello","world"]`, like this:
|
|
||||||
|
|
||||||
char[] json = "[\"hello\",\"world\"]";
|
|
||||||
StaticJsonBuffer<32> buffer;
|
|
||||||
JsonArray& array = buffer.parseArray(json);
|
|
||||||
|
|
||||||
const char* first = array[0];
|
|
||||||
const char* second = array[1];
|
|
||||||
|
|
||||||
In that case, both `first` and `second` are pointers to the content of the original string `json`.
|
|
||||||
So this will only work if `json` is still in memory.
|
|
||||||
|
|
||||||
## 6. JSON string is altered
|
|
||||||
|
|
||||||
If you read carefully the previous section, you may have come to the conclusion that the JSON parser modifies the JSON string.
|
|
||||||
|
|
||||||
Indeed, the parser modifies the string for two reasons:
|
|
||||||
|
|
||||||
1. it inserts `\0` to terminate substrings,
|
|
||||||
2. it translate escaped characters like `\n` or `\t`.
|
|
||||||
|
|
||||||
Most of the time this wont be an issue, but there are some corner cases that can be problematic.
|
|
||||||
|
|
||||||
Let take the example bellow:
|
|
||||||
|
|
||||||
char[] json = "[\"hello\",\"world\"]";
|
|
||||||
StaticJsonBuffer<32> buffer;
|
|
||||||
JsonArray& array = buffer.parseArray(json);
|
|
||||||
|
|
||||||
If you replace it by:
|
|
||||||
|
|
||||||
char* json = "[\"hello\",\"world\"]";
|
|
||||||
StaticJsonBuffer<32> buffer;
|
|
||||||
JsonArray& array = buffer.parseArray(json);
|
|
||||||
|
|
||||||
Depending on your platform, you may have an exception because the parser tries to write at a location that is read-only.
|
|
||||||
In the first case `char json[]` declares an array of `char` initialized to the specified string.
|
|
||||||
In the second case `char* json` declares a pointer to a read-only string, in fact it should be a `const char*` instead of a `char*`.
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
Contributing to Arduino JSON
|
|
||||||
============================
|
|
||||||
|
|
||||||
If you want to contribute to the project, please:
|
|
||||||
|
|
||||||
1. Use GitHub pull request feature
|
|
||||||
2. Follow the coding conventions
|
|
||||||
3. Write tests
|
|
||||||
|
|
||||||
About the coding conventions: I try to follow the [Google C++ Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html) with few variations to match the Arduino conventions.
|
|
||||||
|
|
||||||
I use [ClangFormat](http://clang.llvm.org/docs/ClangFormat.html) to format the code for me.
|
|
||||||
I use [CppLint](http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) to detect non-compliant stuff.
|
|
||||||
|
|
||||||
You should have a look at the `scripts/` folder as it contains a few helpers scripts.
|
|
@ -1,148 +0,0 @@
|
|||||||
Decoding JSON with Arduino JSON
|
|
||||||
===============================
|
|
||||||
|
|
||||||
Before writing any code, don't forget to include the header:
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md).
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
Here an example that parse the string `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`:
|
|
||||||
|
|
||||||
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
|
||||||
|
|
||||||
//
|
|
||||||
// Step 1: Reserve memory space
|
|
||||||
//
|
|
||||||
StaticJsonBuffer<200> jsonBuffer;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Step 2: Deserialize the JSON string
|
|
||||||
//
|
|
||||||
JsonObject& root = jsonBuffer.parseObject(json);
|
|
||||||
|
|
||||||
if (!root.success())
|
|
||||||
{
|
|
||||||
Serial.println("parseObject() failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Step 3: Retrieve the values
|
|
||||||
//
|
|
||||||
const char* sensor = root["sensor"];
|
|
||||||
long time = root["time"];
|
|
||||||
double latitude = root["data"][0];
|
|
||||||
double longitude = root["data"][1];
|
|
||||||
|
|
||||||
## Step 1: Reserve memory space
|
|
||||||
|
|
||||||
Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`.
|
|
||||||
|
|
||||||
Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`.
|
|
||||||
|
|
||||||
## Step 2: Parse the JSON string
|
|
||||||
|
|
||||||
You invoke the JSON parser through the instance of `StaticJsonBuffer`.
|
|
||||||
It exposes two functions for parsing JSON:
|
|
||||||
|
|
||||||
1. `parseArray()` that returns a reference to a `JsonArray`
|
|
||||||
2. `parseObject()` that returns a reference to a `JsonObject`
|
|
||||||
|
|
||||||
Let's see an example.
|
|
||||||
Say we want to parse `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`, it's an object so we call `parseObject()` as follows:
|
|
||||||
|
|
||||||
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
|
||||||
|
|
||||||
JsonObject& root = jsonBuffer.parseObject(json);
|
|
||||||
|
|
||||||
As you can see `parseObject()` takes a `char*` as a parameter.
|
|
||||||
Be careful, it's not a `const char*`, the memory must be writable.
|
|
||||||
Indeed, the parser will modify the string in two cases:
|
|
||||||
|
|
||||||
1. to insert string endings (character `\0`),
|
|
||||||
2. to translate escaped characters (like `\n` or `\t`).
|
|
||||||
|
|
||||||
Another thing that you must keep in mind is that the string (`char json[]` in the example above) must stay in memory during the whole parsing process.
|
|
||||||
That is because the in memory object tree will store pointer to chunks of the string, so as to avoid any memory duplication.
|
|
||||||
|
|
||||||
Now, to check if the parsing was successful, you can call `JsonObject::success()`:
|
|
||||||
|
|
||||||
if (!root.success())
|
|
||||||
{
|
|
||||||
// Parsing fail
|
|
||||||
}
|
|
||||||
|
|
||||||
The result can be `false` for tree reasons:
|
|
||||||
|
|
||||||
1. the JSON string is invalid,
|
|
||||||
2. the JSON string doesn't represent an object,
|
|
||||||
3. the `StaticJsonBuffer` is too small.
|
|
||||||
|
|
||||||
We just saw how to parse an object, there is nothing more to say for arrays, the procedure is exactly the same.
|
|
||||||
|
|
||||||
## Step 3: Retrieve the values
|
|
||||||
|
|
||||||
Now that the object or array is in memory, you can extract the data very easily.
|
|
||||||
|
|
||||||
In this section, we'll see how to do it with a `JsonObject`.
|
|
||||||
Once again, there is nothing more to say about arrays, `JsonArray` works exactly the same as `JsonObject`.
|
|
||||||
|
|
||||||
#### Subscript operator
|
|
||||||
|
|
||||||
The simplest way is to use the subscript operator of `JsonObject`:
|
|
||||||
|
|
||||||
const char* sensor = root["sensor"];
|
|
||||||
long time = root["time"];
|
|
||||||
|
|
||||||
You can chain the subscript operator if you have nested arrays or objects:
|
|
||||||
|
|
||||||
double latitude = root["data"][0];
|
|
||||||
double longitude = root["data"][1];
|
|
||||||
|
|
||||||
But alternatively, you can get a reference to the nested array:
|
|
||||||
|
|
||||||
JsonArray& nestedArray = root["data"];
|
|
||||||
|
|
||||||
#### Casting values
|
|
||||||
|
|
||||||
In the previous examples, the values were implicitly casted to the target type.
|
|
||||||
You can also do this explicitly
|
|
||||||
|
|
||||||
const char* sensor = root["sensor"].asString();
|
|
||||||
long time = root["time"].as<long>();
|
|
||||||
JsonArray& nestedArray = root["data"].asArray();
|
|
||||||
|
|
||||||
If the actual value doesn't match the target type, a default value will be return:
|
|
||||||
|
|
||||||
1. `false` for boolean values
|
|
||||||
2. `0` for integer values
|
|
||||||
3. `NULL` for string values
|
|
||||||
4. `JsonArray::invalid()` for nested arrays
|
|
||||||
5. `JsonObject::invalid()` for nested object
|
|
||||||
|
|
||||||
#### Check values
|
|
||||||
|
|
||||||
If you want to know if some value is present, call `containsKey()`:
|
|
||||||
|
|
||||||
if (root.contains("extra"))
|
|
||||||
{
|
|
||||||
// root["extra"] is valid
|
|
||||||
}
|
|
||||||
|
|
||||||
If you want to check the type value has a certain type, call `is<T>()`:
|
|
||||||
|
|
||||||
if (root["extra"].is<JsonArray&>())
|
|
||||||
{
|
|
||||||
// root["extra"] is an array
|
|
||||||
}
|
|
||||||
|
|
||||||
You can also iterate through the key-value pairs of the object:
|
|
||||||
|
|
||||||
for (JsonObject::itertor it=root.begin(); it!=root.end(); ++it)
|
|
||||||
{
|
|
||||||
Serial.println(it->key);
|
|
||||||
Serial.println(i->value.asString());
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
Encoding JSON with Arduino JSON
|
|
||||||
===============================
|
|
||||||
|
|
||||||
Before writing any code, don't forget to include the header:
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md).
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
Here is an example to generate `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`
|
|
||||||
|
|
||||||
//
|
|
||||||
// Step 1: Reserve memory space
|
|
||||||
//
|
|
||||||
StaticJsonBuffer<200> jsonBuffer;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Step 2: Build object tree in memory
|
|
||||||
//
|
|
||||||
JsonObject& root = jsonBuffer.createObject();
|
|
||||||
root["sensor"] = "gps";
|
|
||||||
root["time"] = 1351824120;
|
|
||||||
|
|
||||||
JsonArray& data = root.createNestedArray("data");
|
|
||||||
data.add(48.756080, 6); // 6 is the number of decimals to print
|
|
||||||
data.add(2.302038, 6); // if not specified, 2 digits are printed
|
|
||||||
|
|
||||||
//
|
|
||||||
// Step 3: Generate the JSON string
|
|
||||||
//
|
|
||||||
root.printTo(Serial);
|
|
||||||
|
|
||||||
## Step 1: Reserve memory space
|
|
||||||
|
|
||||||
Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`.
|
|
||||||
|
|
||||||
Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`.
|
|
||||||
|
|
||||||
## Step 2: Build object tree in memory
|
|
||||||
|
|
||||||
Now that you have enough memory hold by the `StaticJsonBuffer`, you can use it to build your in-memory representation of the JSON string.
|
|
||||||
|
|
||||||
#### Arrays
|
|
||||||
|
|
||||||
You create an array like this:
|
|
||||||
|
|
||||||
JsonArray& array = jsonBuffer.createArray();
|
|
||||||
|
|
||||||
Don't forget the `&` after `JsonArray`, it needs to be a reference to the array.
|
|
||||||
|
|
||||||
Then you can add strings, integer, booleans, etc:
|
|
||||||
|
|
||||||
array.add("bazinga!");
|
|
||||||
array.add(42);
|
|
||||||
array.add(true);
|
|
||||||
|
|
||||||
There are two syntaxes for floating point values:
|
|
||||||
|
|
||||||
array.add(3.1415, 4); // 4 digits: "3.1415"
|
|
||||||
array.add(3.1415); // 2 digits: "3.14"
|
|
||||||
|
|
||||||
> ##### About floating point precision
|
|
||||||
> The overload of `add()` with 2 parameters allows you to specify the number of decimals to save in the JSON string.
|
|
||||||
> When you use the overload with one parameter, you use the default number of decimals which is 2.
|
|
||||||
> Note that this behavior is the exact same as Arduino's `Print::print(double,int);` which is implemented by `Serial`, so you may already be familiar with this behavior.
|
|
||||||
|
|
||||||
You can add a nested array or object if you have a reference to it.
|
|
||||||
Or simpler, you can create nested array or nested objects from the array:
|
|
||||||
|
|
||||||
JsonArray& nestedArray = array.createNestedArray();
|
|
||||||
JsonObject& nestedObject = array.createNestedObject();
|
|
||||||
|
|
||||||
#### Objects
|
|
||||||
|
|
||||||
You create an object like this:
|
|
||||||
|
|
||||||
JsonObject& object = jsonBuffer.createObject();
|
|
||||||
|
|
||||||
Again, don't forget the `&` after `JsonObject`, it needs to be a reference to the object.
|
|
||||||
|
|
||||||
Then you can add strings, integer, booleans, etc:
|
|
||||||
|
|
||||||
object["key1"] = "bazinga!";
|
|
||||||
object["key2"] = 42;
|
|
||||||
object["key3"] = true;
|
|
||||||
|
|
||||||
As for the arrays, there are two syntaxes for the floating point values:
|
|
||||||
|
|
||||||
object["key4"].set(3.1415, 4); // 4 digits "3.1415"
|
|
||||||
object["key5"] = 3.1415; // default: 2 digits "3.14"
|
|
||||||
|
|
||||||
You can add a nested array or object if you have a reference to it.
|
|
||||||
Or simpler, you can create nested array or nested objects from the object:
|
|
||||||
|
|
||||||
JsonArray& nestedArray = object.createNestedArray("key6");
|
|
||||||
JsonObject& nestedObject = object.createNestedObject("key7");
|
|
||||||
|
|
||||||
> ##### Other JsonObject functions
|
|
||||||
> * `object.add(key, value)` is a synonym for `object[key] = value`
|
|
||||||
> * `object.containsKey(key)` returns `true` is the `key` is present in `object`
|
|
||||||
> * `object.remove(key)` removes the `value` associated with `key`
|
|
||||||
|
|
||||||
## Step 3: Generate the JSON string
|
|
||||||
|
|
||||||
There are two ways tho get the resulting JSON string.
|
|
||||||
|
|
||||||
Depending on your project, you may need to dump the string in a classic `char[]` or send it to a `Print` implementation like `Serial` or `EthernetClient `.
|
|
||||||
|
|
||||||
Both ways are the easy way :-)
|
|
||||||
|
|
||||||
#### Use a classic `char[]`
|
|
||||||
|
|
||||||
Whether you have a `JsonArray&` or a `JsonObject&`, simply call `printTo()` with the destination buffer, like so:
|
|
||||||
|
|
||||||
char buffer[256];
|
|
||||||
array.printTo(buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
> ##### Want an indented output?
|
|
||||||
> By default the generated JSON is as small as possible. It contains no extra space, nor line break.
|
|
||||||
> But if you want an indented, more readable output, you can.
|
|
||||||
> Simply call `prettyPrintTo` instead of `printTo()`:
|
|
||||||
>
|
|
||||||
> array.prettyPrintTo(buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
#### Send to a `Print` implementation
|
|
||||||
|
|
||||||
It's very likely that the generated JSON will end up in a stream like `Serial` or `EthernetClient `, so you can save some time and memory by doing this:
|
|
||||||
|
|
||||||
array.printTo(Serial);
|
|
||||||
|
|
||||||
And, of course if you need an indented JSON string:
|
|
||||||
|
|
||||||
array.prettyPrintTo(Serial);
|
|
||||||
|
|
||||||
> ##### About the Print interface
|
|
||||||
> The library is designed to send the JSON string to an implementation of the `Print` interface that is part of Arduino.
|
|
||||||
> In the example above we used `Serial`, but they are many other implementations that would work as well, including: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`...
|
|
||||||
> When you use this library out of the Arduino environment, it will use it's own implementation of `Print` and everything will be the same.
|
|
@ -1,58 +0,0 @@
|
|||||||
Arduino JSON memory model
|
|
||||||
=========================
|
|
||||||
|
|
||||||
## Fixed memory allocation
|
|
||||||
|
|
||||||
### Introducing `StaticJsonBuffer`
|
|
||||||
|
|
||||||
Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer` class.
|
|
||||||
|
|
||||||
Before using any function of the library you need to create a `StaticJsonBuffer`. Then you can use this instance to create arrays and objects, or parse a JSON string.
|
|
||||||
|
|
||||||
`StaticJsonBuffer` has a template parameter that determines its capacity. For example, the following line create a `StaticJsonBuffer` with a capacity of 200 bytes:
|
|
||||||
|
|
||||||
StaticJsonBuffer<200> jsonBuffer;
|
|
||||||
|
|
||||||
The bigger the buffer is, the more complex the object tree can be, but also the more memory you need.
|
|
||||||
|
|
||||||
### How to determine the buffer size?
|
|
||||||
|
|
||||||
So the big question you should have in mind right now is *How can I determine the size?*.
|
|
||||||
|
|
||||||
There are basically two approaches here:
|
|
||||||
|
|
||||||
1. either you can predict the content of the object tree,
|
|
||||||
2. or, you know how much memory is available.
|
|
||||||
|
|
||||||
In the first case, you know some constraints on the object tree. For instance, let's say that your know in advance (and by that I mean "at compilation time") that you want to generate an object with 3 values, one of them being an array with 2 values, like the following:
|
|
||||||
|
|
||||||
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
|
||||||
|
|
||||||
To determine the memory usage of this object tree, you use the two macros `JSON_ARRAY_SIZE(n)` and `JSON_OBJECT_SIZE(n)`, both take the number of elements as an argument.
|
|
||||||
For the example above, it would be:
|
|
||||||
|
|
||||||
const int BUFFER_SIZE = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2);
|
|
||||||
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
|
|
||||||
|
|
||||||
In the second case, let's say you dynamically generate a JSON object tree of a random complexity so you can't put a limit based on that. But on the other hand, you don't want your program to crash because the object tree doesn't fit in memory.
|
|
||||||
The solution here is to determine how much memory is available, or in other words how much memory you can afford for the JSON object tree.
|
|
||||||
|
|
||||||
### Why choosing fixed allocation?
|
|
||||||
|
|
||||||
This fixed allocation approach may seem a bit strange, especially if your a desktop application developer used to dynamic allocation, but it make a lot of sense in an embedded context:
|
|
||||||
|
|
||||||
1. the code is smaller
|
|
||||||
2. it uses less memory
|
|
||||||
3. it doesn't create memory fragmentation
|
|
||||||
4. it predictable
|
|
||||||
|
|
||||||
Don't forget that the memory is "freed" as soon as the `StaticJsonBuffer` is out of scope, like any other variable. It only hold the memory for a short amount of time.
|
|
||||||
|
|
||||||
## Memory usage
|
|
||||||
|
|
||||||
#### Object size for 8-bit AVR
|
|
||||||
|
|
||||||
| Type | Size |
|
|
||||||
|-------------------------|------------|
|
|
||||||
| JsonArray of N element | 4 + 8 * N |
|
|
||||||
| JsonObject of N element | 4 + 10 * N |
|
|
@ -1,80 +0,0 @@
|
|||||||
Migrating code written for Arduino JSON v3 to v4
|
|
||||||
================================================
|
|
||||||
|
|
||||||
Arduino JSON v4 was a major rewrite of the library, and the API changed significantly.
|
|
||||||
|
|
||||||
## Includes
|
|
||||||
|
|
||||||
Arduino JSON v3 had two include files:
|
|
||||||
|
|
||||||
#include <JsonParser.h>
|
|
||||||
#include <JsonGenerator.h>
|
|
||||||
|
|
||||||
Arduino JSON v4 only has one:
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
## Namespaces
|
|
||||||
|
|
||||||
Arduino JSON v3 had two namespaces:
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Parser;
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
|
|
||||||
Arduino JSON v4 doesn't require the `using namespace` statement.
|
|
||||||
It has a namespace but the `using namespace` is done in the header file.
|
|
||||||
|
|
||||||
## StaticJsonBuffer
|
|
||||||
|
|
||||||
Arduino JSON v3 had different memory allocation models for the parser:
|
|
||||||
|
|
||||||
JsonParser<16> parser; // 16 being the capacity in "tokens"
|
|
||||||
|
|
||||||
and for the generator:
|
|
||||||
|
|
||||||
JsonArray<4> array; // 4 being the number of element
|
|
||||||
JsonObject<4> object;
|
|
||||||
|
|
||||||
Arduino JSON v4 only has one memory allocation model:
|
|
||||||
|
|
||||||
StaticJsonBuffer<128> buffer; // 128 being the capacity in bytes
|
|
||||||
|
|
||||||
## Return values for the parser
|
|
||||||
|
|
||||||
Arduino JSON v3 returned value types:
|
|
||||||
|
|
||||||
JsonArray array = parser.parseArray(json);
|
|
||||||
JsonObject object = parser.parseObject(json);
|
|
||||||
|
|
||||||
Arduino JSON v4 returns references types:
|
|
||||||
|
|
||||||
JsonArray& array = buffer.parseArray(json);
|
|
||||||
JsonObject& object = buffer.parseObject(json);
|
|
||||||
|
|
||||||
Everything else is compatible
|
|
||||||
|
|
||||||
## Creating arrays and objects
|
|
||||||
|
|
||||||
Arduino JSON v3 allowed to create `JsonArray` and `JsonObject` directly:
|
|
||||||
|
|
||||||
JsonArray<4> array;
|
|
||||||
JsonObject<4> object;
|
|
||||||
|
|
||||||
Arduino JSON v4 requires that you use a `StaticJsonBuffer` for that:
|
|
||||||
|
|
||||||
JsonArray& array = buffer.createArray();
|
|
||||||
JsonObject& object = buffer.createObject();
|
|
||||||
|
|
||||||
Note: you don't have to specify the capacity anymore.
|
|
||||||
|
|
||||||
## Printable interface
|
|
||||||
|
|
||||||
Arduino JSON v3 used to implement the Printable interface, which allowed statements like:
|
|
||||||
|
|
||||||
Serial.print(array);
|
|
||||||
|
|
||||||
But Arduino JSON v4 doesn't, instead you need to write this:
|
|
||||||
|
|
||||||
array.printTo(Serial);
|
|
||||||
|
|
||||||
Note: there was a good reason for removing that feature, and it's reducing the size of `JsonArray` and `JsonObject`.
|
|
@ -1,30 +0,0 @@
|
|||||||
Using the library with Arduino
|
|
||||||
==============================
|
|
||||||
|
|
||||||
This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment.
|
|
||||||
If you don't use the Arduino IDE, please read [Using the library without Arduino](Using the library without Arduino.md).
|
|
||||||
|
|
||||||
## Install the library
|
|
||||||
|
|
||||||
[Download the zip package](https://github.com/bblanchon/ArduinoJson/releases) and extract it to:
|
|
||||||
|
|
||||||
<your Arduino Sketch folder>/libraries/ArduinoJson
|
|
||||||
|
|
||||||
Then restart the Arduino IDE.
|
|
||||||
|
|
||||||
## Run the examples sketches
|
|
||||||
|
|
||||||
Click `File` / `Example` / `ArduinoJson`.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Use the library in your sketches
|
|
||||||
|
|
||||||
Just add the following line at the top of your program:
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
|
|
||||||
Then follow the instructions:
|
|
||||||
|
|
||||||
1. [Parsing JSON](Parsin JSON.md)
|
|
||||||
2. [Generating JSON](Generating JSON.md)
|
|
@ -1,37 +0,0 @@
|
|||||||
Using the library without Arduino
|
|
||||||
=================================
|
|
||||||
|
|
||||||
This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment.
|
|
||||||
If you use the Arduino IDE, please read [Using the library with Arduino](Using the library with Arduino.md).
|
|
||||||
|
|
||||||
However, it can be used without Arduino IDE with very little effort.
|
|
||||||
|
|
||||||
## Compiling the library
|
|
||||||
|
|
||||||
Step 1: Download source code:
|
|
||||||
|
|
||||||
git clone https://github.com/bblanchon/ArduinoJson.git
|
|
||||||
|
|
||||||
Step 2: Generate the `Makefile` for your environment
|
|
||||||
|
|
||||||
cd ArduinoJson
|
|
||||||
cmake .
|
|
||||||
|
|
||||||
Step 3: Build
|
|
||||||
|
|
||||||
make
|
|
||||||
|
|
||||||
## File paths
|
|
||||||
|
|
||||||
Assuming you installed the library into `<arduino-json>`, you need to add:
|
|
||||||
|
|
||||||
1. `<arduino-json>/include` to your include path
|
|
||||||
2. `<arduino-json>/lib` to your library path
|
|
||||||
|
|
||||||
|
|
||||||
----------
|
|
||||||
|
|
||||||
You are now ready to follow the instructions:
|
|
||||||
|
|
||||||
1. [Parsing JSON](Parsin JSON.md)
|
|
||||||
2. [Generating JSON](Generating JSON.md)
|
|
74
examples/JsonServer/JsonServer.ino
Normal file
74
examples/JsonServer/JsonServer.ino
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Sample Arduino Json Web Server
|
||||||
|
// Created by Benoit Blanchon.
|
||||||
|
// Heavily inspired by "Web Server" from David A. Mellis and Tom Igoe
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Ethernet.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||||
|
IPAddress ip(192, 168, 0, 177);
|
||||||
|
EthernetServer server(80);
|
||||||
|
|
||||||
|
bool readRequest(EthernetClient& client) {
|
||||||
|
bool currentLineIsBlank = true;
|
||||||
|
while (client.connected()) {
|
||||||
|
if (client.available()) {
|
||||||
|
char c = client.read();
|
||||||
|
if (c == '\n' && currentLineIsBlank) {
|
||||||
|
return true;
|
||||||
|
} else if (c == '\n') {
|
||||||
|
currentLineIsBlank = true;
|
||||||
|
} else if (c != '\r') {
|
||||||
|
currentLineIsBlank = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject& prepareResponse(JsonBuffer& jsonBuffer) {
|
||||||
|
JsonObject& root = jsonBuffer.createObject();
|
||||||
|
|
||||||
|
JsonArray& analogValues = root.createNestedArray("analog");
|
||||||
|
for (int pin = 0; pin < 6; pin++) {
|
||||||
|
int value = analogRead(pin);
|
||||||
|
analogValues.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray& digitalValues = root.createNestedArray("digital");
|
||||||
|
for (int pin = 0; pin < 14; pin++) {
|
||||||
|
int value = digitalRead(pin);
|
||||||
|
digitalValues.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeResponse(EthernetClient& client, JsonObject& json) {
|
||||||
|
client.println("HTTP/1.1 200 OK");
|
||||||
|
client.println("Content-Type: application/json");
|
||||||
|
client.println("Connection: close");
|
||||||
|
client.println();
|
||||||
|
|
||||||
|
json.prettyPrintTo(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Ethernet.begin(mac, ip);
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
EthernetClient client = server.available();
|
||||||
|
if (client) {
|
||||||
|
bool success = readRequest(client);
|
||||||
|
if (success) {
|
||||||
|
StaticJsonBuffer<500> jsonBuffer;
|
||||||
|
JsonObject& json = prepareResponse(jsonBuffer);
|
||||||
|
writeResponse(client, json);
|
||||||
|
}
|
||||||
|
delay(1);
|
||||||
|
client.stop();
|
||||||
|
}
|
||||||
|
}
|
55
examples/JsonUdpBeacon/JsonUdpBeacon.ino
Normal file
55
examples/JsonUdpBeacon/JsonUdpBeacon.ino
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Send a JSON object on UDP at regular interval
|
||||||
|
//
|
||||||
|
// You can easily test this program with netcat:
|
||||||
|
// $ nc -ulp 8888
|
||||||
|
//
|
||||||
|
// by Benoit Blanchon, MIT License 2015
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Ethernet.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||||
|
IPAddress localIp(192, 168, 0, 177);
|
||||||
|
IPAddress remoteIp(192, 168, 0, 109);
|
||||||
|
unsigned int remotePort = 8888;
|
||||||
|
unsigned localPort = 8888;
|
||||||
|
EthernetUDP udp;
|
||||||
|
|
||||||
|
JsonObject& buildJson(JsonBuffer& jsonBuffer) {
|
||||||
|
JsonObject& root = jsonBuffer.createObject();
|
||||||
|
|
||||||
|
JsonArray& analogValues = root.createNestedArray("analog");
|
||||||
|
for (int pin = 0; pin < 6; pin++) {
|
||||||
|
int value = analogRead(pin);
|
||||||
|
analogValues.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray& digitalValues = root.createNestedArray("digital");
|
||||||
|
for (int pin = 0; pin < 14; pin++) {
|
||||||
|
int value = digitalRead(pin);
|
||||||
|
digitalValues.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendJson(JsonObject& json) {
|
||||||
|
udp.beginPacket(remoteIp, remotePort);
|
||||||
|
json.printTo(udp);
|
||||||
|
udp.println();
|
||||||
|
udp.endPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Ethernet.begin(mac, localIp);
|
||||||
|
udp.begin(localPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
StaticJsonBuffer<300> jsonBuffer;
|
||||||
|
JsonObject& json = buildJson(jsonBuffer);
|
||||||
|
sendJson(json);
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
// https://github.com/bblanchon/ArduinoJson
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include "../include/ArduinoJson/DynamicJsonBuffer.hpp"
|
||||||
#include "../include/ArduinoJson/JsonArray.hpp"
|
#include "../include/ArduinoJson/JsonArray.hpp"
|
||||||
#include "../include/ArduinoJson/JsonObject.hpp"
|
#include "../include/ArduinoJson/JsonObject.hpp"
|
||||||
#include "../include/ArduinoJson/StaticJsonBuffer.hpp"
|
#include "../include/ArduinoJson/StaticJsonBuffer.hpp"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
17
include/ArduinoJson/DynamicJsonBuffer.hpp
Normal file
17
include/ArduinoJson/DynamicJsonBuffer.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Internals/BlockJsonBuffer.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
// Implements a JsonBuffer with dynamic memory allocation.
|
||||||
|
// You are strongly encouraged to consider using StaticJsonBuffer which is much
|
||||||
|
// more suitable for embedded systems.
|
||||||
|
typedef Internals::BlockJsonBuffer<Internals::DefaultAllocator>
|
||||||
|
DynamicJsonBuffer;
|
||||||
|
}
|
93
include/ArduinoJson/Internals/BlockJsonBuffer.hpp
Normal file
93
include/ArduinoJson/Internals/BlockJsonBuffer.hpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../JsonBuffer.hpp"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
class DefaultAllocator {
|
||||||
|
public:
|
||||||
|
void* allocate(size_t size) { return malloc(size); }
|
||||||
|
void deallocate(void* pointer) { free(pointer); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TAllocator>
|
||||||
|
class BlockJsonBuffer : public JsonBuffer {
|
||||||
|
struct Block;
|
||||||
|
struct EmptyBlock {
|
||||||
|
Block* next;
|
||||||
|
size_t capacity;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
struct Block : EmptyBlock {
|
||||||
|
uint8_t data[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
BlockJsonBuffer() : _head(NULL) {}
|
||||||
|
|
||||||
|
~BlockJsonBuffer() {
|
||||||
|
Block* currentBlock = _head;
|
||||||
|
|
||||||
|
while (currentBlock != NULL) {
|
||||||
|
Block* nextBlock = currentBlock->next;
|
||||||
|
_allocator.deallocate(currentBlock);
|
||||||
|
currentBlock = nextBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
size_t total = 0;
|
||||||
|
for (const Block* b = _head; b; b = b->next) total += b->size;
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void* alloc(size_t bytes) {
|
||||||
|
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const size_t FIRST_BLOCK_CAPACITY = 32;
|
||||||
|
|
||||||
|
bool canAllocInHead(size_t bytes) const {
|
||||||
|
return _head != NULL && _head->size + bytes <= _head->capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* allocInHead(size_t bytes) {
|
||||||
|
void* p = _head->data + _head->size;
|
||||||
|
_head->size += bytes;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* allocInNewBlock(size_t bytes) {
|
||||||
|
size_t capacity = FIRST_BLOCK_CAPACITY;
|
||||||
|
if (_head != NULL) capacity = _head->capacity * 2;
|
||||||
|
if (bytes > capacity) capacity = bytes;
|
||||||
|
if (!addNewBlock(capacity)) return NULL;
|
||||||
|
return allocInHead(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool addNewBlock(size_t capacity) {
|
||||||
|
size_t size = sizeof(EmptyBlock) + capacity;
|
||||||
|
Block* block = static_cast<Block*>(_allocator.allocate(size));
|
||||||
|
if (block == NULL) return false;
|
||||||
|
block->capacity = capacity;
|
||||||
|
block->size = 0;
|
||||||
|
block->next = _head;
|
||||||
|
_head = block;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block* _head;
|
||||||
|
TAllocator _allocator;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
20
include/ArduinoJson/Internals/DummyPrint.hpp
Normal file
20
include/ArduinoJson/Internals/DummyPrint.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Arduino/Print.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
// A dummy Print implementation used in JsonPrintable::measureLength()
|
||||||
|
class DummyPrint : public Print {
|
||||||
|
public:
|
||||||
|
virtual size_t write(uint8_t) { return 1; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
23
include/ArduinoJson/Internals/JsonBufferAllocated.hpp
Normal file
23
include/ArduinoJson/Internals/JsonBufferAllocated.hpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../JsonBuffer.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class JsonBufferAllocated {
|
||||||
|
public:
|
||||||
|
void *operator new(size_t n, JsonBuffer *jsonBuffer) throw() {
|
||||||
|
return jsonBuffer->alloc(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *, JsonBuffer *) throw() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "DummyPrint.hpp"
|
||||||
#include "IndentedPrint.hpp"
|
#include "IndentedPrint.hpp"
|
||||||
#include "JsonWriter.hpp"
|
#include "JsonWriter.hpp"
|
||||||
#include "Prettyfier.hpp"
|
#include "Prettyfier.hpp"
|
||||||
@ -47,6 +48,16 @@ class JsonPrintable {
|
|||||||
return prettyPrintTo(indentedPrint);
|
return prettyPrintTo(indentedPrint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t measureLength() const {
|
||||||
|
DummyPrint dp;
|
||||||
|
return printTo(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t measurePrettyLength() const {
|
||||||
|
DummyPrint dp;
|
||||||
|
return prettyPrintTo(dp);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const T &downcast() const { return *static_cast<const T *>(this); }
|
const T &downcast() const { return *static_cast<const T *>(this); }
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,7 +9,6 @@
|
|||||||
#include "../JsonBuffer.hpp"
|
#include "../JsonBuffer.hpp"
|
||||||
#include "ListConstIterator.hpp"
|
#include "ListConstIterator.hpp"
|
||||||
#include "ListIterator.hpp"
|
#include "ListIterator.hpp"
|
||||||
#include "PlacementNew.hpp"
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -51,8 +50,7 @@ class List {
|
|||||||
protected:
|
protected:
|
||||||
node_type *createNode() {
|
node_type *createNode() {
|
||||||
if (!_buffer) return NULL;
|
if (!_buffer) return NULL;
|
||||||
void *ptr = _buffer->alloc(sizeof(node_type));
|
return new (_buffer) node_type();
|
||||||
return ptr ? new (ptr) node_type() : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addNode(node_type *nodeToAdd) {
|
void addNode(node_type *nodeToAdd) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ListNode.hpp"
|
#include "ListNode.hpp"
|
||||||
|
#include "ListConstIterator.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -33,6 +34,8 @@ class ListIterator {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator ListConstIterator<T>() const { return ListConstIterator<T>(_node); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListNode<T> *_node;
|
ListNode<T> *_node;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -8,16 +8,18 @@
|
|||||||
|
|
||||||
#include <stddef.h> // for NULL
|
#include <stddef.h> // for NULL
|
||||||
|
|
||||||
|
#include "JsonBufferAllocated.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
// A node for a singly-linked list.
|
// A node for a singly-linked list.
|
||||||
// Used by List<T> and its iterators.
|
// Used by List<T> and its iterators.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ListNode {
|
struct ListNode : public Internals::JsonBufferAllocated {
|
||||||
ListNode() : next(NULL) {}
|
ListNode() : next(NULL) {}
|
||||||
|
|
||||||
ListNode<T>* next;
|
ListNode<T> *next;
|
||||||
T content;
|
T content;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
|
||||||
// MIT License
|
|
||||||
//
|
|
||||||
// Arduino JSON library
|
|
||||||
// https://github.com/bblanchon/ArduinoJson
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef ARDUINO
|
|
||||||
|
|
||||||
// Declares the placement new as in <new>.
|
|
||||||
// This is required for Arduino IDE because it doesn't include the <new> header.
|
|
||||||
inline void *operator new(size_t, void *p) throw() { return p; }
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Internals/JsonBufferAllocated.hpp"
|
||||||
#include "Internals/JsonPrintable.hpp"
|
#include "Internals/JsonPrintable.hpp"
|
||||||
#include "Internals/List.hpp"
|
#include "Internals/List.hpp"
|
||||||
#include "Internals/ReferenceType.hpp"
|
#include "Internals/ReferenceType.hpp"
|
||||||
@ -30,7 +31,8 @@ class JsonBuffer;
|
|||||||
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
|
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
|
||||||
class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||||
public Internals::ReferenceType,
|
public Internals::ReferenceType,
|
||||||
public Internals::List<JsonVariant> {
|
public Internals::List<JsonVariant>,
|
||||||
|
public Internals::JsonBufferAllocated {
|
||||||
// JsonBuffer is a friend because it needs to call the private constructor.
|
// JsonBuffer is a friend because it needs to call the private constructor.
|
||||||
friend class JsonBuffer;
|
friend class JsonBuffer;
|
||||||
|
|
||||||
@ -69,6 +71,9 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
|||||||
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
|
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
|
||||||
JsonObject &createNestedObject();
|
JsonObject &createNestedObject();
|
||||||
|
|
||||||
|
// Removes element at specified index.
|
||||||
|
void removeAt(int index);
|
||||||
|
|
||||||
// Returns a reference an invalid JsonArray.
|
// Returns a reference an invalid JsonArray.
|
||||||
// This object is meant to replace a NULL pointer.
|
// This object is meant to replace a NULL pointer.
|
||||||
// This is used when memory allocation or JSON parsing fail.
|
// This is used when memory allocation or JSON parsing fail.
|
||||||
@ -82,6 +87,8 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
|||||||
explicit JsonArray(JsonBuffer *buffer)
|
explicit JsonArray(JsonBuffer *buffer)
|
||||||
: Internals::List<JsonVariant>(buffer) {}
|
: Internals::List<JsonVariant>(buffer) {}
|
||||||
|
|
||||||
|
node_type *getNodeAt(int index) const;
|
||||||
|
|
||||||
// The instance returned by JsonArray::invalid()
|
// The instance returned by JsonArray::invalid()
|
||||||
static JsonArray _invalid;
|
static JsonArray _invalid;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,6 +9,12 @@
|
|||||||
#include <stddef.h> // for size_t
|
#include <stddef.h> // for size_t
|
||||||
#include <stdint.h> // for uint8_t
|
#include <stdint.h> // for uint8_t
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
class JsonArray;
|
class JsonArray;
|
||||||
class JsonObject;
|
class JsonObject;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Internals/JsonBufferAllocated.hpp"
|
||||||
#include "Internals/JsonPrintable.hpp"
|
#include "Internals/JsonPrintable.hpp"
|
||||||
#include "Internals/List.hpp"
|
#include "Internals/List.hpp"
|
||||||
#include "Internals/ReferenceType.hpp"
|
#include "Internals/ReferenceType.hpp"
|
||||||
@ -30,7 +31,8 @@ class JsonBuffer;
|
|||||||
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
|
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
|
||||||
class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||||
public Internals::ReferenceType,
|
public Internals::ReferenceType,
|
||||||
public Internals::List<JsonPair> {
|
public Internals::List<JsonPair>,
|
||||||
|
public Internals::JsonBufferAllocated {
|
||||||
// JsonBuffer is a friend because it needs to call the private constructor.
|
// JsonBuffer is a friend because it needs to call the private constructor.
|
||||||
friend class JsonBuffer;
|
friend class JsonBuffer;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -22,10 +22,10 @@ class StaticJsonBuffer : public JsonBuffer {
|
|||||||
size_t size() const { return _size; }
|
size_t size() const { return _size; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void* alloc(size_t size) {
|
virtual void* alloc(size_t bytes) {
|
||||||
if (_size + size > CAPACITY) return NULL;
|
if (_size + bytes > CAPACITY) return NULL;
|
||||||
void* p = &_buffer[_size];
|
void* p = &_buffer[_size];
|
||||||
_size += size;
|
_size += bytes;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
name=ArduinoJson
|
|
||||||
version=4.0
|
|
||||||
author=Benoit Blanchon <http://blog.benoitblanchon.fr/>
|
|
||||||
maintainer=Benoit Blanchon <http://blog.benoitblanchon.fr/>
|
|
||||||
sentence=An efficient and elegant JSON library for Arduino
|
|
||||||
paragraph=Supports JSON parsing and formatting. Uses fixed memory allocation.
|
|
||||||
url=https://github.com/bblanchon/ArduinoJson
|
|
||||||
architectures=*
|
|
@ -1,6 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
ZIP="C:\Program Files\7-Zip\7z.exe"
|
|
||||||
TAG=$(git describe)
|
TAG=$(git describe)
|
||||||
OUTPUT="ArduinoJson-$TAG.zip"
|
OUTPUT="ArduinoJson-$TAG.zip"
|
||||||
|
|
||||||
@ -10,13 +9,14 @@ cd ../..
|
|||||||
rm -f $OUTPUT
|
rm -f $OUTPUT
|
||||||
|
|
||||||
# create zip
|
# create zip
|
||||||
"$ZIP" a $OUTPUT \
|
7z a $OUTPUT \
|
||||||
ArduinoJson/CHANGELOG.md \
|
ArduinoJson/CHANGELOG.md \
|
||||||
ArduinoJson/doc \
|
|
||||||
ArduinoJson/examples \
|
ArduinoJson/examples \
|
||||||
ArduinoJson/include \
|
ArduinoJson/include \
|
||||||
ArduinoJson/keywords.txt \
|
ArduinoJson/keywords.txt \
|
||||||
ArduinoJson/library.properties \
|
|
||||||
ArduinoJson/LICENSE.md \
|
ArduinoJson/LICENSE.md \
|
||||||
ArduinoJson/README.md \
|
ArduinoJson/README.md \
|
||||||
ArduinoJson/src
|
ArduinoJson/src \
|
||||||
|
ArduinoJson/ArduinoJson.h \
|
||||||
|
ArduinoJson/ArduinoJson.cpp \
|
||||||
|
-x!ArduinoJson/src/CMakeLists.txt
|
@ -20,10 +20,10 @@ build-env()
|
|||||||
if [[ $(uname) == MINGW* ]]
|
if [[ $(uname) == MINGW* ]]
|
||||||
then
|
then
|
||||||
build-env "Make" "MinGW Makefiles"
|
build-env "Make" "MinGW Makefiles"
|
||||||
build-env "SublimeText" "Sublime Text 2 - MinGW Makefiles"
|
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||||
build-env "VisualStudio" "Visual Studio 12 2013"
|
build-env "VisualStudio" "Visual Studio 12 2013"
|
||||||
else
|
else
|
||||||
build-env "SublimeText" "Sublime Text 2 - Unix Makefiles"
|
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||||
build-env "Make" "Unix Makefiles"
|
build-env "Make" "Unix Makefiles"
|
||||||
build-env "Xcode" "Xcode"
|
build-env "Xcode" "Xcode"
|
||||||
fi
|
fi
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
#include "../../include/ArduinoJson/Arduino/Print.hpp"
|
#include "../../include/ArduinoJson/Arduino/Print.hpp"
|
||||||
|
|
||||||
#include <stdio.h> // for sprintf
|
#include <math.h> // for isnan() and isinf()
|
||||||
|
#include <stdio.h> // for sprintf()
|
||||||
|
|
||||||
size_t Print::print(const char s[]) {
|
size_t Print::print(const char s[]) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
@ -19,8 +20,24 @@ size_t Print::print(const char s[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t Print::print(double value, int digits) {
|
size_t Print::print(double value, int digits) {
|
||||||
|
// https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/sam/cores/arduino/Print.cpp#L218
|
||||||
|
if (isnan(value)) return print("nan");
|
||||||
|
if (isinf(value)) return print("inf");
|
||||||
|
|
||||||
char tmp[32];
|
char tmp[32];
|
||||||
|
|
||||||
|
// https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/sam/cores/arduino/Print.cpp#L220
|
||||||
|
bool isBigDouble = value > 4294967040.0 || value < -4294967040.0;
|
||||||
|
|
||||||
|
if (isBigDouble) {
|
||||||
|
// Arduino's implementation prints "ovf"
|
||||||
|
// We prefer trying to use scientific notation, since we have sprintf
|
||||||
|
sprintf(tmp, "%g", value);
|
||||||
|
} else {
|
||||||
|
// Here we have the exact same output as Arduino's implementation
|
||||||
sprintf(tmp, "%.*f", digits, value);
|
sprintf(tmp, "%.*f", digits, value);
|
||||||
|
}
|
||||||
|
|
||||||
return print(tmp);
|
return print(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
|
||||||
// MIT License
|
|
||||||
//
|
|
||||||
// Arduino JSON library
|
|
||||||
// https://github.com/bblanchon/ArduinoJson
|
|
||||||
|
|
||||||
// About this file
|
|
||||||
// ---------------
|
|
||||||
// This file is here to please the Arduino IDE. It must be present in the src/
|
|
||||||
// for the IDE to find it. Feel free to ignore this file if your working in
|
|
||||||
// another environment
|
|
||||||
|
|
||||||
#include "../include/ArduinoJson.h"
|
|
@ -20,6 +20,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
|||||||
-Wno-sign-conversion
|
-Wno-sign-conversion
|
||||||
-Wno-unused
|
-Wno-unused
|
||||||
-Wno-variadic-macros
|
-Wno-variadic-macros
|
||||||
|
-Wnon-virtual-dtor
|
||||||
-Wold-style-cast
|
-Wold-style-cast
|
||||||
-Woverloaded-virtual
|
-Woverloaded-virtual
|
||||||
-Wredundant-decls
|
-Wredundant-decls
|
||||||
@ -38,5 +39,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU)")
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
add_definitions(
|
||||||
|
-Wc++11-compat
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(ArduinoJson ${SRC_FILES} ${INC_FILES})
|
add_library(ArduinoJson ${SRC_FILES} ${INC_FILES})
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "../../include/ArduinoJson/Internals/List.hpp"
|
#include "../../include/ArduinoJson/Internals/List.hpp"
|
||||||
|
|
||||||
#include "../../include/ArduinoJson/Internals/PlacementNew.hpp"
|
|
||||||
#include "../../include/ArduinoJson/JsonPair.hpp"
|
#include "../../include/ArduinoJson/JsonPair.hpp"
|
||||||
#include "../../include/ArduinoJson/JsonVariant.hpp"
|
#include "../../include/ArduinoJson/JsonVariant.hpp"
|
||||||
|
|
||||||
@ -31,5 +30,5 @@ void List<T>::removeNode(node_type *nodeToRemove) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class List<JsonPair>;
|
template class ArduinoJson::Internals::List<JsonPair>;
|
||||||
template class List<JsonVariant>;
|
template class ArduinoJson::Internals::List<JsonVariant>;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -8,16 +8,21 @@
|
|||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
// How to escape special chars:
|
||||||
|
// specialChars[2*i+1] => the special char
|
||||||
|
// specialChars[2*i] => the char to use instead
|
||||||
|
static const char specialChars[] = "\"\"\\\\b\bf\fn\nr\rt\t";
|
||||||
|
|
||||||
static inline char getSpecialChar(char c) {
|
static inline char getSpecialChar(char c) {
|
||||||
// Optimized for code size on a 8-bit AVR
|
// Optimized for code size on a 8-bit AVR
|
||||||
|
|
||||||
const char *p = "\"\"\\\\\bb\ff\nn\rr\tt\0";
|
const char *p = specialChars;
|
||||||
|
|
||||||
while (p[0] && p[0] != c) {
|
while (p[0] && p[1] != c) {
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p[1];
|
return p[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t printCharTo(char c, Print &p) {
|
static inline size_t printCharTo(char c, Print &p) {
|
||||||
@ -41,7 +46,7 @@ size_t QuotedString::printTo(const char *s, Print &p) {
|
|||||||
static char unescapeChar(char c) {
|
static char unescapeChar(char c) {
|
||||||
// Optimized for code size on a 8-bit AVR
|
// Optimized for code size on a 8-bit AVR
|
||||||
|
|
||||||
const char *p = "b\bf\fn\nr\rt\t";
|
const char *p = specialChars + 4;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (p[0] == '\0') return c;
|
if (p[0] == '\0') return c;
|
||||||
@ -53,46 +58,44 @@ static char unescapeChar(char c) {
|
|||||||
static inline bool isQuote(char c) { return c == '\"' || c == '\''; }
|
static inline bool isQuote(char c) { return c == '\"' || c == '\''; }
|
||||||
|
|
||||||
char *QuotedString::extractFrom(char *input, char **endPtr) {
|
char *QuotedString::extractFrom(char *input, char **endPtr) {
|
||||||
char firstChar = *input;
|
|
||||||
|
|
||||||
if (!isQuote(firstChar)) {
|
|
||||||
// must start with a quote
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char stopChar = firstChar; // closing quote is the same as opening quote
|
|
||||||
|
|
||||||
char *startPtr = input + 1; // skip the quote
|
char *startPtr = input + 1; // skip the quote
|
||||||
char *readPtr = startPtr;
|
char *readPtr = startPtr;
|
||||||
char *writePtr = startPtr;
|
char *writePtr = startPtr;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
|
char firstChar = *input;
|
||||||
|
char stopChar = firstChar; // closing quote is the same as opening quote
|
||||||
|
|
||||||
|
if (!isQuote(firstChar)) goto ERROR_OPENING_QUOTE_MISSING;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = *readPtr++;
|
c = *readPtr++;
|
||||||
|
|
||||||
if (c == '\0') {
|
if (c == '\0') goto ERROR_CLOSING_QUOTE_MISSING;
|
||||||
// premature ending
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == stopChar) {
|
if (c == stopChar) goto SUCCESS;
|
||||||
// closing quote
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
// replace char
|
// replace char
|
||||||
c = unescapeChar(*readPtr++);
|
c = unescapeChar(*readPtr++);
|
||||||
|
if (c == '\0') goto ERROR_ESCAPE_SEQUENCE_INTERRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
*writePtr++ = c;
|
*writePtr++ = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUCCESS:
|
||||||
// end the string here
|
// end the string here
|
||||||
*writePtr = '\0';
|
*writePtr = '\0';
|
||||||
|
|
||||||
// update end ptr
|
// update end ptr
|
||||||
*endPtr = readPtr;
|
*endPtr = readPtr;
|
||||||
|
|
||||||
|
// return pointer to unquoted string
|
||||||
return startPtr;
|
return startPtr;
|
||||||
|
|
||||||
|
ERROR_OPENING_QUOTE_MISSING:
|
||||||
|
ERROR_CLOSING_QUOTE_MISSING:
|
||||||
|
ERROR_ESCAPE_SEQUENCE_INTERRUPTED:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -15,8 +15,7 @@ using namespace ArduinoJson::Internals;
|
|||||||
JsonArray JsonArray::_invalid(NULL);
|
JsonArray JsonArray::_invalid(NULL);
|
||||||
|
|
||||||
JsonVariant &JsonArray::at(int index) const {
|
JsonVariant &JsonArray::at(int index) const {
|
||||||
node_type *node = _firstNode;
|
node_type *node = getNodeAt(index);
|
||||||
while (node && index--) node = node->next;
|
|
||||||
return node ? node->content : JsonVariant::invalid();
|
return node ? node->content : JsonVariant::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +42,14 @@ JsonObject &JsonArray::createNestedObject() {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonArray::node_type *JsonArray::getNodeAt(int index) const {
|
||||||
|
node_type *node = _firstNode;
|
||||||
|
while (node && index--) node = node->next;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonArray::removeAt(int index) { removeNode(getNodeAt(index)); }
|
||||||
|
|
||||||
void JsonArray::writeTo(JsonWriter &writer) const {
|
void JsonArray::writeTo(JsonWriter &writer) const {
|
||||||
writer.beginArray();
|
writer.beginArray();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -7,7 +7,6 @@
|
|||||||
#include "../include/ArduinoJson/JsonBuffer.hpp"
|
#include "../include/ArduinoJson/JsonBuffer.hpp"
|
||||||
|
|
||||||
#include "../include/ArduinoJson/Internals/JsonParser.hpp"
|
#include "../include/ArduinoJson/Internals/JsonParser.hpp"
|
||||||
#include "../include/ArduinoJson/Internals/PlacementNew.hpp"
|
|
||||||
#include "../include/ArduinoJson/JsonArray.hpp"
|
#include "../include/ArduinoJson/JsonArray.hpp"
|
||||||
#include "../include/ArduinoJson/JsonObject.hpp"
|
#include "../include/ArduinoJson/JsonObject.hpp"
|
||||||
|
|
||||||
@ -15,15 +14,13 @@ using namespace ArduinoJson;
|
|||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
JsonArray &JsonBuffer::createArray() {
|
JsonArray &JsonBuffer::createArray() {
|
||||||
void *ptr = alloc(sizeof(JsonArray));
|
JsonArray *ptr = new (this) JsonArray(this);
|
||||||
if (ptr) return *new (ptr) JsonArray(this);
|
return ptr ? *ptr : JsonArray::invalid();
|
||||||
return JsonArray::invalid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject &JsonBuffer::createObject() {
|
JsonObject &JsonBuffer::createObject() {
|
||||||
void *ptr = alloc(sizeof(JsonObject));
|
JsonObject *ptr = new (this) JsonObject(this);
|
||||||
if (ptr) return *new (ptr) JsonObject(this);
|
return ptr ? *ptr : JsonObject::invalid();
|
||||||
return JsonObject::invalid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray &JsonBuffer::parseArray(char *json, uint8_t nestingLimit) {
|
JsonArray &JsonBuffer::parseArray(char *json, uint8_t nestingLimit) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <string.h> // for strcmp
|
#include <string.h> // for strcmp
|
||||||
|
|
||||||
#include "../include/ArduinoJson/Internals/PlacementNew.hpp"
|
|
||||||
#include "../include/ArduinoJson/Internals/StringBuilder.hpp"
|
#include "../include/ArduinoJson/Internals/StringBuilder.hpp"
|
||||||
#include "../include/ArduinoJson/JsonArray.hpp"
|
#include "../include/ArduinoJson/JsonArray.hpp"
|
||||||
#include "../include/ArduinoJson/JsonBuffer.hpp"
|
#include "../include/ArduinoJson/JsonBuffer.hpp"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -64,13 +64,13 @@ void JsonVariant::set(long value) {
|
|||||||
|
|
||||||
void JsonVariant::set(JsonArray &array) {
|
void JsonVariant::set(JsonArray &array) {
|
||||||
if (_type == JSON_INVALID) return;
|
if (_type == JSON_INVALID) return;
|
||||||
_type = JSON_ARRAY;
|
_type = array.success() ? JSON_ARRAY : JSON_INVALID;
|
||||||
_content.asArray = &array;
|
_content.asArray = &array;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonVariant::set(JsonObject &object) {
|
void JsonVariant::set(JsonObject &object) {
|
||||||
if (_type == JSON_INVALID) return;
|
if (_type == JSON_INVALID) return;
|
||||||
_type = JSON_OBJECT;
|
_type = object.success() ? JSON_OBJECT : JSON_INVALID;
|
||||||
_content.asObject = &object;
|
_content.asObject = &object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
test/DynamicJsonBuffer_Array_Tests.cpp
Normal file
32
test/DynamicJsonBuffer_Array_Tests.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
TEST(DynamicJsonBuffer_Array_Tests, GrowsWithArray) {
|
||||||
|
DynamicJsonBuffer jsonBuffer;
|
||||||
|
|
||||||
|
JsonArray &array = jsonBuffer.createArray();
|
||||||
|
ASSERT_EQ(JSON_ARRAY_SIZE(0), jsonBuffer.size());
|
||||||
|
|
||||||
|
array.add("hello");
|
||||||
|
ASSERT_EQ(JSON_ARRAY_SIZE(1), jsonBuffer.size());
|
||||||
|
|
||||||
|
array.add("world");
|
||||||
|
ASSERT_EQ(JSON_ARRAY_SIZE(2), jsonBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DynamicJsonBuffer_Array_Tests, CanAdd1000Values) {
|
||||||
|
DynamicJsonBuffer jsonBuffer;
|
||||||
|
|
||||||
|
JsonArray &array = jsonBuffer.createArray();
|
||||||
|
|
||||||
|
for (int i = 1; i <= 1000; i++) {
|
||||||
|
array.add("hello");
|
||||||
|
ASSERT_EQ(array.size(), i);
|
||||||
|
}
|
||||||
|
}
|
34
test/DynamicJsonBuffer_Basic_Tests.cpp
Normal file
34
test/DynamicJsonBuffer_Basic_Tests.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#define protected public
|
||||||
|
#include <ArduinoJson/DynamicJsonBuffer.hpp>
|
||||||
|
|
||||||
|
using namespace ArduinoJson;
|
||||||
|
|
||||||
|
class DynamicJsonBuffer_Basic_Tests : public testing::Test {
|
||||||
|
protected:
|
||||||
|
DynamicJsonBuffer buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_Basic_Tests, InitialSizeIsZero) {
|
||||||
|
ASSERT_EQ(0, buffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_Basic_Tests, SizeIncreasesAfterAlloc) {
|
||||||
|
buffer.alloc(1);
|
||||||
|
ASSERT_EQ(1, buffer.size());
|
||||||
|
buffer.alloc(1);
|
||||||
|
ASSERT_EQ(2, buffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_Basic_Tests, ReturnDifferentPointer) {
|
||||||
|
void* p1 = buffer.alloc(1);
|
||||||
|
void* p2 = buffer.alloc(2);
|
||||||
|
ASSERT_NE(p1, p2);
|
||||||
|
}
|
37
test/DynamicJsonBuffer_NoMemory_Tests.cpp
Normal file
37
test/DynamicJsonBuffer_NoMemory_Tests.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class DynamicJsonBuffer_NoMemory_Tests : public ::testing::Test {
|
||||||
|
class NoMemoryAllocator {
|
||||||
|
public:
|
||||||
|
void* allocate(size_t) { return NULL; }
|
||||||
|
void deallocate(void*) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Internals::BlockJsonBuffer<NoMemoryAllocator> _jsonBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_NoMemory_Tests, CreateArray) {
|
||||||
|
ASSERT_FALSE(_jsonBuffer.createArray().success());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_NoMemory_Tests, CreateObject) {
|
||||||
|
ASSERT_FALSE(_jsonBuffer.createObject().success());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_NoMemory_Tests, ParseArray) {
|
||||||
|
char json[] = "[]";
|
||||||
|
ASSERT_FALSE(_jsonBuffer.parseArray(json).success());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DynamicJsonBuffer_NoMemory_Tests, ParseObject) {
|
||||||
|
char json[] = "{}";
|
||||||
|
ASSERT_FALSE(_jsonBuffer.parseObject(json).success());
|
||||||
|
}
|
24
test/DynamicJsonBuffer_Object_Tests.cpp
Normal file
24
test/DynamicJsonBuffer_Object_Tests.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
TEST(DynamicJsonBuffer_Object_Tests, GrowsWithObject) {
|
||||||
|
DynamicJsonBuffer json;
|
||||||
|
|
||||||
|
JsonObject &obj = json.createObject();
|
||||||
|
ASSERT_EQ(JSON_OBJECT_SIZE(0), json.size());
|
||||||
|
|
||||||
|
obj["hello"];
|
||||||
|
ASSERT_EQ(JSON_OBJECT_SIZE(1), json.size());
|
||||||
|
|
||||||
|
obj["world"];
|
||||||
|
ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size());
|
||||||
|
|
||||||
|
obj["world"]; // <- same value, should not grow
|
||||||
|
ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size());
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -10,16 +10,16 @@
|
|||||||
|
|
||||||
class GbathreeBug : public testing::Test {
|
class GbathreeBug : public testing::Test {
|
||||||
public:
|
public:
|
||||||
GbathreeBug() : object(buffer.parseObject(getJson())) {}
|
GbathreeBug() : _object(_buffer.parseObject(getJson())) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char json[1024];
|
char _json[1024];
|
||||||
StaticJsonBuffer<10000> buffer;
|
DynamicJsonBuffer _buffer;
|
||||||
const JsonObject& object;
|
const JsonObject& _object;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* getJson() {
|
char* getJson() {
|
||||||
strcpy(json,
|
strcpy(_json,
|
||||||
"{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,"
|
"{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,"
|
||||||
"\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_"
|
"\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_"
|
||||||
"baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":"
|
"baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":"
|
||||||
@ -30,46 +30,46 @@ class GbathreeBug : public testing::Test {
|
|||||||
"\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,"
|
"\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,"
|
||||||
"15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],"
|
"15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],"
|
||||||
"[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}");
|
"[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}");
|
||||||
return json;
|
return _json;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Success) { EXPECT_TRUE(object.success()); }
|
TEST_F(GbathreeBug, Success) { EXPECT_TRUE(_object.success()); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, ProtocolName) {
|
TEST_F(GbathreeBug, ProtocolName) {
|
||||||
EXPECT_STREQ("fluorescence", object.at("protocol_name").asString());
|
EXPECT_STREQ("fluorescence", _object.at("protocol_name").asString());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Repeats) { EXPECT_EQ(1, object["repeats"]); }
|
TEST_F(GbathreeBug, Repeats) { EXPECT_EQ(1, _object["repeats"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Wait) { EXPECT_EQ(0, object["wait"]); }
|
TEST_F(GbathreeBug, Wait) { EXPECT_EQ(0, _object["wait"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Measurements) { EXPECT_EQ(3, object["measurements"]); }
|
TEST_F(GbathreeBug, Measurements) { EXPECT_EQ(3, _object["measurements"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Meas2_Light) { EXPECT_EQ(15, object["meas2_light"]); }
|
TEST_F(GbathreeBug, Meas2_Light) { EXPECT_EQ(15, _object["meas2_light"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Meas1_Baseline) { EXPECT_EQ(0, object["meas1_baseline"]); }
|
TEST_F(GbathreeBug, Meas1_Baseline) { EXPECT_EQ(0, _object["meas1_baseline"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Act_Light) { EXPECT_EQ(20, object["act_light"]); }
|
TEST_F(GbathreeBug, Act_Light) { EXPECT_EQ(20, _object["act_light"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Pulsesize) { EXPECT_EQ(25, object["pulsesize"]); }
|
TEST_F(GbathreeBug, Pulsesize) { EXPECT_EQ(25, _object["pulsesize"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Pulsedistance) {
|
TEST_F(GbathreeBug, Pulsedistance) {
|
||||||
EXPECT_EQ(10000, object["pulsedistance"]);
|
EXPECT_EQ(10000, _object["pulsedistance"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Actintensity1) { EXPECT_EQ(50, object["actintensity1"]); }
|
TEST_F(GbathreeBug, Actintensity1) { EXPECT_EQ(50, _object["actintensity1"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Actintensity2) { EXPECT_EQ(255, object["actintensity2"]); }
|
TEST_F(GbathreeBug, Actintensity2) { EXPECT_EQ(255, _object["actintensity2"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Measintensity) { EXPECT_EQ(255, object["measintensity"]); }
|
TEST_F(GbathreeBug, Measintensity) { EXPECT_EQ(255, _object["measintensity"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Calintensity) { EXPECT_EQ(255, object["calintensity"]); }
|
TEST_F(GbathreeBug, Calintensity) { EXPECT_EQ(255, _object["calintensity"]); }
|
||||||
|
|
||||||
TEST_F(GbathreeBug, Pulses) {
|
TEST_F(GbathreeBug, Pulses) {
|
||||||
// "pulses":[50,50,50]
|
// "pulses":[50,50,50]
|
||||||
|
|
||||||
JsonArray& array = object.at("pulses");
|
JsonArray& array = _object.at("pulses");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
|
|
||||||
EXPECT_EQ(3, array.size());
|
EXPECT_EQ(3, array.size());
|
||||||
@ -82,7 +82,7 @@ TEST_F(GbathreeBug, Pulses) {
|
|||||||
TEST_F(GbathreeBug, Act) {
|
TEST_F(GbathreeBug, Act) {
|
||||||
// "act":[2,1,2,2]
|
// "act":[2,1,2,2]
|
||||||
|
|
||||||
JsonArray& array = object.at("act");
|
JsonArray& array = _object.at("act");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
|
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
@ -95,7 +95,7 @@ TEST_F(GbathreeBug, Act) {
|
|||||||
TEST_F(GbathreeBug, Detectors) {
|
TEST_F(GbathreeBug, Detectors) {
|
||||||
// "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]]
|
// "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]]
|
||||||
|
|
||||||
JsonArray& array = object.at("detectors");
|
JsonArray& array = _object.at("detectors");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ TEST_F(GbathreeBug, Detectors) {
|
|||||||
TEST_F(GbathreeBug, Alta) {
|
TEST_F(GbathreeBug, Alta) {
|
||||||
// alta:[2,2,2,2]
|
// alta:[2,2,2,2]
|
||||||
|
|
||||||
JsonArray& array = object.at("alta");
|
JsonArray& array = _object.at("alta");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
|
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
@ -123,7 +123,7 @@ TEST_F(GbathreeBug, Alta) {
|
|||||||
TEST_F(GbathreeBug, Altb) {
|
TEST_F(GbathreeBug, Altb) {
|
||||||
// altb:[2,2,2,2]
|
// altb:[2,2,2,2]
|
||||||
|
|
||||||
JsonArray& array = object.at("altb");
|
JsonArray& array = _object.at("altb");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
|
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
@ -136,7 +136,7 @@ TEST_F(GbathreeBug, Altb) {
|
|||||||
TEST_F(GbathreeBug, Measlights) {
|
TEST_F(GbathreeBug, Measlights) {
|
||||||
// "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
|
// "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
|
||||||
|
|
||||||
JsonArray& array = object.at("measlights");
|
JsonArray& array = _object.at("measlights");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ TEST_F(GbathreeBug, Measlights) {
|
|||||||
TEST_F(GbathreeBug, Measlights2) {
|
TEST_F(GbathreeBug, Measlights2) {
|
||||||
// "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
|
// "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
|
||||||
|
|
||||||
JsonArray& array = object.at("measlights2");
|
JsonArray& array = _object.at("measlights2");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ TEST_F(GbathreeBug, Measlights2) {
|
|||||||
TEST_F(GbathreeBug, Altc) {
|
TEST_F(GbathreeBug, Altc) {
|
||||||
// altc:[2,2,2,2]
|
// altc:[2,2,2,2]
|
||||||
|
|
||||||
JsonArray& array = object.at("altc");
|
JsonArray& array = _object.at("altc");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
|
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
@ -180,7 +180,7 @@ TEST_F(GbathreeBug, Altc) {
|
|||||||
TEST_F(GbathreeBug, Altd) {
|
TEST_F(GbathreeBug, Altd) {
|
||||||
// altd:[2,2,2,2]
|
// altd:[2,2,2,2]
|
||||||
|
|
||||||
JsonArray& array = object.at("altd");
|
JsonArray& array = _object.at("altd");
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(array.success());
|
||||||
|
|
||||||
EXPECT_EQ(4, array.size());
|
EXPECT_EQ(4, array.size());
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -13,34 +13,34 @@ class IntegrationTests : public testing::TestWithParam<const char*> {
|
|||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
_input = GetParam();
|
_input = GetParam();
|
||||||
strcpy(inputBuffer, _input);
|
strcpy(_inputBuffer, _input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseThenPrint(char* input, char* output) {
|
void parseThenPrint(char* input, char* output) {
|
||||||
StaticJsonBuffer<10000> json;
|
DynamicJsonBuffer buffer;
|
||||||
json.parseObject(input).printTo(output, MAX_JSON_SIZE);
|
buffer.parseObject(input).printTo(output, MAX_JSON_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseThenPrettyPrint(char* input, char* output) {
|
void parseThenPrettyPrint(char* input, char* output) {
|
||||||
StaticJsonBuffer<10000> json;
|
DynamicJsonBuffer buffer;
|
||||||
json.parseObject(input).prettyPrintTo(output, MAX_JSON_SIZE);
|
buffer.parseObject(input).prettyPrintTo(output, MAX_JSON_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _input;
|
const char* _input;
|
||||||
char inputBuffer[MAX_JSON_SIZE];
|
char _inputBuffer[MAX_JSON_SIZE];
|
||||||
char outputBuffer[MAX_JSON_SIZE];
|
char _outputBuffer[MAX_JSON_SIZE];
|
||||||
char intermediateBuffer[MAX_JSON_SIZE];
|
char _intermediateBuffer[MAX_JSON_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(IntegrationTests, ParseThenPrint) {
|
TEST_P(IntegrationTests, ParseThenPrint) {
|
||||||
parseThenPrint(inputBuffer, outputBuffer);
|
parseThenPrint(_inputBuffer, _outputBuffer);
|
||||||
ASSERT_STREQ(_input, outputBuffer);
|
ASSERT_STREQ(_input, _outputBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(IntegrationTests, ParseThenPrettyPrintThenParseThenPrint) {
|
TEST_P(IntegrationTests, ParseThenPrettyPrintThenParseThenPrint) {
|
||||||
parseThenPrettyPrint(inputBuffer, intermediateBuffer);
|
parseThenPrettyPrint(_inputBuffer, _intermediateBuffer);
|
||||||
parseThenPrint(intermediateBuffer, outputBuffer);
|
parseThenPrint(_intermediateBuffer, _outputBuffer);
|
||||||
ASSERT_STREQ(_input, outputBuffer);
|
ASSERT_STREQ(_input, _outputBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
39
test/Issue34.cpp
Normal file
39
test/Issue34.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class Issue34 : public testing::Test {
|
||||||
|
protected:
|
||||||
|
template <typename T>
|
||||||
|
void test_with_value(T expected) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> jsonBuffer;
|
||||||
|
|
||||||
|
JsonObject& jsonObject = jsonBuffer.createObject();
|
||||||
|
|
||||||
|
jsonObject["key"] = expected;
|
||||||
|
T actual = jsonObject["key"];
|
||||||
|
|
||||||
|
ASSERT_EQ(expected, actual);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(Issue34, int8_t) { test_with_value<int8_t>(1); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, uint8_t) { test_with_value<uint8_t>(2); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, int16_t) { test_with_value<int16_t>(3); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, uint16_t) { test_with_value<uint16_t>(4); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, int32_t) { test_with_value<int32_t>(5); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, uint32_t) { test_with_value<uint32_t>(6); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, float) { test_with_value<float>(7); }
|
||||||
|
|
||||||
|
TEST_F(Issue34, double) { test_with_value<double>(8); }
|
47
test/Issue67.cpp
Normal file
47
test/Issue67.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class Issue67 : public testing::Test {
|
||||||
|
public:
|
||||||
|
void whenInputIs(double value) { _variant = value; }
|
||||||
|
|
||||||
|
void outputMustBe(const char* expected) {
|
||||||
|
char buffer[1024];
|
||||||
|
_variant.printTo(buffer, sizeof(buffer));
|
||||||
|
ASSERT_STREQ(expected, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
JsonVariant _variant;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(Issue67, BigPositiveDouble) {
|
||||||
|
whenInputIs(1e100);
|
||||||
|
outputMustBe("1e+100");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Issue67, BigNegativeDouble) {
|
||||||
|
whenInputIs(-1e100);
|
||||||
|
outputMustBe("-1e+100");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Issue67, Zero) {
|
||||||
|
whenInputIs(0.0);
|
||||||
|
outputMustBe("0.00");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Issue67, SmallPositiveDouble) {
|
||||||
|
whenInputIs(111.111);
|
||||||
|
outputMustBe("111.11");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Issue67, SmallNegativeDouble) {
|
||||||
|
whenInputIs(-111.111);
|
||||||
|
outputMustBe("-111.11");
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
class JsonArray_Container_Tests : public ::testing::Test {
|
class JsonArray_Container_Tests : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
JsonArray_Container_Tests() : array(json.createArray()) {}
|
JsonArray_Container_Tests() : _array(_jsonBuffer.createArray()) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void firstMustEqual(T expected) {
|
void firstMustEqual(T expected) {
|
||||||
@ -31,106 +31,144 @@ class JsonArray_Container_Tests : public ::testing::Test {
|
|||||||
itemMustReference(1, expected);
|
itemMustReference(1, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sizeMustBe(int expected) { EXPECT_EQ(expected, array.size()); }
|
void sizeMustBe(int expected) { EXPECT_EQ(expected, _array.size()); }
|
||||||
|
|
||||||
StaticJsonBuffer<256> json;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonArray& array;
|
JsonArray& _array;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void itemMustEqual(int index, T expected) {
|
void itemMustEqual(int index, T expected) {
|
||||||
EXPECT_EQ(expected, array[index].as<T>());
|
EXPECT_EQ(expected, _array[index].as<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void itemMustReference(int index, const T& expected) {
|
void itemMustReference(int index, const T& expected) {
|
||||||
EXPECT_EQ(&expected, &array[index].as<T&>());
|
EXPECT_EQ(&expected, &_array[index].as<T&>());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void JsonArray_Container_Tests::itemMustEqual(int index, const char* expected) {
|
||||||
|
EXPECT_STREQ(expected, _array[index].asString());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, SuccessIsTrue) {
|
TEST_F(JsonArray_Container_Tests, SuccessIsTrue) {
|
||||||
EXPECT_TRUE(array.success());
|
EXPECT_TRUE(_array.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, InitialSizeIsZero) { sizeMustBe(0); }
|
TEST_F(JsonArray_Container_Tests, InitialSizeIsZero) { sizeMustBe(0); }
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, Grow_WhenValuesAreAdded) {
|
TEST_F(JsonArray_Container_Tests, Grow_WhenValuesAreAdded) {
|
||||||
array.add("hello");
|
_array.add("hello");
|
||||||
sizeMustBe(1);
|
sizeMustBe(1);
|
||||||
|
|
||||||
array.add("world");
|
_array.add("world");
|
||||||
sizeMustBe(2);
|
sizeMustBe(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanStoreIntegers) {
|
TEST_F(JsonArray_Container_Tests, CanStoreIntegers) {
|
||||||
array.add(123);
|
_array.add(123);
|
||||||
array.add(456);
|
_array.add(456);
|
||||||
|
|
||||||
firstMustEqual(123);
|
firstMustEqual(123);
|
||||||
secondMustEqual(456);
|
secondMustEqual(456);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanStoreDoubles) {
|
TEST_F(JsonArray_Container_Tests, CanStoreDoubles) {
|
||||||
array.add(123.45);
|
_array.add(123.45);
|
||||||
array.add(456.78);
|
_array.add(456.78);
|
||||||
|
|
||||||
firstMustEqual(123.45);
|
firstMustEqual(123.45);
|
||||||
secondMustEqual(456.78);
|
secondMustEqual(456.78);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanStoreBooleans) {
|
TEST_F(JsonArray_Container_Tests, CanStoreBooleans) {
|
||||||
array.add(true);
|
_array.add(true);
|
||||||
array.add(false);
|
_array.add(false);
|
||||||
|
|
||||||
firstMustEqual(true);
|
firstMustEqual(true);
|
||||||
secondMustEqual(false);
|
secondMustEqual(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanStoreStrings) {
|
TEST_F(JsonArray_Container_Tests, CanStoreStrings) {
|
||||||
const char* firstString = "h3110";
|
_array.add("hello");
|
||||||
const char* secondString = "w0r1d";
|
_array.add("world");
|
||||||
|
|
||||||
array.add(firstString);
|
firstMustEqual("hello");
|
||||||
array.add(secondString);
|
secondMustEqual("world");
|
||||||
|
|
||||||
firstMustEqual(firstString);
|
|
||||||
secondMustEqual(secondString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanStoreNestedArrays) {
|
TEST_F(JsonArray_Container_Tests, CanStoreNestedArrays) {
|
||||||
JsonArray& innerarray1 = json.createArray();
|
JsonArray& inner_array1 = _jsonBuffer.createArray();
|
||||||
JsonArray& innerarray2 = json.createArray();
|
JsonArray& inner_array2 = _jsonBuffer.createArray();
|
||||||
|
|
||||||
array.add(innerarray1);
|
_array.add(inner_array1);
|
||||||
array.add(innerarray2);
|
_array.add(inner_array2);
|
||||||
|
|
||||||
firstMustReference(innerarray1);
|
firstMustReference(inner_array1);
|
||||||
secondMustReference(innerarray2);
|
secondMustReference(inner_array2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanStoreNestedObjects) {
|
TEST_F(JsonArray_Container_Tests, CanStoreNestedObjects) {
|
||||||
JsonObject& innerObject1 = json.createObject();
|
JsonObject& innerObject1 = _jsonBuffer.createObject();
|
||||||
JsonObject& innerObject2 = json.createObject();
|
JsonObject& innerObject2 = _jsonBuffer.createObject();
|
||||||
|
|
||||||
array.add(innerObject1);
|
_array.add(innerObject1);
|
||||||
array.add(innerObject2);
|
_array.add(innerObject2);
|
||||||
|
|
||||||
firstMustReference(innerObject1);
|
firstMustReference(innerObject1);
|
||||||
secondMustReference(innerObject2);
|
secondMustReference(innerObject2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanCreateNestedArrays) {
|
TEST_F(JsonArray_Container_Tests, CanCreateNestedArrays) {
|
||||||
JsonArray& innerarray1 = array.createNestedArray();
|
JsonArray& inner_array1 = _array.createNestedArray();
|
||||||
JsonArray& innerarray2 = array.createNestedArray();
|
JsonArray& inner_array2 = _array.createNestedArray();
|
||||||
|
|
||||||
firstMustReference(innerarray1);
|
firstMustReference(inner_array1);
|
||||||
secondMustReference(innerarray2);
|
secondMustReference(inner_array2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonArray_Container_Tests, CanCreateNestedObjects) {
|
TEST_F(JsonArray_Container_Tests, CanCreateNestedObjects) {
|
||||||
JsonObject& innerObject1 = array.createNestedObject();
|
JsonObject& innerObject1 = _array.createNestedObject();
|
||||||
JsonObject& innerObject2 = array.createNestedObject();
|
JsonObject& innerObject2 = _array.createNestedObject();
|
||||||
|
|
||||||
firstMustReference(innerObject1);
|
firstMustReference(innerObject1);
|
||||||
secondMustReference(innerObject2);
|
secondMustReference(innerObject2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonArray_Container_Tests, RemoveFirstElement) {
|
||||||
|
_array.add("one");
|
||||||
|
_array.add("two");
|
||||||
|
_array.add("three");
|
||||||
|
|
||||||
|
_array.removeAt(0);
|
||||||
|
|
||||||
|
sizeMustBe(2);
|
||||||
|
firstMustEqual("two");
|
||||||
|
secondMustEqual("three");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonArray_Container_Tests, RemoveMiddleElement) {
|
||||||
|
_array.add("one");
|
||||||
|
_array.add("two");
|
||||||
|
_array.add("three");
|
||||||
|
|
||||||
|
_array.removeAt(1);
|
||||||
|
|
||||||
|
sizeMustBe(2);
|
||||||
|
firstMustEqual("one");
|
||||||
|
secondMustEqual("three");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(JsonArray_Container_Tests, RemoveLastElement) {
|
||||||
|
_array.add("one");
|
||||||
|
_array.add("two");
|
||||||
|
_array.add("three");
|
||||||
|
|
||||||
|
_array.removeAt(2);
|
||||||
|
|
||||||
|
sizeMustBe(2);
|
||||||
|
firstMustEqual("one");
|
||||||
|
secondMustEqual("two");
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -7,21 +7,32 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
TEST(JsonArray_Iterator_Test, SimpleTest) {
|
template <typename TIterator>
|
||||||
StaticJsonBuffer<100> jsonBuffer;
|
static void run_iterator_test() {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> jsonBuffer;
|
||||||
|
|
||||||
JsonArray &array = jsonBuffer.createArray();
|
JsonArray &array = jsonBuffer.createArray();
|
||||||
array.add(12);
|
array.add(12);
|
||||||
array.add(34);
|
array.add(34);
|
||||||
|
|
||||||
JsonArray::iterator it = array.begin();
|
TIterator it = array.begin();
|
||||||
JsonArray::iterator end = array.end();
|
TIterator end = array.end();
|
||||||
|
|
||||||
EXPECT_NE(end, it);
|
EXPECT_NE(end, it);
|
||||||
EXPECT_EQ(12, it->as<int>());
|
EXPECT_EQ(12, it->template as<int>());
|
||||||
|
EXPECT_EQ(12, static_cast<int>(*it));
|
||||||
++it;
|
++it;
|
||||||
EXPECT_NE(end, it);
|
EXPECT_NE(end, it);
|
||||||
EXPECT_EQ(34, it->as<int>());
|
EXPECT_EQ(34, it->template as<int>());
|
||||||
|
EXPECT_EQ(34, static_cast<int>(*it));
|
||||||
++it;
|
++it;
|
||||||
EXPECT_EQ(end, it);
|
EXPECT_EQ(end, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(JsonArray_Iterator_Test, RunItertorToEnd) {
|
||||||
|
run_iterator_test<JsonArray::iterator>();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(JsonArray_Iterator_Test, RunConstItertorToEnd) {
|
||||||
|
run_iterator_test<JsonArray::const_iterator>();
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,20 +9,22 @@
|
|||||||
|
|
||||||
class JsonArray_PrettyPrintTo_Tests : public testing::Test {
|
class JsonArray_PrettyPrintTo_Tests : public testing::Test {
|
||||||
public:
|
public:
|
||||||
JsonArray_PrettyPrintTo_Tests() : array(json.createArray()) {}
|
JsonArray_PrettyPrintTo_Tests() : array(jsonBuffer.createArray()) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StaticJsonBuffer<200> json;
|
DynamicJsonBuffer jsonBuffer;
|
||||||
JsonArray& array;
|
JsonArray& array;
|
||||||
|
|
||||||
void outputMustBe(const char* expected) {
|
void outputMustBe(const char* expected) {
|
||||||
size_t n = array.prettyPrintTo(buffer, sizeof(buffer));
|
char actual[256];
|
||||||
EXPECT_STREQ(expected, buffer);
|
|
||||||
EXPECT_EQ(strlen(expected), n);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
size_t actualLen = array.prettyPrintTo(actual, sizeof(actual));
|
||||||
char buffer[256];
|
size_t measuredLen = array.measurePrettyLength();
|
||||||
|
|
||||||
|
EXPECT_STREQ(expected, actual);
|
||||||
|
EXPECT_EQ(strlen(expected), actualLen);
|
||||||
|
EXPECT_EQ(strlen(expected), measuredLen);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonArray_PrettyPrintTo_Tests, Empty) { outputMustBe("[]"); }
|
TEST_F(JsonArray_PrettyPrintTo_Tests, Empty) { outputMustBe("[]"); }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -16,9 +16,12 @@ class JsonArray_PrintTo_Tests : public testing::Test {
|
|||||||
JsonArray &array;
|
JsonArray &array;
|
||||||
|
|
||||||
void outputMustBe(const char *expected) {
|
void outputMustBe(const char *expected) {
|
||||||
size_t n = array.printTo(buffer, sizeof(buffer));
|
size_t actualLen = array.printTo(buffer, sizeof(buffer));
|
||||||
|
size_t measuredLen = array.measureLength();
|
||||||
|
|
||||||
EXPECT_STREQ(expected, buffer);
|
EXPECT_STREQ(expected, buffer);
|
||||||
EXPECT_EQ(strlen(expected), n);
|
EXPECT_EQ(strlen(expected), actualLen);
|
||||||
|
EXPECT_EQ(strlen(expected), measuredLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,118 +9,118 @@
|
|||||||
|
|
||||||
class JsonObject_Container_Tests : public ::testing::Test {
|
class JsonObject_Container_Tests : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
JsonObject_Container_Tests() : object(json.createObject()) {}
|
JsonObject_Container_Tests() : _object(_jsonBuffer.createObject()) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StaticJsonBuffer<256> json;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonObject& object;
|
JsonObject& _object;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, InitialSizeIsZero) {
|
TEST_F(JsonObject_Container_Tests, InitialSizeIsZero) {
|
||||||
EXPECT_EQ(0, object.size());
|
EXPECT_EQ(0, _object.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, Grow_WhenValuesAreAdded) {
|
TEST_F(JsonObject_Container_Tests, Grow_WhenValuesAreAdded) {
|
||||||
object["hello"];
|
_object["hello"];
|
||||||
EXPECT_EQ(1, object.size());
|
EXPECT_EQ(1, _object.size());
|
||||||
|
|
||||||
object["world"];
|
_object["world"];
|
||||||
EXPECT_EQ(2, object.size());
|
EXPECT_EQ(2, _object.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, DoNotGrow_WhenSameValueIsAdded) {
|
TEST_F(JsonObject_Container_Tests, DoNotGrow_WhenSameValueIsAdded) {
|
||||||
object["hello"];
|
_object["hello"];
|
||||||
EXPECT_EQ(1, object.size());
|
EXPECT_EQ(1, _object.size());
|
||||||
|
|
||||||
object["hello"];
|
_object["hello"];
|
||||||
EXPECT_EQ(1, object.size());
|
EXPECT_EQ(1, _object.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, Shrink_WhenValuesAreRemoved) {
|
TEST_F(JsonObject_Container_Tests, Shrink_WhenValuesAreRemoved) {
|
||||||
object["hello"];
|
_object["hello"];
|
||||||
object["world"];
|
_object["world"];
|
||||||
|
|
||||||
object.remove("hello");
|
_object.remove("hello");
|
||||||
EXPECT_EQ(1, object.size());
|
EXPECT_EQ(1, _object.size());
|
||||||
|
|
||||||
object.remove("world");
|
_object.remove("world");
|
||||||
EXPECT_EQ(0, object.size());
|
EXPECT_EQ(0, _object.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests,
|
TEST_F(JsonObject_Container_Tests,
|
||||||
DoNotShrink_WhenRemoveIsCalledWithAWrongKey) {
|
DoNotShrink_WhenRemoveIsCalledWithAWrongKey) {
|
||||||
object["hello"];
|
_object["hello"];
|
||||||
object["world"];
|
_object["world"];
|
||||||
|
|
||||||
object.remove(":-P");
|
_object.remove(":-P");
|
||||||
|
|
||||||
EXPECT_EQ(2, object.size());
|
EXPECT_EQ(2, _object.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, CanStoreIntegers) {
|
TEST_F(JsonObject_Container_Tests, CanStoreIntegers) {
|
||||||
object["hello"] = 123;
|
_object["hello"] = 123;
|
||||||
object["world"] = 456;
|
_object["world"] = 456;
|
||||||
|
|
||||||
EXPECT_EQ(123, object["hello"].as<int>());
|
EXPECT_EQ(123, _object["hello"].as<int>());
|
||||||
EXPECT_EQ(456, object["world"].as<int>());
|
EXPECT_EQ(456, _object["world"].as<int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, CanStoreDoubles) {
|
TEST_F(JsonObject_Container_Tests, CanStoreDoubles) {
|
||||||
object["hello"] = 123.45;
|
_object["hello"] = 123.45;
|
||||||
object["world"] = 456.78;
|
_object["world"] = 456.78;
|
||||||
|
|
||||||
EXPECT_EQ(123.45, object["hello"].as<double>());
|
EXPECT_EQ(123.45, _object["hello"].as<double>());
|
||||||
EXPECT_EQ(456.78, object["world"].as<double>());
|
EXPECT_EQ(456.78, _object["world"].as<double>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, CanStoreBooleans) {
|
TEST_F(JsonObject_Container_Tests, CanStoreBooleans) {
|
||||||
object["hello"] = true;
|
_object["hello"] = true;
|
||||||
object["world"] = false;
|
_object["world"] = false;
|
||||||
|
|
||||||
EXPECT_TRUE(object["hello"].as<bool>());
|
EXPECT_TRUE(_object["hello"].as<bool>());
|
||||||
EXPECT_FALSE(object["world"].as<bool>());
|
EXPECT_FALSE(_object["world"].as<bool>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, CanStoreStrings) {
|
TEST_F(JsonObject_Container_Tests, CanStoreStrings) {
|
||||||
object["hello"] = "h3110";
|
_object["hello"] = "h3110";
|
||||||
object["world"] = "w0r1d";
|
_object["world"] = "w0r1d";
|
||||||
|
|
||||||
EXPECT_STREQ("h3110", object["hello"].as<const char*>());
|
EXPECT_STREQ("h3110", _object["hello"].as<const char*>());
|
||||||
EXPECT_STREQ("w0r1d", object["world"].as<const char*>());
|
EXPECT_STREQ("w0r1d", _object["world"].as<const char*>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) {
|
TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) {
|
||||||
JsonArray& innerarray1 = json.createArray();
|
JsonArray& innerarray1 = _jsonBuffer.createArray();
|
||||||
JsonArray& innerarray2 = json.createArray();
|
JsonArray& innerarray2 = _jsonBuffer.createArray();
|
||||||
|
|
||||||
object["hello"] = innerarray1;
|
_object["hello"] = innerarray1;
|
||||||
object["world"] = innerarray2;
|
_object["world"] = innerarray2;
|
||||||
|
|
||||||
EXPECT_EQ(&innerarray1, &object["hello"].asArray());
|
EXPECT_EQ(&innerarray1, &_object["hello"].asArray());
|
||||||
EXPECT_EQ(&innerarray2, &object["world"].asArray());
|
EXPECT_EQ(&innerarray2, &_object["world"].asArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) {
|
TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) {
|
||||||
JsonObject& innerObject1 = json.createObject();
|
JsonObject& innerObject1 = _jsonBuffer.createObject();
|
||||||
JsonObject& innerObject2 = json.createObject();
|
JsonObject& innerObject2 = _jsonBuffer.createObject();
|
||||||
|
|
||||||
object["hello"] = innerObject1;
|
_object["hello"] = innerObject1;
|
||||||
object["world"] = innerObject2;
|
_object["world"] = innerObject2;
|
||||||
|
|
||||||
EXPECT_EQ(&innerObject1, &object["hello"].asObject());
|
EXPECT_EQ(&innerObject1, &_object["hello"].asObject());
|
||||||
EXPECT_EQ(&innerObject2, &object["world"].asObject());
|
EXPECT_EQ(&innerObject2, &_object["world"].asObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, ContainsKeyReturnFalseForNonExistingKey) {
|
TEST_F(JsonObject_Container_Tests, ContainsKeyReturnFalseForNonExistingKey) {
|
||||||
EXPECT_FALSE(object.containsKey("hello"));
|
EXPECT_FALSE(_object.containsKey("hello"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, ContainsKeyReturnTrueForDefinedValue) {
|
TEST_F(JsonObject_Container_Tests, ContainsKeyReturnTrueForDefinedValue) {
|
||||||
object.add("hello", 42);
|
_object.add("hello", 42);
|
||||||
EXPECT_TRUE(object.containsKey("hello"));
|
EXPECT_TRUE(_object.containsKey("hello"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Container_Tests, ContainsKeyReturnFalseForUndefinedValue) {
|
TEST_F(JsonObject_Container_Tests, ContainsKeyReturnFalseForUndefinedValue) {
|
||||||
object.add("hello");
|
_object.add("hello");
|
||||||
EXPECT_FALSE(object.containsKey("hello"));
|
EXPECT_FALSE(_object.containsKey("hello"));
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -10,39 +10,39 @@
|
|||||||
|
|
||||||
class JsonObject_Iterator_Test : public testing::Test {
|
class JsonObject_Iterator_Test : public testing::Test {
|
||||||
public:
|
public:
|
||||||
JsonObject_Iterator_Test() : object(_buffer.createObject()) {
|
JsonObject_Iterator_Test() : _object(_buffer.createObject()) {
|
||||||
object["ab"] = 12;
|
_object["ab"] = 12;
|
||||||
object["cd"] = 34;
|
_object["cd"] = 34;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StaticJsonBuffer<256> _buffer;
|
StaticJsonBuffer<JSON_OBJECT_SIZE(2)> _buffer;
|
||||||
JsonObject& object;
|
JsonObject& _object;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonObject_Iterator_Test, NonConstIterator) {
|
TEST_F(JsonObject_Iterator_Test, NonConstIterator) {
|
||||||
JsonObject::iterator it = object.begin();
|
JsonObject::iterator it = _object.begin();
|
||||||
ASSERT_NE(object.end(), it);
|
ASSERT_NE(_object.end(), it);
|
||||||
EXPECT_STREQ("ab", it->key);
|
EXPECT_STREQ("ab", it->key);
|
||||||
EXPECT_EQ(12, it->value);
|
EXPECT_EQ(12, it->value);
|
||||||
it->key = "a.b";
|
it->key = "a.b";
|
||||||
it->value = 1.2;
|
it->value = 1.2;
|
||||||
++it;
|
++it;
|
||||||
ASSERT_NE(object.end(), it);
|
ASSERT_NE(_object.end(), it);
|
||||||
EXPECT_STREQ("cd", it->key);
|
EXPECT_STREQ("cd", it->key);
|
||||||
EXPECT_EQ(34, it->value);
|
EXPECT_EQ(34, it->value);
|
||||||
it->key = "c.d";
|
it->key = "c.d";
|
||||||
it->value = 3.4;
|
it->value = 3.4;
|
||||||
++it;
|
++it;
|
||||||
ASSERT_EQ(object.end(), it);
|
ASSERT_EQ(_object.end(), it);
|
||||||
|
|
||||||
ASSERT_EQ(2, object.size());
|
ASSERT_EQ(2, _object.size());
|
||||||
EXPECT_EQ(1.2, object["a.b"]);
|
EXPECT_EQ(1.2, _object["a.b"]);
|
||||||
EXPECT_EQ(3.4, object["c.d"]);
|
EXPECT_EQ(3.4, _object["c.d"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_Iterator_Test, ConstIterator) {
|
TEST_F(JsonObject_Iterator_Test, ConstIterator) {
|
||||||
const JsonObject& const_object = object;
|
const JsonObject& const_object = _object;
|
||||||
JsonObject::const_iterator it = const_object.begin();
|
JsonObject::const_iterator it = const_object.begin();
|
||||||
|
|
||||||
ASSERT_NE(const_object.end(), it);
|
ASSERT_NE(const_object.end(), it);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,26 +9,28 @@
|
|||||||
|
|
||||||
class JsonObject_PrettyPrintTo_Tests : public testing::Test {
|
class JsonObject_PrettyPrintTo_Tests : public testing::Test {
|
||||||
public:
|
public:
|
||||||
JsonObject_PrettyPrintTo_Tests() : object(json.createObject()) {}
|
JsonObject_PrettyPrintTo_Tests() : _object(_jsonBuffer.createObject()) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StaticJsonBuffer<300> json;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonObject &object;
|
JsonObject &_object;
|
||||||
|
|
||||||
void outputMustBe(const char *expected) {
|
void outputMustBe(const char *expected) {
|
||||||
size_t n = object.prettyPrintTo(buffer, sizeof(buffer));
|
|
||||||
EXPECT_STREQ(expected, buffer);
|
|
||||||
EXPECT_EQ(strlen(expected), n);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
|
||||||
|
size_t actualLen = _object.prettyPrintTo(buffer, sizeof(buffer));
|
||||||
|
size_t measuredLen = _object.measurePrettyLength();
|
||||||
|
|
||||||
|
EXPECT_STREQ(expected, buffer);
|
||||||
|
EXPECT_EQ(strlen(expected), actualLen);
|
||||||
|
EXPECT_EQ(strlen(expected), measuredLen);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyObject) { outputMustBe("{}"); }
|
TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyObject) { outputMustBe("{}"); }
|
||||||
|
|
||||||
TEST_F(JsonObject_PrettyPrintTo_Tests, OneMember) {
|
TEST_F(JsonObject_PrettyPrintTo_Tests, OneMember) {
|
||||||
object["key"] = "value";
|
_object["key"] = "value";
|
||||||
|
|
||||||
outputMustBe(
|
outputMustBe(
|
||||||
"{\r\n"
|
"{\r\n"
|
||||||
@ -37,8 +39,8 @@ TEST_F(JsonObject_PrettyPrintTo_Tests, OneMember) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_PrettyPrintTo_Tests, TwoMembers) {
|
TEST_F(JsonObject_PrettyPrintTo_Tests, TwoMembers) {
|
||||||
object["key1"] = "value1";
|
_object["key1"] = "value1";
|
||||||
object["key2"] = "value2";
|
_object["key2"] = "value2";
|
||||||
|
|
||||||
outputMustBe(
|
outputMustBe(
|
||||||
"{\r\n"
|
"{\r\n"
|
||||||
@ -48,8 +50,8 @@ TEST_F(JsonObject_PrettyPrintTo_Tests, TwoMembers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyNestedContainers) {
|
TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyNestedContainers) {
|
||||||
object.createNestedObject("key1");
|
_object.createNestedObject("key1");
|
||||||
object.createNestedArray("key2");
|
_object.createNestedArray("key2");
|
||||||
|
|
||||||
outputMustBe(
|
outputMustBe(
|
||||||
"{\r\n"
|
"{\r\n"
|
||||||
@ -59,10 +61,10 @@ TEST_F(JsonObject_PrettyPrintTo_Tests, EmptyNestedContainers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonObject_PrettyPrintTo_Tests, NestedContainers) {
|
TEST_F(JsonObject_PrettyPrintTo_Tests, NestedContainers) {
|
||||||
JsonObject &nested1 = object.createNestedObject("key1");
|
JsonObject &nested1 = _object.createNestedObject("key1");
|
||||||
nested1["a"] = 1;
|
nested1["a"] = 1;
|
||||||
|
|
||||||
JsonArray &nested2 = object.createNestedArray("key2");
|
JsonArray &nested2 = _object.createNestedArray("key2");
|
||||||
nested2.add(2);
|
nested2.add(2);
|
||||||
|
|
||||||
outputMustBe(
|
outputMustBe(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -16,10 +16,12 @@ class JsonObject_PrintTo_Tests : public testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
void outputMustBe(const char *expected) {
|
void outputMustBe(const char *expected) {
|
||||||
char actual[256];
|
char actual[256];
|
||||||
int result = object.printTo(actual, sizeof(actual));
|
size_t actualLen = object.printTo(actual, sizeof(actual));
|
||||||
|
size_t measuredLen = object.measureLength();
|
||||||
|
|
||||||
EXPECT_STREQ(expected, actual);
|
EXPECT_STREQ(expected, actual);
|
||||||
EXPECT_EQ(strlen(expected), result);
|
EXPECT_EQ(strlen(expected), actualLen);
|
||||||
|
EXPECT_EQ(strlen(expected), measuredLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticJsonBuffer<JSON_OBJECT_SIZE(2)> json;
|
StaticJsonBuffer<JSON_OBJECT_SIZE(2)> json;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -42,7 +42,7 @@ class JsonParser_Array_Tests : public testing::Test {
|
|||||||
EXPECT_STREQ(expected, _array->at(index).as<const char *>());
|
EXPECT_STREQ(expected, _array->at(index).as<const char *>());
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticJsonBuffer<256> _jsonBuffer;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonArray *_array;
|
JsonArray *_array;
|
||||||
char _jsonString[256];
|
char _jsonString[256];
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
TEST(JsonParser_Nested_Tests, ArrayNestedInObject) {
|
TEST(JsonParser_Nested_Tests, ArrayNestedInObject) {
|
||||||
StaticJsonBuffer<256> jsonBuffer;
|
DynamicJsonBuffer jsonBuffer;
|
||||||
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
|
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
|
||||||
|
|
||||||
JsonObject &object = jsonBuffer.parseObject(jsonString);
|
JsonObject &object = jsonBuffer.parseObject(jsonString);
|
||||||
@ -31,7 +31,7 @@ TEST(JsonParser_Nested_Tests, ArrayNestedInObject) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(JsonParser_Nested_Tests, ObjectNestedInArray) {
|
TEST(JsonParser_Nested_Tests, ObjectNestedInArray) {
|
||||||
StaticJsonBuffer<256> jsonBuffer;
|
DynamicJsonBuffer jsonBuffer;
|
||||||
char jsonString[] =
|
char jsonString[] =
|
||||||
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
|
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -31,14 +31,14 @@ class JsonParser_NestingLimit_Tests : public testing::Test {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool tryParseArray(const char *json) {
|
bool tryParseArray(const char *json) {
|
||||||
StaticJsonBuffer<256> buffer;
|
DynamicJsonBuffer buffer;
|
||||||
char s[256];
|
char s[256];
|
||||||
strcpy(s, json);
|
strcpy(s, json);
|
||||||
return buffer.parseArray(s, _nestingLimit).success();
|
return buffer.parseArray(s, _nestingLimit).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tryParseObject(const char *json) {
|
bool tryParseObject(const char *json) {
|
||||||
StaticJsonBuffer<256> buffer;
|
DynamicJsonBuffer buffer;
|
||||||
char s[256];
|
char s[256];
|
||||||
strcpy(s, json);
|
strcpy(s, json);
|
||||||
return buffer.parseObject(s, _nestingLimit).success();
|
return buffer.parseObject(s, _nestingLimit).success();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -30,7 +30,7 @@ class JsonParser_Object_Test : public testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StaticJsonBuffer<256> _jsonBuffer;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonObject *_object;
|
JsonObject *_object;
|
||||||
char _jsonString[256];
|
char _jsonString[256];
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,59 +9,59 @@
|
|||||||
|
|
||||||
class JsonVariant_Copy_Tests : public ::testing::Test {
|
class JsonVariant_Copy_Tests : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
StaticJsonBuffer<200> json;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonVariant variant1;
|
JsonVariant _variant1;
|
||||||
JsonVariant variant2;
|
JsonVariant _variant2;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonVariant_Copy_Tests, IntegersAreCopiedByValue) {
|
TEST_F(JsonVariant_Copy_Tests, IntegersAreCopiedByValue) {
|
||||||
variant1 = 123;
|
_variant1 = 123;
|
||||||
variant2 = variant1;
|
_variant2 = _variant1;
|
||||||
variant1 = 456;
|
_variant1 = 456;
|
||||||
|
|
||||||
EXPECT_EQ(123, variant2.as<int>());
|
EXPECT_EQ(123, _variant2.as<int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Copy_Tests, DoublesAreCopiedByValue) {
|
TEST_F(JsonVariant_Copy_Tests, DoublesAreCopiedByValue) {
|
||||||
variant1 = 123.45;
|
_variant1 = 123.45;
|
||||||
variant2 = variant1;
|
_variant2 = _variant1;
|
||||||
variant1 = 456.78;
|
_variant1 = 456.78;
|
||||||
|
|
||||||
EXPECT_EQ(123.45, variant2.as<double>());
|
EXPECT_EQ(123.45, _variant2.as<double>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Copy_Tests, BooleansAreCopiedByValue) {
|
TEST_F(JsonVariant_Copy_Tests, BooleansAreCopiedByValue) {
|
||||||
variant1 = true;
|
_variant1 = true;
|
||||||
variant2 = variant1;
|
_variant2 = _variant1;
|
||||||
variant1 = false;
|
_variant1 = false;
|
||||||
|
|
||||||
EXPECT_TRUE(variant2.as<bool>());
|
EXPECT_TRUE(_variant2.as<bool>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Copy_Tests, StringsAreCopiedByValue) {
|
TEST_F(JsonVariant_Copy_Tests, StringsAreCopiedByValue) {
|
||||||
variant1 = "hello";
|
_variant1 = "hello";
|
||||||
variant2 = variant1;
|
_variant2 = _variant1;
|
||||||
variant1 = "world";
|
_variant1 = "world";
|
||||||
|
|
||||||
EXPECT_STREQ("hello", variant2.as<const char *>());
|
EXPECT_STREQ("hello", _variant2.as<const char *>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Copy_Tests, ObjectsAreCopiedByReference) {
|
TEST_F(JsonVariant_Copy_Tests, ObjectsAreCopiedByReference) {
|
||||||
JsonObject &object = json.createObject();
|
JsonObject &object = _jsonBuffer.createObject();
|
||||||
|
|
||||||
variant1 = object;
|
_variant1 = object;
|
||||||
|
|
||||||
object["hello"] = "world";
|
object["hello"] = "world";
|
||||||
|
|
||||||
EXPECT_EQ(1, variant1.asObject().size());
|
EXPECT_EQ(1, _variant1.asObject().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Copy_Tests, ArraysAreCopiedByReference) {
|
TEST_F(JsonVariant_Copy_Tests, ArraysAreCopiedByReference) {
|
||||||
JsonArray &array = json.createArray();
|
JsonArray &array = _jsonBuffer.createArray();
|
||||||
|
|
||||||
variant1 = array;
|
_variant1 = array;
|
||||||
|
|
||||||
array.add("world");
|
array.add("world");
|
||||||
|
|
||||||
EXPECT_EQ(1, variant1.asArray().size());
|
EXPECT_EQ(1, _variant1.asArray().size());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -11,18 +11,18 @@ class JsonVariant_Storage_Tests : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void testValue(T expected) {
|
void testValue(T expected) {
|
||||||
actual.set(expected);
|
_actual.set(expected);
|
||||||
EXPECT_EQ(expected, actual.as<T>());
|
EXPECT_EQ(expected, _actual.as<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void testReference(T &expected) {
|
void testReference(T &expected) {
|
||||||
actual.set(expected);
|
_actual.set(expected);
|
||||||
EXPECT_EQ(expected, actual.as<T &>());
|
EXPECT_EQ(expected, _actual.as<T &>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JsonVariant actual;
|
JsonVariant _actual;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonVariant_Storage_Tests, Double) { testValue<double>(123.45); }
|
TEST_F(JsonVariant_Storage_Tests, Double) { testValue<double>(123.45); }
|
||||||
@ -41,8 +41,8 @@ TEST_F(JsonVariant_Storage_Tests, ULong) { testValue<unsigned long>(123UL); }
|
|||||||
TEST_F(JsonVariant_Storage_Tests, UShort) { testValue<unsigned short>(123); }
|
TEST_F(JsonVariant_Storage_Tests, UShort) { testValue<unsigned short>(123); }
|
||||||
|
|
||||||
TEST_F(JsonVariant_Storage_Tests, CanStoreObject) {
|
TEST_F(JsonVariant_Storage_Tests, CanStoreObject) {
|
||||||
StaticJsonBuffer<200> json;
|
DynamicJsonBuffer jsonBuffer;
|
||||||
JsonObject &object = json.createObject();
|
JsonObject &object = jsonBuffer.createObject();
|
||||||
|
|
||||||
testReference(object);
|
testReference(object);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -9,56 +9,56 @@
|
|||||||
|
|
||||||
class JsonVariant_Subscript_Tests : public ::testing::Test {
|
class JsonVariant_Subscript_Tests : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
StaticJsonBuffer<200> buffer;
|
DynamicJsonBuffer _jsonBuffer;
|
||||||
JsonVariant variant;
|
JsonVariant _variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(JsonVariant_Subscript_Tests, Array) {
|
TEST_F(JsonVariant_Subscript_Tests, Array) {
|
||||||
JsonArray &array = buffer.createArray();
|
JsonArray &array = _jsonBuffer.createArray();
|
||||||
array.add("element at index 0");
|
array.add("element at index 0");
|
||||||
array.add("element at index 1");
|
array.add("element at index 1");
|
||||||
|
|
||||||
variant = array;
|
_variant = array;
|
||||||
|
|
||||||
EXPECT_EQ(2, variant.size());
|
EXPECT_EQ(2, _variant.size());
|
||||||
EXPECT_STREQ("element at index 0", variant[0].asString());
|
EXPECT_STREQ("element at index 0", _variant[0].asString());
|
||||||
EXPECT_STREQ("element at index 1", variant[1].asString());
|
EXPECT_STREQ("element at index 1", _variant[1].asString());
|
||||||
EXPECT_FALSE(variant[-1].success());
|
EXPECT_FALSE(_variant[-1].success());
|
||||||
EXPECT_FALSE(variant[3].success());
|
EXPECT_FALSE(_variant[3].success());
|
||||||
EXPECT_FALSE(variant["0"].success());
|
EXPECT_FALSE(_variant["0"].success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Subscript_Tests, Object) {
|
TEST_F(JsonVariant_Subscript_Tests, Object) {
|
||||||
JsonObject &object = buffer.createObject();
|
JsonObject &object = _jsonBuffer.createObject();
|
||||||
object["a"] = "element at key \"a\"";
|
object["a"] = "element at key \"a\"";
|
||||||
object["b"] = "element at key \"b\"";
|
object["b"] = "element at key \"b\"";
|
||||||
|
|
||||||
variant = object;
|
_variant = object;
|
||||||
|
|
||||||
EXPECT_EQ(2, variant.size());
|
EXPECT_EQ(2, _variant.size());
|
||||||
EXPECT_STREQ("element at key \"a\"", variant["a"].asString());
|
EXPECT_STREQ("element at key \"a\"", _variant["a"].asString());
|
||||||
EXPECT_STREQ("element at key \"b\"", variant["b"].asString());
|
EXPECT_STREQ("element at key \"b\"", _variant["b"].asString());
|
||||||
EXPECT_FALSE(variant["c"].success());
|
EXPECT_FALSE(_variant["c"].success());
|
||||||
EXPECT_FALSE(variant[0].success());
|
EXPECT_FALSE(_variant[0].success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Subscript_Tests, Undefined) {
|
TEST_F(JsonVariant_Subscript_Tests, Undefined) {
|
||||||
variant = JsonVariant();
|
_variant = JsonVariant();
|
||||||
EXPECT_EQ(0, variant.size());
|
EXPECT_EQ(0, _variant.size());
|
||||||
EXPECT_FALSE(variant["0"].success());
|
EXPECT_FALSE(_variant["0"].success());
|
||||||
EXPECT_FALSE(variant[0].success());
|
EXPECT_FALSE(_variant[0].success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Subscript_Tests, Invalid) {
|
TEST_F(JsonVariant_Subscript_Tests, Invalid) {
|
||||||
variant = JsonVariant::invalid();
|
_variant = JsonVariant::invalid();
|
||||||
EXPECT_EQ(0, variant.size());
|
EXPECT_EQ(0, _variant.size());
|
||||||
EXPECT_FALSE(variant["0"].success());
|
EXPECT_FALSE(_variant["0"].success());
|
||||||
EXPECT_FALSE(variant[0].success());
|
EXPECT_FALSE(_variant[0].success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Subscript_Tests, String) {
|
TEST_F(JsonVariant_Subscript_Tests, String) {
|
||||||
variant = "hello world";
|
_variant = "hello world";
|
||||||
EXPECT_EQ(0, variant.size());
|
EXPECT_EQ(0, _variant.size());
|
||||||
EXPECT_FALSE(variant["0"].success());
|
EXPECT_FALSE(_variant["0"].success());
|
||||||
EXPECT_FALSE(variant[0].success());
|
EXPECT_FALSE(_variant[0].success());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -62,11 +62,13 @@ TEST_F(JsonVariant_Undefined_Tests, CanBeSetToBool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Undefined_Tests, CanBeSetToArray) {
|
TEST_F(JsonVariant_Undefined_Tests, CanBeSetToArray) {
|
||||||
variant = JsonArray::invalid();
|
DynamicJsonBuffer jsonBuffer;
|
||||||
|
variant = jsonBuffer.createArray();
|
||||||
EXPECT_TRUE(variant.success());
|
EXPECT_TRUE(variant.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(JsonVariant_Undefined_Tests, CanBeSetToObject) {
|
TEST_F(JsonVariant_Undefined_Tests, CanBeSetToObject) {
|
||||||
variant = JsonObject::invalid();
|
DynamicJsonBuffer jsonBuffer;
|
||||||
|
variant = jsonBuffer.createObject();
|
||||||
EXPECT_TRUE(variant.success());
|
EXPECT_TRUE(variant.success());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -16,6 +16,11 @@ class QuotedString_ExtractFrom_Tests : public testing::Test {
|
|||||||
_result = QuotedString::extractFrom(_jsonString, &_trailing);
|
_result = QuotedString::extractFrom(_jsonString, &_trailing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void whenInputIs(const char *json, size_t len) {
|
||||||
|
memcpy(_jsonString, json, len);
|
||||||
|
_result = QuotedString::extractFrom(_jsonString, &_trailing);
|
||||||
|
}
|
||||||
|
|
||||||
void resultMustBe(const char *expected) { EXPECT_STREQ(expected, _result); }
|
void resultMustBe(const char *expected) { EXPECT_STREQ(expected, _result); }
|
||||||
|
|
||||||
void trailingMustBe(const char *expected) {
|
void trailingMustBe(const char *expected) {
|
||||||
@ -41,6 +46,12 @@ TEST_F(QuotedString_ExtractFrom_Tests, NoQuotes) {
|
|||||||
resultMustBe(0);
|
resultMustBe(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(QuotedString_ExtractFrom_Tests, MissingClosingQuote) {
|
||||||
|
whenInputIs("\"hello world");
|
||||||
|
|
||||||
|
resultMustBe(0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(QuotedString_ExtractFrom_Tests, EmptySingleQuotedString) {
|
TEST_F(QuotedString_ExtractFrom_Tests, EmptySingleQuotedString) {
|
||||||
whenInputIs("''");
|
whenInputIs("''");
|
||||||
|
|
||||||
@ -128,3 +139,8 @@ TEST_F(QuotedString_ExtractFrom_Tests, AllEscapedCharsTogether) {
|
|||||||
whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
|
whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
|
||||||
resultMustBe("1\"2\\3/4\b5\f6\n7\r8\t9");
|
resultMustBe("1\"2\\3/4\b5\f6\n7\r8\t9");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(QuotedString_ExtractFrom_Tests, UnterminatedEscapeSequence) {
|
||||||
|
whenInputIs("\"\\\0\"", 4);
|
||||||
|
resultMustBe(0);
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -7,7 +7,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Array_Tests, GrowsWithArray) {
|
TEST(StaticJsonBuffer_CreateArray_Tests, GrowsWithArray) {
|
||||||
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> json;
|
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> json;
|
||||||
|
|
||||||
JsonArray &array = json.createArray();
|
JsonArray &array = json.createArray();
|
||||||
@ -20,21 +20,21 @@ TEST(StaticJsonBuffer_Array_Tests, GrowsWithArray) {
|
|||||||
ASSERT_EQ(JSON_ARRAY_SIZE(2), json.size());
|
ASSERT_EQ(JSON_ARRAY_SIZE(2), json.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Array_Tests, SucceedWhenBigEnough) {
|
TEST(StaticJsonBuffer_CreateArray_Tests, SucceedWhenBigEnough) {
|
||||||
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> json;
|
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> json;
|
||||||
|
|
||||||
JsonArray &array = json.createArray();
|
JsonArray &array = json.createArray();
|
||||||
ASSERT_TRUE(array.success());
|
ASSERT_TRUE(array.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Array_Tests, FailsWhenTooSmall) {
|
TEST(StaticJsonBuffer_CreateArray_Tests, FailsWhenTooSmall) {
|
||||||
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> json;
|
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> json;
|
||||||
|
|
||||||
JsonArray &array = json.createArray();
|
JsonArray &array = json.createArray();
|
||||||
ASSERT_FALSE(array.success());
|
ASSERT_FALSE(array.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Array_Tests, ArrayDoesntGrowWhenFull) {
|
TEST(StaticJsonBuffer_CreateArray_Tests, ArrayDoesntGrowWhenFull) {
|
||||||
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> json;
|
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> json;
|
||||||
|
|
||||||
JsonArray &array = json.createArray();
|
JsonArray &array = json.createArray();
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright Benoit Blanchon 2014
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
// MIT License
|
// MIT License
|
||||||
//
|
//
|
||||||
// Arduino JSON library
|
// Arduino JSON library
|
||||||
@ -7,7 +7,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Object_Tests, GrowsWithObject) {
|
TEST(StaticJsonBuffer_CreateObject_Tests, GrowsWithObject) {
|
||||||
StaticJsonBuffer<JSON_OBJECT_SIZE(3)> json;
|
StaticJsonBuffer<JSON_OBJECT_SIZE(3)> json;
|
||||||
|
|
||||||
JsonObject &obj = json.createObject();
|
JsonObject &obj = json.createObject();
|
||||||
@ -23,21 +23,21 @@ TEST(StaticJsonBuffer_Object_Tests, GrowsWithObject) {
|
|||||||
ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size());
|
ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Object_Tests, SucceedWhenBigEnough) {
|
TEST(StaticJsonBuffer_CreateObject_Tests, SucceedWhenBigEnough) {
|
||||||
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> json;
|
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> json;
|
||||||
|
|
||||||
JsonObject &object = json.createObject();
|
JsonObject &object = json.createObject();
|
||||||
ASSERT_TRUE(object.success());
|
ASSERT_TRUE(object.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Object_Tests, FailsWhenTooSmall) {
|
TEST(StaticJsonBuffer_CreateObject_Tests, FailsWhenTooSmall) {
|
||||||
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> json;
|
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> json;
|
||||||
|
|
||||||
JsonObject &object = json.createObject();
|
JsonObject &object = json.createObject();
|
||||||
ASSERT_FALSE(object.success());
|
ASSERT_FALSE(object.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StaticJsonBuffer_Object_Tests, ObjectDoesntGrowWhenFull) {
|
TEST(StaticJsonBuffer_CreateObject_Tests, ObjectDoesntGrowWhenFull) {
|
||||||
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> json;
|
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> json;
|
||||||
|
|
||||||
JsonObject &obj = json.createObject();
|
JsonObject &obj = json.createObject();
|
72
test/StaticJsonBuffer_ParseArray_Tests.cpp
Normal file
72
test/StaticJsonBuffer_ParseArray_Tests.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class StaticJsonBuffer_ParseArray_Tests : public testing::Test {
|
||||||
|
protected:
|
||||||
|
void with(JsonBuffer& jsonBuffer) { _jsonBuffer = &jsonBuffer; }
|
||||||
|
|
||||||
|
void whenInputIs(const char* json) { strcpy(_jsonString, json); }
|
||||||
|
|
||||||
|
void parseMustSucceed() {
|
||||||
|
EXPECT_TRUE(_jsonBuffer->parseArray(_jsonString).success());
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseMustFail() {
|
||||||
|
EXPECT_FALSE(_jsonBuffer->parseArray(_jsonString).success());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
JsonBuffer* _jsonBuffer;
|
||||||
|
char _jsonString[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseArray_Tests, TooSmallBufferForEmptyArray) {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> bufferTooSmall;
|
||||||
|
with(bufferTooSmall);
|
||||||
|
whenInputIs("[]");
|
||||||
|
parseMustFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseArray_Tests, BufferOfTheRightSizeForEmptyArray) {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> bufferOfRightSize;
|
||||||
|
with(bufferOfRightSize);
|
||||||
|
whenInputIs("[]");
|
||||||
|
parseMustSucceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseArray_Tests, TooSmallBufferForArrayWithOneValue) {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(1) - 1> bufferTooSmall;
|
||||||
|
with(bufferTooSmall);
|
||||||
|
whenInputIs("[1]");
|
||||||
|
parseMustFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseArray_Tests,
|
||||||
|
BufferOfTheRightSizeForArrayWithOneValue) {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> bufferOfRightSize;
|
||||||
|
with(bufferOfRightSize);
|
||||||
|
whenInputIs("[1]");
|
||||||
|
parseMustSucceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseArray_Tests,
|
||||||
|
TooSmallBufferForArrayWithNestedObject) {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1> bufferTooSmall;
|
||||||
|
with(bufferTooSmall);
|
||||||
|
whenInputIs("[{}]");
|
||||||
|
parseMustFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseArray_Tests,
|
||||||
|
BufferOfTheRightSizeForArrayWithNestedObject) {
|
||||||
|
StaticJsonBuffer<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> bufferOfRightSize;
|
||||||
|
with(bufferOfRightSize);
|
||||||
|
whenInputIs("[{}]");
|
||||||
|
parseMustSucceed();
|
||||||
|
}
|
73
test/StaticJsonBuffer_ParseObject_Tests.cpp
Normal file
73
test/StaticJsonBuffer_ParseObject_Tests.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014-2015
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
class StaticJsonBuffer_ParseObject_Tests : public testing::Test {
|
||||||
|
protected:
|
||||||
|
void with(JsonBuffer& jsonBuffer) { _jsonBuffer = &jsonBuffer; }
|
||||||
|
|
||||||
|
void whenInputIs(const char* json) { strcpy(_jsonString, json); }
|
||||||
|
|
||||||
|
void parseMustSucceed() {
|
||||||
|
EXPECT_TRUE(_jsonBuffer->parseObject(_jsonString).success());
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseMustFail() {
|
||||||
|
EXPECT_FALSE(_jsonBuffer->parseObject(_jsonString).success());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
JsonBuffer* _jsonBuffer;
|
||||||
|
char _jsonString[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseObject_Tests, TooSmallBufferForEmptyObject) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> bufferTooSmall;
|
||||||
|
with(bufferTooSmall);
|
||||||
|
whenInputIs("{}");
|
||||||
|
parseMustFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseObject_Tests, BufferOfTheRightSizeForEmptyObject) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> bufferOfRightSize;
|
||||||
|
with(bufferOfRightSize);
|
||||||
|
whenInputIs("{}");
|
||||||
|
parseMustSucceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseObject_Tests,
|
||||||
|
TooSmallBufferForObjectWithOneValue) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(1) - 1> bufferTooSmall;
|
||||||
|
with(bufferTooSmall);
|
||||||
|
whenInputIs("{\"a\":1}");
|
||||||
|
parseMustFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseObject_Tests,
|
||||||
|
BufferOfTheRightSizeForObjectWithOneValue) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> bufferOfRightSize;
|
||||||
|
with(bufferOfRightSize);
|
||||||
|
whenInputIs("{\"a\":1}");
|
||||||
|
parseMustSucceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseObject_Tests,
|
||||||
|
TooSmallBufferForObjectWithNestedObject) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1> bufferTooSmall;
|
||||||
|
with(bufferTooSmall);
|
||||||
|
whenInputIs("{\"a\":[]}");
|
||||||
|
parseMustFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StaticJsonBuffer_ParseObject_Tests,
|
||||||
|
BufferOfTheRightSizeForObjectWithNestedObject) {
|
||||||
|
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> bufferOfRightSize;
|
||||||
|
with(bufferOfRightSize);
|
||||||
|
whenInputIs("{\"a\":[]}");
|
||||||
|
parseMustSucceed();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user