@@ -109,19 +109,22 @@ void SortFields(google_firestore_v1_ArrayValue& value) {
109
109
}
110
110
}
111
111
112
+ void SortFields (google_firestore_v1_MapValue& value) {
113
+ std::sort (value.fields , value.fields + value.fields_count ,
114
+ [](const google_firestore_v1_MapValue_FieldsEntry& lhs,
115
+ const google_firestore_v1_MapValue_FieldsEntry& rhs) {
116
+ return nanopb::MakeStringView (lhs.key ) <
117
+ nanopb::MakeStringView (rhs.key );
118
+ });
119
+
120
+ for (pb_size_t i = 0 ; i < value.fields_count ; ++i) {
121
+ SortFields (value.fields [i].value );
122
+ }
123
+ }
124
+
112
125
void SortFields (google_firestore_v1_Value& value) {
113
126
if (IsMap (value)) {
114
- google_firestore_v1_MapValue& map_value = value.map_value ;
115
- std::sort (map_value.fields , map_value.fields + map_value.fields_count ,
116
- [](const google_firestore_v1_MapValue_FieldsEntry& lhs,
117
- const google_firestore_v1_MapValue_FieldsEntry& rhs) {
118
- return nanopb::MakeStringView (lhs.key ) <
119
- nanopb::MakeStringView (rhs.key );
120
- });
121
-
122
- for (pb_size_t i = 0 ; i < map_value.fields_count ; ++i) {
123
- SortFields (map_value.fields [i].value );
124
- }
127
+ SortFields (value.map_value );
125
128
} else if (IsArray (value)) {
126
129
SortFields (value.array_value );
127
130
}
@@ -223,30 +226,31 @@ ComparisonResult CompareArrays(const google_firestore_v1_Value& left,
223
226
right.array_value .values_count );
224
227
}
225
228
226
- ComparisonResult CompareObjects (const google_firestore_v1_Value& left,
227
- const google_firestore_v1_Value& right) {
228
- google_firestore_v1_MapValue left_map = left.map_value ;
229
- google_firestore_v1_MapValue right_map = right.map_value ;
229
+ ComparisonResult CompareMaps (const google_firestore_v1_MapValue& left,
230
+ const google_firestore_v1_MapValue& right) {
231
+ // Sort the given MapValues
232
+ auto left_map = DeepClone (left);
233
+ auto right_map = DeepClone (right);
234
+ SortFields (*left_map);
235
+ SortFields (*right_map);
230
236
231
- // Porting Note: MapValues in iOS are always kept in sorted order. We
232
- // therefore do no need to sort them before comparing.
233
- for (pb_size_t i = 0 ; i < left_map.fields_count && i < right_map.fields_count ;
234
- ++i) {
235
- ComparisonResult key_cmp =
236
- util::Compare (nanopb::MakeStringView (left_map.fields [i].key ),
237
- nanopb::MakeStringView (right_map.fields [i].key ));
237
+ for (pb_size_t i = 0 ;
238
+ i < left_map->fields_count && i < right_map->fields_count ; ++i) {
239
+ const ComparisonResult key_cmp =
240
+ util::Compare (nanopb::MakeStringView (left_map->fields [i].key ),
241
+ nanopb::MakeStringView (right_map->fields [i].key ));
238
242
if (key_cmp != ComparisonResult::Same) {
239
243
return key_cmp;
240
244
}
241
245
242
- ComparisonResult value_cmp =
243
- Compare (left_map. fields [i].value , right. map_value . fields [i].value );
246
+ const ComparisonResult value_cmp =
247
+ Compare (left_map-> fields [i].value , right_map-> fields [i].value );
244
248
if (value_cmp != ComparisonResult::Same) {
245
249
return value_cmp;
246
250
}
247
251
}
248
252
249
- return util::Compare (left_map. fields_count , right_map. fields_count );
253
+ return util::Compare (left_map-> fields_count , right_map-> fields_count );
250
254
}
251
255
252
256
ComparisonResult Compare (const google_firestore_v1_Value& left,
@@ -291,7 +295,7 @@ ComparisonResult Compare(const google_firestore_v1_Value& left,
291
295
return CompareArrays (left, right);
292
296
293
297
case TypeOrder::kMap :
294
- return CompareObjects (left, right);
298
+ return CompareMaps (left. map_value , right. map_value );
295
299
296
300
case TypeOrder::kMaxValue :
297
301
return util::ComparisonResult::Same;
@@ -366,26 +370,12 @@ bool ArrayEquals(const google_firestore_v1_ArrayValue& left,
366
370
return true ;
367
371
}
368
372
369
- bool ObjectEquals (const google_firestore_v1_MapValue& left,
370
- const google_firestore_v1_MapValue& right) {
373
+ bool MapValueEquals (const google_firestore_v1_MapValue& left,
374
+ const google_firestore_v1_MapValue& right) {
371
375
if (left.fields_count != right.fields_count ) {
372
376
return false ;
373
377
}
374
-
375
- // Porting Note: MapValues in iOS are always kept in sorted order. We
376
- // therefore do no need to sort them before comparing.
377
- for (size_t i = 0 ; i < right.fields_count ; ++i) {
378
- if (nanopb::MakeStringView (left.fields [i].key ) !=
379
- nanopb::MakeStringView (right.fields [i].key )) {
380
- return false ;
381
- }
382
-
383
- if (left.fields [i].value != right.fields [i].value ) {
384
- return false ;
385
- }
386
- }
387
-
388
- return true ;
378
+ return CompareMaps (left, right) == ComparisonResult::Same;
389
379
}
390
380
391
381
bool Equals (const google_firestore_v1_Value& lhs,
@@ -436,10 +426,10 @@ bool Equals(const google_firestore_v1_Value& lhs,
436
426
return ArrayEquals (lhs.array_value , rhs.array_value );
437
427
438
428
case TypeOrder::kMap :
439
- return ObjectEquals (lhs.map_value , rhs.map_value );
429
+ return MapValueEquals (lhs.map_value , rhs.map_value );
440
430
441
431
case TypeOrder::kMaxValue :
442
- return ObjectEquals (lhs.map_value , rhs.map_value );
432
+ return MapValueEquals (lhs.map_value , rhs.map_value );
443
433
444
434
default :
445
435
HARD_FAIL (" Invalid type value: %s" , left_type);
@@ -794,27 +784,11 @@ Message<google_firestore_v1_Value> DeepClone(
794
784
break ;
795
785
796
786
case google_firestore_v1_Value_array_value_tag:
797
- target->array_value .values_count = source.array_value .values_count ;
798
- target->array_value .values = nanopb::MakeArray<google_firestore_v1_Value>(
799
- source.array_value .values_count );
800
- for (pb_size_t i = 0 ; i < source.array_value .values_count ; ++i) {
801
- target->array_value .values [i] =
802
- *DeepClone (source.array_value .values [i]).release ();
803
- }
787
+ target->array_value = *DeepClone (source.array_value ).release ();
804
788
break ;
805
789
806
790
case google_firestore_v1_Value_map_value_tag:
807
- target->map_value .fields_count = source.map_value .fields_count ;
808
- target->map_value .fields =
809
- nanopb::MakeArray<google_firestore_v1_MapValue_FieldsEntry>(
810
- source.map_value .fields_count );
811
- for (pb_size_t i = 0 ; i < source.map_value .fields_count ; ++i) {
812
- target->map_value .fields [i].key =
813
- nanopb::MakeBytesArray (source.map_value .fields [i].key ->bytes ,
814
- source.map_value .fields [i].key ->size );
815
- target->map_value .fields [i].value =
816
- *DeepClone (source.map_value .fields [i].value ).release ();
817
- }
791
+ target->map_value = *DeepClone (source.map_value ).release ();
818
792
break ;
819
793
}
820
794
return target;
@@ -832,6 +806,20 @@ Message<google_firestore_v1_ArrayValue> DeepClone(
832
806
return target;
833
807
}
834
808
809
+ Message<google_firestore_v1_MapValue> DeepClone (
810
+ const google_firestore_v1_MapValue& source) {
811
+ Message<google_firestore_v1_MapValue> target{source};
812
+ target->fields_count = source.fields_count ;
813
+ target->fields = nanopb::MakeArray<google_firestore_v1_MapValue_FieldsEntry>(
814
+ source.fields_count );
815
+ for (pb_size_t i = 0 ; i < source.fields_count ; ++i) {
816
+ target->fields [i].key = nanopb::MakeBytesArray (source.fields [i].key ->bytes ,
817
+ source.fields [i].key ->size );
818
+ target->fields [i].value = *DeepClone (source.fields [i].value ).release ();
819
+ }
820
+ return target;
821
+ }
822
+
835
823
} // namespace model
836
824
} // namespace firestore
837
825
} // namespace firebase
0 commit comments