summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/ipc_message_utils.cc549
-rw-r--r--ipc/ipc_message_utils.h545
2 files changed, 587 insertions, 507 deletions
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index 3caf2a4..a8392cf 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -12,21 +12,45 @@
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
+#include "ipc/ipc_channel_handle.h"
+
#if defined(OS_POSIX)
#include "ipc/file_descriptor_set_posix.h"
#endif
-#include "ipc/ipc_channel_handle.h"
namespace IPC {
+namespace {
+
const int kMaxRecursionDepth = 100;
-// Value serialization
+template<typename CharType>
+void LogBytes(const std::vector<CharType>& data, std::string* out) {
+#if defined(OS_WIN)
+ // Windows has a GUI for logging, which can handle arbitrary binary data.
+ for (size_t i = 0; i < data.size(); ++i)
+ out->push_back(data[i]);
+#else
+ // On POSIX, we log to stdout, which we assume can display ASCII.
+ static const size_t kMaxBytesToLog = 100;
+ for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
+ if (isprint(data[i]))
+ out->push_back(data[i]);
+ else
+ out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
+ }
+ if (data.size() > kMaxBytesToLog) {
+ out->append(
+ StringPrintf(" and %u more bytes",
+ static_cast<unsigned>(data.size() - kMaxBytesToLog)));
+ }
+#endif
+}
-static bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
- int recursion);
+bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
+ int recursion);
-static void WriteValue(Message* m, const Value* value, int recursion) {
+void WriteValue(Message* m, const Value* value, int recursion) {
if (recursion > kMaxRecursionDepth) {
LOG(WARNING) << "Max recursion depth hit in WriteValue.";
return;
@@ -102,8 +126,8 @@ static void WriteValue(Message* m, const Value* value, int recursion) {
// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
// object.
-static bool ReadDictionaryValue(const Message* m, PickleIterator* iter,
- DictionaryValue* value, int recursion) {
+bool ReadDictionaryValue(const Message* m, PickleIterator* iter,
+ DictionaryValue* value, int recursion) {
int size;
if (!ReadParam(m, iter, &size))
return false;
@@ -122,8 +146,8 @@ static bool ReadDictionaryValue(const Message* m, PickleIterator* iter,
// Helper for ReadValue that reads a ReadListValue into a pre-allocated
// object.
-static bool ReadListValue(const Message* m, PickleIterator* iter,
- ListValue* value, int recursion) {
+bool ReadListValue(const Message* m, PickleIterator* iter,
+ ListValue* value, int recursion) {
int size;
if (!ReadParam(m, iter, &size))
return false;
@@ -138,8 +162,8 @@ static bool ReadListValue(const Message* m, PickleIterator* iter,
return true;
}
-static bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
- int recursion) {
+bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
+ int recursion) {
if (recursion > kMaxRecursionDepth) {
LOG(WARNING) << "Max recursion depth hit in ReadValue.";
return false;
@@ -210,6 +234,42 @@ static bool ReadValue(const Message* m, PickleIterator* iter, Value** value,
return true;
}
+} // namespace
+
+// -----------------------------------------------------------------------------
+
+LogData::LogData()
+ : routing_id(0),
+ type(0),
+ sent(0),
+ receive(0),
+ dispatch(0) {
+}
+
+LogData::~LogData() {
+}
+
+MessageIterator::MessageIterator(const Message& m) : iter_(m) {
+}
+
+int MessageIterator::NextInt() const {
+ int val = -1;
+ if (!iter_.ReadInt(&val))
+ NOTREACHED();
+ return val;
+}
+
+const std::string MessageIterator::NextString() const {
+ std::string val;
+ if (!iter_.ReadString(&val))
+ NOTREACHED();
+ return val;
+}
+
+void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
+ l->append(p ? "true" : "false");
+}
+
void ParamTraits<int>::Log(const param_type& p, std::string* l) {
l->append(base::IntToString(p));
}
@@ -251,102 +311,145 @@ void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
l->append(base::UintToString(p));
}
-void ParamTraits<base::PlatformFileInfo>::Write(
- Message* m, const param_type& p) {
- WriteParam(m, p.size);
- WriteParam(m, p.is_directory);
- WriteParam(m, p.last_modified.ToDoubleT());
- WriteParam(m, p.last_accessed.ToDoubleT());
- WriteParam(m, p.creation_time.ToDoubleT());
+void ParamTraits<float>::Write(Message* m, const param_type& p) {
+ m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
}
-bool ParamTraits<base::PlatformFileInfo>::Read(
- const Message* m, PickleIterator* iter, param_type* p) {
- double last_modified;
- double last_accessed;
- double creation_time;
- bool result =
- ReadParam(m, iter, &p->size) &&
- ReadParam(m, iter, &p->is_directory) &&
- ReadParam(m, iter, &last_modified) &&
- ReadParam(m, iter, &last_accessed) &&
- ReadParam(m, iter, &creation_time);
- if (result) {
- p->last_modified = base::Time::FromDoubleT(last_modified);
- p->last_accessed = base::Time::FromDoubleT(last_accessed);
- p->creation_time = base::Time::FromDoubleT(creation_time);
+bool ParamTraits<float>::Read(const Message* m, PickleIterator* iter,
+ param_type* r) {
+ const char *data;
+ int data_size;
+ if (!m->ReadData(iter, &data, &data_size) ||
+ data_size != sizeof(param_type)) {
+ NOTREACHED();
+ return false;
}
- return result;
+ memcpy(r, data, sizeof(param_type));
+ return true;
}
-void ParamTraits<base::PlatformFileInfo>::Log(
- const param_type& p, std::string* l) {
- l->append("(");
- LogParam(p.size, l);
- l->append(",");
- LogParam(p.is_directory, l);
- l->append(",");
- LogParam(p.last_modified.ToDoubleT(), l);
- l->append(",");
- LogParam(p.last_accessed.ToDoubleT(), l);
- l->append(",");
- LogParam(p.creation_time.ToDoubleT(), l);
- l->append(")");
+void ParamTraits<float>::Log(const param_type& p, std::string* l) {
+ l->append(StringPrintf("%e", p));
}
-void ParamTraits<base::Time>::Write(Message* m, const param_type& p) {
- ParamTraits<int64>::Write(m, p.ToInternalValue());
+void ParamTraits<double>::Write(Message* m, const param_type& p) {
+ m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
}
-bool ParamTraits<base::Time>::Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- int64 value;
- if (!ParamTraits<int64>::Read(m, iter, &value))
+bool ParamTraits<double>::Read(const Message* m, PickleIterator* iter,
+ param_type* r) {
+ const char *data;
+ int data_size;
+ if (!m->ReadData(iter, &data, &data_size) ||
+ data_size != sizeof(param_type)) {
+ NOTREACHED();
return false;
- *r = base::Time::FromInternalValue(value);
+ }
+ memcpy(r, data, sizeof(param_type));
return true;
}
-void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
- ParamTraits<int64>::Log(p.ToInternalValue(), l);
+void ParamTraits<double>::Log(const param_type& p, std::string* l) {
+ l->append(StringPrintf("%e", p));
}
-void ParamTraits<base::TimeDelta> ::Write(Message* m, const param_type& p) {
- ParamTraits<int64> ::Write(m, p.ToInternalValue());
+
+void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
+ l->append(p);
}
-bool ParamTraits<base::TimeDelta> ::Read(const Message* m,
- PickleIterator* iter,
- param_type* r) {
- int64 value;
- bool ret = ParamTraits<int64> ::Read(m, iter, &value);
- if (ret)
- *r = base::TimeDelta::FromInternalValue(value);
+void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
+ l->append(WideToUTF8(p));
+}
- return ret;
+#if !defined(WCHAR_T_IS_UTF16)
+void ParamTraits<string16>::Log(const param_type& p, std::string* l) {
+ l->append(UTF16ToUTF8(p));
}
+#endif
-void ParamTraits<base::TimeDelta> ::Log(const param_type& p, std::string* l) {
- ParamTraits<int64> ::Log(p.ToInternalValue(), l);
+void ParamTraits<std::vector<char> >::Write(Message* m, const param_type& p) {
+ if (p.empty()) {
+ m->WriteData(NULL, 0);
+ } else {
+ m->WriteData(&p.front(), static_cast<int>(p.size()));
+ }
}
-void ParamTraits<base::TimeTicks> ::Write(Message* m, const param_type& p) {
- ParamTraits<int64> ::Write(m, p.ToInternalValue());
+bool ParamTraits<std::vector<char> >::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ const char *data;
+ int data_size = 0;
+ if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
+ return false;
+ r->resize(data_size);
+ if (data_size)
+ memcpy(&r->front(), data, data_size);
+ return true;
}
-bool ParamTraits<base::TimeTicks> ::Read(const Message* m,
- PickleIterator* iter,
- param_type* r) {
- int64 value;
- bool ret = ParamTraits<int64> ::Read(m, iter, &value);
- if (ret)
- *r = base::TimeTicks::FromInternalValue(value);
+void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
+ LogBytes(p, l);
+}
- return ret;
+void ParamTraits<std::vector<unsigned char> >::Write(Message* m,
+ const param_type& p) {
+ if (p.empty()) {
+ m->WriteData(NULL, 0);
+ } else {
+ m->WriteData(reinterpret_cast<const char*>(&p.front()),
+ static_cast<int>(p.size()));
+ }
+}
+
+bool ParamTraits<std::vector<unsigned char> >::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ const char *data;
+ int data_size = 0;
+ if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
+ return false;
+ r->resize(data_size);
+ if (data_size)
+ memcpy(&r->front(), data, data_size);
+ return true;
}
-void ParamTraits<base::TimeTicks> ::Log(const param_type& p, std::string* l) {
- ParamTraits<int64> ::Log(p.ToInternalValue(), l);
+void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
+ std::string* l) {
+ LogBytes(p, l);
+}
+
+void ParamTraits<std::vector<bool> >::Write(Message* m, const param_type& p) {
+ WriteParam(m, static_cast<int>(p.size()));
+ for (size_t i = 0; i < p.size(); i++)
+ WriteParam(m, p[i]);
+}
+
+bool ParamTraits<std::vector<bool> >::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ int size;
+ // ReadLength() checks for < 0 itself.
+ if (!m->ReadLength(iter, &size))
+ return false;
+ r->resize(size);
+ for (int i = 0; i < size; i++) {
+ bool value;
+ if (!ReadParam(m, iter, &value))
+ return false;
+ (*r)[i] = value;
+ }
+ return true;
+}
+
+void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
+ for (size_t i = 0; i < p.size(); ++i) {
+ if (i != 0)
+ l->push_back(' ');
+ LogParam((p[i]), l);
+ }
}
void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) {
@@ -368,6 +471,61 @@ void ParamTraits<DictionaryValue>::Log(const param_type& p, std::string* l) {
l->append(json);
}
+#if defined(OS_POSIX)
+void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) {
+ const bool valid = p.fd >= 0;
+ WriteParam(m, valid);
+
+ if (valid) {
+ if (!m->WriteFileDescriptor(p))
+ NOTREACHED();
+ }
+}
+
+bool ParamTraits<base::FileDescriptor>::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ bool valid;
+ if (!ReadParam(m, iter, &valid))
+ return false;
+
+ if (!valid) {
+ r->fd = -1;
+ r->auto_close = false;
+ return true;
+ }
+
+ return m->ReadFileDescriptor(iter, r);
+}
+
+void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
+ std::string* l) {
+ if (p.auto_close) {
+ l->append(StringPrintf("FD(%d auto-close)", p.fd));
+ } else {
+ l->append(StringPrintf("FD(%d)", p.fd));
+ }
+}
+#endif // defined(OS_POSIX)
+
+void ParamTraits<FilePath>::Write(Message* m, const param_type& p) {
+ ParamTraits<FilePath::StringType>::Write(m, p.value());
+}
+
+bool ParamTraits<FilePath>::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ FilePath::StringType value;
+ if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
+ return false;
+ *r = FilePath(value);
+ return true;
+}
+
+void ParamTraits<FilePath>::Log(const param_type& p, std::string* l) {
+ ParamTraits<FilePath::StringType>::Log(p.value(), l);
+}
+
void ParamTraits<ListValue>::Write(Message* m, const param_type& p) {
WriteValue(m, &p, 0);
}
@@ -387,10 +545,6 @@ void ParamTraits<ListValue>::Log(const param_type& p, std::string* l) {
l->append(json);
}
-void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
- l->append(WideToUTF8(p));
-}
-
void ParamTraits<NullableString16>::Write(Message* m, const param_type& p) {
WriteParam(m, p.string());
WriteParam(m, p.is_null());
@@ -416,67 +570,104 @@ void ParamTraits<NullableString16>::Log(const param_type& p, std::string* l) {
l->append(")");
}
-#if !defined(WCHAR_T_IS_UTF16)
-void ParamTraits<string16>::Log(const param_type& p, std::string* l) {
- l->append(UTF16ToUTF8(p));
+void ParamTraits<base::PlatformFileInfo>::Write(Message* m,
+ const param_type& p) {
+ WriteParam(m, p.size);
+ WriteParam(m, p.is_directory);
+ WriteParam(m, p.last_modified.ToDoubleT());
+ WriteParam(m, p.last_accessed.ToDoubleT());
+ WriteParam(m, p.creation_time.ToDoubleT());
}
-#endif
+bool ParamTraits<base::PlatformFileInfo>::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* p) {
+ double last_modified;
+ double last_accessed;
+ double creation_time;
+ bool result =
+ ReadParam(m, iter, &p->size) &&
+ ReadParam(m, iter, &p->is_directory) &&
+ ReadParam(m, iter, &last_modified) &&
+ ReadParam(m, iter, &last_accessed) &&
+ ReadParam(m, iter, &creation_time);
+ if (result) {
+ p->last_modified = base::Time::FromDoubleT(last_modified);
+ p->last_accessed = base::Time::FromDoubleT(last_accessed);
+ p->creation_time = base::Time::FromDoubleT(creation_time);
+ }
+ return result;
+}
-void ParamTraits<FilePath>::Write(Message* m, const param_type& p) {
- ParamTraits<FilePath::StringType>::Write(m, p.value());
+void ParamTraits<base::PlatformFileInfo>::Log(const param_type& p,
+ std::string* l) {
+ l->append("(");
+ LogParam(p.size, l);
+ l->append(",");
+ LogParam(p.is_directory, l);
+ l->append(",");
+ LogParam(p.last_modified.ToDoubleT(), l);
+ l->append(",");
+ LogParam(p.last_accessed.ToDoubleT(), l);
+ l->append(",");
+ LogParam(p.creation_time.ToDoubleT(), l);
+ l->append(")");
}
-bool ParamTraits<FilePath>::Read(const Message* m,
- PickleIterator* iter,
- param_type* r) {
- FilePath::StringType value;
- if (!ParamTraits<FilePath::StringType>::Read(m, iter, &value))
+void ParamTraits<base::Time>::Write(Message* m, const param_type& p) {
+ ParamTraits<int64>::Write(m, p.ToInternalValue());
+}
+
+bool ParamTraits<base::Time>::Read(const Message* m, PickleIterator* iter,
+ param_type* r) {
+ int64 value;
+ if (!ParamTraits<int64>::Read(m, iter, &value))
return false;
- *r = FilePath(value);
+ *r = base::Time::FromInternalValue(value);
return true;
}
-void ParamTraits<FilePath>::Log(const param_type& p, std::string* l) {
- ParamTraits<FilePath::StringType>::Log(p.value(), l);
+void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
+ ParamTraits<int64>::Log(p.ToInternalValue(), l);
}
-#if defined(OS_POSIX)
-void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) {
- const bool valid = p.fd >= 0;
- WriteParam(m, valid);
+void ParamTraits<base::TimeDelta>::Write(Message* m, const param_type& p) {
+ ParamTraits<int64>::Write(m, p.ToInternalValue());
+}
- if (valid) {
- if (!m->WriteFileDescriptor(p))
- NOTREACHED();
- }
+bool ParamTraits<base::TimeDelta>::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ int64 value;
+ bool ret = ParamTraits<int64>::Read(m, iter, &value);
+ if (ret)
+ *r = base::TimeDelta::FromInternalValue(value);
+
+ return ret;
}
-bool ParamTraits<base::FileDescriptor>::Read(const Message* m,
- PickleIterator* iter,
- param_type* r) {
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
+void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
+ ParamTraits<int64>::Log(p.ToInternalValue(), l);
+}
- if (!valid) {
- r->fd = -1;
- r->auto_close = false;
- return true;
- }
+void ParamTraits<base::TimeTicks>::Write(Message* m, const param_type& p) {
+ ParamTraits<int64>::Write(m, p.ToInternalValue());
+}
- return m->ReadFileDescriptor(iter, r);
+bool ParamTraits<base::TimeTicks>::Read(const Message* m,
+ PickleIterator* iter,
+ param_type* r) {
+ int64 value;
+ bool ret = ParamTraits<int64>::Read(m, iter, &value);
+ if (ret)
+ *r = base::TimeTicks::FromInternalValue(value);
+
+ return ret;
}
-void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
- std::string* l) {
- if (p.auto_close) {
- l->append(StringPrintf("FD(%d auto-close)", p.fd));
- } else {
- l->append(StringPrintf("FD(%d)", p.fd));
- }
+void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
+ ParamTraits<int64>::Log(p.ToInternalValue(), l);
}
-#endif // defined(OS_POSIX)
void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) {
#if defined(OS_WIN)
@@ -509,17 +700,6 @@ void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
l->append(")");
}
-LogData::LogData()
- : routing_id(0),
- type(0),
- sent(0),
- receive(0),
- dispatch(0) {
-}
-
-LogData::~LogData() {
-}
-
void ParamTraits<LogData>::Write(Message* m, const param_type& p) {
WriteParam(m, p.channel);
WriteParam(m, p.routing_id);
@@ -545,4 +725,99 @@ bool ParamTraits<LogData>::Read(const Message* m,
ReadParam(m, iter, &r->params);
}
+void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
+ // Doesn't make sense to implement this!
+}
+
+void ParamTraits<Message>::Write(Message* m, const Message& p) {
+ DCHECK(p.size() <= INT_MAX);
+ int message_size = static_cast<int>(p.size());
+ m->WriteInt(message_size);
+ m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
+}
+
+bool ParamTraits<Message>::Read(const Message* m, PickleIterator* iter,
+ Message* r) {
+ int size;
+ if (!m->ReadInt(iter, &size))
+ return false;
+ const char* data;
+ if (!m->ReadData(iter, &data, &size))
+ return false;
+ *r = Message(data, size);
+ return true;
+}
+
+void ParamTraits<Message>::Log(const Message& p, std::string* l) {
+ l->append("<IPC::Message>");
+}
+
+#if defined(OS_WIN)
+// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
+// bit systems.
+void ParamTraits<HANDLE>::Write(Message* m, const param_type& p) {
+ m->WriteUInt32(reinterpret_cast<uint32>(p));
+}
+
+bool ParamTraits<HANDLE>::Read(const Message* m, PickleIterator* iter,
+ param_type* r) {
+ uint32 temp;
+ if (!m->ReadUInt32(iter, &temp))
+ return false;
+ *r = reinterpret_cast<HANDLE>(temp);
+ return true;
+}
+
+void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
+ l->append(StringPrintf("0x%X", p));
+}
+
+void ParamTraits<LOGFONT>::Write(Message* m, const param_type& p) {
+ m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
+}
+
+bool ParamTraits<LOGFONT>::Read(const Message* m, PickleIterator* iter,
+ param_type* r) {
+ const char *data;
+ int data_size = 0;
+ bool result = m->ReadData(iter, &data, &data_size);
+ if (result && data_size == sizeof(LOGFONT)) {
+ memcpy(r, data, sizeof(LOGFONT));
+ } else {
+ result = false;
+ NOTREACHED();
+ }
+
+ return result;
+}
+
+void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
+ l->append(StringPrintf("<LOGFONT>"));
+}
+
+void ParamTraits<MSG>::Write(Message* m, const param_type& p) {
+ m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
+}
+
+bool ParamTraits<MSG>::Read(const Message* m, PickleIterator* iter,
+ param_type* r) {
+ const char *data;
+ int data_size = 0;
+ bool result = m->ReadData(iter, &data, &data_size);
+ if (result && data_size == sizeof(MSG)) {
+ memcpy(r, data, sizeof(MSG));
+ } else {
+ result = false;
+ NOTREACHED();
+ }
+
+ return result;
+}
+
+void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
+ l->append("<MSG>");
+}
+
+#endif // OS_WIN
+
} // namespace IPC
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index aad9049..1682e81 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -124,36 +124,43 @@ struct ChannelHandle;
//-----------------------------------------------------------------------------
// An iterator class for reading the fields contained within a Message.
-
-class MessageIterator {
+class IPC_EXPORT MessageIterator {
public:
- explicit MessageIterator(const Message& m) : iter_(m) {
- }
- int NextInt() const {
- int val = -1;
- if (!iter_.ReadInt(&val))
- NOTREACHED();
- return val;
- }
- const std::string NextString() const {
- std::string val;
- if (!iter_.ReadString(&val))
- NOTREACHED();
- return val;
- }
+ explicit MessageIterator(const Message& m);
+
+ int NextInt() const;
+ const std::string NextString() const;
+
private:
mutable PickleIterator iter_;
};
+// -----------------------------------------------------------------------------
+// How we send IPC message logs across channels.
+struct IPC_EXPORT LogData {
+ LogData();
+ ~LogData();
+
+ std::string channel;
+ int32 routing_id;
+ uint32 type; // "User-defined" message type, from ipc_message.h.
+ std::string flags;
+ int64 sent; // Time that the message was sent (i.e. at Send()).
+ int64 receive; // Time before it was dispatched (i.e. before calling
+ // OnMessageReceived).
+ int64 dispatch; // Time after it was dispatched (i.e. after calling
+ // OnMessageReceived).
+ std::string message_name;
+ std::string params;
+};
+
+
//-----------------------------------------------------------------------------
// A dummy struct to place first just to allow leading commas for all
// members in the macro-generated constructor initializer lists.
struct NoParams {
};
-//-----------------------------------------------------------------------------
-// ParamTraits specializations, etc.
-
template <class P>
static inline void WriteParam(Message* m, const P& p) {
typedef typename SimilarTypeTraits<P>::Type Type;
@@ -174,19 +181,18 @@ static inline void LogParam(const P& p, std::string* l) {
ParamTraits<Type>::Log(static_cast<const Type& >(p), l);
}
+// Primitive ParamTraits -------------------------------------------------------
+
template <>
struct ParamTraits<bool> {
typedef bool param_type;
static void Write(Message* m, const param_type& p) {
m->WriteBool(p);
}
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
return m->ReadBool(iter, r);
}
- static void Log(const param_type& p, std::string* l) {
- l->append(p ? "true" : "false");
- }
+ IPC_EXPORT static void Log(const param_type& p, std::string* l);
};
template <>
@@ -195,8 +201,7 @@ struct ParamTraits<int> {
static void Write(Message* m, const param_type& p) {
m->WriteInt(p);
}
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
return m->ReadInt(iter, r);
}
IPC_EXPORT static void Log(const param_type& p, std::string* l);
@@ -208,8 +213,7 @@ struct ParamTraits<unsigned int> {
static void Write(Message* m, const param_type& p) {
m->WriteInt(p);
}
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
return m->ReadInt(iter, reinterpret_cast<int*>(r));
}
IPC_EXPORT static void Log(const param_type& p, std::string* l);
@@ -221,8 +225,7 @@ struct ParamTraits<long> {
static void Write(Message* m, const param_type& p) {
m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
}
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
return m->ReadLong(iter, r);
}
IPC_EXPORT static void Log(const param_type& p, std::string* l);
@@ -234,8 +237,7 @@ struct ParamTraits<unsigned long> {
static void Write(Message* m, const param_type& p) {
m->WriteLongUsingDangerousNonPortableLessPersistableForm(p);
}
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
return m->ReadLong(iter, reinterpret_cast<long*>(r));
}
IPC_EXPORT static void Log(const param_type& p, std::string* l);
@@ -279,277 +281,88 @@ struct IPC_EXPORT ParamTraits<unsigned short> {
// should be sure to check the sanity of these values after receiving them over
// IPC.
template <>
-struct ParamTraits<float> {
+struct IPC_EXPORT ParamTraits<float> {
typedef float param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- const char *data;
- int data_size;
- if (!m->ReadData(iter, &data, &data_size) ||
- data_size != sizeof(param_type)) {
- NOTREACHED();
- return false;
- }
- memcpy(r, data, sizeof(param_type));
- return true;
- }
- static void Log(const param_type& p, std::string* l) {
- l->append(StringPrintf("%e", p));
- }
-};
-
-template <>
-struct ParamTraits<double> {
- typedef double param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(param_type));
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- const char *data;
- int data_size;
- if (!m->ReadData(iter, &data, &data_size) ||
- data_size != sizeof(param_type)) {
- NOTREACHED();
- return false;
- }
- memcpy(r, data, sizeof(param_type));
- return true;
- }
- static void Log(const param_type& p, std::string* l) {
- l->append(StringPrintf("%e", p));
- }
-};
-
-template <>
-struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> {
- typedef base::PlatformFileInfo param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, PickleIterator* iter, param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct SimilarTypeTraits<base::PlatformFileError> {
- typedef int Type;
-};
-
-template <>
-struct IPC_EXPORT ParamTraits<base::Time> {
- typedef base::Time param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, PickleIterator* iter, param_type* r);
static void Log(const param_type& p, std::string* l);
};
template <>
-struct IPC_EXPORT ParamTraits<base::TimeDelta> {
- typedef base::TimeDelta param_type;
+struct IPC_EXPORT ParamTraits<double> {
+ typedef double param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, PickleIterator* iter, param_type* r);
static void Log(const param_type& p, std::string* l);
};
-template <>
-struct IPC_EXPORT ParamTraits<base::TimeTicks> {
- typedef base::TimeTicks param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, PickleIterator* iter, param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
+// STL ParamTraits -------------------------------------------------------------
-#if defined(OS_WIN)
template <>
-struct ParamTraits<LOGFONT> {
- typedef LOGFONT param_type;
+struct ParamTraits<std::string> {
+ typedef std::string param_type;
static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
+ m->WriteString(p);
}
static bool Read(const Message* m, PickleIterator* iter,
param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(LOGFONT)) {
- memcpy(r, data, sizeof(LOGFONT));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
- static void Log(const param_type& p, std::string* l) {
- l->append(StringPrintf("<LOGFONT>"));
+ return m->ReadString(iter, r);
}
+ IPC_EXPORT static void Log(const param_type& p, std::string* l);
};
template <>
-struct ParamTraits<MSG> {
- typedef MSG param_type;
+struct ParamTraits<std::wstring> {
+ typedef std::wstring param_type;
static void Write(Message* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
+ m->WriteWString(p);
}
static bool Read(const Message* m, PickleIterator* iter,
param_type* r) {
- const char *data;
- int data_size = 0;
- bool result = m->ReadData(iter, &data, &data_size);
- if (result && data_size == sizeof(MSG)) {
- memcpy(r, data, sizeof(MSG));
- } else {
- result = false;
- NOTREACHED();
- }
-
- return result;
- }
- static void Log(const param_type& p, std::string* l) {
- l->append("<MSG>");
+ return m->ReadWString(iter, r);
}
-};
-#endif // defined(OS_WIN)
-
-template <>
-struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
- typedef base::DictionaryValue param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, PickleIterator* iter, param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-template <>
-struct IPC_EXPORT ParamTraits<base::ListValue> {
- typedef base::ListValue param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, PickleIterator* iter, param_type* r);
- static void Log(const param_type& p, std::string* l);
+ IPC_EXPORT static void Log(const param_type& p, std::string* l);
};
+// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
+// need this trait.
+#if !defined(WCHAR_T_IS_UTF16)
template <>
-struct ParamTraits<std::string> {
- typedef std::string param_type;
+struct ParamTraits<string16> {
+ typedef string16 param_type;
static void Write(Message* m, const param_type& p) {
- m->WriteString(p);
+ m->WriteString16(p);
}
static bool Read(const Message* m, PickleIterator* iter,
param_type* r) {
- return m->ReadString(iter, r);
- }
- static void Log(const param_type& p, std::string* l) {
- l->append(p);
+ return m->ReadString16(iter, r);
}
+ IPC_EXPORT static void Log(const param_type& p, std::string* l);
};
-
-template<typename CharType>
-static void LogBytes(const std::vector<CharType>& data, std::string* out) {
-#if defined(OS_WIN)
- // Windows has a GUI for logging, which can handle arbitrary binary data.
- for (size_t i = 0; i < data.size(); ++i)
- out->push_back(data[i]);
-#else
- // On POSIX, we log to stdout, which we assume can display ASCII.
- static const size_t kMaxBytesToLog = 100;
- for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
- if (isprint(data[i]))
- out->push_back(data[i]);
- else
- out->append(StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
- }
- if (data.size() > kMaxBytesToLog) {
- out->append(
- StringPrintf(" and %u more bytes",
- static_cast<unsigned>(data.size() - kMaxBytesToLog)));
- }
#endif
-}
template <>
-struct ParamTraits<std::vector<unsigned char> > {
- typedef std::vector<unsigned char> param_type;
- static void Write(Message* m, const param_type& p) {
- if (p.empty()) {
- m->WriteData(NULL, 0);
- } else {
- m->WriteData(reinterpret_cast<const char*>(&p.front()),
- static_cast<int>(p.size()));
- }
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- const char *data;
- int data_size = 0;
- if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
- return false;
- r->resize(data_size);
- if (data_size)
- memcpy(&r->front(), data, data_size);
- return true;
- }
- static void Log(const param_type& p, std::string* l) {
- LogBytes(p, l);
- }
+struct IPC_EXPORT ParamTraits<std::vector<char> > {
+ typedef std::vector<char> param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message*, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
};
template <>
-struct ParamTraits<std::vector<char> > {
- typedef std::vector<char> param_type;
- static void Write(Message* m, const param_type& p) {
- if (p.empty()) {
- m->WriteData(NULL, 0);
- } else {
- m->WriteData(&p.front(), static_cast<int>(p.size()));
- }
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- const char *data;
- int data_size = 0;
- if (!m->ReadData(iter, &data, &data_size) || data_size < 0)
- return false;
- r->resize(data_size);
- if (data_size)
- memcpy(&r->front(), data, data_size);
- return true;
- }
- static void Log(const param_type& p, std::string* l) {
- LogBytes(p, l);
- }
+struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > {
+ typedef std::vector<unsigned char> param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
};
template <>
-struct ParamTraits<std::vector<bool> > {
+struct IPC_EXPORT ParamTraits<std::vector<bool> > {
typedef std::vector<bool> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, static_cast<int>(p.size()));
- for (size_t i = 0; i < p.size(); i++)
- WriteParam(m, p[i]);
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- int size;
- // ReadLength() checks for < 0 itself.
- if (!m->ReadLength(iter, &size))
- return false;
- r->resize(size);
- for (int i = 0; i < size; i++) {
- bool value;
- if (!ReadParam(m, iter, &value))
- return false;
- (*r)[i] = value;
- }
- return true;
- }
- static void Log(const param_type& p, std::string* l) {
- for (size_t i = 0; i < p.size(); ++i) {
- if (i != 0)
- l->append(" ");
- LogParam((p[i]), l);
- }
- }
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
};
template <class P>
@@ -612,7 +425,6 @@ struct ParamTraits<std::set<P> > {
}
};
-
template <class K, class V>
struct ParamTraits<std::map<K, V> > {
typedef std::map<K, V> param_type;
@@ -644,20 +456,6 @@ struct ParamTraits<std::map<K, V> > {
}
};
-
-template <>
-struct ParamTraits<std::wstring> {
- typedef std::wstring param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteWString(p);
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- return m->ReadWString(iter, r);
- }
- IPC_EXPORT static void Log(const param_type& p, std::string* l);
-};
-
template <class A, class B>
struct ParamTraits<std::pair<A, B> > {
typedef std::pair<A, B> param_type;
@@ -678,59 +476,11 @@ struct ParamTraits<std::pair<A, B> > {
}
};
-template <>
-struct IPC_EXPORT ParamTraits<NullableString16> {
- typedef NullableString16 param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r);
- static void Log(const param_type& p, std::string* l);
-};
-
-// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
-// need this trait.
-#if !defined(WCHAR_T_IS_UTF16)
-template <>
-struct ParamTraits<string16> {
- typedef string16 param_type;
- static void Write(Message* m, const param_type& p) {
- m->WriteString16(p);
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- return m->ReadString16(iter, r);
- }
- IPC_EXPORT static void Log(const param_type& p, std::string* l);
-};
-#endif
-
-// and, a few more useful types...
-#if defined(OS_WIN)
-template <>
-struct ParamTraits<HANDLE> {
- typedef HANDLE param_type;
- // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
- // bit systems.
- static void Write(Message* m, const param_type& p) {
- m->WriteUInt32(reinterpret_cast<uint32>(p));
- }
- static bool Read(const Message* m, PickleIterator* iter,
- param_type* r) {
- uint32 temp;
- if (!m->ReadUInt32(iter, &temp))
- return false;
- *r = reinterpret_cast<HANDLE>(temp);
- return true;
- }
- static void Log(const param_type& p, std::string* l) {
- l->append(StringPrintf("0x%X", p));
- }
-};
-#endif // defined(OS_WIN)
+// Base ParamTraits ------------------------------------------------------------
template <>
-struct IPC_EXPORT ParamTraits<FilePath> {
- typedef FilePath param_type;
+struct IPC_EXPORT ParamTraits<base::DictionaryValue> {
+ typedef base::DictionaryValue param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, PickleIterator* iter, param_type* r);
static void Log(const param_type& p, std::string* l);
@@ -761,65 +511,66 @@ struct IPC_EXPORT ParamTraits<base::FileDescriptor> {
};
#endif // defined(OS_POSIX)
-// A ChannelHandle is basically a platform-inspecific wrapper around the
-// fact that IPC endpoints are handled specially on POSIX. See above comments
-// on FileDescriptor for more background.
-template<>
-struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
- typedef ChannelHandle param_type;
+template <>
+struct IPC_EXPORT ParamTraits<FilePath> {
+ typedef FilePath param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, PickleIterator* iter, param_type* r);
static void Log(const param_type& p, std::string* l);
};
-struct IPC_EXPORT LogData {
- LogData();
- ~LogData();
+template <>
+struct IPC_EXPORT ParamTraits<base::ListValue> {
+ typedef base::ListValue param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
- std::string channel;
- int32 routing_id;
- uint32 type; // "User-defined" message type, from ipc_message.h.
- std::string flags;
- int64 sent; // Time that the message was sent (i.e. at Send()).
- int64 receive; // Time before it was dispatched (i.e. before calling
- // OnMessageReceived).
- int64 dispatch; // Time after it was dispatched (i.e. after calling
- // OnMessageReceived).
- std::string message_name;
- std::string params;
+template <>
+struct IPC_EXPORT ParamTraits<NullableString16> {
+ typedef NullableString16 param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter,
+ param_type* r);
+ static void Log(const param_type& p, std::string* l);
};
template <>
-struct IPC_EXPORT ParamTraits<LogData> {
- typedef LogData param_type;
+struct IPC_EXPORT ParamTraits<base::PlatformFileInfo> {
+ typedef base::PlatformFileInfo param_type;
static void Write(Message* m, const param_type& p);
static bool Read(const Message* m, PickleIterator* iter, param_type* r);
- static void Log(const param_type& p, std::string* l) {
- // Doesn't make sense to implement this!
- }
+ static void Log(const param_type& p, std::string* l);
};
template <>
-struct ParamTraits<Message> {
- static void Write(Message* m, const Message& p) {
- DCHECK(p.size() <= INT_MAX);
- int message_size = static_cast<int>(p.size());
- m->WriteInt(message_size);
- m->WriteData(reinterpret_cast<const char*>(p.data()), message_size);
- }
- static bool Read(const Message* m, PickleIterator* iter, Message* r) {
- int size;
- if (!m->ReadInt(iter, &size))
- return false;
- const char* data;
- if (!m->ReadData(iter, &data, &size))
- return false;
- *r = Message(data, size);
- return true;
- }
- static void Log(const Message& p, std::string* l) {
- l->append("<IPC::Message>");
- }
+struct SimilarTypeTraits<base::PlatformFileError> {
+ typedef int Type;
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<base::Time> {
+ typedef base::Time param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<base::TimeDelta> {
+ typedef base::TimeDelta param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<base::TimeTicks> {
+ typedef base::TimeTicks param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
};
template <>
@@ -944,6 +695,62 @@ struct ParamTraits< Tuple5<A, B, C, D, E> > {
}
};
+// IPC types ParamTraits -------------------------------------------------------
+
+// A ChannelHandle is basically a platform-inspecific wrapper around the
+// fact that IPC endpoints are handled specially on POSIX. See above comments
+// on FileDescriptor for more background.
+template<>
+struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> {
+ typedef ChannelHandle param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<LogData> {
+ typedef LogData param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<Message> {
+ static void Write(Message* m, const Message& p);
+ static bool Read(const Message* m, PickleIterator* iter, Message* r);
+ static void Log(const Message& p, std::string* l);
+};
+
+// Windows ParamTraits ---------------------------------------------------------
+
+#if defined(OS_WIN)
+template <>
+struct IPC_EXPORT ParamTraits<HANDLE> {
+ typedef HANDLE param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<LOGFONT> {
+ typedef LOGFONT param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<MSG> {
+ typedef MSG param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, PickleIterator* iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+#endif // defined(OS_WIN)
+
//-----------------------------------------------------------------------------
// Generic message subclasses
@@ -1100,8 +907,6 @@ class SyncMessageSchema {
}
};
-//-----------------------------------------------------------------------------
-
} // namespace IPC
#endif // IPC_IPC_MESSAGE_UTILS_H_