IPDL Type Serialization

All types used in IPDL must be serializable. This is accomplished through type specialization of a C++ traits class.

Types are serialized and deserialized from an IPC::Message type declared in ipc_message.h. Each type specializes IPC::ParamTraits as follows:

namespace IPC {

template <>
struct ParamTraits<MyType>
{
  typedef MyType paramType;

  static void Write(Message* aMsg, const paramType& aParam) {
    // implement serialization here
  }

  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
  {
    // implement deserialization here. return false if deserialization failed
  }
};

} // namespace IPC

The standard IPDL types (integers, floats, and XPCOM strings) already have serializers. Other types need to have serializers written for them explicitly.

In many cases a serializer can be written by combining existing serializers. Most structures can be serialized in this manner:

struct ExampleStruct
{
  int i;
  nsCString j;
  int k[4];
};

namespace IPC {

template <>
struct ParamTraits<ExampleStruct>
{
  typedef ExampleStruct paramType;

  static void Write(Message* aMsg, const paramType& aParam)
  {
    WriteParam(aMsg, aParam.i);
    WriteParam(aMsg, aParam.j);
    for (int i = 0; i < 4; ++i)
      WriteParam(aMsg, aParam.k[i]);
  }

  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
  {
    if (!ReadParam(aMsg, aIter, &(aResult->i)) ||
        !ReadParam(aMsg, aIter, &(aResult->j)))
      return false;

    for (int i = 0; i < 4; ++i)
      if (!ReadParam(aMsg, aIter, &(aResult->k[i])))
        return false;

    return true;
  }
};

} // namespace IPC

Once you have a serializer for a type, you can serialize a collection of it (ex: an nsTArray<ExampleStruct>) by simply declaring "using nsTArray<ExampleStruct>;' in your IPDL file, then using it in a IPC method.

Serializers and deserializers are security-sensitive and must always receive two reviews from module owners who understand IPC serialization well. If in doubt, please ask for help! It is never acceptable to serialize/deserialize raw pointer values; if you are tempted, you probably should create a subprotocol for that data, so that IPDL can check the values and lifetime.