aboutsummaryrefslogtreecommitdiff
path: root/mojo/public/cpp/bindings/lib/message_buffer.cc
blob: af79cfd251354ba919f1734acf7edfea22ecadef (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
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/public/cpp/bindings/lib/message_buffer.h"

#include <limits>

#include "mojo/public/cpp/bindings/lib/serialization_util.h"

namespace mojo {
namespace internal {

MessageBuffer::MessageBuffer(size_t capacity, bool zero_initialized) {
  DCHECK_LE(capacity, std::numeric_limits<uint32_t>::max());
  data_num_bytes_ = static_cast<uint32_t>(capacity);

  MojoResult rv = AllocMessage(capacity, nullptr, 0,
                               MOJO_ALLOC_MESSAGE_FLAG_NONE, &message_);
  CHECK_EQ(rv, MOJO_RESULT_OK);

  if (capacity == 0) {
    buffer_ = nullptr;
  } else {
    rv = GetMessageBuffer(message_.get(), &buffer_);
    CHECK_EQ(rv, MOJO_RESULT_OK);

    if (zero_initialized)
      memset(buffer_, 0, capacity);
  }
}

MessageBuffer::MessageBuffer(ScopedMessageHandle message, uint32_t num_bytes) {
  message_ = std::move(message);
  data_num_bytes_ = num_bytes;

  if (num_bytes == 0) {
    buffer_ = nullptr;
  } else {
    MojoResult rv = GetMessageBuffer(message_.get(), &buffer_);
    CHECK_EQ(rv, MOJO_RESULT_OK);
  }
}

MessageBuffer::~MessageBuffer() {}

void* MessageBuffer::Allocate(size_t delta) {
  delta = internal::Align(delta);

  DCHECK_LE(delta, static_cast<size_t>(data_num_bytes_));
  DCHECK_GT(bytes_claimed_ + static_cast<uint32_t>(delta), bytes_claimed_);

  uint32_t new_bytes_claimed = bytes_claimed_ + static_cast<uint32_t>(delta);
  if (new_bytes_claimed > data_num_bytes_) {
    NOTREACHED();
    return nullptr;
  }

  char* start = static_cast<char*>(buffer_) + bytes_claimed_;
  bytes_claimed_ = new_bytes_claimed;
  return static_cast<void*>(start);
}

void MessageBuffer::NotifyBadMessage(const std::string& error) {
  DCHECK(message_.is_valid());
  MojoResult result = mojo::NotifyBadMessage(message_.get(), error);
  DCHECK_EQ(result, MOJO_RESULT_OK);
}

}  // namespace internal
}  // namespace mojo