1// Copyright 2013 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/message.h"
6
7#include <stdlib.h>
8
9#include <algorithm>
10
11#include "mojo/public/cpp/environment/logging.h"
12
13namespace mojo {
14
15Message::Message()
16    : data_num_bytes_(0),
17      data_(NULL) {
18}
19
20Message::~Message() {
21  free(data_);
22
23  for (std::vector<Handle>::iterator it = handles_.begin();
24       it != handles_.end(); ++it) {
25    if (it->is_valid())
26      CloseRaw(*it);
27  }
28}
29
30void Message::AllocUninitializedData(uint32_t num_bytes) {
31  MOJO_DCHECK(!data_);
32  data_num_bytes_ = num_bytes;
33  data_ = static_cast<internal::MessageData*>(malloc(num_bytes));
34}
35
36void Message::AdoptData(uint32_t num_bytes, internal::MessageData* data) {
37  MOJO_DCHECK(!data_);
38  data_num_bytes_ = num_bytes;
39  data_ = data;
40}
41
42void Message::Swap(Message* other) {
43  std::swap(data_num_bytes_, other->data_num_bytes_);
44  std::swap(data_, other->data_);
45  std::swap(handles_, other->handles_);
46}
47
48MojoResult ReadAndDispatchMessage(MessagePipeHandle handle,
49                                  MessageReceiver* receiver,
50                                  bool* receiver_result) {
51  MojoResult rv;
52
53  uint32_t num_bytes = 0, num_handles = 0;
54  rv = ReadMessageRaw(handle,
55                      NULL,
56                      &num_bytes,
57                      NULL,
58                      &num_handles,
59                      MOJO_READ_MESSAGE_FLAG_NONE);
60  if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED)
61    return rv;
62
63  Message message;
64  message.AllocUninitializedData(num_bytes);
65  message.mutable_handles()->resize(num_handles);
66
67  rv = ReadMessageRaw(handle,
68                      message.mutable_data(),
69                      &num_bytes,
70                      message.mutable_handles()->empty()
71                          ? NULL
72                          : reinterpret_cast<MojoHandle*>(
73                                &message.mutable_handles()->front()),
74                      &num_handles,
75                      MOJO_READ_MESSAGE_FLAG_NONE);
76  if (receiver && rv == MOJO_RESULT_OK)
77    *receiver_result = receiver->Accept(&message);
78
79  return rv;
80}
81
82}  // namespace mojo
83