BSON writer: write to_bson(j) in one pass, with sizes written afterwards
BSON prefixes every document and array with its size. to_bson() therefore walked the value twice: once to compute every size, once to write. When the output is the vector that to_bson(j) returns, the writer now puts a placeholder in front of each document and array and writes its size there once the document is complete, so one walk is enough. Every key and value is still checked as the size pass checked it, in the same order, so the same exception is thrown; the partial output is discarded with the vector. If a length would not fit BSON's 32-bit size fields, the writer drops what it has written and writes the document in two passes, which reports that error before writing anything, as before. The two passes remain for output adapters (streams, strings, vectors passed by reference), for error_handler_t::replace and ignore (which change sizes), and for integer types wider than 64 bits. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
4 files changed
+627
-2
No files matched your search
@@ -227,6 +227,29 @@ class output_vector_sink
|
||||
void flush() noexcept
|
||||
{}
|
||||
|
||||
/// the number of characters written so far, the position of the next one
|
||||
std::size_t written() const noexcept
|
||||
{
|
||||
return position();
|
||||
}
|
||||
|
||||
/// @brief replace @a length characters written before, from position @a pos
|
||||
///
|
||||
/// Lets a writer put a length in front of data it has written since, such
|
||||
/// as the size of a BSON document, without computing it in advance.
|
||||
void overwrite(const std::size_t pos, const CharType* s, const std::size_t length) noexcept
|
||||
{
|
||||
JSON_ASSERT(pos + length <= position());
|
||||
std::memcpy(v->data() + pos, s, length * sizeof(CharType));
|
||||
}
|
||||
|
||||
/// drop the characters written from position @a pos on
|
||||
void rewind(const std::size_t pos) noexcept
|
||||
{
|
||||
JSON_ASSERT(pos <= position());
|
||||
cursor = v->data() + pos;
|
||||
}
|
||||
|
||||
private:
|
||||
/// number of characters of *v written so far
|
||||
std::size_t position() const noexcept
|
||||
|
||||
Reference in new issue
Block a user