18
18
19
19
#include < algorithm>
20
20
#include < cmath>
21
+ #include < iostream>
21
22
#include < memory>
22
23
#include < new>
23
24
#include < utility>
27
28
#include " Firestore/core/src/firebase/firestore/util/comparison.h"
28
29
#include " Firestore/core/src/firebase/firestore/util/hard_assert.h"
29
30
#include " Firestore/core/src/firebase/firestore/util/hashing.h"
31
+ #include " Firestore/core/src/firebase/firestore/util/to_string.h"
30
32
#include " absl/memory/memory.h"
33
+ #include " absl/strings/escaping.h"
31
34
32
35
namespace firebase {
33
36
namespace firestore {
@@ -38,6 +41,37 @@ using Type = FieldValue::Type;
38
41
using util::Compare;
39
42
using util::ComparisonResult;
40
43
44
+ std::string ServerTimestamp::ToString () const {
45
+ std::string time = local_write_time.ToString ();
46
+ return absl::StrCat (" ServerTimestamp(local_write_time=" , time, " )" );
47
+ }
48
+
49
+ std::ostream& operator <<(std::ostream& os, const ServerTimestamp& value) {
50
+ return os << value.ToString ();
51
+ }
52
+
53
+ size_t ServerTimestamp::Hash () const {
54
+ size_t result =
55
+ util::Hash (local_write_time.seconds (), local_write_time.nanoseconds ());
56
+
57
+ if (previous_value) {
58
+ result = util::Hash (result, *previous_value);
59
+ }
60
+ return result;
61
+ }
62
+
63
+ std::string ReferenceValue::ToString () const {
64
+ return absl::StrCat (" Reference(key=" , reference.ToString (), " )" );
65
+ }
66
+
67
+ std::ostream& operator <<(std::ostream& os, const ReferenceValue& value) {
68
+ return os << value.ToString ();
69
+ }
70
+
71
+ size_t ReferenceValue::Hash () const {
72
+ return util::Hash (reference, *database_id);
73
+ }
74
+
41
75
FieldValue::FieldValue (const FieldValue& value) {
42
76
*this = value;
43
77
}
@@ -97,8 +131,6 @@ FieldValue& FieldValue::operator=(const FieldValue& value) {
97
131
std::swap (*object_value_, tmp);
98
132
break ;
99
133
}
100
- default :
101
- HARD_FAIL (" Unsupported type %s" , value.type ());
102
134
}
103
135
return *this ;
104
136
}
@@ -210,6 +242,14 @@ ObjectValue ObjectValue::SetChild(const std::string& child_name,
210
242
return ObjectValue::FromMap (fv_.object_value_ ->insert (child_name, value));
211
243
}
212
244
245
+ absl::string_view FieldValue::blob_value_as_string_view () const {
246
+ const std::vector<uint8_t >& blob = blob_value ();
247
+
248
+ // string_view accepts const char*, but treats it internally as unsigned.
249
+ auto data = reinterpret_cast <const char *>(blob.data ());
250
+ return absl::string_view (data, blob.size ());
251
+ }
252
+
213
253
FieldValue FieldValue::Null () {
214
254
return FieldValue ();
215
255
}
@@ -256,7 +296,7 @@ FieldValue FieldValue::FromTimestamp(const Timestamp& value) {
256
296
}
257
297
258
298
FieldValue FieldValue::FromServerTimestamp (const Timestamp& local_write_time,
259
- const Timestamp & previous_value) {
299
+ const FieldValue & previous_value) {
260
300
FieldValue result;
261
301
result.SwitchTo (Type::ServerTimestamp);
262
302
result.server_timestamp_value_ ->local_write_time = local_write_time;
@@ -348,29 +388,43 @@ FieldValue FieldValue::FromMap(FieldValue::Map&& value) {
348
388
return result;
349
389
}
350
390
391
+ static size_t HashObject (const FieldValue::Map& object) {
392
+ size_t result = 0 ;
393
+ for (auto && entry : object) {
394
+ result = util::Hash (result, entry.first , entry.second );
395
+ }
396
+ return result;
397
+ }
398
+
351
399
size_t FieldValue::Hash () const {
352
400
switch (type ()) {
353
401
case FieldValue::Type::Null:
354
- HARD_FAIL ( " TODO(rsgowman): Implement " );
355
-
402
+ // std::hash is not defined for nullptr_t.
403
+ return util::Hash ( static_cast < void *>( nullptr ));
356
404
case FieldValue::Type::Boolean:
357
- return util::Hash (boolean_value ());
358
-
405
+ return util::Hash (boolean_value_);
359
406
case FieldValue::Type::Integer:
407
+ return util::Hash (integer_value_);
360
408
case FieldValue::Type::Double:
409
+ return util::DoubleBitwiseHash (double_value_);
361
410
case FieldValue::Type::Timestamp:
411
+ return util::Hash (timestamp_value_->seconds (),
412
+ timestamp_value_->nanoseconds ());
362
413
case FieldValue::Type::ServerTimestamp:
363
- HARD_FAIL (" TODO(rsgowman): Implement" );
364
-
414
+ return util::Hash (*server_timestamp_value_);
365
415
case FieldValue::Type::String:
366
- return util::Hash (string_value ());
367
-
416
+ return util::Hash (*string_value_);
368
417
case FieldValue::Type::Blob:
418
+ return util::Hash (*blob_value_);
369
419
case FieldValue::Type::Reference:
420
+ return util::Hash (*reference_value_);
370
421
case FieldValue::Type::GeoPoint:
422
+ return util::Hash (geo_point_value_->latitude (),
423
+ geo_point_value_->longitude ());
371
424
case FieldValue::Type::Array:
425
+ return util::Hash (*array_value_);
372
426
case FieldValue::Type::Object:
373
- HARD_FAIL ( " TODO(rsgowman): Implement " );
427
+ return HashObject (*object_value_ );
374
428
}
375
429
376
430
UNREACHABLE ();
@@ -430,12 +484,45 @@ ComparisonResult FieldValue::CompareTo(const FieldValue& rhs) const {
430
484
return CompareContainer (*array_value_, *rhs.array_value_ );
431
485
case Type::Object:
432
486
return CompareContainer (*object_value_, *rhs.object_value_ );
433
- default :
434
- HARD_FAIL (" Unsupported type %s" , type ());
435
- // return false if assertion does not abort the program. We will say
436
- // each unsupported type takes only one value thus everything is equal.
437
- return ComparisonResult::Same;
438
487
}
488
+
489
+ UNREACHABLE ();
490
+ }
491
+
492
+ std::string FieldValue::ToString () const {
493
+ switch (tag_) {
494
+ case Type::Null:
495
+ return util::ToString (nullptr );
496
+ case Type::Boolean:
497
+ return util::ToString (boolean_value_);
498
+ case Type::Integer:
499
+ return util::ToString (integer_value_);
500
+ case Type::Double:
501
+ return util::ToString (double_value_);
502
+ case Type::Timestamp:
503
+ return util::ToString (*timestamp_value_);
504
+ case Type::ServerTimestamp:
505
+ return util::ToString (*server_timestamp_value_);
506
+ case Type::String:
507
+ return util::ToString (*string_value_);
508
+ case Type::Blob:
509
+ return absl::StrCat (
510
+ " <" , absl::BytesToHexString (blob_value_as_string_view ()), " >" );
511
+ case Type::Reference:
512
+ return util::ToString (*reference_value_);
513
+ case Type::GeoPoint:
514
+ return util::ToString (*geo_point_value_);
515
+ case Type::Array:
516
+ return util::ToString (*array_value_);
517
+ case Type::Object:
518
+ return util::ToString (*object_value_);
519
+ }
520
+
521
+ UNREACHABLE ();
522
+ }
523
+
524
+ std::ostream& operator <<(std::ostream& os, const FieldValue& value) {
525
+ return os << value.ToString ();
439
526
}
440
527
441
528
void FieldValue::SwitchTo (const Type type) {
@@ -522,6 +609,18 @@ ComparisonResult ObjectValue::CompareTo(const ObjectValue& rhs) const {
522
609
return fv_.CompareTo (rhs.fv_ );
523
610
}
524
611
612
+ std::string ObjectValue::ToString () const {
613
+ return fv_.ToString ();
614
+ }
615
+
616
+ std::ostream& operator <<(std::ostream& os, const ObjectValue& value) {
617
+ return os << value.ToString ();
618
+ }
619
+
620
+ size_t ObjectValue::Hash () const {
621
+ return fv_.Hash ();
622
+ }
623
+
525
624
} // namespace model
526
625
} // namespace firestore
527
626
} // namespace firebase
0 commit comments