From bf5aedf0248412f07fb2b610d810ea610eeb3cd2 Mon Sep 17 00:00:00 2001 From: "brettw@chromium.org" Date: Mon, 4 Jun 2012 21:18:25 +0000 Subject: 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 --- ipc/ipc_message_utils.h | 545 ++++++++++++++++-------------------------------- 1 file changed, 175 insertions(+), 370 deletions(-) (limited to 'ipc/ipc_message_utils.h') 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 static inline void WriteParam(Message* m, const P& p) { typedef typename SimilarTypeTraits

::Type Type; @@ -174,19 +181,18 @@ static inline void LogParam(const P& p, std::string* l) { ParamTraits::Log(static_cast(p), l); } +// Primitive ParamTraits ------------------------------------------------------- + template <> struct ParamTraits { 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 { 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 { 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(r)); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -221,8 +225,7 @@ struct ParamTraits { 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 { 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(r)); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -279,277 +281,88 @@ struct IPC_EXPORT ParamTraits { // should be sure to check the sanity of these values after receiving them over // IPC. template <> -struct ParamTraits { +struct IPC_EXPORT ParamTraits { typedef float param_type; - static void Write(Message* m, const param_type& p) { - m->WriteData(reinterpret_cast(&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 { - typedef double param_type; - static void Write(Message* m, const param_type& p) { - m->WriteData(reinterpret_cast(&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 { - 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 { - typedef int Type; -}; - -template <> -struct IPC_EXPORT ParamTraits { - 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 { - typedef base::TimeDelta param_type; +struct IPC_EXPORT ParamTraits { + 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 { - 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 { - typedef LOGFONT param_type; +struct ParamTraits { + typedef std::string param_type; static void Write(Message* m, const param_type& p) { - m->WriteData(reinterpret_cast(&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("")); + return m->ReadString(iter, r); } + IPC_EXPORT static void Log(const param_type& p, std::string* l); }; template <> -struct ParamTraits { - typedef MSG param_type; +struct ParamTraits { + typedef std::wstring param_type; static void Write(Message* m, const param_type& p) { - m->WriteData(reinterpret_cast(&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(""); + return m->ReadWString(iter, r); } -}; -#endif // defined(OS_WIN) - -template <> -struct IPC_EXPORT ParamTraits { - 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 { - 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 { - typedef std::string param_type; +struct ParamTraits { + 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 -static void LogBytes(const std::vector& 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(data[i]))); - } - if (data.size() > kMaxBytesToLog) { - out->append( - StringPrintf(" and %u more bytes", - static_cast(data.size() - kMaxBytesToLog))); - } #endif -} template <> -struct ParamTraits > { - typedef std::vector param_type; - static void Write(Message* m, const param_type& p) { - if (p.empty()) { - m->WriteData(NULL, 0); - } else { - m->WriteData(reinterpret_cast(&p.front()), - static_cast(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 > { + typedef std::vector 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 > { - typedef std::vector 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(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 > { + typedef std::vector 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 > { +struct IPC_EXPORT ParamTraits > { typedef std::vector param_type; - static void Write(Message* m, const param_type& p) { - WriteParam(m, static_cast(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 @@ -612,7 +425,6 @@ struct ParamTraits > { } }; - template struct ParamTraits > { typedef std::map param_type; @@ -644,20 +456,6 @@ struct ParamTraits > { } }; - -template <> -struct ParamTraits { - 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 struct ParamTraits > { typedef std::pair param_type; @@ -678,59 +476,11 @@ struct ParamTraits > { } }; -template <> -struct IPC_EXPORT ParamTraits { - 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 { - 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 { - 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(p)); - } - static bool Read(const Message* m, PickleIterator* iter, - param_type* r) { - uint32 temp; - if (!m->ReadUInt32(iter, &temp)) - return false; - *r = reinterpret_cast(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 { - typedef FilePath param_type; +struct IPC_EXPORT ParamTraits { + 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 { }; #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 { - typedef ChannelHandle param_type; +template <> +struct IPC_EXPORT ParamTraits { + 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 { + 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 { + 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 { - typedef LogData param_type; +struct IPC_EXPORT ParamTraits { + 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 { - static void Write(Message* m, const Message& p) { - DCHECK(p.size() <= INT_MAX); - int message_size = static_cast(p.size()); - m->WriteInt(message_size); - m->WriteData(reinterpret_cast(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(""); - } +struct SimilarTypeTraits { + typedef int Type; +}; + +template <> +struct IPC_EXPORT ParamTraits { + 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 { + 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 { + 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 > { } }; +// 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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_ -- cgit v1.1