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