aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/src/firebase/firestore/remote
diff options
context:
space:
mode:
authorGravatar rsgowman <rgowman@google.com>2018-03-12 18:15:08 -0400
committerGravatar GitHub <noreply@github.com>2018-03-12 18:15:08 -0400
commit2b82a2eef7e897203a191adca996435d091fe4c2 (patch)
treef60f655d4b6c646471d3c830879e40d921f8397f /Firestore/core/src/firebase/firestore/remote
parent3e41f2585cefaef1d37f76224cdd8e8908c529da (diff)
Allow serializing arbitrary length FieldValues (#889)
Uses a custom pb_ostream_t. Previously used a stack allocated 1k buffer.
Diffstat (limited to 'Firestore/core/src/firebase/firestore/remote')
-rw-r--r--Firestore/core/src/firebase/firestore/remote/serializer.cc29
1 files changed, 23 insertions, 6 deletions
diff --git a/Firestore/core/src/firebase/firestore/remote/serializer.cc b/Firestore/core/src/firebase/firestore/remote/serializer.cc
index 02ed1ae..fcf8633 100644
--- a/Firestore/core/src/firebase/firestore/remote/serializer.cc
+++ b/Firestore/core/src/firebase/firestore/remote/serializer.cc
@@ -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) {