diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-04 21:18:25 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-04 21:18:25 +0000 |
commit | bf5aedf0248412f07fb2b610d810ea610eeb3cd2 (patch) | |
tree | 765acf8c10fd1e1ce62b6e44d96a5b728372fcbd /ipc | |
parent | 8408f82d28750bbe349120ac6e108284d4ea081d (diff) | |
download | chromium_src-bf5aedf0248412f07fb2b610d810ea610eeb3cd2.zip chromium_src-bf5aedf0248412f07fb2b610d810ea610eeb3cd2.tar.gz chromium_src-bf5aedf0248412f07fb2b610d810ea610eeb3cd2.tar.bz2 |
This groups the ParamTraits into different categories and orders the .cc file the same. It makes all non-trivial Read/Write calls non-inline.
TEST=it compiles
BUG=none
Review URL: https://chromiumcodereview.appspot.com/10498002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140375 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_message_utils.cc | 549 | ||||
-rw-r--r-- | ipc/ipc_message_utils.h | 545 |
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_ |