Minor corrections to the doc

This commit is contained in:
Benoit Blanchon
2014-11-29 09:30:11 +01:00
parent 33654a480b
commit a61fc5b836
5 changed files with 47 additions and 41 deletions

View File

@ -1,7 +1,7 @@
Avoiding common pitfalls in Arduino JSON Avoiding common pitfalls in Arduino JSON
======================================== ========================================
As `StaticJsonBuffer` is the corner stone of this library, you'll see that every pitfall listed here is related to a wrong understanding of the memory model. 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. Make sure you read [Arduino JSON memory model](Memory model.md) before going further.
@ -14,7 +14,7 @@ There are basically two reasons why they may fail:
1. the JSON string is invalid, 1. the JSON string is invalid,
2. the JSON string contains more values that the buffer can store. 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 slightly increase the number of token of the parser. 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 ## 2. Make sure everything fits in memory
@ -25,8 +25,8 @@ To diagnose this, look at every big objects in you code and sum their size to ch
For example, don't do this: For example, don't do this:
char json[1024]; // 1 KB char json[1024]; // 1 KB
JsonParser<512> parser; // 514 B 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. 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.
@ -34,9 +34,9 @@ That is why an 8-bit processor is not able to parse long and complex JSON string
## 3. Keep the `StaticJsonBuffer` in memory long enough ## 3. Keep the `StaticJsonBuffer` in memory long enough
Remember that the function of `StaticJsonBuffer` return references. Remember that `StaticJsonBuffer`'s function return references.
References don't store data, they are just pointer to the actual. References don't contain data, they are just pointer to the actual.
This will only work if the data actual is still in memory. So they can only work if the actual data is in memory.
For example, don't do this: For example, don't do this:
@ -48,12 +48,13 @@ For example, don't do this:
because the local variable `buffer` will be *removed* from memory when the function `parseArray()` returns, and the `JsonArray&` will point to an invalid location. 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 make `StaticJsonBuffer` global ## 4. Don't reuse the same `StaticJsonBuffer`
If you read the previous point, you may come to the idea of using a global variable for your `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.
This is probably a bad idea because `StaticJsonBuffer` can be quite big (depending on your requirement) and would be eating a lot of memory, even when you don't use it.
There are some cases were a `StaticJsonBuffer` can be a global variable, but must of the time you should declare it in a local scope, in a function which unique role is to handle the JSON serialization. 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 ## 5. Keep the JSON string in memory long enough
@ -69,21 +70,21 @@ For instance, let's imagine that you parse `["hello","world"]`, like this:
const char* first = array[0]; const char* first = array[0];
const char* second = array[1]; const char* second = array[1];
In that case, both `first` and `second` are pointer to the content of the original string `json`. 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. So this will only work if `json` is still in memory.
## 6. JSON string is altered ## 6. JSON string is altered
If you read carefully the previous pitfall, you may I come to the conclusion that the JSON parser modifies the JSON string. 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: Indeed, the parser modifies the string for two reasons:
1. it inserts `\0` to terminate substrings, 1. it inserts `\0` to terminate substrings,
2. it translate escaped characters like `\n` or `\t`. 2. it translate escaped characters like `\n` or `\t`.
Most of the time this wont be an issue, but it there are some corner case that can be problematic. Most of the time this wont be an issue, but there are some corner cases that can be problematic.
Let take the example above: Let take the example bellow:
char[] json = "[\"hello\",\"world\"]"; char[] json = "[\"hello\",\"world\"]";
StaticJsonBuffer<32> buffer; StaticJsonBuffer<32> buffer;
@ -97,5 +98,5 @@ If you replace it by:
Depending on your platform, you may have an exception because the parser tries to write at a location that is read-only. 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 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*`. 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*`.

View File

@ -7,7 +7,7 @@ If you want to contribute to the project, please:
2. Follow the coding conventions 2. Follow the coding conventions
3. Write tests 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) which few variations to match the Arduino conventions. 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 [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. I use [CppLint](http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) to detect non-compliant stuff.

View File

@ -1,6 +1,12 @@
Decoding JSON with Arduino JSON 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 ## Example
Here an example that parse the string `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`: Here an example that parse the string `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`:
@ -39,14 +45,14 @@ Before continuing please read the page [Arduino JSON memory model](Memory model.
## Step 2: Parse the JSON string ## Step 2: Parse the JSON string
You call the JSON parser through the instance of `StaticJsonBuffer`. You invoke the JSON parser through the instance of `StaticJsonBuffer`.
It exposes two function for parsing JSON: It exposes two functions for parsing JSON:
1. parseArray() that returns a reference to a `JsonArray` 1. `parseArray()` that returns a reference to a `JsonArray`
2. parseObject() that returns a reference to a `JsonObject` 2. `parseObject()` that returns a reference to a `JsonObject`
Let's see an example. 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: 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]}"; char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

View File

@ -5,7 +5,7 @@ Before writing any code, don't forget to include the header:
#include <ArduinoJson.h> #include <ArduinoJson.h>
If your not using the Arduino IDE, please read [Using the library without Arduino](Using the library without Arduino.md). 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 ## Example
@ -58,14 +58,13 @@ Then you can add strings, integer, booleans, etc:
There are two syntaxes for floating point values: There are two syntaxes for floating point values:
array.add<4>(3.1415); // 4 digits: "3.1415" array.add(3.1415, 4); // 4 digits: "3.1415"
array.add(3.1415); // 2 digits: "3.14" array.add(3.1415); // 2 digits: "3.14"
> ##### About floating point precision > ##### 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. > 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 two. > 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`. > 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.
> So you may already be familiar with it.
You can add a nested array or object if you have a reference to it. 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: Or simpler, you can create nested array or nested objects from the array:
@ -75,7 +74,7 @@ Or simpler, you can create nested array or nested objects from the array:
#### Objects #### Objects
You create an array like this: You create an object like this:
JsonObject& object = jsonBuffer.createObject(); JsonObject& object = jsonBuffer.createObject();
@ -89,7 +88,7 @@ Then you can add strings, integer, booleans, etc:
As for the arrays, there are two syntaxes for the floating point values: As for the arrays, there are two syntaxes for the floating point values:
object["key4"].set<4>(3.1415); // 4 digits "3.1415" object["key4"].set(3.1415, 4); // 4 digits "3.1415"
object["key5"] = 3.1415; // default: 2 digits "3.14" object["key5"] = 3.1415; // default: 2 digits "3.14"
You can add a nested array or object if you have a reference to it. You can add a nested array or object if you have a reference to it.
@ -137,5 +136,5 @@ And, of course if you need an indented JSON string:
> ##### About the Print interface > ##### 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. > 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 implementation that would work as well, including: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`... > 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. > 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.