| // Copyright 2013 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/system/message_in_transit.h" |
| |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <new> |
| |
| #include "base/basictypes.h" |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| #include "mojo/system/constants.h" |
| |
| namespace mojo { |
| namespace system { |
| |
| // Avoid dangerous situations, but making sure that the size of the "header" + |
| // the size of the data fits into a 31-bit number. |
| COMPILE_ASSERT(static_cast<uint64_t>(sizeof(MessageInTransit)) + |
| kMaxMessageNumBytes <= 0x7fffffff, |
| kMaxMessageNumBytes_too_big); |
| |
| COMPILE_ASSERT(sizeof(MessageInTransit) % |
| MessageInTransit::kMessageAlignment == 0, |
| sizeof_MessageInTransit_not_a_multiple_of_alignment); |
| |
| STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| MessageInTransit::kTypeMessagePipeEndpoint; |
| STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| MessageInTransit::kTypeMessagePipe; |
| STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| MessageInTransit::TYPE_CHANNEL; |
| STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| MessageInTransit::kSubtypeMessagePipeEndpointData; |
| STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| MessageInTransit::kSubtypeMessagePipePeerClosed; |
| STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId |
| MessageInTransit::kInvalidEndpointId; |
| STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; |
| |
| // static |
| MessageInTransit* MessageInTransit::Create(Type type, |
| Subtype subtype, |
| const void* bytes, |
| uint32_t num_bytes) { |
| const size_t size_with_header = sizeof(MessageInTransit) + num_bytes; |
| const size_t size_with_header_and_padding = |
| RoundUpMessageAlignment(size_with_header); |
| |
| char* buffer = static_cast<char*>(malloc(size_with_header_and_padding)); |
| DCHECK_EQ(reinterpret_cast<size_t>(buffer) % |
| MessageInTransit::kMessageAlignment, 0u); |
| |
| // The buffer consists of the header (a |MessageInTransit|, constructed using |
| // a placement new), followed by the data, followed by padding (of zeros). |
| MessageInTransit* rv = |
| new (buffer) MessageInTransit(num_bytes, type, subtype); |
| memcpy(buffer + sizeof(MessageInTransit), bytes, num_bytes); |
| memset(buffer + size_with_header, 0, |
| size_with_header_and_padding - size_with_header); |
| return rv; |
| } |
| |
| } // namespace system |
| } // namespace mojo |