// |plugin| must not be null. The caller takes ownership of the result, except // when it is null (at the end of the stream). No transfer of ownership of // |*plugin|. |*serializer| must be null on the first call and must be passed // unchanged to the successive calls; its ownership is not transferred. char const* principia__SerializePlugin(Plugin const* const plugin, PullSerializer** const serializer) { journal::Method<journal::SerializePlugin> m({plugin, serializer}, {serializer}); LOG(INFO) << __FUNCTION__; CHECK_NOTNULL(plugin); CHECK_NOTNULL(serializer); // Create and start a serializer if the caller didn't provide one. if (*serializer == nullptr) { *serializer = new PullSerializer(chunk_size, number_of_chunks); auto message = make_not_null_unique<serialization::Plugin>(); plugin->WriteToMessage(message.get()); (*serializer)->Start(std::move(message)); } // Pull a chunk. Bytes bytes; bytes = (*serializer)->Pull(); // If this is the end of the serialization, delete the serializer and return a // nullptr. if (bytes.size == 0) { TakeOwnership(serializer); return m.Return(nullptr); } // Convert to hexadecimal and return to the client. std::int64_t const hexadecimal_size = (bytes.size << 1) + 1; UniqueBytes hexadecimal(hexadecimal_size); HexadecimalEncode(bytes, hexadecimal.get()); hexadecimal.data.get()[hexadecimal_size - 1] = '\0'; return m.Return(reinterpret_cast<char const*>(hexadecimal.data.release())); }
void HexEncode(not_null<benchmark::State*> const state, not_null<bool*> const correct, std::vector<uint8_t> const& input_bytes, std::vector<uint8_t> const& expected_digits) { state->PauseTiming(); std::vector<uint8_t> digits(input_bytes.size() << 1); state->ResumeTiming(); HexadecimalEncode({input_bytes.data(), input_bytes.size()}, {digits.data(), digits.size()}); state->PauseTiming(); *correct &= digits == expected_digits; state->ResumeTiming(); }