ArduinoJson icon indicating copy to clipboard operation
ArduinoJson copied to clipboard

Lazy encoding of binary data

Open jputcu opened this issue 2 years ago • 4 comments

Use case: To debug a large binary communication buffer I would like to send it as a hex encoded json string without needing to create a encoded copy first, which is twice as big.

For example:

uint8_t received_data[] = {0xff,0xff,0ff};
// 1 byte becomes 2 characters
struct IterObj {
  IterObj(const uint8_t* d, size_t data_size);
  size_t size() -> would give data_size * 2
  
  // Iterator interface
  uint8_t const* operator++();
  char operator*(); // return nibble, depending on even/odd position

  // or using an index
  char operator[](size_t i); // return nibble, depending on even/odd position
};
json["bytes"] = IterObj{received_data, sizeof(received_data)};
// gives: "bytes"="FFFFFF"

jputcu avatar Feb 14 '22 14:02 jputcu

Hi @jputcu,

Unfortunately, there is no easy way to implement this feature. Moreover, ArduinoJson 6 contains no virtual functions, and I want to keep it that way so it stays as small as possible.

I see the benefit of such a feature, but honestly, I don't think I will implement it any time soon.

As a workaround, I recommend that you send a string instead, like so:

json["bytes"] = JsonString{received_data, sizeof(received_data)};

Best regards, Benoit

bblanchon avatar Feb 16 '22 08:02 bblanchon

Hello

I also try to avoid virtual methods on my AVR, but was more thinking in template programming. Though, sometimes virtual methods can provide a nice solution. The issue I have with the string view is dat my data is binary, so I can't send it that way.

jputcu avatar Feb 16 '22 09:02 jputcu

Perhaps being able to register simple callbacks to normal functions:

size_t my_object_size(); // size_t (*)();
char my_object_char(size_t pos); // char (*)(size_t)

This would not require any virtual methods nor complex template programming.

jputcu avatar Feb 17 '22 07:02 jputcu

Hi @jputcu,

The issue I have with the string view is dat my data is binary, so I can't send it that way.

A string view can contain binary data. What matters is how you interpret this data. Please give this a try.

Perhaps being able to register simple callbacks to normal functions

ArduinoJson already supports custom converters that lets you insert custom types in a JsonDocument, but they require you to convert to one of the built-in types.

At first sight, it may look like a simple template programming trick would provide a solution, but if you think it through, you'll realize that a virtual table is required at some point. Look at the implementation of std::function if you're not convinced.

Again, I don't think this feature is a bad idea; I'm just saying that the library cannot implement it at this point because it contradicts the current design constraints.

Best regards, Benoit

bblanchon avatar Feb 17 '22 08:02 bblanchon