Skip to content

Commit

Permalink
Allow serializing arbitrary length FieldValues (firebase#889)
Browse files Browse the repository at this point in the history
Uses a custom pb_ostream_t. Previously used a stack allocated 1k buffer.
  • Loading branch information
rsgowman authored Mar 12, 2018
1 parent 3e41f25 commit 2b82a2e
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions Firestore/core/src/firebase/firestore/remote/serializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -550,13 +550,30 @@ std::map<std::string, FieldValue> DecodeObject(pb_istream_t* stream) {

void Serializer::EncodeFieldValue(const FieldValue& field_value,
std::vector<uint8_t>* out_bytes) {
// TODO(rsgowman): how large should the output buffer be? Do some
// investigation to see if we can get nanopb to tell us how much space it's
// going to need. (Hint: use a sizing stream, i.e. PB_OSTREAM_SIZING)
uint8_t buf[1024];
pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
// TODO(rsgowman): find a better home for this constant.
// A document is defined to have a max size of 1MiB - 4 bytes.
static const size_t kMaxDocumentSize = 1 * 1024 * 1024 - 4;

// Construct a nanopb output stream.
//
// Set the max_size to be the max document size (as an upper bound; one would
// expect individual FieldValue's to be smaller than this).
//
// bytes_written is (always) initialized to 0. (NB: nanopb does not know or
// care about the underlying output vector, so where we are in the vector
// itself is irrelevant. i.e. don't use out_bytes->size())
pb_ostream_t stream = {
/*callback=*/[](pb_ostream_t* stream, const pb_byte_t* buf,
size_t count) -> bool {
auto* out_bytes = static_cast<std::vector<uint8_t>*>(stream->state);
out_bytes->insert(out_bytes->end(), buf, buf + count);
return true;
},
/*state=*/out_bytes,
/*max_size=*/kMaxDocumentSize,
/*bytes_written=*/0,
/*errmsg=*/NULL};
EncodeFieldValueImpl(&stream, field_value);
out_bytes->insert(out_bytes->end(), buf, buf + stream.bytes_written);
}

FieldValue Serializer::DecodeFieldValue(const uint8_t* bytes, size_t length) {
Expand Down

0 comments on commit 2b82a2e

Please sign in to comment.