Remove now-passing tests and rebaseline one after the Big Scary Roll.
[chromium-blink-merge.git] / ipc / ipc_message_utils.cc
blob464dd26ac227d7de7e277dc4001d4885527697df
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/ipc_message_utils.h"
7 #include "base/json/json_writer.h"
8 #include "base/scoped_ptr.h"
9 #include "base/time.h"
10 #include "base/values.h"
12 namespace IPC {
14 const int kMaxRecursionDepth = 100;
16 // Value serialization
18 static bool ReadValue(const Message* m, void** iter, Value** value,
19 int recursion);
21 static void WriteValue(Message* m, const Value* value, int recursion) {
22 if (recursion > kMaxRecursionDepth) {
23 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
24 return;
27 m->WriteInt(value->GetType());
29 switch (value->GetType()) {
30 case Value::TYPE_NULL:
31 break;
32 case Value::TYPE_BOOLEAN: {
33 bool val;
34 value->GetAsBoolean(&val);
35 WriteParam(m, val);
36 break;
38 case Value::TYPE_INTEGER: {
39 int val;
40 value->GetAsInteger(&val);
41 WriteParam(m, val);
42 break;
44 case Value::TYPE_REAL: {
45 double val;
46 value->GetAsReal(&val);
47 WriteParam(m, val);
48 break;
50 case Value::TYPE_STRING: {
51 std::string val;
52 value->GetAsString(&val);
53 WriteParam(m, val);
54 break;
56 case Value::TYPE_BINARY: {
57 const BinaryValue* binary = static_cast<const BinaryValue*>(value);
58 m->WriteData(binary->GetBuffer(), binary->GetSize());
59 break;
61 case Value::TYPE_DICTIONARY: {
62 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
64 WriteParam(m, static_cast<int>(dict->size()));
66 for (DictionaryValue::key_iterator it = dict->begin_keys();
67 it != dict->end_keys(); ++it) {
68 Value* subval;
69 if (dict->GetWithoutPathExpansion(*it, &subval)) {
70 WriteParam(m, *it);
71 WriteValue(m, subval, recursion + 1);
72 } else {
73 NOTREACHED() << "DictionaryValue iterators are filthy liars.";
76 break;
78 case Value::TYPE_LIST: {
79 const ListValue* list = static_cast<const ListValue*>(value);
80 WriteParam(m, static_cast<int>(list->GetSize()));
81 for (size_t i = 0; i < list->GetSize(); ++i) {
82 Value* subval;
83 if (list->Get(i, &subval)) {
84 WriteValue(m, subval, recursion + 1);
85 } else {
86 NOTREACHED() << "ListValue::GetSize is a filthy liar.";
89 break;
94 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated
95 // object.
96 static bool ReadDictionaryValue(const Message* m, void** iter,
97 DictionaryValue* value, int recursion) {
98 int size;
99 if (!ReadParam(m, iter, &size))
100 return false;
102 for (int i = 0; i < size; ++i) {
103 std::wstring key;
104 Value* subval;
105 if (!ReadParam(m, iter, &key) ||
106 !ReadValue(m, iter, &subval, recursion + 1))
107 return false;
108 value->Set(key, subval);
111 return true;
114 // Helper for ReadValue that reads a ReadListValue into a pre-allocated
115 // object.
116 static bool ReadListValue(const Message* m, void** iter,
117 ListValue* value, int recursion) {
118 int size;
119 if (!ReadParam(m, iter, &size))
120 return false;
122 for (int i = 0; i < size; ++i) {
123 Value* subval;
124 if (!ReadValue(m, iter, &subval, recursion + 1))
125 return false;
126 value->Set(i, subval);
129 return true;
132 static bool ReadValue(const Message* m, void** iter, Value** value,
133 int recursion) {
134 if (recursion > kMaxRecursionDepth) {
135 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
136 return false;
139 int type;
140 if (!ReadParam(m, iter, &type))
141 return false;
143 switch (type) {
144 case Value::TYPE_NULL:
145 *value = Value::CreateNullValue();
146 break;
147 case Value::TYPE_BOOLEAN: {
148 bool val;
149 if (!ReadParam(m, iter, &val))
150 return false;
151 *value = Value::CreateBooleanValue(val);
152 break;
154 case Value::TYPE_INTEGER: {
155 int val;
156 if (!ReadParam(m, iter, &val))
157 return false;
158 *value = Value::CreateIntegerValue(val);
159 break;
161 case Value::TYPE_REAL: {
162 double val;
163 if (!ReadParam(m, iter, &val))
164 return false;
165 *value = Value::CreateRealValue(val);
166 break;
168 case Value::TYPE_STRING: {
169 std::string val;
170 if (!ReadParam(m, iter, &val))
171 return false;
172 *value = Value::CreateStringValue(val);
173 break;
175 case Value::TYPE_BINARY: {
176 const char* data;
177 int length;
178 if (!m->ReadData(iter, &data, &length))
179 return false;
180 *value = BinaryValue::CreateWithCopiedBuffer(data, length);
181 break;
183 case Value::TYPE_DICTIONARY: {
184 scoped_ptr<DictionaryValue> val(new DictionaryValue());
185 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
186 return false;
187 *value = val.release();
188 break;
190 case Value::TYPE_LIST: {
191 scoped_ptr<ListValue> val(new ListValue());
192 if (!ReadListValue(m, iter, val.get(), recursion))
193 return false;
194 *value = val.release();
195 break;
197 default:
198 return false;
201 return true;
204 void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) {
205 WriteValue(m, &p, 0);
208 bool ParamTraits<DictionaryValue>::Read(
209 const Message* m, void** iter, param_type* r) {
210 int type;
211 if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY)
212 return false;
214 return ReadDictionaryValue(m, iter, r, 0);
217 void ParamTraits<DictionaryValue>::Log(const param_type& p, std::wstring* l) {
218 std::string json;
219 base::JSONWriter::Write(&p, false, &json);
220 l->append(UTF8ToWide(json));
223 void ParamTraits<ListValue>::Write(Message* m, const param_type& p) {
224 WriteValue(m, &p, 0);
227 bool ParamTraits<ListValue>::Read(
228 const Message* m, void** iter, param_type* r) {
229 int type;
230 if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST)
231 return false;
233 return ReadListValue(m, iter, r, 0);
236 void ParamTraits<ListValue>::Log(const param_type& p, std::wstring* l) {
237 std::string json;
238 base::JSONWriter::Write(&p, false, &json);
239 l->append(UTF8ToWide(json));
241 } // namespace IPC