OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "dbus/values_util.h" | 5 #include "dbus/values_util.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "dbus/message.h" | 11 #include "dbus/message.h" |
12 | 12 |
13 namespace dbus { | 13 namespace dbus { |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Returns whether |value| is exactly representable by double or not. | 17 // Returns whether |value| is exactly representable by double or not. |
18 template<typename T> | 18 template<typename T> |
19 bool IsExactlyRepresentableByDouble(T value) { | 19 bool IsExactlyRepresentableByDouble(T value) { |
20 return value == static_cast<T>(static_cast<double>(value)); | 20 return value == static_cast<T>(static_cast<double>(value)); |
21 } | 21 } |
22 | 22 |
23 // Pops values from |reader| and appends them to |list_value|. | 23 // Pops values from |reader| and appends them to |list_value|. |
24 bool PopListElements(MessageReader* reader, ListValue* list_value) { | 24 bool PopListElements(MessageReader* reader, base::ListValue* list_value) { |
25 while (reader->HasMoreData()) { | 25 while (reader->HasMoreData()) { |
26 Value* element_value = PopDataAsValue(reader); | 26 base::Value* element_value = PopDataAsValue(reader); |
27 if (!element_value) | 27 if (!element_value) |
28 return false; | 28 return false; |
29 list_value->Append(element_value); | 29 list_value->Append(element_value); |
30 } | 30 } |
31 return true; | 31 return true; |
32 } | 32 } |
33 | 33 |
34 // Pops dict-entries from |reader| and sets them to |dictionary_value| | 34 // Pops dict-entries from |reader| and sets them to |dictionary_value| |
35 bool PopDictionaryEntries(MessageReader* reader, | 35 bool PopDictionaryEntries(MessageReader* reader, |
36 DictionaryValue* dictionary_value) { | 36 base::DictionaryValue* dictionary_value) { |
37 while (reader->HasMoreData()) { | 37 while (reader->HasMoreData()) { |
38 DCHECK_EQ(Message::DICT_ENTRY, reader->GetDataType()); | 38 DCHECK_EQ(Message::DICT_ENTRY, reader->GetDataType()); |
39 MessageReader entry_reader(NULL); | 39 MessageReader entry_reader(NULL); |
40 if (!reader->PopDictEntry(&entry_reader)) | 40 if (!reader->PopDictEntry(&entry_reader)) |
41 return false; | 41 return false; |
42 // Get key as a string. | 42 // Get key as a string. |
43 std::string key_string; | 43 std::string key_string; |
44 if (entry_reader.GetDataType() == Message::STRING) { | 44 if (entry_reader.GetDataType() == Message::STRING) { |
45 // If the type of keys is STRING, pop it directly. | 45 // If the type of keys is STRING, pop it directly. |
46 if (!entry_reader.PopString(&key_string)) | 46 if (!entry_reader.PopString(&key_string)) |
47 return false; | 47 return false; |
48 } else { | 48 } else { |
49 // If the type of keys is not STRING, convert it to string. | 49 // If the type of keys is not STRING, convert it to string. |
50 scoped_ptr<Value> key(PopDataAsValue(&entry_reader)); | 50 scoped_ptr<base::Value> key(PopDataAsValue(&entry_reader)); |
51 if (!key.get()) | 51 if (!key.get()) |
52 return false; | 52 return false; |
53 // Use JSONWriter to convert an arbitrary value to a string. | 53 // Use JSONWriter to convert an arbitrary value to a string. |
54 base::JSONWriter::Write(key.get(), &key_string); | 54 base::JSONWriter::Write(key.get(), &key_string); |
55 } | 55 } |
56 // Get the value and set the key-value pair. | 56 // Get the value and set the key-value pair. |
57 Value* value = PopDataAsValue(&entry_reader); | 57 base::Value* value = PopDataAsValue(&entry_reader); |
58 if (!value) | 58 if (!value) |
59 return false; | 59 return false; |
60 dictionary_value->SetWithoutPathExpansion(key_string, value); | 60 dictionary_value->SetWithoutPathExpansion(key_string, value); |
61 } | 61 } |
62 return true; | 62 return true; |
63 } | 63 } |
64 | 64 |
65 // Gets the D-Bus type signature for the value. | 65 // Gets the D-Bus type signature for the value. |
66 std::string GetTypeSignature(const base::Value& value) { | 66 std::string GetTypeSignature(const base::Value& value) { |
67 switch (value.GetType()) { | 67 switch (value.GetType()) { |
(...skipping 10 matching lines...) Expand all Loading... |
78 case base::Value::TYPE_DICTIONARY: | 78 case base::Value::TYPE_DICTIONARY: |
79 return "a{sv}"; | 79 return "a{sv}"; |
80 default: | 80 default: |
81 DLOG(ERROR) << "Unexpected type " << value.GetType(); | 81 DLOG(ERROR) << "Unexpected type " << value.GetType(); |
82 return ""; | 82 return ""; |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 } // namespace | 86 } // namespace |
87 | 87 |
88 Value* PopDataAsValue(MessageReader* reader) { | 88 base::Value* PopDataAsValue(MessageReader* reader) { |
89 Value* result = NULL; | 89 base::Value* result = NULL; |
90 switch (reader->GetDataType()) { | 90 switch (reader->GetDataType()) { |
91 case Message::INVALID_DATA: | 91 case Message::INVALID_DATA: |
92 // Do nothing. | 92 // Do nothing. |
93 break; | 93 break; |
94 case Message::BYTE: { | 94 case Message::BYTE: { |
95 uint8 value = 0; | 95 uint8 value = 0; |
96 if (reader->PopByte(&value)) | 96 if (reader->PopByte(&value)) |
97 result = Value::CreateIntegerValue(value); | 97 result = new base::FundamentalValue(value); |
98 break; | 98 break; |
99 } | 99 } |
100 case Message::BOOL: { | 100 case Message::BOOL: { |
101 bool value = false; | 101 bool value = false; |
102 if (reader->PopBool(&value)) | 102 if (reader->PopBool(&value)) |
103 result = Value::CreateBooleanValue(value); | 103 result = new base::FundamentalValue(value); |
104 break; | 104 break; |
105 } | 105 } |
106 case Message::INT16: { | 106 case Message::INT16: { |
107 int16 value = 0; | 107 int16 value = 0; |
108 if (reader->PopInt16(&value)) | 108 if (reader->PopInt16(&value)) |
109 result = Value::CreateIntegerValue(value); | 109 result = new base::FundamentalValue(value); |
110 break; | 110 break; |
111 } | 111 } |
112 case Message::UINT16: { | 112 case Message::UINT16: { |
113 uint16 value = 0; | 113 uint16 value = 0; |
114 if (reader->PopUint16(&value)) | 114 if (reader->PopUint16(&value)) |
115 result = Value::CreateIntegerValue(value); | 115 result = new base::FundamentalValue(value); |
116 break; | 116 break; |
117 } | 117 } |
118 case Message::INT32: { | 118 case Message::INT32: { |
119 int32 value = 0; | 119 int32 value = 0; |
120 if (reader->PopInt32(&value)) | 120 if (reader->PopInt32(&value)) |
121 result = Value::CreateIntegerValue(value); | 121 result = new base::FundamentalValue(value); |
122 break; | 122 break; |
123 } | 123 } |
124 case Message::UINT32: { | 124 case Message::UINT32: { |
125 uint32 value = 0; | 125 uint32 value = 0; |
126 if (reader->PopUint32(&value)) | 126 if (reader->PopUint32(&value)) |
127 result = Value::CreateDoubleValue(value); | 127 result = new base::FundamentalValue(static_cast<double>(value)); |
128 break; | 128 break; |
129 } | 129 } |
130 case Message::INT64: { | 130 case Message::INT64: { |
131 int64 value = 0; | 131 int64 value = 0; |
132 if (reader->PopInt64(&value)) { | 132 if (reader->PopInt64(&value)) { |
133 DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) << | 133 DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) << |
134 value << " is not exactly representable by double"; | 134 value << " is not exactly representable by double"; |
135 result = Value::CreateDoubleValue(value); | 135 result = new base::FundamentalValue(static_cast<double>(value)); |
136 } | 136 } |
137 break; | 137 break; |
138 } | 138 } |
139 case Message::UINT64: { | 139 case Message::UINT64: { |
140 uint64 value = 0; | 140 uint64 value = 0; |
141 if (reader->PopUint64(&value)) { | 141 if (reader->PopUint64(&value)) { |
142 DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) << | 142 DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) << |
143 value << " is not exactly representable by double"; | 143 value << " is not exactly representable by double"; |
144 result = Value::CreateDoubleValue(value); | 144 result = new base::FundamentalValue(static_cast<double>(value)); |
145 } | 145 } |
146 break; | 146 break; |
147 } | 147 } |
148 case Message::DOUBLE: { | 148 case Message::DOUBLE: { |
149 double value = 0; | 149 double value = 0; |
150 if (reader->PopDouble(&value)) | 150 if (reader->PopDouble(&value)) |
151 result = Value::CreateDoubleValue(value); | 151 result = new base::FundamentalValue(value); |
152 break; | 152 break; |
153 } | 153 } |
154 case Message::STRING: { | 154 case Message::STRING: { |
155 std::string value; | 155 std::string value; |
156 if (reader->PopString(&value)) | 156 if (reader->PopString(&value)) |
157 result = Value::CreateStringValue(value); | 157 result = new base::StringValue(value); |
158 break; | 158 break; |
159 } | 159 } |
160 case Message::OBJECT_PATH: { | 160 case Message::OBJECT_PATH: { |
161 ObjectPath value; | 161 ObjectPath value; |
162 if (reader->PopObjectPath(&value)) | 162 if (reader->PopObjectPath(&value)) |
163 result = Value::CreateStringValue(value.value()); | 163 result = new base::StringValue(value.value()); |
164 break; | 164 break; |
165 } | 165 } |
166 case Message::UNIX_FD: { | 166 case Message::UNIX_FD: { |
167 // Cannot distinguish a file descriptor from an int | 167 // Cannot distinguish a file descriptor from an int |
168 NOTREACHED(); | 168 NOTREACHED(); |
169 break; | 169 break; |
170 } | 170 } |
171 case Message::ARRAY: { | 171 case Message::ARRAY: { |
172 MessageReader sub_reader(NULL); | 172 MessageReader sub_reader(NULL); |
173 if (reader->PopArray(&sub_reader)) { | 173 if (reader->PopArray(&sub_reader)) { |
174 // If the type of the array's element is DICT_ENTRY, create a | 174 // If the type of the array's element is DICT_ENTRY, create a |
175 // DictionaryValue, otherwise create a ListValue. | 175 // DictionaryValue, otherwise create a ListValue. |
176 if (sub_reader.GetDataType() == Message::DICT_ENTRY) { | 176 if (sub_reader.GetDataType() == Message::DICT_ENTRY) { |
177 scoped_ptr<DictionaryValue> dictionary_value(new DictionaryValue); | 177 scoped_ptr<base::DictionaryValue> dictionary_value( |
| 178 new base::DictionaryValue); |
178 if (PopDictionaryEntries(&sub_reader, dictionary_value.get())) | 179 if (PopDictionaryEntries(&sub_reader, dictionary_value.get())) |
179 result = dictionary_value.release(); | 180 result = dictionary_value.release(); |
180 } else { | 181 } else { |
181 scoped_ptr<ListValue> list_value(new ListValue); | 182 scoped_ptr<base::ListValue> list_value(new base::ListValue); |
182 if (PopListElements(&sub_reader, list_value.get())) | 183 if (PopListElements(&sub_reader, list_value.get())) |
183 result = list_value.release(); | 184 result = list_value.release(); |
184 } | 185 } |
185 } | 186 } |
186 break; | 187 break; |
187 } | 188 } |
188 case Message::STRUCT: { | 189 case Message::STRUCT: { |
189 MessageReader sub_reader(NULL); | 190 MessageReader sub_reader(NULL); |
190 if (reader->PopStruct(&sub_reader)) { | 191 if (reader->PopStruct(&sub_reader)) { |
191 scoped_ptr<ListValue> list_value(new ListValue); | 192 scoped_ptr<base::ListValue> list_value(new base::ListValue); |
192 if (PopListElements(&sub_reader, list_value.get())) | 193 if (PopListElements(&sub_reader, list_value.get())) |
193 result = list_value.release(); | 194 result = list_value.release(); |
194 } | 195 } |
195 break; | 196 break; |
196 } | 197 } |
197 case Message::DICT_ENTRY: | 198 case Message::DICT_ENTRY: |
198 // DICT_ENTRY must be popped as an element of an array. | 199 // DICT_ENTRY must be popped as an element of an array. |
199 NOTREACHED(); | 200 NOTREACHED(); |
200 break; | 201 break; |
201 case Message::VARIANT: { | 202 case Message::VARIANT: { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 247 |
247 void AppendBasicTypeValueDataAsVariant(MessageWriter* writer, | 248 void AppendBasicTypeValueDataAsVariant(MessageWriter* writer, |
248 const base::Value& value) { | 249 const base::Value& value) { |
249 MessageWriter sub_writer(NULL); | 250 MessageWriter sub_writer(NULL); |
250 writer->OpenVariant(GetTypeSignature(value), &sub_writer); | 251 writer->OpenVariant(GetTypeSignature(value), &sub_writer); |
251 AppendBasicTypeValueData(&sub_writer, value); | 252 AppendBasicTypeValueData(&sub_writer, value); |
252 writer->CloseContainer(&sub_writer); | 253 writer->CloseContainer(&sub_writer); |
253 } | 254 } |
254 | 255 |
255 } // namespace dbus | 256 } // namespace dbus |
OLD | NEW |