// 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