Arduinojson: Shared StaticJsonBuffer for request/response juggling

Created on 27 Oct 2015  Â·  16Comments  Â·  Source: bblanchon/ArduinoJson

Hi there,

Awesome work ! Thank you so much ! You saved me endless hours of work. May I suggest you to officially provide a method/functionality to allow for the StaticJsonBuffer to be cleared or reparsed? Since I doing a lot of MQTT command parsing on a AVR 328 memory is always low. Reusing the JSON request buffer to build the JSON response saves one of reallocating a second StaticJsonBuffer for this purpose while the request is usually not necessary anymore. Also a method to delete a element (in cascade too) would be of great help. Thank you again!

question

All 16 comments

Hi,
I added it to the FAQ
Regards

Forgive me for being naive, but if the StaticJsonBuffer was internally/privately cleared at each StaticJsonBuffer.parseObject() call one could reuse the already allocated buffer forever in its scope avoiding tedious and program byte consuming calls to create and recreate the very same stuff we already have reserved in the stack, a simple static uint_8 array. I am saying this because I could not grasp how one would use new & delete to allocate and free a StaticJsonBuffer object as per your recommendation "new StaticJsonBuffer<200>()" in FAQ. Thank you so much, Luis

JsonObject& object1 = jsonBuffer.parseObject(json1);
JsonObject& object2 = jsonBuffer.parseObject(json2);

So you think it's OK to say that object1 is no longer valid? I do not agree.

new StaticJsonBuffer<200>()

I've been misunderstood.
It' not a recommendation, it's a workaround for environments that have a limit on stack size.
This doesn't apply to ATMega 328.

JsonObject& object1 = jsonBuffer.parseObject(json1);
JsonObject& object2 = jsonBuffer.parseObject(json2);

Well, it is the practical equivalent as:

char s[] = "test";
char* request= s;
char* response = s;

Isn´t it ? Both pint to the same string, so what, no body will ever be surprised that Serial.print() of both will render the same

The clever memory design used in your JSON lib is away too tricky for beginners because the object is actually only a collection of pointers to local variables, added to the fact that you modify the incoming parsed JSON buffer with '0'´s, and these are in my opinion the main sources for wrong doings like inadvertently printTo() using previously scoped (and now invalid) char[] buffers.

I really think that allowing the user to reload a new JSON to the already allocated StaticJsonBuffer is very reasonable with far more benefits than risks. Actually this is what I decided to do doing after spending TWO days trimming fat everywhere to fit your library into the remaining few SRAM I could afford I had in my poor 328u.

Then, against your advice, I added the following line to the StaticJsonBuffer.hpp, called before each parseObject() call and everything worked as a charm, parsing a re parsing as many buffers I needed, clean & simple:

void clear() { memset(_buffer, 0, CAPACITY); _size = 0;}

Best, Luís

auto myObject = jsonBuffer.parseObject(jsonObjectString);
auto myArray = jsonBuffer.parseArray(jsonArrayString);

Do you really think that this is equivalent to the pointer example you mentioned?
I'm sorry but I don't see it.

And what about this example:

JsonObject& config = jsonBuffer.parseObject(eepromConfig);
config["sensor"] = jsonBuffer.parseObject(httpPostContent);
config.printTo(eepromConfig, sizeof(eepromConfig));

This would be broken by your suggestion too.

I added What's the best way to use the library? to the FAQ.
I hope it will help you.

Well, this is a very convoluted way of getting i trouble with pointers,as you can do with any other object at hand, nothing is bullet proof in C.

Here is the char[] equivalent of this new postulate:

char s[] = "test";
char* request= s;
char* response = s[3];

The problem (in my case) with the serialization/deserialization approach is that one must know in advance where he is getting into, I have code that send JSON inside JSON so I need to crawl out of the darkness trying to figure out what should a expect in a message, but this is a very pecuiliar application.

Thank you anyway, your lib has been of great help decoding MQTT commands received from different sources/formats and expecting different responses as well.

Thanks Benoit for this example!!

2015-10-28 12:07 GMT-03:00 Benoît Blanchon [email protected]:

I added What's the best way to use the library?
https://arduinojson.org/faq/whats-the-best-way-to-use-the-library
to the FAQ.
I hope it will help you.

—
Reply to this email directly or view it on GitHub
https://github.com/bblanchon/ArduinoJson/issues/141#issuecomment-151875307
.

El que pregunta aprende, y el que contesta aprende a responder.

No a la obsolecencia programada:
http://www.rtve.es/noticias/20110104/productos-consumo-duran-cada-vez-menos/392498.shtml

Linux User #495070
http://domonetic.com/blog

@domonetic, I should have written that a long time ago. Sorry about that.

What matters is the library.
Do not be sorry.

2015-10-28 13:30 GMT-03:00 Benoît Blanchon [email protected]:

@domonetic https://github.com/domonetic, I should have written that a
long time ago. Sorry about that.

—
Reply to this email directly or view it on GitHub
https://github.com/bblanchon/ArduinoJson/issues/141#issuecomment-151901601
.

El que pregunta aprende, y el que contesta aprende a responder.

No a la obsolecencia programada:
http://www.rtve.es/noticias/20110104/productos-consumo-duran-cada-vez-menos/392498.shtml

Linux User #495070
http://domonetic.com/blog

If I have a very big aligned memory, for example:

DMAMEM
volatile uint16_t
 __attribute__((aligned(ADC_RING_SIZE_BYTES)))
adc_ring_buffer[ADC_RING_SIZE];

how to reuse this memory with a StaticJsonBuffer?, there exist any way to make this?, this is critical in some applications were it's needed a long chunks of memory aligned to perform some audio recording with the DMA and then send these data in a json base64encode... thanks!!!

I need some like this:

StaticJsonBuffer<0> jsonBuffer;
jsonBuffer._buffer = (uint8_t*)adc_ring_buffer;
jsonBuffer.CAPACITY = ADC_RING_SIZE_BYTES;
jsonBuffer._size = ???;

or better something like this:

StaticJsonBuffer<0> jsonBuffer;
jsonBuffer.setBuffer((uint8_t*)adc_ring_buffer, ADC_RING_SIZE_BYTES);

best regards and thanks!!!

@lsaavedr You should write your own implementation of StaticJsonBuffer, it's just a few lines.

for this I need only these three function: capacity, size, alloc?
thaaaanks!!!

That's all of it.
Note that I plan to change the implementation for v6, but the migration will be simple.

thaaanks!!!

Was this page helpful?
0 / 5 - 0 ratings