summaryrefslogtreecommitdiffstats
path: root/ipc/glue/SerializedStructuredCloneBuffer.h
blob: c81a1525b3d661e88b7807c96e44c35516602440 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef __IPC_GLUE_SERIALIZEDSTRUCTUREDCLONEBUFFER_H__
#define __IPC_GLUE_SERIALIZEDSTRUCTUREDCLONEBUFFER_H__

#include <algorithm>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <utility>
#include "chrome/common/ipc_message.h"
#include "chrome/common/ipc_message_utils.h"
#include "js/AllocPolicy.h"
#include "js/StructuredClone.h"
#include "mozilla/Assertions.h"
#include "mozilla/BufferList.h"
#include "mozilla/Vector.h"
#include "mozilla/mozalloc.h"
class PickleIterator;

namespace mozilla {
template <typename...>
class Variant;

namespace detail {
template <typename...>
struct VariantTag;
}
}  // namespace mozilla

namespace mozilla {

struct SerializedStructuredCloneBuffer final {
  SerializedStructuredCloneBuffer() = default;

  SerializedStructuredCloneBuffer(SerializedStructuredCloneBuffer&&) = default;
  SerializedStructuredCloneBuffer& operator=(
      SerializedStructuredCloneBuffer&&) = default;

  SerializedStructuredCloneBuffer(const SerializedStructuredCloneBuffer&) =
      delete;
  SerializedStructuredCloneBuffer& operator=(
      const SerializedStructuredCloneBuffer& aOther) = delete;

  bool operator==(const SerializedStructuredCloneBuffer& aOther) const {
    // The copy assignment operator and the equality operator are
    // needed by the IPDL generated code. We relied on the copy
    // assignment operator at some places but we never use the
    // equality operator.
    return false;
  }

  JSStructuredCloneData data{JS::StructuredCloneScope::Unassigned};
};

}  // namespace mozilla

namespace IPC {
template <>
struct ParamTraits<JSStructuredCloneData> {
  typedef JSStructuredCloneData paramType;

  static void Write(Message* aMsg, const paramType& aParam) {
    MOZ_ASSERT(!(aParam.Size() % sizeof(uint64_t)));
    WriteParam(aMsg, aParam.Size());
    aParam.ForEachDataChunk([&](const char* aData, size_t aSize) {
      return aMsg->WriteBytes(aData, aSize, sizeof(uint64_t));
    });
  }

  static bool Read(const Message* aMsg, PickleIterator* aIter,
                   paramType* aResult) {
    size_t length = 0;
    if (!ReadParam(aMsg, aIter, &length)) {
      return false;
    }
    MOZ_ASSERT(!(length % sizeof(uint64_t)));

    mozilla::BufferList<InfallibleAllocPolicy> buffers(0, 0, 4096);

    // Borrowing is not suitable to use for IPC to hand out data
    // because we often want to store the data somewhere for
    // processing after IPC has released the underlying buffers. One
    // case is PContentChild::SendGetXPCOMProcessAttributes. We can't
    // return a borrowed buffer because the out param outlives the
    // IPDL callback.
    if (length &&
        !aMsg->ExtractBuffers(aIter, length, &buffers, sizeof(uint64_t))) {
      return false;
    }

    bool success;
    mozilla::BufferList<js::SystemAllocPolicy> out =
        buffers.MoveFallible<js::SystemAllocPolicy>(&success);
    if (!success) {
      return false;
    }

    *aResult = JSStructuredCloneData(
        std::move(out), JS::StructuredCloneScope::DifferentProcess);

    return true;
  }
};

template <>
struct ParamTraits<mozilla::SerializedStructuredCloneBuffer> {
  typedef mozilla::SerializedStructuredCloneBuffer paramType;

  static void Write(Message* aMsg, const paramType& aParam) {
    WriteParam(aMsg, aParam.data);
  }

  static bool Read(const Message* aMsg, PickleIterator* aIter,
                   paramType* aResult) {
    return ReadParam(aMsg, aIter, &aResult->data);
  }

  static void Log(const paramType& aParam, std::wstring* aLog) {
    LogParam(aParam.data.Size(), aLog);
  }
};

}  // namespace IPC

#endif /* __IPC_GLUE_SERIALIZEDSTRUCTUREDCLONEBUFFER_H__ */