Json: Reuse memory in to_cbor and to_msgpack functions

Created on 27 Feb 2017  路  13Comments  路  Source: nlohmann/json

It would be good to add the implementation of functions for memory reuse purposes:

static void to_cbor(const basic_json& j, std::vector<uint8_t> &result)
{
    result.clear();
    to_cbor_internal(j, result);
}

static void to_msgpack(const basic_json& j, std::vector<uint8_t> &result)
{
    result.clear();
    to_msgpack_internal(j, result);
}
binary formats enhancemenimprovement proposed fix

All 13 comments

I think if such functions are added, the should not clear the vector - it should be the user's responsibility.

Yes, perhaps it would be better.

Since we already are at C++11, a return value would be clearer. Move semantics already takes care of passing return values without additional memory handling, also it can be directly used in other functions.

The void return value also forces the break of a call chain like
httprequest::send( json::to_cbor( request ) );
which I prefer.

It is not about copying on assignment. As an example of using such functions - some service exchange messages cbor or msgpack format and using a buffer to receive and transmit them. I do not mind to call these functions like - otherwise, but would like to have them available.

I think if such functions are added, the should not clear the vector - it should be the user's responsibility.

This is not a universally accepted convention, however. It more depends on the context - what would make most sense. For example, std::getline clears out the string passed to it rather than simply appending.

Usually, to make it unambiguous that the function will not clear out a container, but will rather append to it, the convention is to pass back_insert_iterator rather than the object itself.

You could also put _append on the function name.

I'm just wondering whether it would make sense to provide a reference to a vector when we do not know the size and hence cannot control whether the vector would use other memory anyways.

This is useful if we use the same vector multiple times. When the "clear" method is executed, the vector does not free up memory and can reuse it.

Alright, so I would propose a function like

template<typename CharT, typename std::enable_if<
             std::is_integral<CharT>::value and
             sizeof(CharT) == 1, int>::type = 0>
static void to_cbor(const basic_json& j, std::vector<CharT>& vec)

which writes to the vector vec, but does not take care of clearing it before.

As #477 would also introduce a function like

static void to_cbor(const basic_json &j, std::ostream &o)

I would propose to deprecate the

static std::vector<uint8_t> to_cbor(const basic_json& j)

function to unify the function signatures.

What's your opinion on this?

Looks good. I like.

Opened #623 as place to discuss the structure of the parsing functions.

Function

static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
{
    binary_writer(o).write_cbor(j);
}

now allows to write CBOR (and similarly, MessagePack) to the following types from which an output_adapter<uint8_t> can be constructed:

  • std::vector< uint8_t >&
  • std::basic_ostream< uint8_t >&
  • std::basic_string< uint8_t >&

Note the function does not clear passed vectors.

Done.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jmlemetayer picture jmlemetayer  路  3Comments

mlund picture mlund  路  4Comments

zkelo picture zkelo  路  3Comments

afowles picture afowles  路  3Comments

Fonger picture Fonger  路  4Comments