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#include "mojo/public/cpp/bindings/tests/router_test_util.h"
6
7#include <stddef.h>
8#include <stdint.h>
9#include <string.h>
10
11#include "mojo/public/cpp/bindings/lib/message_builder.h"
12#include "mojo/public/cpp/bindings/tests/message_queue.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace mojo {
16namespace test {
17
18void AllocRequestMessage(uint32_t name, const char* text, Message* message) {
19  size_t payload_size = strlen(text) + 1;  // Plus null terminator.
20  internal::RequestMessageBuilder builder(name, payload_size);
21  memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
22
23  builder.message()->MoveTo(message);
24}
25
26void AllocResponseMessage(uint32_t name,
27                          const char* text,
28                          uint64_t request_id,
29                          Message* message) {
30  size_t payload_size = strlen(text) + 1;  // Plus null terminator.
31  internal::ResponseMessageBuilder builder(name, payload_size, request_id);
32  memcpy(builder.buffer()->Allocate(payload_size), text, payload_size);
33
34  builder.message()->MoveTo(message);
35}
36
37MessageAccumulator::MessageAccumulator(MessageQueue* queue,
38                                       const base::Closure& closure)
39    : queue_(queue), closure_(closure) {}
40
41MessageAccumulator::~MessageAccumulator() {}
42
43bool MessageAccumulator::Accept(Message* message) {
44  queue_->Push(message);
45  if (!closure_.is_null()) {
46    closure_.Run();
47    closure_.Reset();
48  }
49  return true;
50}
51
52ResponseGenerator::ResponseGenerator() {}
53
54bool ResponseGenerator::Accept(Message* message) {
55  return false;
56}
57
58bool ResponseGenerator::AcceptWithResponder(
59    Message* message,
60    MessageReceiverWithStatus* responder) {
61  EXPECT_TRUE(message->has_flag(Message::kFlagExpectsResponse));
62
63  bool result = SendResponse(message->name(), message->request_id(),
64                             reinterpret_cast<const char*>(message->payload()),
65                             responder);
66  EXPECT_TRUE(responder->IsValid());
67  delete responder;
68  return result;
69}
70
71bool ResponseGenerator::SendResponse(uint32_t name,
72                                     uint64_t request_id,
73                                     const char* request_string,
74                                     MessageReceiver* responder) {
75  Message response;
76  std::string response_string(request_string);
77  response_string += " world!";
78  AllocResponseMessage(name, response_string.c_str(), request_id, &response);
79
80  return responder->Accept(&response);
81}
82
83LazyResponseGenerator::LazyResponseGenerator(const base::Closure& closure)
84    : responder_(nullptr), name_(0), request_id_(0), closure_(closure) {}
85
86LazyResponseGenerator::~LazyResponseGenerator() {
87  delete responder_;
88}
89
90bool LazyResponseGenerator::AcceptWithResponder(
91    Message* message,
92    MessageReceiverWithStatus* responder) {
93  name_ = message->name();
94  request_id_ = message->request_id();
95  request_string_ =
96      std::string(reinterpret_cast<const char*>(message->payload()));
97  responder_ = responder;
98  if (!closure_.is_null()) {
99    closure_.Run();
100    closure_.Reset();
101  }
102  return true;
103}
104
105void LazyResponseGenerator::Complete(bool send_response) {
106  if (send_response) {
107    SendResponse(name_, request_id_, request_string_.c_str(), responder_);
108  }
109  delete responder_;
110  responder_ = nullptr;
111}
112
113}  // namespace test
114}  // namespace mojo
115