| Index: ipc/ipc_message_utils.cc
|
| diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ac188bfb52e736d873a3cfe23b5b4b600bc03278
|
| --- /dev/null
|
| +++ b/ipc/ipc_message_utils.cc
|
| @@ -0,0 +1,235 @@
|
| +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ipc/ipc_message_utils.h"
|
| +
|
| +#include "base/json_writer.h"
|
| +#include "base/scoped_ptr.h"
|
| +#include "base/time.h"
|
| +#include "base/values.h"
|
| +
|
| +namespace IPC {
|
| +
|
| +const int kMaxRecursionDepth = 100;
|
| +
|
| +// Value serialization
|
| +
|
| +static bool ReadValue(const Message* m, void** iter, Value** value,
|
| + int recursion);
|
| +
|
| +static void WriteValue(Message* m, const Value* value, int recursion) {
|
| + if (recursion > kMaxRecursionDepth) {
|
| + LOG(WARNING) << "Max recursion depth hit in WriteValue.";
|
| + return;
|
| + }
|
| +
|
| + m->WriteInt(value->GetType());
|
| +
|
| + switch (value->GetType()) {
|
| + case Value::TYPE_NULL:
|
| + break;
|
| + case Value::TYPE_BOOLEAN: {
|
| + bool val;
|
| + value->GetAsBoolean(&val);
|
| + WriteParam(m, val);
|
| + break;
|
| + }
|
| + case Value::TYPE_INTEGER: {
|
| + int val;
|
| + value->GetAsInteger(&val);
|
| + WriteParam(m, val);
|
| + break;
|
| + }
|
| + case Value::TYPE_REAL: {
|
| + double val;
|
| + value->GetAsReal(&val);
|
| + WriteParam(m, val);
|
| + break;
|
| + }
|
| + case Value::TYPE_STRING: {
|
| + std::string val;
|
| + value->GetAsString(&val);
|
| + WriteParam(m, val);
|
| + break;
|
| + }
|
| + case Value::TYPE_BINARY: {
|
| + NOTREACHED() << "Don't send BinaryValues over IPC.";
|
| + }
|
| + case Value::TYPE_DICTIONARY: {
|
| + const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
|
| +
|
| + WriteParam(m, static_cast<int>(dict->GetSize()));
|
| +
|
| + for (DictionaryValue::key_iterator it = dict->begin_keys();
|
| + it != dict->end_keys(); ++it) {
|
| + Value* subval;
|
| + if (dict->Get(*it, &subval)) {
|
| + WriteParam(m, *it);
|
| + WriteValue(m, subval, recursion + 1);
|
| + } else {
|
| + NOTREACHED() << "DictionaryValue iterators are filthy liars.";
|
| + }
|
| + }
|
| + break;
|
| + }
|
| + case Value::TYPE_LIST: {
|
| + const ListValue* list = static_cast<const ListValue*>(value);
|
| + WriteParam(m, static_cast<int>(list->GetSize()));
|
| + for (size_t i = 0; i < list->GetSize(); ++i) {
|
| + Value* subval;
|
| + if (list->Get(i, &subval)) {
|
| + WriteValue(m, subval, recursion + 1);
|
| + } else {
|
| + NOTREACHED() << "ListValue::GetSize is a filthy liar.";
|
| + }
|
| + }
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
|
| +// object.
|
| +static bool ReadDictionaryValue(const Message* m, void** iter,
|
| + DictionaryValue* value, int recursion) {
|
| + int size;
|
| + if (!ReadParam(m, iter, &size))
|
| + return false;
|
| +
|
| + for (int i = 0; i < size; ++i) {
|
| + std::wstring key;
|
| + Value* subval;
|
| + if (!ReadParam(m, iter, &key) ||
|
| + !ReadValue(m, iter, &subval, recursion + 1))
|
| + return false;
|
| + value->Set(key, subval);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +// Helper for ReadValue that reads a ReadListValue into a pre-allocated
|
| +// object.
|
| +static bool ReadListValue(const Message* m, void** iter,
|
| + ListValue* value, int recursion) {
|
| + int size;
|
| + if (!ReadParam(m, iter, &size))
|
| + return false;
|
| +
|
| + for (int i = 0; i < size; ++i) {
|
| + Value* subval;
|
| + if (!ReadValue(m, iter, &subval, recursion + 1))
|
| + return false;
|
| + value->Set(i, subval);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +static bool ReadValue(const Message* m, void** iter, Value** value,
|
| + int recursion) {
|
| + if (recursion > kMaxRecursionDepth) {
|
| + LOG(WARNING) << "Max recursion depth hit in ReadValue.";
|
| + return false;
|
| + }
|
| +
|
| + int type;
|
| + if (!ReadParam(m, iter, &type))
|
| + return false;
|
| +
|
| + switch (type) {
|
| + case Value::TYPE_NULL:
|
| + *value = Value::CreateNullValue();
|
| + break;
|
| + case Value::TYPE_BOOLEAN: {
|
| + bool val;
|
| + if (!ReadParam(m, iter, &val))
|
| + return false;
|
| + *value = Value::CreateBooleanValue(val);
|
| + break;
|
| + }
|
| + case Value::TYPE_INTEGER: {
|
| + int val;
|
| + if (!ReadParam(m, iter, &val))
|
| + return false;
|
| + *value = Value::CreateIntegerValue(val);
|
| + break;
|
| + }
|
| + case Value::TYPE_REAL: {
|
| + double val;
|
| + if (!ReadParam(m, iter, &val))
|
| + return false;
|
| + *value = Value::CreateRealValue(val);
|
| + break;
|
| + }
|
| + case Value::TYPE_STRING: {
|
| + std::string val;
|
| + if (!ReadParam(m, iter, &val))
|
| + return false;
|
| + *value = Value::CreateStringValue(val);
|
| + break;
|
| + }
|
| + case Value::TYPE_BINARY: {
|
| + NOTREACHED() << "Don't send BinaryValues over IPC.";
|
| + break;
|
| + }
|
| + case Value::TYPE_DICTIONARY: {
|
| + scoped_ptr<DictionaryValue> val(new DictionaryValue());
|
| + if (!ReadDictionaryValue(m, iter, val.get(), recursion))
|
| + return false;
|
| + *value = val.release();
|
| + break;
|
| + }
|
| + case Value::TYPE_LIST: {
|
| + scoped_ptr<ListValue> val(new ListValue());
|
| + if (!ReadListValue(m, iter, val.get(), recursion))
|
| + return false;
|
| + *value = val.release();
|
| + break;
|
| + }
|
| + default:
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) {
|
| + WriteValue(m, &p, 0);
|
| +}
|
| +
|
| +bool ParamTraits<DictionaryValue>::Read(
|
| + const Message* m, void** iter, param_type* r) {
|
| + int type;
|
| + if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY)
|
| + return false;
|
| +
|
| + return ReadDictionaryValue(m, iter, r, 0);
|
| +}
|
| +
|
| +void ParamTraits<DictionaryValue>::Log(const param_type& p, std::wstring* l) {
|
| + std::string json;
|
| + JSONWriter::Write(&p, false, &json);
|
| + l->append(UTF8ToWide(json));
|
| +}
|
| +
|
| +void ParamTraits<ListValue>::Write(Message* m, const param_type& p) {
|
| + WriteValue(m, &p, 0);
|
| +}
|
| +
|
| +bool ParamTraits<ListValue>::Read(
|
| + const Message* m, void** iter, param_type* r) {
|
| + int type;
|
| + if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST)
|
| + return false;
|
| +
|
| + return ReadListValue(m, iter, r, 0);
|
| +}
|
| +
|
| +void ParamTraits<ListValue>::Log(const param_type& p, std::wstring* l) {
|
| + std::string json;
|
| + JSONWriter::Write(&p, false, &json);
|
| + l->append(UTF8ToWide(json));
|
| +}
|
| +} // namespace IPC
|
|
|