diff options
author | rockot <rockot@chromium.org> | 2016-02-04 18:12:32 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-05 02:14:00 +0000 |
commit | 0457af10a70c2ecf0e0b11a54881fe129232b739 (patch) | |
tree | f6382c744d7c8269d3de3c1c4d8f35dc3d832dbf /ipc | |
parent | c469cac201cc21a97b38d7bf6b5e23cac14d814f (diff) | |
download | chromium_src-0457af10a70c2ecf0e0b11a54881fe129232b739.zip chromium_src-0457af10a70c2ecf0e0b11a54881fe129232b739.tar.gz chromium_src-0457af10a70c2ecf0e0b11a54881fe129232b739.tar.bz2 |
Add message sizing to basic IPC traits and struct macros.
BUG=577685
Review URL: https://codereview.chromium.org/1655333002
Cr-Commit-Position: refs/heads/master@{#373720}
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_message_macros.h | 5 | ||||
-rw-r--r-- | ipc/ipc_message_utils.cc | 168 | ||||
-rw-r--r-- | ipc/ipc_message_utils.h | 123 | ||||
-rw-r--r-- | ipc/ipc_message_utils_unittest.cc | 26 | ||||
-rw-r--r-- | ipc/param_traits_macros.h | 4 | ||||
-rw-r--r-- | ipc/param_traits_size_macros.h | 40 |
6 files changed, 366 insertions, 0 deletions
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h index 7365b6c..9e9b3e0 100644 --- a/ipc/ipc_message_macros.h +++ b/ipc/ipc_message_macros.h @@ -45,6 +45,11 @@ // // Generate destructors. // #include "ipc/struct_destructor_macros.h" // #include "path/to/YYY_message_generator.h" +// // Generate param traits size methods. +// #include "ipc/param_traits_size_macros.h" +// namespace IPC { +// #include "path/to/YYY_message_generator.h" +// } // namespace IPC // // Generate param traits write methods. // #include "ipc/param_traits_write_macros.h" // namespace IPC { diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc index 6c829c2..639cedd 100644 --- a/ipc/ipc_message_utils.cc +++ b/ipc/ipc_message_utils.cc @@ -72,6 +72,65 @@ bool ReadValue(const base::Pickle* m, base::Value** value, int recursion); +void GetValueSize(base::PickleSizer* sizer, + const base::Value* value, + int recursion) { + if (recursion > kMaxRecursionDepth) { + LOG(WARNING) << "Max recursion depth hit in GetValueSize."; + return; + } + + sizer->AddInt(); + switch (value->GetType()) { + case base::Value::TYPE_NULL: + break; + case base::Value::TYPE_BOOLEAN: + sizer->AddBool(); + break; + case base::Value::TYPE_INTEGER: + sizer->AddInt(); + break; + case base::Value::TYPE_DOUBLE: + sizer->AddDouble(); + break; + case base::Value::TYPE_STRING: { + const base::StringValue* result; + value->GetAsString(&result); + DCHECK(result); + GetParamSize(sizer, result->GetString()); + break; + } + case base::Value::TYPE_BINARY: { + const base::BinaryValue* binary = + static_cast<const base::BinaryValue*>(value); + sizer->AddData(static_cast<int>(binary->GetSize())); + break; + } + case base::Value::TYPE_DICTIONARY: { + sizer->AddInt(); + const base::DictionaryValue* dict = + static_cast<const base::DictionaryValue*>(value); + for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); + it.Advance()) { + GetParamSize(sizer, it.key()); + GetValueSize(sizer, &it.value(), recursion + 1); + } + break; + } + case base::Value::TYPE_LIST: { + sizer->AddInt(); + const base::ListValue* list = static_cast<const base::ListValue*>(value); + for (base::ListValue::const_iterator it = list->begin(); + it != list->end(); ++it) { + GetValueSize(sizer, *it, recursion + 1); + } + break; + } + default: + NOTREACHED() << "Invalid base::Value type."; + } +} + void WriteValue(base::Pickle* m, const base::Value* value, int recursion) { bool result; if (recursion > kMaxRecursionDepth) { @@ -278,6 +337,11 @@ void ParamTraits<bool>::Log(const param_type& p, std::string* l) { l->append(p ? "true" : "false"); } +void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddBytes(sizeof(param_type)); +} + void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) { m->WriteBytes(&p, sizeof(param_type)); } @@ -296,6 +360,11 @@ void ParamTraits<signed char>::Log(const param_type& p, std::string* l) { l->append(base::IntToString(p)); } +void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddBytes(sizeof(param_type)); +} + void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) { m->WriteBytes(&p, sizeof(param_type)); } @@ -314,6 +383,11 @@ void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) { l->append(base::UintToString(p)); } +void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddBytes(sizeof(param_type)); +} + void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) { m->WriteBytes(&p, sizeof(param_type)); } @@ -360,6 +434,11 @@ void ParamTraits<float>::Log(const param_type& p, std::string* l) { l->append(base::StringPrintf("%e", p)); } +void ParamTraits<double>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddBytes(sizeof(param_type)); +} + void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) { m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type)); } @@ -389,6 +468,11 @@ void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) { l->append(base::UTF16ToUTF8(p)); } +void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddData(static_cast<int>(p.size())); +} + void ParamTraits<std::vector<char>>::Write(base::Pickle* m, const param_type& p) { if (p.empty()) { @@ -415,6 +499,11 @@ void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) { LogBytes(p, l); } +void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddData(static_cast<int>(p.size())); +} + void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m, const param_type& p) { if (p.empty()) { @@ -443,6 +532,13 @@ void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p, LogBytes(p, l); } +void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + GetParamSize(sizer, static_cast<int>(p.size())); + for (size_t i = 0; i < p.size(); ++i) + GetParamSize(sizer, static_cast<bool>(p[i])); +} + void ParamTraits<std::vector<bool>>::Write(base::Pickle* m, const param_type& p) { WriteParam(m, static_cast<int>(p.size())); @@ -500,6 +596,11 @@ void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p, l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize)); } +void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + GetValueSize(sizer, &p, 0); +} + void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m, const param_type& p) { WriteValue(m, &p, 0); @@ -712,6 +813,11 @@ void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p, } #endif // defined(OS_MACOSX) && !defined(OS_IOS) +void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + p.GetSizeForPickle(sizer); +} + void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) { p.WriteToPickle(m); } @@ -726,6 +832,11 @@ void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) { ParamTraits<base::FilePath::StringType>::Log(p.value(), l); } +void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + GetValueSize(sizer, &p, 0); +} + void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) { WriteValue(m, &p, 0); } @@ -746,6 +857,12 @@ void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) { l->append(json); } +void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + GetParamSize(sizer, p.string()); + GetParamSize(sizer, p.is_null()); +} + void ParamTraits<base::NullableString16>::Write(base::Pickle* m, const param_type& p) { WriteParam(m, p.string()); @@ -774,6 +891,15 @@ void ParamTraits<base::NullableString16>::Log(const param_type& p, l->append(")"); } +void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + GetParamSize(sizer, p.size); + GetParamSize(sizer, p.is_directory); + GetParamSize(sizer, p.last_modified.ToDoubleT()); + GetParamSize(sizer, p.last_accessed.ToDoubleT()); + GetParamSize(sizer, p.creation_time.ToDoubleT()); +} + void ParamTraits<base::File::Info>::Write(base::Pickle* m, const param_type& p) { WriteParam(m, p.size); @@ -814,6 +940,11 @@ void ParamTraits<base::File::Info>::Log(const param_type& p, l->append(")"); } +void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddInt64(); +} + void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) { ParamTraits<int64_t>::Write(m, p.ToInternalValue()); } @@ -832,6 +963,11 @@ void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) { ParamTraits<int64_t>::Log(p.ToInternalValue(), l); } +void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddInt64(); +} + void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) { ParamTraits<int64_t>::Write(m, p.ToInternalValue()); } @@ -851,6 +987,11 @@ void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) { ParamTraits<int64_t>::Log(p.ToInternalValue(), l); } +void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddInt64(); +} + void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) { ParamTraits<int64_t>::Write(m, p.ToInternalValue()); } @@ -902,6 +1043,19 @@ void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p, l->append(")"); } +void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + GetParamSize(sizer, p.channel); + GetParamSize(sizer, p.routing_id); + GetParamSize(sizer, p.type); + GetParamSize(sizer, p.flags); + GetParamSize(sizer, p.sent); + GetParamSize(sizer, p.receive); + GetParamSize(sizer, p.dispatch); + GetParamSize(sizer, p.message_name); + GetParamSize(sizer, p.params); +} + void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) { WriteParam(m, p.channel); WriteParam(m, p.routing_id); @@ -979,6 +1133,11 @@ void ParamTraits<Message>::Log(const Message& p, std::string* l) { } #if defined(OS_WIN) +void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddInt(); +} + // Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64 // bit systems. That's why we use the Windows macros to convert to 32 bits. void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) { @@ -999,6 +1158,11 @@ void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) { l->append(base::StringPrintf("0x%p", p)); } +void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer, + const param_type& p) { + sizer->AddData(sizeof(LOGFONT)); +} + void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) { m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT)); } @@ -1024,6 +1188,10 @@ void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) { l->append(base::StringPrintf("<LOGFONT>")); } +void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddData(sizeof(MSG)); +} + void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) { m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG)); } diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index 5654e75..d8b6607 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h @@ -100,6 +100,12 @@ struct NoParams { }; template <class P> +static inline void GetParamSize(base::PickleSizer* sizer, const P& p) { + typedef typename SimilarTypeTraits<P>::Type Type; + ParamTraits<Type>::GetSize(sizer, static_cast<const Type&>(p)); +} + +template <class P> static inline void WriteParam(base::Pickle* m, const P& p) { typedef typename SimilarTypeTraits<P>::Type Type; ParamTraits<Type>::Write(m, static_cast<const Type& >(p)); @@ -124,6 +130,9 @@ static inline void LogParam(const P& p, std::string* l) { template <> struct ParamTraits<bool> { typedef bool param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddBool(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteBool(p); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -136,6 +145,7 @@ struct ParamTraits<bool> { template <> struct IPC_EXPORT ParamTraits<signed char> { typedef signed char param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -146,6 +156,7 @@ struct IPC_EXPORT ParamTraits<signed char> { template <> struct IPC_EXPORT ParamTraits<unsigned char> { typedef unsigned char param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -156,6 +167,7 @@ struct IPC_EXPORT ParamTraits<unsigned char> { template <> struct IPC_EXPORT ParamTraits<unsigned short> { typedef unsigned short param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -166,6 +178,9 @@ struct IPC_EXPORT ParamTraits<unsigned short> { template <> struct ParamTraits<int> { typedef int param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddInt(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -178,6 +193,9 @@ struct ParamTraits<int> { template <> struct ParamTraits<unsigned int> { typedef unsigned int param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddInt(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteInt(p); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -190,6 +208,9 @@ struct ParamTraits<unsigned int> { template <> struct ParamTraits<long> { typedef long param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddLongUsingDangerousNonPortableLessPersistableForm(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); } @@ -204,6 +225,9 @@ struct ParamTraits<long> { template <> struct ParamTraits<unsigned long> { typedef unsigned long param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddLongUsingDangerousNonPortableLessPersistableForm(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); } @@ -218,6 +242,9 @@ struct ParamTraits<unsigned long> { template <> struct ParamTraits<long long> { typedef long long param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddInt64(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteInt64(static_cast<int64_t>(p)); } @@ -232,6 +259,9 @@ struct ParamTraits<long long> { template <> struct ParamTraits<unsigned long long> { typedef unsigned long long param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddInt64(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteInt64(p); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -247,6 +277,9 @@ struct ParamTraits<unsigned long long> { template <> struct IPC_EXPORT ParamTraits<float> { typedef float param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddFloat(); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteFloat(p); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -259,6 +292,7 @@ struct IPC_EXPORT ParamTraits<float> { template <> struct IPC_EXPORT ParamTraits<double> { typedef double param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -271,6 +305,9 @@ struct IPC_EXPORT ParamTraits<double> { template <> struct ParamTraits<std::string> { typedef std::string param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddString(p); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteString(p); } static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -283,6 +320,9 @@ struct ParamTraits<std::string> { template <> struct ParamTraits<base::string16> { typedef base::string16 param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + sizer->AddString16(p); + } static void Write(base::Pickle* m, const param_type& p) { m->WriteString16(p); } @@ -297,6 +337,7 @@ struct ParamTraits<base::string16> { template <> struct IPC_EXPORT ParamTraits<std::vector<char> > { typedef std::vector<char> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle*, base::PickleIterator* iter, @@ -307,6 +348,7 @@ struct IPC_EXPORT ParamTraits<std::vector<char> > { template <> struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > { typedef std::vector<unsigned char> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -317,6 +359,7 @@ struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > { template <> struct IPC_EXPORT ParamTraits<std::vector<bool> > { typedef std::vector<bool> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -327,6 +370,11 @@ struct IPC_EXPORT ParamTraits<std::vector<bool> > { template <class P> struct ParamTraits<std::vector<P> > { typedef std::vector<P> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, static_cast<int>(p.size())); + for (size_t i = 0; i < p.size(); i++) + GetParamSize(sizer, p[i]); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, static_cast<int>(p.size())); for (size_t i = 0; i < p.size(); i++) @@ -361,6 +409,12 @@ struct ParamTraits<std::vector<P> > { template <class P> struct ParamTraits<std::set<P> > { typedef std::set<P> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, static_cast<int>(p.size())); + typename param_type::const_iterator iter; + for (iter = p.begin(); iter != p.end(); ++iter) + GetParamSize(sizer, *iter); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, static_cast<int>(p.size())); typename param_type::const_iterator iter; @@ -389,6 +443,14 @@ struct ParamTraits<std::set<P> > { template <class K, class V, class C, class A> struct ParamTraits<std::map<K, V, C, A> > { typedef std::map<K, V, C, A> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, static_cast<int>(p.size())); + typename param_type::const_iterator iter; + for (iter = p.begin(); iter != p.end(); ++iter) { + GetParamSize(sizer, iter->first); + GetParamSize(sizer, iter->second); + } + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, static_cast<int>(p.size())); typename param_type::const_iterator iter; @@ -421,6 +483,10 @@ struct ParamTraits<std::map<K, V, C, A> > { template <class A, class B> struct ParamTraits<std::pair<A, B> > { typedef std::pair<A, B> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, p.first); + GetParamSize(sizer, p.second); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, p.first); WriteParam(m, p.second); @@ -455,6 +521,7 @@ struct IPC_EXPORT ParamTraits<BrokerableAttachment::AttachmentId> { template <> struct IPC_EXPORT ParamTraits<base::DictionaryValue> { typedef base::DictionaryValue param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -504,6 +571,7 @@ struct IPC_EXPORT ParamTraits<base::SharedMemoryHandle> { template <> struct IPC_EXPORT ParamTraits<base::FilePath> { typedef base::FilePath param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -514,6 +582,7 @@ struct IPC_EXPORT ParamTraits<base::FilePath> { template <> struct IPC_EXPORT ParamTraits<base::ListValue> { typedef base::ListValue param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -524,6 +593,7 @@ struct IPC_EXPORT ParamTraits<base::ListValue> { template <> struct IPC_EXPORT ParamTraits<base::NullableString16> { typedef base::NullableString16 param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -534,6 +604,7 @@ struct IPC_EXPORT ParamTraits<base::NullableString16> { template <> struct IPC_EXPORT ParamTraits<base::File::Info> { typedef base::File::Info param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -556,6 +627,7 @@ struct SimilarTypeTraits<HWND> { template <> struct IPC_EXPORT ParamTraits<base::Time> { typedef base::Time param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -566,6 +638,7 @@ struct IPC_EXPORT ParamTraits<base::Time> { template <> struct IPC_EXPORT ParamTraits<base::TimeDelta> { typedef base::TimeDelta param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -576,6 +649,7 @@ struct IPC_EXPORT ParamTraits<base::TimeDelta> { template <> struct IPC_EXPORT ParamTraits<base::TimeTicks> { typedef base::TimeTicks param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -586,6 +660,7 @@ struct IPC_EXPORT ParamTraits<base::TimeTicks> { template <> struct ParamTraits<base::Tuple<>> { typedef base::Tuple<> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) {} static void Write(base::Pickle* m, const param_type& p) {} static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -599,6 +674,9 @@ struct ParamTraits<base::Tuple<>> { template <class A> struct ParamTraits<base::Tuple<A>> { typedef base::Tuple<A> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, base::get<0>(p)); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, base::get<0>(p)); } @@ -615,6 +693,10 @@ struct ParamTraits<base::Tuple<A>> { template <class A, class B> struct ParamTraits<base::Tuple<A, B>> { typedef base::Tuple<A, B> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, base::get<0>(p)); + GetParamSize(sizer, base::get<1>(p)); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, base::get<0>(p)); WriteParam(m, base::get<1>(p)); @@ -635,6 +717,11 @@ struct ParamTraits<base::Tuple<A, B>> { template <class A, class B, class C> struct ParamTraits<base::Tuple<A, B, C>> { typedef base::Tuple<A, B, C> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, base::get<0>(p)); + GetParamSize(sizer, base::get<1>(p)); + GetParamSize(sizer, base::get<2>(p)); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, base::get<0>(p)); WriteParam(m, base::get<1>(p)); @@ -659,6 +746,12 @@ struct ParamTraits<base::Tuple<A, B, C>> { template <class A, class B, class C, class D> struct ParamTraits<base::Tuple<A, B, C, D>> { typedef base::Tuple<A, B, C, D> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, base::get<0>(p)); + GetParamSize(sizer, base::get<1>(p)); + GetParamSize(sizer, base::get<2>(p)); + GetParamSize(sizer, base::get<3>(p)); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, base::get<0>(p)); WriteParam(m, base::get<1>(p)); @@ -687,6 +780,13 @@ struct ParamTraits<base::Tuple<A, B, C, D>> { template <class A, class B, class C, class D, class E> struct ParamTraits<base::Tuple<A, B, C, D, E>> { typedef base::Tuple<A, B, C, D, E> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, base::get<0>(p)); + GetParamSize(sizer, base::get<1>(p)); + GetParamSize(sizer, base::get<2>(p)); + GetParamSize(sizer, base::get<3>(p)); + GetParamSize(sizer, base::get<4>(p)); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, base::get<0>(p)); WriteParam(m, base::get<1>(p)); @@ -752,6 +852,11 @@ struct ParamTraits<ScopedVector<P> > { template <class P, size_t stack_capacity> struct ParamTraits<base::StackVector<P, stack_capacity> > { typedef base::StackVector<P, stack_capacity> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, static_cast<int>(p->size())); + for (size_t i = 0; i < p->size(); i++) + GetParamSize(sizer, p[i]); + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, static_cast<int>(p->size())); for (size_t i = 0; i < p->size(); i++) @@ -792,6 +897,14 @@ struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > { typedef base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> param_type; typedef typename param_type::key_type K; typedef typename param_type::data_type V; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + GetParamSize(sizer, static_cast<int>(p.size())); + typename param_type::const_iterator iter; + for (iter = p.begin(); iter != p.end(); ++iter) { + GetParamSize(sizer, iter->first); + GetParamSize(sizer, iter->second); + } + } static void Write(base::Pickle* m, const param_type& p) { WriteParam(m, static_cast<int>(p.size())); typename param_type::const_iterator iter; @@ -824,6 +937,12 @@ struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > { template <class P> struct ParamTraits<scoped_ptr<P> > { typedef scoped_ptr<P> param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p) { + bool valid = !!p; + GetParamSize(sizer, valid); + if (valid) + GetParamSize(sizer, *p); + } static void Write(base::Pickle* m, const param_type& p) { bool valid = !!p; WriteParam(m, valid); @@ -875,6 +994,7 @@ struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> { template <> struct IPC_EXPORT ParamTraits<LogData> { typedef LogData param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -897,6 +1017,7 @@ struct IPC_EXPORT ParamTraits<Message> { template <> struct IPC_EXPORT ParamTraits<HANDLE> { typedef HANDLE param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -907,6 +1028,7 @@ struct IPC_EXPORT ParamTraits<HANDLE> { template <> struct IPC_EXPORT ParamTraits<LOGFONT> { typedef LOGFONT param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, @@ -917,6 +1039,7 @@ struct IPC_EXPORT ParamTraits<LOGFONT> { template <> struct IPC_EXPORT ParamTraits<MSG> { typedef MSG param_type; + static void GetSize(base::PickleSizer* sizer, const param_type& p); static void Write(base::Pickle* m, const param_type& p); static bool Read(const base::Pickle* m, base::PickleIterator* iter, diff --git a/ipc/ipc_message_utils_unittest.cc b/ipc/ipc_message_utils_unittest.cc index f3aa31a..0c9a7da 100644 --- a/ipc/ipc_message_utils_unittest.cc +++ b/ipc/ipc_message_utils_unittest.cc @@ -90,5 +90,31 @@ TEST(IPCMessageUtilsTest, StackVector) { EXPECT_EQ(stack_vector[i], output[i]); } +// Tests that PickleSizer and Pickle agree on the size of a complex base::Value. +TEST(IPCMessageUtilsTest, ValueSize) { + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue); + value->SetWithoutPathExpansion("foo", new base::FundamentalValue(42)); + value->SetWithoutPathExpansion("bar", new base::FundamentalValue(3.14)); + value->SetWithoutPathExpansion("baz", new base::StringValue("hello")); + value->SetWithoutPathExpansion("qux", base::Value::CreateNullValue()); + + scoped_ptr<base::DictionaryValue> nested_dict(new base::DictionaryValue); + nested_dict->SetWithoutPathExpansion("foobar", new base::FundamentalValue(5)); + value->SetWithoutPathExpansion("nested", std::move(nested_dict)); + + scoped_ptr<base::ListValue> list_value(new base::ListValue); + list_value->Append(new base::StringValue("im a string")); + list_value->Append(new base::StringValue("im another string")); + value->SetWithoutPathExpansion("awesome-list", std::move(list_value)); + + base::Pickle pickle; + IPC::WriteParam(&pickle, *value); + + base::PickleSizer sizer; + IPC::GetParamSize(&sizer, *value); + + EXPECT_EQ(sizer.payload_size(), pickle.payload_size()); +} + } // namespace } // namespace IPC diff --git a/ipc/param_traits_macros.h b/ipc/param_traits_macros.h index 7c4cc692..1003440 100644 --- a/ipc/param_traits_macros.h +++ b/ipc/param_traits_macros.h @@ -13,6 +13,8 @@ template <> \ struct IPC_MESSAGE_EXPORT ParamTraits<struct_name> { \ typedef struct_name param_type; \ + static void GetSize(base::PickleSizer* sizer, \ + const param_type& p); \ static void Write(base::Pickle* m, const param_type& p); \ static bool Read(const base::Pickle* m, \ base::PickleIterator* iter, \ @@ -53,6 +55,8 @@ template <> \ struct IPC_MESSAGE_EXPORT ParamTraits<enum_name> { \ typedef enum_name param_type; \ + static void GetSize(base::PickleSizer* sizer, \ + const param_type& p); \ static void Write(base::Pickle* m, const param_type& p); \ static bool Read(const base::Pickle* m, \ base::PickleIterator* iter, \ diff --git a/ipc/param_traits_size_macros.h b/ipc/param_traits_size_macros.h new file mode 100644 index 0000000..142b55a --- /dev/null +++ b/ipc/param_traits_size_macros.h @@ -0,0 +1,40 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IPC_PARAM_TRAITS_SIZE_MACROS_H_ +#define IPC_PARAM_TRAITS_SIZE_MACROS_H_ + +// Null out all the macros that need nulling. +#include "ipc/ipc_message_null_macros.h" + +// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur. +#undef IPC_STRUCT_BEGIN_WITH_PARENT +#undef IPC_STRUCT_MEMBER +#undef IPC_STRUCT_END +#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \ + IPC_STRUCT_TRAITS_BEGIN(struct_name) +#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name) +#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END() + +// Set up so next include will generate size methods. +#undef IPC_STRUCT_TRAITS_BEGIN +#undef IPC_STRUCT_TRAITS_MEMBER +#undef IPC_STRUCT_TRAITS_PARENT +#undef IPC_STRUCT_TRAITS_END +#define IPC_STRUCT_TRAITS_BEGIN(struct_name) \ + void ParamTraits<struct_name>::GetSize(base::PickleSizer* sizer, \ + const param_type& p) { +#define IPC_STRUCT_TRAITS_MEMBER(name) GetParamSize(sizer, p.name); +#define IPC_STRUCT_TRAITS_PARENT(type) ParamTraits<type>::GetSize(sizer, p); +#define IPC_STRUCT_TRAITS_END() } + +#undef IPC_ENUM_TRAITS_VALIDATE +#define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \ + void ParamTraits<enum_name>::GetSize(base::PickleSizer* sizer, \ + const param_type& value) { \ + sizer->AddInt(); \ + } + +#endif // IPC_PARAM_TRAITS_SIZE_MACROS_H_ + |