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

ipc / ipc_message_templates_impl.h [blame]

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_
#define IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_

#include <tuple>

namespace IPC {

template <typename... Ts>
class ParamDeserializer : public MessageReplyDeserializer {
 public:
  explicit ParamDeserializer(const std::tuple<Ts&...>& out) : out_(out) {}

  bool SerializeOutputParameters(const IPC::Message& msg,
                                 base::PickleIterator iter) override {
    return ReadParam(&msg, &iter, &out_);
  }

  std::tuple<Ts&...> out_;
};

template <typename Meta, typename... Ins>
MessageT<Meta, std::tuple<Ins...>, void>::MessageT(Routing routing,
                                                    const Ins&... ins)
    : Message(routing.id, ID, PRIORITY_NORMAL) {
  WriteParam(this, std::tie(ins...));
}

template <typename Meta, typename... Ins>
bool MessageT<Meta, std::tuple<Ins...>, void>::Read(const Message* msg,
                                                     Param* p) {
  base::PickleIterator iter(*msg);
  return ReadParam(msg, &iter, p);
}

template <typename Meta, typename... Ins>
void MessageT<Meta, std::tuple<Ins...>, void>::Log(std::string* name,
                                                    const Message* msg,
                                                    std::string* l) {
  if (name)
    *name = Meta::kName;
  if (!msg || !l)
    return;
  Param p;
  if (Read(msg, &p))
    LogParam(p, l);
}

template <typename Meta, typename... Ins, typename... Outs>
MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::MessageT(
    Routing routing,
    const Ins&... ins,
    Outs*... outs)
    : SyncMessage(
          routing.id,
          ID,
          PRIORITY_NORMAL,
          std::make_unique<ParamDeserializer<Outs...>>(std::tie(*outs...))) {
  WriteParam(this, std::tie(ins...));
}

template <typename Meta, typename... Ins, typename... Outs>
bool MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::ReadSendParam(
    const Message* msg,
    SendParam* p) {
  base::PickleIterator iter = SyncMessage::GetDataIterator(msg);
  return ReadParam(msg, &iter, p);
}

template <typename Meta, typename... Ins, typename... Outs>
bool MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::ReadReplyParam(
    const Message* msg,
    ReplyParam* p) {
  base::PickleIterator iter = SyncMessage::GetDataIterator(msg);
  return ReadParam(msg, &iter, p);
}

template <typename Meta, typename... Ins, typename... Outs>
void MessageT<Meta,
              std::tuple<Ins...>,
              std::tuple<Outs...>>::WriteReplyParams(Message* reply,
                                                      const Outs&... outs) {
  WriteParam(reply, std::tie(outs...));
}

template <typename Meta, typename... Ins, typename... Outs>
void MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::Log(
    std::string* name,
    const Message* msg,
    std::string* l) {
  if (name)
    *name = Meta::kName;
  if (!msg || !l)
    return;
  if (msg->is_sync()) {
    SendParam p;
    if (ReadSendParam(msg, &p))
      LogParam(p, l);
    AddOutputParamsToLog(msg, l);
  } else {
    ReplyParam p;
    if (ReadReplyParam(msg, &p))
      LogParam(p, l);
  }
}

}  // namespace IPC

#endif  // IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_