0

I would like convert my created json object to array of uint8_t[1000]. I tried something like this:

    nlohmann::json j_file;
    j_file["number"] = 2;
    j_file["example"] = "dog";

    uint8_t parsed_json[1000] ={0};
    auto str = j_file.dump();
    std::vector<std::uint8_t> v (str.begin(), str.end());
    std::copy(v.begin(), v.end(), parsed_json);

but is there an easier way to convert json to uint8_t array?

Creatorek
  • 9
  • 3
  • A `std::string` is pretty similar to `std::vector` and can be used in most container algorithms as drop in replacement. Do you really need that conversion? – Timo May 06 '21 at 12:15
  • 2
    Your code is vulnerable to buffer overflow. – rustyx May 06 '21 at 12:17
  • What's the purpose of `parsed_json[1000]`? Why not keep it in a `std::string` to not loose the `size()`? `const auto& tmp = j_file.dump(); std::basic_string str(tmp.data(), std::next(tmp.data(), tmp.size()));` and then you can use `str.data()` to get your `uint8_t*` + you have `str.size()` too. – Ted Lyngmo May 06 '21 at 12:35

2 Answers2

1

Potential XY-problem: Perhaps you don't need to convert to an array at all. You can reinterpret a pointer to the string without copying anything:

static_assert(std::is_same_v<unsigned char, std::uint8_t>);
std::uint8_t* parsed_json = reinterpret_cast<std::uint8_t*>(str.data());

Avoiding copying is both more efficient, and will also fix the buffer overflow bug in case the JSON is long.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • this will work in most implementations but is technically undefined behavior as I understand it. Nvm, looks like I am wrong: https://stackoverflow.com/questions/16260033/reinterpret-cast-between-char-and-stduint8-t-safe – PeterT May 06 '21 at 12:19
  • @PeterT The cast itself is never UB. Techically accessing through the pointer could be UB in theory **if** `std::uint8_t` wasn't an alias of `unsigned char`. But it always is when it is defined at all (in all C++ implementations that I've seen). I've added modification to make sure there is no UB in the example even in such theoretical case. – eerorika May 06 '21 at 12:24
0

You can copy contents of std::string to the array without using std::vector as proxy.

    uint8_t parsed_json[1000] ={0};
    auto str = j_file.dump();
    std::copy(str.begin(), str.end(), parsed_json);
MikeCAT
  • 73,922
  • 11
  • 45
  • 70