| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2006-2008 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. | 
|  | 4 | 
|  | 5 #include "ipc/ipc_message_utils.h" | 
|  | 6 | 
|  | 7 #include "base/json_writer.h" | 
|  | 8 #include "base/scoped_ptr.h" | 
|  | 9 #include "base/time.h" | 
|  | 10 #include "base/values.h" | 
|  | 11 | 
|  | 12 namespace IPC { | 
|  | 13 | 
|  | 14 const int kMaxRecursionDepth = 100; | 
|  | 15 | 
|  | 16 // Value serialization | 
|  | 17 | 
|  | 18 static bool ReadValue(const Message* m, void** iter, Value** value, | 
|  | 19                       int recursion); | 
|  | 20 | 
|  | 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; | 
|  | 25   } | 
|  | 26 | 
|  | 27   m->WriteInt(value->GetType()); | 
|  | 28 | 
|  | 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; | 
|  | 37     } | 
|  | 38   case Value::TYPE_INTEGER: { | 
|  | 39       int val; | 
|  | 40       value->GetAsInteger(&val); | 
|  | 41       WriteParam(m, val); | 
|  | 42       break; | 
|  | 43     } | 
|  | 44   case Value::TYPE_REAL: { | 
|  | 45       double val; | 
|  | 46       value->GetAsReal(&val); | 
|  | 47       WriteParam(m, val); | 
|  | 48       break; | 
|  | 49     } | 
|  | 50   case Value::TYPE_STRING: { | 
|  | 51       std::string val; | 
|  | 52       value->GetAsString(&val); | 
|  | 53       WriteParam(m, val); | 
|  | 54       break; | 
|  | 55     } | 
|  | 56   case Value::TYPE_BINARY: { | 
|  | 57       NOTREACHED() << "Don't send BinaryValues over IPC."; | 
|  | 58     } | 
|  | 59   case Value::TYPE_DICTIONARY: { | 
|  | 60       const DictionaryValue* dict = static_cast<const DictionaryValue*>(value); | 
|  | 61 | 
|  | 62       WriteParam(m, static_cast<int>(dict->GetSize())); | 
|  | 63 | 
|  | 64       for (DictionaryValue::key_iterator it = dict->begin_keys(); | 
|  | 65            it != dict->end_keys(); ++it) { | 
|  | 66         Value* subval; | 
|  | 67         if (dict->Get(*it, &subval)) { | 
|  | 68           WriteParam(m, *it); | 
|  | 69           WriteValue(m, subval, recursion + 1); | 
|  | 70         } else { | 
|  | 71           NOTREACHED() << "DictionaryValue iterators are filthy liars."; | 
|  | 72         } | 
|  | 73       } | 
|  | 74       break; | 
|  | 75     } | 
|  | 76   case Value::TYPE_LIST: { | 
|  | 77       const ListValue* list = static_cast<const ListValue*>(value); | 
|  | 78       WriteParam(m, static_cast<int>(list->GetSize())); | 
|  | 79       for (size_t i = 0; i < list->GetSize(); ++i) { | 
|  | 80         Value* subval; | 
|  | 81         if (list->Get(i, &subval)) { | 
|  | 82           WriteValue(m, subval, recursion + 1); | 
|  | 83         } else { | 
|  | 84           NOTREACHED() << "ListValue::GetSize is a filthy liar."; | 
|  | 85         } | 
|  | 86       } | 
|  | 87       break; | 
|  | 88     } | 
|  | 89   } | 
|  | 90 } | 
|  | 91 | 
|  | 92 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated | 
|  | 93 // object. | 
|  | 94 static bool ReadDictionaryValue(const Message* m, void** iter, | 
|  | 95                                 DictionaryValue* value, int recursion) { | 
|  | 96   int size; | 
|  | 97   if (!ReadParam(m, iter, &size)) | 
|  | 98     return false; | 
|  | 99 | 
|  | 100   for (int i = 0; i < size; ++i) { | 
|  | 101     std::wstring key; | 
|  | 102     Value* subval; | 
|  | 103     if (!ReadParam(m, iter, &key) || | 
|  | 104         !ReadValue(m, iter, &subval, recursion + 1)) | 
|  | 105       return false; | 
|  | 106     value->Set(key, subval); | 
|  | 107   } | 
|  | 108 | 
|  | 109   return true; | 
|  | 110 } | 
|  | 111 | 
|  | 112 // Helper for ReadValue that reads a ReadListValue into a pre-allocated | 
|  | 113 // object. | 
|  | 114 static bool ReadListValue(const Message* m, void** iter, | 
|  | 115                           ListValue* value, int recursion) { | 
|  | 116   int size; | 
|  | 117   if (!ReadParam(m, iter, &size)) | 
|  | 118     return false; | 
|  | 119 | 
|  | 120   for (int i = 0; i < size; ++i) { | 
|  | 121     Value* subval; | 
|  | 122     if (!ReadValue(m, iter, &subval, recursion + 1)) | 
|  | 123       return false; | 
|  | 124     value->Set(i, subval); | 
|  | 125   } | 
|  | 126 | 
|  | 127   return true; | 
|  | 128 } | 
|  | 129 | 
|  | 130 static bool ReadValue(const Message* m, void** iter, Value** value, | 
|  | 131                       int recursion) { | 
|  | 132   if (recursion > kMaxRecursionDepth) { | 
|  | 133     LOG(WARNING) << "Max recursion depth hit in ReadValue."; | 
|  | 134     return false; | 
|  | 135   } | 
|  | 136 | 
|  | 137   int type; | 
|  | 138   if (!ReadParam(m, iter, &type)) | 
|  | 139     return false; | 
|  | 140 | 
|  | 141   switch (type) { | 
|  | 142   case Value::TYPE_NULL: | 
|  | 143     *value = Value::CreateNullValue(); | 
|  | 144     break; | 
|  | 145   case Value::TYPE_BOOLEAN: { | 
|  | 146       bool val; | 
|  | 147       if (!ReadParam(m, iter, &val)) | 
|  | 148         return false; | 
|  | 149       *value = Value::CreateBooleanValue(val); | 
|  | 150       break; | 
|  | 151     } | 
|  | 152   case Value::TYPE_INTEGER: { | 
|  | 153       int val; | 
|  | 154       if (!ReadParam(m, iter, &val)) | 
|  | 155         return false; | 
|  | 156       *value = Value::CreateIntegerValue(val); | 
|  | 157       break; | 
|  | 158     } | 
|  | 159   case Value::TYPE_REAL: { | 
|  | 160       double val; | 
|  | 161       if (!ReadParam(m, iter, &val)) | 
|  | 162         return false; | 
|  | 163       *value = Value::CreateRealValue(val); | 
|  | 164       break; | 
|  | 165     } | 
|  | 166   case Value::TYPE_STRING: { | 
|  | 167       std::string val; | 
|  | 168       if (!ReadParam(m, iter, &val)) | 
|  | 169         return false; | 
|  | 170       *value = Value::CreateStringValue(val); | 
|  | 171       break; | 
|  | 172     } | 
|  | 173   case Value::TYPE_BINARY: { | 
|  | 174       NOTREACHED() << "Don't send BinaryValues over IPC."; | 
|  | 175       break; | 
|  | 176     } | 
|  | 177   case Value::TYPE_DICTIONARY: { | 
|  | 178       scoped_ptr<DictionaryValue> val(new DictionaryValue()); | 
|  | 179       if (!ReadDictionaryValue(m, iter, val.get(), recursion)) | 
|  | 180         return false; | 
|  | 181       *value = val.release(); | 
|  | 182       break; | 
|  | 183     } | 
|  | 184   case Value::TYPE_LIST: { | 
|  | 185       scoped_ptr<ListValue> val(new ListValue()); | 
|  | 186       if (!ReadListValue(m, iter, val.get(), recursion)) | 
|  | 187         return false; | 
|  | 188       *value = val.release(); | 
|  | 189       break; | 
|  | 190     } | 
|  | 191   default: | 
|  | 192     return false; | 
|  | 193   } | 
|  | 194 | 
|  | 195   return true; | 
|  | 196 } | 
|  | 197 | 
|  | 198 void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) { | 
|  | 199   WriteValue(m, &p, 0); | 
|  | 200 } | 
|  | 201 | 
|  | 202 bool ParamTraits<DictionaryValue>::Read( | 
|  | 203     const Message* m, void** iter, param_type* r) { | 
|  | 204   int type; | 
|  | 205   if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY) | 
|  | 206     return false; | 
|  | 207 | 
|  | 208   return ReadDictionaryValue(m, iter, r, 0); | 
|  | 209 } | 
|  | 210 | 
|  | 211 void ParamTraits<DictionaryValue>::Log(const param_type& p, std::wstring* l) { | 
|  | 212   std::string json; | 
|  | 213   JSONWriter::Write(&p, false, &json); | 
|  | 214   l->append(UTF8ToWide(json)); | 
|  | 215 } | 
|  | 216 | 
|  | 217 void ParamTraits<ListValue>::Write(Message* m, const param_type& p) { | 
|  | 218   WriteValue(m, &p, 0); | 
|  | 219 } | 
|  | 220 | 
|  | 221 bool ParamTraits<ListValue>::Read( | 
|  | 222     const Message* m, void** iter, param_type* r) { | 
|  | 223   int type; | 
|  | 224   if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST) | 
|  | 225     return false; | 
|  | 226 | 
|  | 227   return ReadListValue(m, iter, r, 0); | 
|  | 228 } | 
|  | 229 | 
|  | 230 void ParamTraits<ListValue>::Log(const param_type& p, std::wstring* l) { | 
|  | 231   std::string json; | 
|  | 232   JSONWriter::Write(&p, false, &json); | 
|  | 233   l->append(UTF8ToWide(json)); | 
|  | 234 } | 
|  | 235 }  // namespace IPC | 
| OLD | NEW | 
|---|