OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sync/internal_api/public/base/invalidation.h" | 5 #include "sync/internal_api/public/base/invalidation.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
| 8 |
| 9 #include "base/json/json_string_value_serializer.h" |
8 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
9 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
10 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "sync/notifier/invalidation_util.h" |
11 | 14 |
12 namespace syncer { | 15 namespace syncer { |
13 | 16 |
14 namespace { | 17 namespace { |
15 // Hopefully enough bytes for uniqueness. | 18 const char kObjectIdKey[] = "objectId"; |
16 const size_t kBytesInHandle = 16; | 19 const char kIsUnknownVersionKey[] = "isUnknownVersion"; |
17 } // namespace | 20 const char kVersionKey[] = "version"; |
18 | 21 const char kPayloadKey[] = "payload"; |
19 AckHandle AckHandle::CreateUnique() { | |
20 // This isn't a valid UUID, so we don't attempt to format it like one. | |
21 uint8 random_bytes[kBytesInHandle]; | |
22 base::RandBytes(random_bytes, sizeof(random_bytes)); | |
23 return AckHandle(base::HexEncode(random_bytes, sizeof(random_bytes)), | |
24 base::Time::Now()); | |
25 } | 22 } |
26 | 23 |
27 AckHandle AckHandle::InvalidAckHandle() { | 24 Invalidation Invalidation::Init( |
28 return AckHandle(std::string(), base::Time()); | 25 const invalidation::ObjectId& id, |
| 26 int64 version, |
| 27 const std::string& payload) { |
| 28 return Invalidation(id, false, version, payload, AckHandle::CreateUnique()); |
29 } | 29 } |
30 | 30 |
31 bool AckHandle::Equals(const AckHandle& other) const { | 31 Invalidation Invalidation::InitUnknownVersion( |
32 return state_ == other.state_ && timestamp_ == other.timestamp_; | 32 const invalidation::ObjectId& id) { |
| 33 return Invalidation(id, true, -1, std::string(), AckHandle::CreateUnique()); |
33 } | 34 } |
34 | 35 |
35 scoped_ptr<base::DictionaryValue> AckHandle::ToValue() const { | 36 scoped_ptr<Invalidation> Invalidation::InitFromValue( |
36 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | 37 const base::DictionaryValue& value) { |
37 value->SetString("state", state_); | 38 invalidation::ObjectId id; |
38 value->SetString("timestamp", | 39 |
39 base::Int64ToString(timestamp_.ToInternalValue())); | 40 const base::DictionaryValue* object_id_dict; |
40 return value.Pass(); | 41 if (!value.GetDictionary(kObjectIdKey, &object_id_dict) |
| 42 || !ObjectIdFromValue(*object_id_dict, &id)) { |
| 43 DLOG(WARNING) << "Failed to parse id"; |
| 44 return scoped_ptr<Invalidation>(); |
| 45 } |
| 46 bool is_unknown_version; |
| 47 if (!value.GetBoolean(kIsUnknownVersionKey, &is_unknown_version)) { |
| 48 DLOG(WARNING) << "Failed to parse is_unknown_version flag"; |
| 49 return scoped_ptr<Invalidation>(); |
| 50 } |
| 51 if (is_unknown_version) { |
| 52 return scoped_ptr<Invalidation>(new Invalidation( |
| 53 id, |
| 54 true, |
| 55 -1, |
| 56 std::string(), |
| 57 AckHandle::CreateUnique())); |
| 58 } else { |
| 59 int64 version; |
| 60 std::string version_as_string; |
| 61 if (!value.GetString(kVersionKey, &version_as_string) |
| 62 || !base::StringToInt64(version_as_string, &version)) { |
| 63 DLOG(WARNING) << "Failed to parse version"; |
| 64 return scoped_ptr<Invalidation>(); |
| 65 } |
| 66 std::string payload; |
| 67 if (!value.GetString(kPayloadKey, &payload)) { |
| 68 DLOG(WARNING) << "Failed to parse payload"; |
| 69 return scoped_ptr<Invalidation>(); |
| 70 } |
| 71 return scoped_ptr<Invalidation>(new Invalidation( |
| 72 id, |
| 73 false, |
| 74 version, |
| 75 payload, |
| 76 AckHandle::CreateUnique())); |
| 77 } |
41 } | 78 } |
42 | 79 |
43 bool AckHandle::ResetFromValue(const base::DictionaryValue& value) { | 80 Invalidation::~Invalidation() {} |
44 if (!value.GetString("state", &state_)) | 81 |
45 return false; | 82 invalidation::ObjectId Invalidation::object_id() const { |
46 std::string timestamp_as_string; | 83 return id_; |
47 if (!value.GetString("timestamp", ×tamp_as_string)) | |
48 return false; | |
49 int64 timestamp_value; | |
50 if (!base::StringToInt64(timestamp_as_string, ×tamp_value)) | |
51 return false; | |
52 timestamp_ = base::Time::FromInternalValue(timestamp_value); | |
53 return true; | |
54 } | 84 } |
55 | 85 |
56 bool AckHandle::IsValid() const { | 86 bool Invalidation::is_unknown_version() const { |
57 return !state_.empty(); | 87 return is_unknown_version_; |
58 } | 88 } |
59 | 89 |
60 AckHandle::AckHandle(const std::string& state, base::Time timestamp) | 90 int64 Invalidation::version() const { |
61 : state_(state), timestamp_(timestamp) { | 91 DCHECK(!is_unknown_version_); |
| 92 return version_; |
62 } | 93 } |
63 | 94 |
64 AckHandle::~AckHandle() { | 95 const std::string& Invalidation::payload() const { |
| 96 DCHECK(!is_unknown_version_); |
| 97 return payload_; |
65 } | 98 } |
66 | 99 |
67 const int64 Invalidation::kUnknownVersion = -1; | 100 const AckHandle& Invalidation::ack_handle() const { |
68 | 101 return ack_handle_; |
69 Invalidation::Invalidation() | |
70 : version(kUnknownVersion), ack_handle(AckHandle::InvalidAckHandle()) { | |
71 } | 102 } |
72 | 103 |
73 Invalidation::~Invalidation() { | 104 void Invalidation::set_ack_handle(const AckHandle& ack_handle) { |
| 105 ack_handle_ = ack_handle; |
74 } | 106 } |
75 | 107 |
76 bool Invalidation::Equals(const Invalidation& other) const { | 108 bool Invalidation::Equals(const Invalidation& other) const { |
77 return (version == other.version) && (payload == other.payload) && | 109 return id_ == other.id_ |
78 ack_handle.Equals(other.ack_handle); | 110 && is_unknown_version_ == other.is_unknown_version_ |
| 111 && version_ == other.version_ |
| 112 && payload_ == other.payload_; |
79 } | 113 } |
80 | 114 |
81 scoped_ptr<base::DictionaryValue> Invalidation::ToValue() const { | 115 scoped_ptr<base::DictionaryValue> Invalidation::ToValue() const { |
82 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); | 116 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); |
83 value->SetString("version", base::Int64ToString(version)); | 117 value->Set(kObjectIdKey, ObjectIdToValue(id_).release()); |
84 value->SetString("payload", payload); | 118 if (is_unknown_version_) { |
85 value->Set("ackHandle", ack_handle.ToValue().release()); | 119 value->SetBoolean(kIsUnknownVersionKey, true); |
| 120 } else { |
| 121 value->SetBoolean(kIsUnknownVersionKey, false); |
| 122 value->SetString(kVersionKey, base::Int64ToString(version_)); |
| 123 value->SetString(kPayloadKey, payload_); |
| 124 } |
86 return value.Pass(); | 125 return value.Pass(); |
87 } | 126 } |
88 | 127 |
89 bool Invalidation::ResetFromValue(const base::DictionaryValue& value) { | 128 std::string Invalidation::ToString() const { |
90 const base::DictionaryValue* ack_handle_value = NULL; | 129 std::string output; |
91 std::string version_as_string; | 130 JSONStringValueSerializer serializer(&output); |
92 if (value.GetString("version", &version_as_string)) { | 131 serializer.set_pretty_print(true); |
93 if (!base::StringToInt64(version_as_string, &version)) | 132 serializer.Serialize(*ToValue().get()); |
94 return false; | 133 return output; |
95 } else { | |
96 version = kUnknownVersion; | |
97 } | |
98 return | |
99 value.GetString("payload", &payload) && | |
100 value.GetDictionary("ackHandle", &ack_handle_value) && | |
101 ack_handle.ResetFromValue(*ack_handle_value); | |
102 } | 134 } |
103 | 135 |
| 136 Invalidation::Invalidation( |
| 137 const invalidation::ObjectId& id, |
| 138 bool is_unknown_version, |
| 139 int64 version, |
| 140 const std::string& payload, |
| 141 AckHandle ack_handle) |
| 142 : id_(id), |
| 143 is_unknown_version_(is_unknown_version), |
| 144 version_(version), |
| 145 payload_(payload), |
| 146 ack_handle_(ack_handle) {} |
| 147 |
104 } // namespace syncer | 148 } // namespace syncer |
OLD | NEW |