@@ -286,38 +286,62 @@ google_firestore_v1_Value Serializer::EncodeFieldValue(
286
286
case FieldValue::Type::Null:
287
287
result.which_value_type = google_firestore_v1_Value_null_value_tag;
288
288
result.null_value = google_protobuf_NullValue_NULL_VALUE;
289
- break ;
289
+ return result ;
290
290
291
291
case FieldValue::Type::Boolean :
292
292
result.which_value_type = google_firestore_v1_Value_boolean_value_tag;
293
293
result.boolean_value = field_value.boolean_value ();
294
- break ;
294
+ return result ;
295
295
296
296
case FieldValue::Type::Integer:
297
297
result.which_value_type = google_firestore_v1_Value_integer_value_tag;
298
298
result.integer_value = field_value.integer_value ();
299
- break ;
299
+ return result ;
300
300
301
- case FieldValue::Type::String :
302
- result.which_value_type = google_firestore_v1_Value_string_value_tag ;
303
- result.string_value = EncodeString ( field_value.string_value () );
304
- break ;
301
+ case FieldValue::Type::Double :
302
+ result.which_value_type = google_firestore_v1_Value_double_value_tag ;
303
+ result.double_value = field_value.double_value ( );
304
+ return result ;
305
305
306
306
case FieldValue::Type::Timestamp:
307
307
result.which_value_type = google_firestore_v1_Value_timestamp_value_tag;
308
308
result.timestamp_value = EncodeTimestamp (field_value.timestamp_value ());
309
- break ;
309
+ return result;
310
+
311
+ case FieldValue::Type::ServerTimestamp:
312
+ // TODO(rsgowman): Implement
313
+ abort ();
314
+
315
+ case FieldValue::Type::String:
316
+ result.which_value_type = google_firestore_v1_Value_string_value_tag;
317
+ result.string_value = EncodeString (field_value.string_value ());
318
+ return result;
319
+
320
+ case FieldValue::Type::Blob:
321
+ result.which_value_type = google_firestore_v1_Value_bytes_value_tag;
322
+ result.bytes_value = EncodeBytes (field_value.blob_value ());
323
+ return result;
324
+
325
+ case FieldValue::Type::Reference:
326
+ // TODO(rsgowman): Implement
327
+ abort ();
328
+
329
+ case FieldValue::Type::GeoPoint:
330
+ result.which_value_type = google_firestore_v1_Value_geo_point_value_tag;
331
+ result.geo_point_value = EncodeGeoPoint (field_value.geo_point_value ());
332
+ return result;
333
+
334
+ case FieldValue::Type::Array:
335
+ result.which_value_type = google_firestore_v1_Value_array_value_tag;
336
+ result.array_value = EncodeArray (field_value.array_value ());
337
+ return result;
310
338
311
339
case FieldValue::Type::Object:
312
340
result.which_value_type = google_firestore_v1_Value_map_value_tag;
313
341
result.map_value = EncodeMapValue (ObjectValue (field_value));
314
- break ;
315
-
316
- default :
317
- // TODO(rsgowman): implement the other types
318
- abort ();
342
+ return result;
319
343
}
320
- return result ;
344
+ UNREACHABLE () ;
321
345
}
322
346
323
347
FieldValue Serializer::DecodeFieldValue (Reader* reader,
@@ -342,27 +366,38 @@ FieldValue Serializer::DecodeFieldValue(Reader* reader,
342
366
case google_firestore_v1_Value_integer_value_tag:
343
367
return FieldValue::FromInteger (msg.integer_value );
344
368
345
- case google_firestore_v1_Value_string_value_tag :
346
- return FieldValue::FromString ( DecodeString ( msg.string_value ) );
369
+ case google_firestore_v1_Value_double_value_tag :
370
+ return FieldValue::FromDouble ( msg.double_value );
347
371
348
372
case google_firestore_v1_Value_timestamp_value_tag: {
349
373
return FieldValue::FromTimestamp (
350
374
DecodeTimestamp (reader, msg.timestamp_value ));
351
375
}
352
376
353
- case google_firestore_v1_Value_map_value_tag: {
354
- return FieldValue::FromMap (DecodeMapValue (reader, msg.map_value ));
377
+ case google_firestore_v1_Value_string_value_tag:
378
+ return FieldValue::FromString (DecodeString (msg.string_value ));
379
+
380
+ case google_firestore_v1_Value_bytes_value_tag: {
381
+ std::vector<uint8_t > bytes = DecodeBytes (msg.bytes_value );
382
+ return FieldValue::FromBlob (bytes.data (), bytes.size ());
355
383
}
356
384
357
- case google_firestore_v1_Value_double_value_tag:
358
- case google_firestore_v1_Value_bytes_value_tag:
359
385
case google_firestore_v1_Value_reference_value_tag:
360
- case google_firestore_v1_Value_geo_point_value_tag:
361
- case google_firestore_v1_Value_array_value_tag:
362
386
// TODO(b/74243929): Implement remaining types.
363
387
HARD_FAIL (" Unhandled message field number (tag): %i." ,
364
388
msg.which_value_type );
365
389
390
+ case google_firestore_v1_Value_geo_point_value_tag:
391
+ return FieldValue::FromGeoPoint (
392
+ DecodeGeoPoint (reader, msg.geo_point_value ));
393
+
394
+ case google_firestore_v1_Value_array_value_tag:
395
+ return FieldValue::FromArray (DecodeArray (reader, msg.array_value ));
396
+
397
+ case google_firestore_v1_Value_map_value_tag: {
398
+ return FieldValue::FromMap (DecodeMapValue (reader, msg.map_value ));
399
+ }
400
+
366
401
default :
367
402
reader->Fail (StringFormat (" Invalid type while decoding FieldValue: %s" ,
368
403
msg.which_value_type ));
@@ -667,7 +702,7 @@ google_firestore_v1_DocumentMask Serializer::EncodeDocumentMask(
667
702
google_firestore_v1_DocumentMask result{};
668
703
669
704
size_t count = mask.size ();
670
- HARD_ASSERT (count <= std::numeric_limits< pb_size_t >:: max () ,
705
+ HARD_ASSERT (count <= PB_SIZE_MAX ,
671
706
" Unable to encode specified document mask. Too many fields." );
672
707
result.field_paths_count = static_cast <pb_size_t >(count);
673
708
result.field_paths = MakeArray<pb_bytes_array_t *>(count);
@@ -816,7 +851,7 @@ Timestamp Serializer::DecodeTimestamp(
816
851
reader->Fail (
817
852
" Invalid message: timestamp beyond the earliest supported date" );
818
853
} else if (TimestampInternal::Max ().seconds () < timestamp_proto.seconds ) {
819
- reader->Fail (" Invalid message: timestamp behond the latest supported date" );
854
+ reader->Fail (" Invalid message: timestamp beyond the latest supported date" );
820
855
} else if (timestamp_proto.nanos < 0 || timestamp_proto.nanos > 999999999 ) {
821
856
reader->Fail (
822
857
" Invalid message: timestamp nanos must be between 0 and 999999999" );
@@ -826,6 +861,66 @@ Timestamp Serializer::DecodeTimestamp(
826
861
return Timestamp{timestamp_proto.seconds , timestamp_proto.nanos };
827
862
}
828
863
864
+ /* static */
865
+ google_type_LatLng Serializer::EncodeGeoPoint (const GeoPoint& geo_point_value) {
866
+ google_type_LatLng result{};
867
+ result.latitude = geo_point_value.latitude ();
868
+ result.longitude = geo_point_value.longitude ();
869
+ return result;
870
+ }
871
+
872
+ /* static */
873
+ GeoPoint Serializer::DecodeGeoPoint (nanopb::Reader* reader,
874
+ const google_type_LatLng& latlng_proto) {
875
+ // The GeoPoint ctor will assert if we provide values outside the valid range.
876
+ // However, since we're decoding, a single corrupt byte could cause this to
877
+ // occur, so we'll verify the ranges before passing them in since we'd rather
878
+ // not abort in these situations.
879
+ double latitude = latlng_proto.latitude ;
880
+ double longitude = latlng_proto.longitude ;
881
+ if (std::isnan (latitude) || latitude < -90 || 90 < latitude) {
882
+ reader->Fail (" Invalid message: Latitude must be in the range of [-90, 90]" );
883
+ } else if (std::isnan (longitude) || longitude < -180 || 180 < longitude) {
884
+ reader->Fail (
885
+ " Invalid message: Latitude must be in the range of [-180, 180]" );
886
+ }
887
+
888
+ if (!reader->status ().ok ()) return GeoPoint ();
889
+ return GeoPoint (latitude, longitude);
890
+ }
891
+
892
+ /* static */
893
+ google_firestore_v1_ArrayValue Serializer::EncodeArray (
894
+ const std::vector<FieldValue>& array_value) {
895
+ google_firestore_v1_ArrayValue result{};
896
+
897
+ size_t count = array_value.size ();
898
+ HARD_ASSERT (count <= PB_SIZE_MAX,
899
+ " Unable to encode specified array. Too many entries." );
900
+ result.values_count = count;
901
+ result.values = MakeArray<google_firestore_v1_Value>(count);
902
+
903
+ size_t i = 0 ;
904
+ for (const FieldValue& fv : array_value) {
905
+ result.values [i++] = EncodeFieldValue (fv);
906
+ }
907
+
908
+ return result;
909
+ }
910
+
911
+ /* static */
912
+ std::vector<FieldValue> Serializer::DecodeArray (
913
+ nanopb::Reader* reader, const google_firestore_v1_ArrayValue& array_proto) {
914
+ std::vector<FieldValue> result;
915
+ result.reserve (array_proto.values_count );
916
+
917
+ for (size_t i = 0 ; i < array_proto.values_count ; i++) {
918
+ result.push_back (DecodeFieldValue (reader, array_proto.values [i]));
919
+ }
920
+
921
+ return result;
922
+ }
923
+
829
924
} // namespace remote
830
925
} // namespace firestore
831
926
} // namespace firebase
0 commit comments