1// Copyright 2015 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef MOJO_PUBLIC_CPP_BINDINGS_STRUCT_TRAITS_H_ 6#define MOJO_PUBLIC_CPP_BINDINGS_STRUCT_TRAITS_H_ 7 8namespace mojo { 9 10// This must be specialized for any type |T| to be serialized/deserialized as 11// a mojom struct of type |MojomType|. 12// 13// Each specialization needs to implement a few things: 14// 1. Static getters for each field in the Mojom type. These should be 15// of the form: 16// 17// static <return type> <field name>(const T& input); 18// 19// and should return a serializable form of the named field as extracted 20// from |input|. 21// 22// Serializable form of a field: 23// Value or reference of the same type used in |MojomType|, or the 24// following alternatives: 25// - string: 26// Value or reference of any type that has a StringTraits defined. 27// Supported by default: base::StringPiece, std::string. 28// 29// - array: 30// Value or reference of any type that has an ArrayTraits defined. 31// Supported by default: std::vector, WTF::Vector (in blink), CArray. 32// 33// - map: 34// Value or reference of any type that has a MapTraits defined. 35// Supported by default: std::map. 36// 37// - struct: 38// Value or reference of any type that has a StructTraits defined. 39// 40// - enum: 41// Value of any type that has an EnumTraits defined. 42// 43// During serialization, getters for string/struct/array/map/union fields 44// are called twice (one for size calculation and one for actual 45// serialization). If you want to return a value (as opposed to a 46// reference) from these getters, you have to be sure that constructing and 47// copying the returned object is really cheap. 48// 49// Getters for fields of other types are called once. 50// 51// 2. A static Read() method to set the contents of a |T| instance from a 52// |MojomType|DataView (e.g., if |MojomType| is test::Example, the data 53// view will be test::ExampleDataView). 54// 55// static bool Read(|MojomType|DataView data, T* output); 56// 57// The generated |MojomType|DataView type provides a convenient, 58// inexpensive view of a serialized struct's field data. 59// 60// Returning false indicates invalid incoming data and causes the message 61// pipe receiving it to be disconnected. Therefore, you can do custom 62// validation for |T| in this method. 63// 64// 3. [Optional] A static IsNull() method indicating whether a given |T| 65// instance is null: 66// 67// static bool IsNull(const T& input); 68// 69// If this method returns true, it is guaranteed that none of the getters 70// (described in section 1) will be called for the same |input|. So you 71// don't have to check whether |input| is null in those getters. 72// 73// If it is not defined, |T| instances are always considered non-null. 74// 75// [Optional] A static SetToNull() method to set the contents of a given 76// |T| instance to null. 77// 78// static void SetToNull(T* output); 79// 80// When a null serialized struct is received, the deserialization code 81// calls this method instead of Read(). 82// 83// NOTE: It is to set |*output|'s contents to a null state, not to set the 84// |output| pointer itself to null. "Null state" means whatever state you 85// think it makes sense to map a null serialized struct to. 86// 87// If it is not defined, null is not allowed to be converted to |T|. In 88// that case, an incoming null value is considered invalid and causes the 89// message pipe to be disconnected. 90// 91// 4. [Optional] As mentioned above, getters for string/struct/array/map/union 92// fields are called multiple times (twice to be exact). If you need to do 93// some expensive calculation/conversion, you probably want to cache the 94// result across multiple calls. You can introduce an arbitrary context 95// object by adding two optional methods: 96// static void* SetUpContext(const T& input); 97// static void TearDownContext(const T& input, void* context); 98// 99// And then you append a second parameter, void* context, to getters: 100// static <return type> <field name>(const T& input, void* context); 101// 102// If a T instance is not null, the serialization code will call 103// SetUpContext() at the beginning, and pass the resulting context pointer 104// to getters. After serialization is done, it calls TearDownContext() so 105// that you can do any necessary cleanup. 106// 107// In the description above, methods having an |input| parameter define it as 108// const reference of T. Actually, it can be a non-const reference of T too. 109// E.g., if T contains Mojo handles or interfaces whose ownership needs to be 110// transferred. Correspondingly, it requies you to always give non-const T 111// reference/value to the Mojo bindings for serialization: 112// - if T is used in the "type_mappings" section of a typemap config file, 113// you need to declare it as pass-by-value: 114// type_mappings = [ "MojomType=T(pass_by_value)" ] 115// - if another type U's StructTraits has a getter for T, it needs to return 116// non-const reference/value. 117// 118// EXAMPLE: 119// 120// Mojom definition: 121// struct Bar {}; 122// struct Foo { 123// int32 f_integer; 124// string f_string; 125// array<string> f_string_array; 126// Bar f_bar; 127// }; 128// 129// StructTraits for Foo: 130// template <> 131// struct StructTraits<Foo, CustomFoo> { 132// // Optional methods dealing with null: 133// static bool IsNull(const CustomFoo& input); 134// static void SetToNull(CustomFoo* output); 135// 136// // Field getters: 137// static int32_t f_integer(const CustomFoo& input); 138// static const std::string& f_string(const CustomFoo& input); 139// static const std::vector<std::string>& f_string_array( 140// const CustomFoo& input); 141// // Assuming there is a StructTraits<Bar, CustomBar> defined. 142// static const CustomBar& f_bar(const CustomFoo& input); 143// 144// static bool Read(FooDataView data, CustomFoo* output); 145// }; 146// 147template <typename MojomType, typename T> 148struct StructTraits; 149 150} // namespace mojo 151 152#endif // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_TRAITS_H_ 153