12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ipc/ipc_message_utils.h"
- #include <stddef.h>
- #include <stdint.h>
- #include "base/files/file_path.h"
- #include "base/json/json_writer.h"
- #include "base/logging.h"
- #include "base/memory/ptr_util.h"
- #include "base/notreached.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/time/time.h"
- #include "base/unguessable_token.h"
- #include "build/build_config.h"
- #include "ipc/ipc_channel_handle.h"
- #include "ipc/ipc_message.h"
- #include "ipc/ipc_message_attachment.h"
- #include "ipc/ipc_message_attachment_set.h"
- #include "ipc/ipc_mojo_param_traits.h"
- #if BUILDFLAG(IS_APPLE)
- #include "ipc/mach_port_mac.h"
- #endif
- #if BUILDFLAG(IS_WIN)
- #include <tchar.h>
- #include "ipc/handle_win.h"
- #include "ipc/ipc_platform_file.h"
- #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- #include "base/file_descriptor_posix.h"
- #include "ipc/ipc_platform_file_attachment_posix.h"
- #endif
- #if BUILDFLAG(IS_FUCHSIA)
- #include "base/fuchsia/fuchsia_logging.h"
- #include "ipc/handle_attachment_fuchsia.h"
- #endif
- #if BUILDFLAG(IS_ANDROID)
- #include "base/android/scoped_hardware_buffer_handle.h"
- #include "ipc/ipc_mojo_handle_attachment.h"
- #include "mojo/public/cpp/system/message_pipe.h"
- #include "mojo/public/cpp/system/scope_to_message_pipe.h"
- #endif
- namespace IPC {
- namespace {
- const int kMaxRecursionDepth = 200;
- template<typename CharType>
- void LogBytes(const std::vector<CharType>& data, std::string* out) {
- #if BUILDFLAG(IS_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]);
- #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- // 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(
- base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
- }
- if (data.size() > kMaxBytesToLog) {
- out->append(base::StringPrintf(
- " and %u more bytes",
- static_cast<unsigned>(data.size() - kMaxBytesToLog)));
- }
- #endif
- }
- void WriteValue(const base::Value& value, int recursion, base::Pickle* pickle);
- void WriteDictValue(const base::Value::Dict& value,
- int recursion,
- base::Pickle* pickle) {
- WriteParam(pickle, base::checked_cast<int>(value.size()));
- for (const auto entry : value) {
- WriteParam(pickle, entry.first);
- WriteValue(entry.second, recursion + 1, pickle);
- }
- }
- void WriteListValue(const base::Value::List& value,
- int recursion,
- base::Pickle* pickle) {
- WriteParam(pickle, base::checked_cast<int>(value.size()));
- for (const auto& entry : value) {
- WriteValue(entry, recursion + 1, pickle);
- }
- }
- void WriteValue(const base::Value& value, int recursion, base::Pickle* pickle) {
- bool result;
- if (recursion > kMaxRecursionDepth) {
- LOG(ERROR) << "Max recursion depth hit in WriteValue.";
- return;
- }
- pickle->WriteInt(static_cast<int>(value.type()));
- switch (value.type()) {
- case base::Value::Type::NONE:
- break;
- case base::Value::Type::BOOLEAN: {
- WriteParam(pickle, value.GetBool());
- break;
- }
- case base::Value::Type::INTEGER: {
- DCHECK(value.is_int());
- WriteParam(pickle, value.GetInt());
- break;
- }
- case base::Value::Type::DOUBLE: {
- DCHECK(value.is_int() || value.is_double());
- WriteParam(pickle, value.GetDouble());
- break;
- }
- case base::Value::Type::STRING: {
- const std::string* val = value.GetIfString();
- result = !!val;
- DCHECK(result);
- WriteParam(pickle, *val);
- break;
- }
- case base::Value::Type::BINARY: {
- pickle->WriteData(reinterpret_cast<const char*>(value.GetBlob().data()),
- value.GetBlob().size());
- break;
- }
- case base::Value::Type::DICT: {
- DCHECK(value.is_dict());
- WriteDictValue(value.GetDict(), recursion, pickle);
- break;
- }
- case base::Value::Type::LIST: {
- DCHECK(value.is_list());
- WriteListValue(value.GetList(), recursion, pickle);
- break;
- }
- }
- }
- bool ReadValue(const base::Pickle* pickle,
- base::PickleIterator* iter,
- int recursion,
- base::Value* value);
- // Helper for ReadValue that reads a Value::Dict into a pre-allocated object.
- bool ReadDictValue(const base::Pickle* pickle,
- base::PickleIterator* iter,
- int recursion,
- base::Value::Dict* value) {
- int size;
- if (!ReadParam(pickle, iter, &size))
- return false;
- for (int i = 0; i < size; i++) {
- std::string key;
- base::Value subvalue;
- if (!ReadParam(pickle, iter, &key) ||
- !ReadValue(pickle, iter, recursion + 1, &subvalue)) {
- return false;
- }
- value->Set(key, std::move(subvalue));
- }
- return true;
- }
- // Helper for ReadValue that reads a Value::List into a pre-allocated object.
- bool ReadListValue(const base::Pickle* pickle,
- base::PickleIterator* iter,
- int recursion,
- base::Value::List* value) {
- int size;
- if (!ReadParam(pickle, iter, &size))
- return false;
- value->reserve(size);
- for (int i = 0; i < size; i++) {
- base::Value subval;
- if (!ReadValue(pickle, iter, recursion + 1, &subval))
- return false;
- value->Append(std::move(subval));
- }
- return true;
- }
- bool ReadValue(const base::Pickle* pickle,
- base::PickleIterator* iter,
- int recursion,
- base::Value* value) {
- if (recursion > kMaxRecursionDepth) {
- LOG(ERROR) << "Max recursion depth hit in ReadValue.";
- return false;
- }
- int type;
- if (!ReadParam(pickle, iter, &type))
- return false;
- constexpr int kMinValueType = static_cast<int>(base::Value::Type::NONE);
- constexpr int kMaxValueType = static_cast<int>(base::Value::Type::LIST);
- if (type > kMaxValueType || type < kMinValueType)
- return false;
- switch (static_cast<base::Value::Type>(type)) {
- case base::Value::Type::NONE:
- *value = base::Value();
- break;
- case base::Value::Type::BOOLEAN: {
- bool val;
- if (!ReadParam(pickle, iter, &val))
- return false;
- *value = base::Value(val);
- break;
- }
- case base::Value::Type::INTEGER: {
- int val;
- if (!ReadParam(pickle, iter, &val))
- return false;
- *value = base::Value(val);
- break;
- }
- case base::Value::Type::DOUBLE: {
- double val;
- if (!ReadParam(pickle, iter, &val))
- return false;
- *value = base::Value(val);
- break;
- }
- case base::Value::Type::STRING: {
- std::string val;
- if (!ReadParam(pickle, iter, &val))
- return false;
- *value = base::Value(std::move(val));
- break;
- }
- case base::Value::Type::BINARY: {
- base::span<const uint8_t> data;
- if (!iter->ReadData(&data))
- return false;
- *value = base::Value(data);
- break;
- }
- case base::Value::Type::DICTIONARY: {
- base::Value::Dict val;
- if (!ReadDictValue(pickle, iter, recursion, &val))
- return false;
- *value = base::Value(std::move(val));
- break;
- }
- case base::Value::Type::LIST: {
- base::Value::List val;
- if (!ReadListValue(pickle, iter, recursion, &val))
- return false;
- *value = base::Value(std::move(val));
- break;
- }
- default:
- NOTREACHED();
- return false;
- }
- return true;
- }
- } // namespace
- // -----------------------------------------------------------------------------
- LogData::LogData()
- : routing_id(0),
- type(0),
- sent(0),
- receive(0),
- dispatch(0) {
- }
- LogData::LogData(const LogData& other) = default;
- LogData::~LogData() = default;
- void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
- l->append(p ? "true" : "false");
- }
- void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
- m->WriteBytes(&p, sizeof(param_type));
- }
- bool ParamTraits<signed char>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char* data;
- if (!iter->ReadBytes(&data, sizeof(param_type)))
- return false;
- memcpy(r, data, sizeof(param_type));
- return true;
- }
- void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
- m->WriteBytes(&p, sizeof(param_type));
- }
- bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char* data;
- if (!iter->ReadBytes(&data, sizeof(param_type)))
- return false;
- memcpy(r, data, sizeof(param_type));
- return true;
- }
- void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
- m->WriteBytes(&p, sizeof(param_type));
- }
- bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char* data;
- if (!iter->ReadBytes(&data, sizeof(param_type)))
- return false;
- memcpy(r, data, sizeof(param_type));
- return true;
- }
- void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<int>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
- BUILDFLAG(IS_FUCHSIA) || \
- (BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_64_BITS))
- void ParamTraits<long>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- #endif
- void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
- l->append(base::NumberToString(p));
- }
- void ParamTraits<float>::Log(const param_type& p, std::string* l) {
- l->append(base::StringPrintf("%e", p));
- }
- void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
- m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
- }
- bool ParamTraits<double>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char *data;
- if (!iter->ReadBytes(&data, sizeof(*r))) {
- NOTREACHED();
- return false;
- }
- memcpy(r, data, sizeof(param_type));
- return true;
- }
- void ParamTraits<double>::Log(const param_type& p, std::string* l) {
- l->append(base::StringPrintf("%e", p));
- }
- void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
- l->append(p);
- }
- void ParamTraits<std::u16string>::Log(const param_type& p, std::string* l) {
- l->append(base::UTF16ToUTF8(p));
- }
- #if BUILDFLAG(IS_WIN)
- bool ParamTraits<std::wstring>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- base::StringPiece16 piece16;
- if (!iter->ReadStringPiece16(&piece16))
- return false;
- *r = base::AsWString(piece16);
- return true;
- }
- void ParamTraits<std::wstring>::Log(const param_type& p, std::string* l) {
- l->append(base::WideToUTF8(p));
- }
- #endif
- void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
- const param_type& p) {
- if (p.empty()) {
- m->WriteData(NULL, 0);
- } else {
- m->WriteData(&p.front(), p.size());
- }
- }
- bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char *data;
- size_t data_size = 0;
- if (!iter->ReadData(&data, &data_size))
- return false;
- r->resize(data_size);
- if (data_size)
- memcpy(&r->front(), data, data_size);
- return true;
- }
- void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
- LogBytes(p, l);
- }
- void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
- const param_type& p) {
- if (p.empty()) {
- m->WriteData(NULL, 0);
- } else {
- m->WriteData(reinterpret_cast<const char*>(&p.front()), p.size());
- }
- }
- bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char *data;
- size_t data_size = 0;
- if (!iter->ReadData(&data, &data_size))
- return false;
- r->resize(data_size);
- if (data_size)
- memcpy(&r->front(), data, data_size);
- return true;
- }
- void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
- std::string* l) {
- LogBytes(p, l);
- }
- void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
- const param_type& p) {
- WriteParam(m, base::checked_cast<int>(p.size()));
- // Cast to bool below is required because libc++'s
- // vector<bool>::const_reference is different from bool, and we want to avoid
- // writing an extra specialization of ParamTraits for it.
- for (size_t i = 0; i < p.size(); i++)
- WriteParam(m, static_cast<bool>(p[i]));
- }
- bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- size_t size;
- if (!iter->ReadLength(&size))
- return false;
- r->resize(size);
- for (size_t 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(static_cast<bool>(p[i]), l);
- }
- }
- void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
- const param_type& p) {
- WriteDictValue(p.GetDict(), 0, m);
- }
- bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return ReadDictValue(m, iter, 0, &(r->GetDict()));
- }
- void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
- std::string* l) {
- std::string json;
- base::JSONWriter::Write(p, &json);
- l->append(json);
- }
- void ParamTraits<base::Value::Dict>::Write(base::Pickle* m,
- const param_type& p) {
- WriteDictValue(p, 0, m);
- }
- bool ParamTraits<base::Value::Dict>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return ReadDictValue(m, iter, 0, r);
- }
- void ParamTraits<base::Value::Dict>::Log(const param_type& p, std::string* l) {
- std::string json;
- base::JSONWriter::Write(p, &json);
- l->append(json);
- }
- #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
- const param_type& p) {
- // This serialization must be kept in sync with
- // nacl_message_scanner.cc:WriteHandle().
- const bool valid = p.fd >= 0;
- WriteParam(m, valid);
- if (!valid)
- return;
- if (p.auto_close) {
- if (!m->WriteAttachment(
- new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
- NOTREACHED();
- } else {
- if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
- NOTREACHED();
- }
- }
- bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- *r = base::FileDescriptor();
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
- if (!valid)
- return true;
- scoped_refptr<base::Pickle::Attachment> attachment;
- if (!m->ReadAttachment(iter, &attachment))
- return false;
- if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
- MessageAttachment::Type::PLATFORM_FILE) {
- return false;
- }
- *r = base::FileDescriptor(
- static_cast<internal::PlatformFileAttachment*>(attachment.get())
- ->TakePlatformFile(),
- true);
- return true;
- }
- void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
- std::string* l) {
- if (p.auto_close) {
- l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
- } else {
- l->append(base::StringPrintf("FD(%d)", p.fd));
- }
- }
- void ParamTraits<base::ScopedFD>::Write(base::Pickle* m, const param_type& p) {
- // This serialization must be kept in sync with
- // nacl_message_scanner.cc:WriteHandle().
- const bool valid = p.is_valid();
- WriteParam(m, valid);
- if (!valid)
- return;
- if (!m->WriteAttachment(new internal::PlatformFileAttachment(
- std::move(const_cast<param_type&>(p))))) {
- NOTREACHED();
- }
- }
- bool ParamTraits<base::ScopedFD>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- r->reset();
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
- if (!valid)
- return true;
- scoped_refptr<base::Pickle::Attachment> attachment;
- if (!m->ReadAttachment(iter, &attachment))
- return false;
- if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
- MessageAttachment::Type::PLATFORM_FILE) {
- return false;
- }
- *r = base::ScopedFD(
- static_cast<internal::PlatformFileAttachment*>(attachment.get())
- ->TakePlatformFile());
- return true;
- }
- void ParamTraits<base::ScopedFD>::Log(const param_type& p, std::string* l) {
- l->append(base::StringPrintf("ScopedFD(%d)", p.get()));
- }
- #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- #if BUILDFLAG(IS_WIN)
- void ParamTraits<base::win::ScopedHandle>::Write(base::Pickle* m,
- const param_type& p) {
- const bool valid = p.IsValid();
- WriteParam(m, valid);
- if (!valid)
- return;
- HandleWin handle(p.Get());
- WriteParam(m, handle);
- }
- bool ParamTraits<base::win::ScopedHandle>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- r->Close();
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
- if (!valid)
- return true;
- HandleWin handle;
- if (!ReadParam(m, iter, &handle))
- return false;
- r->Set(handle.get_handle());
- return true;
- }
- void ParamTraits<base::win::ScopedHandle>::Log(const param_type& p,
- std::string* l) {
- l->append(base::StringPrintf("ScopedHandle(%p)", p.Get()));
- }
- #endif // BUILDFLAG(IS_WIN)
- #if BUILDFLAG(IS_FUCHSIA)
- void ParamTraits<zx::vmo>::Write(base::Pickle* m, const param_type& p) {
- // This serialization must be kept in sync with
- // nacl_message_scanner.cc:WriteHandle().
- const bool valid = p.is_valid();
- WriteParam(m, valid);
- if (!valid)
- return;
- if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
- std::move(const_cast<param_type&>(p))))) {
- NOTREACHED();
- }
- }
- bool ParamTraits<zx::vmo>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- r->reset();
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
- if (!valid)
- return true;
- scoped_refptr<base::Pickle::Attachment> attachment;
- if (!m->ReadAttachment(iter, &attachment))
- return false;
- if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
- MessageAttachment::Type::FUCHSIA_HANDLE) {
- return false;
- }
- *r = zx::vmo(static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
- ->Take());
- return true;
- }
- void ParamTraits<zx::vmo>::Log(const param_type& p, std::string* l) {
- l->append("ZirconVMO");
- }
- void ParamTraits<zx::channel>::Write(base::Pickle* m, const param_type& p) {
- // This serialization must be kept in sync with
- // nacl_message_scanner.cc:WriteHandle().
- const bool valid = p.is_valid();
- WriteParam(m, valid);
- if (!valid)
- return;
- if (!m->WriteAttachment(new internal::HandleAttachmentFuchsia(
- std::move(const_cast<param_type&>(p))))) {
- NOTREACHED();
- }
- }
- bool ParamTraits<zx::channel>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- r->reset();
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
- if (!valid)
- return true;
- scoped_refptr<base::Pickle::Attachment> attachment;
- if (!m->ReadAttachment(iter, &attachment))
- return false;
- if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
- MessageAttachment::Type::FUCHSIA_HANDLE) {
- return false;
- }
- *r = zx::channel(
- static_cast<internal::HandleAttachmentFuchsia*>(attachment.get())
- ->Take());
- return true;
- }
- void ParamTraits<zx::channel>::Log(const param_type& p, std::string* l) {
- l->append("ZirconChannel");
- }
- #endif // BUILDFLAG(IS_FUCHSIA)
- #if BUILDFLAG(IS_ANDROID)
- void ParamTraits<base::android::ScopedHardwareBufferHandle>::Write(
- base::Pickle* m,
- const param_type& p) {
- const bool is_valid = p.is_valid();
- WriteParam(m, is_valid);
- if (!is_valid)
- return;
- // We must keep a ref to the AHardwareBuffer alive until the receiver has
- // acquired its own reference. We do this by sending a message pipe handle
- // along with the buffer. When the receiver deserializes (or even if they
- // die without ever reading the message) their end of the pipe will be
- // closed. We will eventually detect this and release the AHB reference.
- mojo::MessagePipe tracking_pipe;
- m->WriteAttachment(new internal::MojoHandleAttachment(
- mojo::ScopedHandle::From(std::move(tracking_pipe.handle0))));
- WriteParam(m, base::FileDescriptor(p.SerializeAsFileDescriptor().release(),
- true /* auto_close */));
- // Pass ownership of the input handle to our tracking pipe to keep the AHB
- // alive long enough to be deserialized by the receiver.
- mojo::ScopeToMessagePipe(std::move(const_cast<param_type&>(p)),
- std::move(tracking_pipe.handle1));
- }
- bool ParamTraits<base::android::ScopedHardwareBufferHandle>::Read(
- const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- *r = base::android::ScopedHardwareBufferHandle();
- bool is_valid;
- if (!ReadParam(m, iter, &is_valid))
- return false;
- if (!is_valid)
- return true;
- scoped_refptr<base::Pickle::Attachment> tracking_pipe_attachment;
- if (!m->ReadAttachment(iter, &tracking_pipe_attachment))
- return false;
- // We keep this alive until the AHB is safely deserialized below. When this
- // goes out of scope, the sender holding the other end of this pipe will treat
- // this handle closure as a signal that it's safe to release their AHB
- // keepalive ref.
- mojo::ScopedHandle tracking_pipe =
- static_cast<MessageAttachment*>(tracking_pipe_attachment.get())
- ->TakeMojoHandle();
- base::FileDescriptor descriptor;
- if (!ReadParam(m, iter, &descriptor))
- return false;
- // NOTE: It is valid to deserialize an invalid FileDescriptor, so the success
- // of |ReadParam()| above does not imply that |descriptor| is valid.
- base::ScopedFD scoped_fd(descriptor.fd);
- if (!scoped_fd.is_valid())
- return false;
- *r = base::android::ScopedHardwareBufferHandle::DeserializeFromFileDescriptor(
- std::move(scoped_fd));
- return true;
- }
- void ParamTraits<base::android::ScopedHardwareBufferHandle>::Log(
- const param_type& p,
- std::string* l) {
- l->append(base::StringPrintf("base::android::ScopedHardwareBufferHandle(%p)",
- p.get()));
- }
- #endif // BUILDFLAG(IS_ANDROID)
- void ParamTraits<base::ReadOnlySharedMemoryRegion>::Write(base::Pickle* m,
- const param_type& p) {
- base::subtle::PlatformSharedMemoryRegion handle =
- base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
- std::move(const_cast<param_type&>(p)));
- WriteParam(m, std::move(handle));
- }
- bool ParamTraits<base::ReadOnlySharedMemoryRegion>::Read(
- const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- base::subtle::PlatformSharedMemoryRegion handle;
- if (!ReadParam(m, iter, &handle))
- return false;
- *r = base::ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
- return true;
- }
- void ParamTraits<base::ReadOnlySharedMemoryRegion>::Log(const param_type& p,
- std::string* l) {
- *l = "<base::ReadOnlySharedMemoryRegion>";
- // TODO(alexilin): currently there is no way to access underlying handle
- // without destructing a ReadOnlySharedMemoryRegion instance.
- }
- void ParamTraits<base::WritableSharedMemoryRegion>::Write(base::Pickle* m,
- const param_type& p) {
- base::subtle::PlatformSharedMemoryRegion handle =
- base::WritableSharedMemoryRegion::TakeHandleForSerialization(
- std::move(const_cast<param_type&>(p)));
- WriteParam(m, std::move(handle));
- }
- bool ParamTraits<base::WritableSharedMemoryRegion>::Read(
- const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- base::subtle::PlatformSharedMemoryRegion handle;
- if (!ReadParam(m, iter, &handle))
- return false;
- *r = base::WritableSharedMemoryRegion::Deserialize(std::move(handle));
- return true;
- }
- void ParamTraits<base::WritableSharedMemoryRegion>::Log(const param_type& p,
- std::string* l) {
- *l = "<base::WritableSharedMemoryRegion>";
- // TODO(alexilin): currently there is no way to access underlying handle
- // without destructing a ReadOnlySharedMemoryRegion instance.
- }
- void ParamTraits<base::UnsafeSharedMemoryRegion>::Write(base::Pickle* m,
- const param_type& p) {
- base::subtle::PlatformSharedMemoryRegion handle =
- base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
- std::move(const_cast<param_type&>(p)));
- WriteParam(m, std::move(handle));
- }
- bool ParamTraits<base::UnsafeSharedMemoryRegion>::Read(
- const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- base::subtle::PlatformSharedMemoryRegion handle;
- if (!ReadParam(m, iter, &handle))
- return false;
- *r = base::UnsafeSharedMemoryRegion::Deserialize(std::move(handle));
- return true;
- }
- void ParamTraits<base::UnsafeSharedMemoryRegion>::Log(const param_type& p,
- std::string* l) {
- *l = "<base::UnsafeSharedMemoryRegion>";
- // TODO(alexilin): currently there is no way to access underlying handle
- // without destructing a ReadOnlySharedMemoryRegion instance.
- }
- void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Write(
- base::Pickle* m,
- const param_type& p) {
- // This serialization must be kept in sync with
- // nacl_message_scanner.cc::WriteHandle().
- const bool valid = p.IsValid();
- WriteParam(m, valid);
- if (!valid)
- return;
- WriteParam(m, p.GetMode());
- WriteParam(m, static_cast<uint64_t>(p.GetSize()));
- WriteParam(m, p.GetGUID());
- #if BUILDFLAG(IS_WIN)
- base::win::ScopedHandle h = const_cast<param_type&>(p).PassPlatformHandle();
- HandleWin handle_win(h.Get());
- WriteParam(m, handle_win);
- #elif BUILDFLAG(IS_FUCHSIA)
- zx::vmo vmo = const_cast<param_type&>(p).PassPlatformHandle();
- WriteParam(m, vmo);
- #elif BUILDFLAG(IS_APPLE)
- base::mac::ScopedMachSendRight h =
- const_cast<param_type&>(p).PassPlatformHandle();
- MachPortMac mach_port_mac(h.get());
- WriteParam(m, mach_port_mac);
- #elif BUILDFLAG(IS_ANDROID)
- m->WriteAttachment(new internal::PlatformFileAttachment(
- base::ScopedFD(const_cast<param_type&>(p).PassPlatformHandle())));
- #elif BUILDFLAG(IS_POSIX)
- base::subtle::ScopedFDPair h =
- const_cast<param_type&>(p).PassPlatformHandle();
- m->WriteAttachment(new internal::PlatformFileAttachment(std::move(h.fd)));
- if (p.GetMode() ==
- base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
- m->WriteAttachment(
- new internal::PlatformFileAttachment(std::move(h.readonly_fd)));
- }
- #endif
- }
- bool ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Read(
- const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- bool valid;
- if (!ReadParam(m, iter, &valid))
- return false;
- if (!valid) {
- *r = base::subtle::PlatformSharedMemoryRegion();
- return true;
- }
- base::subtle::PlatformSharedMemoryRegion::Mode mode;
- uint64_t shm_size;
- base::UnguessableToken guid;
- if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &shm_size) ||
- !base::IsValueInRangeForNumericType<size_t>(shm_size) ||
- !ReadParam(m, iter, &guid)) {
- return false;
- }
- size_t size = static_cast<size_t>(shm_size);
- #if BUILDFLAG(IS_WIN)
- HandleWin handle_win;
- if (!ReadParam(m, iter, &handle_win))
- return false;
- *r = base::subtle::PlatformSharedMemoryRegion::Take(
- base::win::ScopedHandle(handle_win.get_handle()), mode, size, guid);
- #elif BUILDFLAG(IS_FUCHSIA)
- zx::vmo vmo;
- if (!ReadParam(m, iter, &vmo))
- return false;
- *r = base::subtle::PlatformSharedMemoryRegion::Take(std::move(vmo), mode,
- size, guid);
- #elif BUILDFLAG(IS_APPLE)
- MachPortMac mach_port_mac;
- if (!ReadParam(m, iter, &mach_port_mac))
- return false;
- *r = base::subtle::PlatformSharedMemoryRegion::Take(
- base::mac::ScopedMachSendRight(mach_port_mac.get_mach_port()), mode, size,
- guid);
- #elif BUILDFLAG(IS_POSIX)
- scoped_refptr<base::Pickle::Attachment> attachment;
- if (!m->ReadAttachment(iter, &attachment))
- return false;
- if (static_cast<MessageAttachment*>(attachment.get())->GetType() !=
- MessageAttachment::Type::PLATFORM_FILE) {
- return false;
- }
- #if BUILDFLAG(IS_ANDROID)
- *r = base::subtle::PlatformSharedMemoryRegion::Take(
- base::ScopedFD(
- static_cast<internal::PlatformFileAttachment*>(attachment.get())
- ->TakePlatformFile()),
- mode, size, guid);
- #else
- scoped_refptr<base::Pickle::Attachment> readonly_attachment;
- if (mode == base::subtle::PlatformSharedMemoryRegion::Mode::kWritable) {
- if (!m->ReadAttachment(iter, &readonly_attachment))
- return false;
- if (static_cast<MessageAttachment*>(readonly_attachment.get())->GetType() !=
- MessageAttachment::Type::PLATFORM_FILE) {
- return false;
- }
- }
- *r = base::subtle::PlatformSharedMemoryRegion::Take(
- base::subtle::ScopedFDPair(
- base::ScopedFD(
- static_cast<internal::PlatformFileAttachment*>(attachment.get())
- ->TakePlatformFile()),
- readonly_attachment
- ? base::ScopedFD(static_cast<internal::PlatformFileAttachment*>(
- readonly_attachment.get())
- ->TakePlatformFile())
- : base::ScopedFD()),
- mode, size, guid);
- #endif // BUILDFLAG(IS_ANDROID)
- #endif
- return true;
- }
- void ParamTraits<base::subtle::PlatformSharedMemoryRegion>::Log(
- const param_type& p,
- std::string* l) {
- #if BUILDFLAG(IS_FUCHSIA)
- l->append("Handle: ");
- LogParam(p.GetPlatformHandle()->get(), l);
- #elif BUILDFLAG(IS_WIN)
- l->append("Handle: ");
- LogParam(p.GetPlatformHandle(), l);
- #elif BUILDFLAG(IS_APPLE)
- l->append("Mach port: ");
- LogParam(p.GetPlatformHandle(), l);
- #elif BUILDFLAG(IS_ANDROID)
- l->append("FD: ");
- LogParam(p.GetPlatformHandle(), l);
- #elif BUILDFLAG(IS_POSIX)
- base::subtle::FDPair h = p.GetPlatformHandle();
- l->append("FD: ");
- LogParam(h.fd, l);
- l->append("Read-only FD: ");
- LogParam(h.readonly_fd, l);
- #endif
- l->append("Mode: ");
- LogParam(p.GetMode(), l);
- l->append("size: ");
- LogParam(static_cast<uint64_t>(p.GetSize()), l);
- l->append("GUID: ");
- LogParam(p.GetGUID(), l);
- }
- void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Write(
- base::Pickle* m,
- const param_type& value) {
- DCHECK(static_cast<int>(value) >= 0 &&
- static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue));
- m->WriteInt(static_cast<int>(value));
- }
- bool ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Read(
- const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- int value;
- if (!iter->ReadInt(&value))
- return false;
- if (!(static_cast<int>(value) >= 0 &&
- static_cast<int>(value) <= static_cast<int>(param_type::kMaxValue))) {
- return false;
- }
- *p = static_cast<param_type>(value);
- return true;
- }
- void ParamTraits<base::subtle::PlatformSharedMemoryRegion::Mode>::Log(
- const param_type& p,
- std::string* l) {
- LogParam(static_cast<int>(p), l);
- }
- #if BUILDFLAG(IS_WIN)
- void ParamTraits<PlatformFileForTransit>::Write(base::Pickle* m,
- const param_type& p) {
- m->WriteBool(p.IsValid());
- if (p.IsValid()) {
- HandleWin handle_win(p.GetHandle());
- ParamTraits<HandleWin>::Write(m, handle_win);
- ::CloseHandle(p.GetHandle());
- }
- }
- bool ParamTraits<PlatformFileForTransit>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- bool is_valid;
- if (!iter->ReadBool(&is_valid))
- return false;
- if (!is_valid) {
- *r = PlatformFileForTransit();
- return true;
- }
- HandleWin handle_win;
- if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
- return false;
- *r = PlatformFileForTransit(handle_win.get_handle());
- return true;
- }
- void ParamTraits<PlatformFileForTransit>::Log(const param_type& p,
- std::string* l) {
- LogParam(p.GetHandle(), l);
- }
- #endif // BUILDFLAG(IS_WIN)
- void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
- p.WriteToPickle(m);
- }
- bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return r->ReadFromPickle(iter);
- }
- void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
- ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
- }
- void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
- WriteListValue(p.GetList(), 0, m);
- }
- bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return ReadListValue(m, iter, 0, &(r->GetList()));
- }
- void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
- std::string json;
- base::JSONWriter::Write(p, &json);
- l->append(json);
- }
- void ParamTraits<base::Value::List>::Write(base::Pickle* m,
- const param_type& p) {
- WriteListValue(p, 0, m);
- }
- bool ParamTraits<base::Value::List>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return ReadListValue(m, iter, 0, r);
- }
- void ParamTraits<base::Value::List>::Log(const param_type& p, std::string* l) {
- std::string json;
- base::JSONWriter::Write(p, &json);
- l->append(json);
- }
- void ParamTraits<base::Value>::Write(base::Pickle* m, const param_type& p) {
- WriteValue(p, 0, m);
- }
- bool ParamTraits<base::Value>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return ReadValue(m, iter, 0, r);
- }
- void ParamTraits<base::Value>::Log(const param_type& p, std::string* l) {
- std::string json;
- base::JSONWriter::Write(p, &json);
- l->append(json);
- }
- void ParamTraits<base::File::Info>::Write(base::Pickle* 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());
- }
- bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* p) {
- double last_modified, last_accessed, creation_time;
- if (!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))
- return false;
- 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 true;
- }
- void ParamTraits<base::File::Info>::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<base::Time>::Write(base::Pickle* m, const param_type& p) {
- ParamTraits<int64_t>::Write(m, p.ToInternalValue());
- }
- bool ParamTraits<base::Time>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- int64_t value;
- if (!ParamTraits<int64_t>::Read(m, iter, &value))
- return false;
- *r = base::Time::FromInternalValue(value);
- return true;
- }
- void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
- ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
- }
- void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
- ParamTraits<int64_t>::Write(m, p.ToInternalValue());
- }
- bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- int64_t value;
- bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
- if (ret)
- *r = base::TimeDelta::FromInternalValue(value);
- return ret;
- }
- void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
- ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
- }
- void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
- ParamTraits<int64_t>::Write(m, p.ToInternalValue());
- }
- bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- int64_t value;
- bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
- if (ret)
- *r = base::TimeTicks::FromInternalValue(value);
- return ret;
- }
- void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
- ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
- }
- // If base::UnguessableToken is no longer 128 bits, the IPC serialization logic
- // below should be updated.
- static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
- "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
- void ParamTraits<base::UnguessableToken>::Write(base::Pickle* m,
- const param_type& p) {
- DCHECK(!p.is_empty());
- ParamTraits<uint64_t>::Write(m, p.GetHighForSerialization());
- ParamTraits<uint64_t>::Write(m, p.GetLowForSerialization());
- }
- bool ParamTraits<base::UnguessableToken>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- uint64_t high, low;
- if (!ParamTraits<uint64_t>::Read(m, iter, &high) ||
- !ParamTraits<uint64_t>::Read(m, iter, &low))
- return false;
- // Receiving a zeroed UnguessableToken is a security issue.
- if (high == 0 && low == 0)
- return false;
- *r = base::UnguessableToken::Deserialize(high, low);
- return true;
- }
- void ParamTraits<base::UnguessableToken>::Log(const param_type& p,
- std::string* l) {
- l->append(p.ToString());
- }
- void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
- const param_type& p) {
- #if BUILDFLAG(IS_NACL)
- WriteParam(m, p.socket);
- #else
- WriteParam(m, p.mojo_handle);
- #endif
- }
- bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- #if BUILDFLAG(IS_NACL)
- return ReadParam(m, iter, &r->socket);
- #else
- return ReadParam(m, iter, &r->mojo_handle);
- #endif
- }
- void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
- std::string* l) {
- l->append("ChannelHandle(");
- #if BUILDFLAG(IS_NACL)
- ParamTraits<base::FileDescriptor>::Log(p.socket, l);
- #else
- LogParam(p.mojo_handle, l);
- #endif
- l->append(")");
- }
- void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, p.channel);
- WriteParam(m, p.routing_id);
- WriteParam(m, p.type);
- WriteParam(m, p.flags);
- WriteParam(m, p.sent);
- WriteParam(m, p.receive);
- WriteParam(m, p.dispatch);
- WriteParam(m, p.message_name);
- WriteParam(m, p.params);
- }
- bool ParamTraits<LogData>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return
- ReadParam(m, iter, &r->channel) &&
- ReadParam(m, iter, &r->routing_id) &&
- ReadParam(m, iter, &r->type) &&
- ReadParam(m, iter, &r->flags) &&
- ReadParam(m, iter, &r->sent) &&
- ReadParam(m, iter, &r->receive) &&
- ReadParam(m, iter, &r->dispatch) &&
- ReadParam(m, iter, &r->message_name) &&
- 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(base::Pickle* m, const Message& p) {
- #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- // We don't serialize the file descriptors in the nested message, so there
- // better not be any.
- DCHECK(!p.HasAttachments());
- #endif
- // Don't just write out the message. This is used to send messages between
- // NaCl (Posix environment) and the browser (could be on Windows). The message
- // header formats differ between these systems (so does handle sharing, but
- // we already asserted we don't have any handles). So just write out the
- // parts of the header we use.
- //
- // Be careful also to use only explicitly-sized types. The NaCl environment
- // could be 64-bit and the host browser could be 32-bits. The nested message
- // may or may not be safe to send between 32-bit and 64-bit systems, but we
- // leave that up to the code sending the message to ensure.
- m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
- m->WriteUInt32(p.type());
- m->WriteUInt32(p.flags());
- m->WriteData(p.payload(), p.payload_size());
- }
- bool ParamTraits<Message>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- Message* r) {
- uint32_t routing_id, type, flags;
- if (!iter->ReadUInt32(&routing_id) ||
- !iter->ReadUInt32(&type) ||
- !iter->ReadUInt32(&flags))
- return false;
- size_t payload_size;
- const char* payload;
- if (!iter->ReadData(&payload, &payload_size))
- return false;
- r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
- r->WriteBytes(payload, payload_size);
- return true;
- }
- void ParamTraits<Message>::Log(const Message& p, std::string* l) {
- l->append("<IPC::Message>");
- }
- #if BUILDFLAG(IS_WIN)
- // 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) {
- m->WriteInt(HandleToLong(p));
- }
- bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- int32_t temp;
- if (!iter->ReadInt(&temp))
- return false;
- *r = LongToHandle(temp);
- return true;
- }
- void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
- l->append(base::StringPrintf("0x%p", p));
- }
- void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
- m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
- }
- bool ParamTraits<MSG>::Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- const char *data;
- size_t data_size = 0;
- bool result = iter->ReadData(&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 // BUILDFLAG(IS_WIN)
- } // namespace IPC
|