@@ -39,16 +39,72 @@ void EncodeObject(pb_ostream_t* stream,
39
39
std::map<std::string, FieldValue> DecodeObject (pb_istream_t * stream);
40
40
41
41
/* *
42
- * Note that (despite the value parameter type) this works for bool, enum,
43
- * int32, int64, uint32 and uint64 proto field types.
44
- *
45
- * Note: This is not expected to be called direclty, but rather only via the
46
- * other Encode* methods (i.e. EncodeBool, EncodeLong, etc)
47
- *
48
- * @param value The value to encode, represented as a uint64_t.
42
+ * Docs TODO(rsgowman). But currently, this just wraps the underlying nanopb
43
+ * pb_ostream_t. Eventually, this might use static factory methods to create the
44
+ * underlying pb_ostream_t rather than directly passing it in.
49
45
*/
50
- void EncodeVarint (pb_ostream_t * stream, uint64_t value) {
51
- bool status = pb_encode_varint (stream, value);
46
+ // TODO(rsgowman): Encode* -> Write*
47
+ class Writer {
48
+ public:
49
+ explicit Writer (pb_ostream_t * stream) : stream_(stream) {
50
+ }
51
+
52
+ /* *
53
+ * Encodes a message type to the output stream.
54
+ *
55
+ * This essentially wraps calls to nanopb's pb_encode_tag() method.
56
+ *
57
+ * @param field_number is one of the field tags that nanopb generates based
58
+ * off of the proto messages. They're typically named in the format:
59
+ * <parentNameSpace>_<childNameSpace>_<message>_<field>_tag, e.g.
60
+ * google_firestore_v1beta1_Document_name_tag.
61
+ */
62
+ void EncodeTag (pb_wire_type_t wiretype, uint32_t field_number);
63
+
64
+ void EncodeSize (size_t size);
65
+ void EncodeNull ();
66
+ void EncodeBool (bool bool_value);
67
+ void EncodeInteger (int64_t integer_value);
68
+
69
+ private:
70
+ /* *
71
+ * Encodes a "varint" to the output stream.
72
+ *
73
+ * This essentially wraps calls to nanopb's pb_encode_varint() method.
74
+ *
75
+ * Note that (despite the value parameter type) this works for bool, enum,
76
+ * int32, int64, uint32 and uint64 proto field types.
77
+ *
78
+ * Note: This is not expected to be called directly, but rather only
79
+ * via the other Encode* methods (i.e. EncodeBool, EncodeLong, etc)
80
+ *
81
+ * @param value The value to encode, represented as a uint64_t.
82
+ */
83
+ void EncodeVarint (uint64_t value);
84
+
85
+ pb_ostream_t * stream_;
86
+ };
87
+
88
+ // TODO(rsgowman): I've left the methods as near as possible to where they were
89
+ // before, which implies that the Writer methods are interspersed with the
90
+ // PbIstream methods (or what will become the PbIstream methods). This should
91
+ // make it a bit easier to review. Refactor these to group the related methods
92
+ // together (probably within their own file rather than here).
93
+
94
+ void Writer::EncodeTag (pb_wire_type_t wiretype, uint32_t field_number) {
95
+ bool status = pb_encode_tag (stream_, wiretype, field_number);
96
+ if (!status) {
97
+ // TODO(rsgowman): figure out error handling
98
+ abort ();
99
+ }
100
+ }
101
+
102
+ void Writer::EncodeSize (size_t size) {
103
+ return EncodeVarint (size);
104
+ }
105
+
106
+ void Writer::EncodeVarint (uint64_t value) {
107
+ bool status = pb_encode_varint (stream_, value);
52
108
if (!status) {
53
109
// TODO(rsgowman): figure out error handling
54
110
abort ();
@@ -74,8 +130,8 @@ uint64_t DecodeVarint(pb_istream_t* stream) {
74
130
return varint_value;
75
131
}
76
132
77
- void EncodeNull (pb_ostream_t * stream ) {
78
- return EncodeVarint (stream, google_protobuf_NullValue_NULL_VALUE);
133
+ void Writer:: EncodeNull () {
134
+ return EncodeVarint (google_protobuf_NullValue_NULL_VALUE);
79
135
}
80
136
81
137
void DecodeNull (pb_istream_t * stream) {
@@ -86,8 +142,8 @@ void DecodeNull(pb_istream_t* stream) {
86
142
}
87
143
}
88
144
89
- void EncodeBool (pb_ostream_t * stream, bool bool_value) {
90
- return EncodeVarint (stream, bool_value);
145
+ void Writer:: EncodeBool (bool bool_value) {
146
+ return EncodeVarint (bool_value);
91
147
}
92
148
93
149
bool DecodeBool (pb_istream_t * stream) {
@@ -103,8 +159,8 @@ bool DecodeBool(pb_istream_t* stream) {
103
159
}
104
160
}
105
161
106
- void EncodeInteger (pb_ostream_t * stream, int64_t integer_value) {
107
- return EncodeVarint (stream, integer_value);
162
+ void Writer:: EncodeInteger (int64_t integer_value) {
163
+ return EncodeVarint (integer_value);
108
164
}
109
165
110
166
int64_t DecodeInteger (pb_istream_t * stream) {
@@ -156,59 +212,49 @@ std::string DecodeString(pb_istream_t* stream) {
156
212
// TODO(rsgowman): Refactor to use a helper class that wraps the stream struct.
157
213
// This will help with error handling, and should eliminate the issue of two
158
214
// 'EncodeFieldValue' methods.
159
- void EncodeFieldValueImpl (pb_ostream_t * stream, const FieldValue& field_value) {
215
+ void EncodeFieldValueImpl (pb_ostream_t * raw_stream,
216
+ const FieldValue& field_value) {
160
217
// TODO(rsgowman): some refactoring is in order... but will wait until after a
161
218
// non-varint, non-fixed-size (i.e. string) type is present before doing so.
219
+ Writer stream (raw_stream);
162
220
bool status = false ;
163
221
switch (field_value.type ()) {
164
222
case FieldValue::Type::Null:
165
- status = pb_encode_tag (stream, PB_WT_VARINT,
166
- google_firestore_v1beta1_Value_null_value_tag);
167
- if (!status) {
168
- // TODO(rsgowman): figure out error handling
169
- abort ();
170
- }
171
- EncodeNull (stream);
223
+ stream.EncodeTag (PB_WT_VARINT,
224
+ google_firestore_v1beta1_Value_null_value_tag);
225
+ stream.EncodeNull ();
172
226
break ;
173
227
174
228
case FieldValue::Type::Boolean :
175
- status = pb_encode_tag (stream, PB_WT_VARINT,
176
- google_firestore_v1beta1_Value_boolean_value_tag);
177
- if (!status) {
178
- // TODO(rsgowman): figure out error handling
179
- abort ();
180
- }
181
- EncodeBool (stream, field_value.boolean_value ());
229
+ stream.EncodeTag (PB_WT_VARINT,
230
+ google_firestore_v1beta1_Value_boolean_value_tag);
231
+ stream.EncodeBool (field_value.boolean_value ());
182
232
break ;
183
233
184
234
case FieldValue::Type::Integer:
185
- status = pb_encode_tag (stream, PB_WT_VARINT,
186
- google_firestore_v1beta1_Value_integer_value_tag);
187
- if (!status) {
188
- // TODO(rsgowman): figure out error handling
189
- abort ();
190
- }
191
- EncodeInteger (stream, field_value.integer_value ());
235
+ stream.EncodeTag (PB_WT_VARINT,
236
+ google_firestore_v1beta1_Value_integer_value_tag);
237
+ stream.EncodeInteger (field_value.integer_value ());
192
238
break ;
193
239
194
240
case FieldValue::Type::String:
195
- status = pb_encode_tag (stream , PB_WT_STRING,
241
+ status = pb_encode_tag (raw_stream , PB_WT_STRING,
196
242
google_firestore_v1beta1_Value_string_value_tag);
197
243
if (!status) {
198
244
// TODO(rsgowman): figure out error handling
199
245
abort ();
200
246
}
201
- EncodeString (stream , field_value.string_value ());
247
+ EncodeString (raw_stream , field_value.string_value ());
202
248
break ;
203
249
204
250
case FieldValue::Type::Object:
205
- status = pb_encode_tag (stream , PB_WT_STRING,
251
+ status = pb_encode_tag (raw_stream , PB_WT_STRING,
206
252
google_firestore_v1beta1_Value_map_value_tag);
207
253
if (!status) {
208
254
// TODO(rsgowman): figure out error handling
209
255
abort ();
210
256
}
211
- EncodeObject (stream , field_value.object_value ());
257
+ EncodeObject (raw_stream , field_value.object_value ());
212
258
break ;
213
259
214
260
default :
@@ -291,7 +337,7 @@ void EncodeNestedFieldValue(pb_ostream_t* stream,
291
337
size_t size = substream.bytes_written ;
292
338
293
339
// Write out the size to the output stream.
294
- EncodeVarint (stream, size);
340
+ Writer (stream). EncodeSize ( size);
295
341
296
342
// If stream is itself a sizing stream, then we don't need to actually parse
297
343
// field_value a second time; just update the bytes_written via a call to
@@ -452,7 +498,7 @@ void EncodeObject(pb_ostream_t* stream,
452
498
EncodeFieldsEntry (&sizing_stream, kv);
453
499
size_t size = sizing_stream.bytes_written ;
454
500
// Write out the size to the output stream.
455
- EncodeVarint (stream, size);
501
+ Writer (stream). EncodeSize ( size);
456
502
457
503
EncodeFieldsEntry (stream, kv);
458
504
}
0 commit comments