bblanchon / ArduinoJson

📟 JSON library for Arduino and embedded C++. Simple and efficient.
https://arduinojson.org
MIT License
6.72k stars 1.12k forks source link

How to declare const size_t buffersize if the input data for parse function has more values #692

Closed sierraalpha83 closed 6 years ago

sierraalpha83 commented 6 years ago

Hi,

I used the assistant to determine the size of the buffer and my json data looks like if I request it for the first time and it works perfect.

{"version":"xmr-stak/2.2.0/c4400d19/master/win/nvidia-amd-cpu/aeon-monero/20","hashrate":{"threads":[[182.2,181.9,181.6],[191.1,195.9,196.7],[183.5,181.5,181.7],[224.3,198.0,196.9],[181.9,181.6,181.7],[185.9,196.3,196.9],[178.7,180.0,181.7],[195.6,196.1,196.8]],"total":[1523.3,1511.4,1514.0],"highest":1666.6},"results":{"diff_current":38430,"shares_good":748,"shares_total":829,"avg_time":28.2,"hashes_total":7326280,"best":[426485891,146952210,15009307,9783946,8356245,7093401,5225016,4166380,3814323,3418391],"error_log":[]},"connection":{"pool": "pool.electroneum.hashvault.pro:5555","uptime":5777,"ping":85,"error_log":[]}}

In my case the data will be changed if I get some errors in my application and it will look like:

{"version":"xmr-stak/2.2.0/c4400d19/master/win/nvidia-amd-cpu/aeon-monero/20","hashrate":{"threads":[[182.2,181.9,181.6],[191.1,195.9,196.7],[183.5,181.5,181.7],[224.3,198.0,196.9],[181.9,181.6,181.7],[185.9,196.3,196.9],[178.7,180.0,181.7],[195.6,196.1,196.8]],"total":[1523.3,1511.4,1514.0],"highest":1666.6},"results":{"diff_current":38430,"shares_good":748,"shares_total":829,"avg_time":28.2,"hashes_total":7326280,"best":[426485891,146952210,15009307,9783946,8356245,7093401,5225016,4166380,3814323,3418391],"error_log":[{"count":77,"last_seen":1520461772,"text":"[NETWORK ERROR]"},{"count":4,"last_seen":1520457845,"text":"Duplicate share"}]},"connection":{"pool": "pool.electroneum.hashvault.pro:5555","uptime":5777,"ping":85,"error_log":[{"last_seen":1520467519,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"},{"last_seen":1520461772,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"},{"last_seen":1520457845,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"},{"last_seen":0,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"},{"last_seen":0,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"},{"last_seen":0,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"},{"last_seen":0,"text":"[pool.electroneum.hashvault.pro:5555] CALL error: Timeout while waiting for a reply"}]}}

root.success() returns false in this case. What can I do if the data grows?

Thank you for your help.

bblanchon commented 6 years ago

Hi @sierraalpha83,

There are three solutions:

  1. Test all shapes of input in the ArduinoJson Assistant and pick the biggest.
  2. Determine a memory budget according to the available memory in the device.
  3. Let the DynamicJsonBuffer grow.

Regards, Benoit

sierraalpha83 commented 6 years ago

Hi @bblanchon ,

I'm using DynamicJsonBuffer in a function and call this in the loop:

JsonObject& JSONCLIENT::parseJsonResponse(String responseBody, size_t bufferSize ) { DynamicJsonBuffer jsonBuffer(bufferSize); char _responseBody[strlen(responseBody) + 1]; _response.body.toCharArray(_responseBody, strlen(responseBody) + 1); JsonObject& root = jsonBuffer.parseObject(_responseBody); return root; }

The Buffersize is defined before const size_t minerBufferSize = 2*JSON_ARRAY_SIZE(0) + 9*JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(8) + JSON_ARRAY_SIZE(10) + JSON_OBJECT_SIZE(3) + 2*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(7) + 590; void setup(){ }

Is the useage of the method correct? How can I let the DynamicJsonBuffer grow?

Regards

bblanchon commented 6 years ago

Hi @sierraalpha83,

There is a major problem with this function: you cannot return the JsonObject& because it point to a destructed variable.

Indeed, the returned JsonObject is stored in jsonBuffer, but this variable is destructed as soon as the function exits. Unfortunately, it's not possible to write such a function; you need to make sure that the JsonBuffer outlives the JsonObject.

BTW, if you're interested in learning more about this topic, there is a complete walk-through in the chapter "Troubleshooting / Program crashes" of Mastering ArduinoJson

Regards, Benoit

sierraalpha83 commented 6 years ago

Hi @bblanchon,

ok. thanks for your support.

Regards

bblanchon commented 6 years ago

You're welcome @sierraalpha83. Thank you for using ArduinoJson.