// 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. #ifndef MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ #define MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ #include <stdint.h> #include <stdlib.h> // For |free()|. #include "base/basictypes.h" #include "mojo/system/system_impl_export.h" namespace mojo { namespace system { // This class is used to represent data in transit. It is thread-unsafe. // Note: This class is POD. class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { public: typedef uint16_t Type; // Messages that are forwarded to |MessagePipeEndpoint|s. static const Type kTypeMessagePipeEndpoint = 0; // Messages that are forwarded to |MessagePipe|s. static const Type kTypeMessagePipe = 1; // Messages that are consumed by the channel. static const Type TYPE_CHANNEL = 2; typedef uint16_t Subtype; // Subtypes for type |kTypeMessagePipeEndpoint|: static const Subtype kSubtypeMessagePipeEndpointData = 0; // Subtypes for type |kTypeMessagePipe|: static const Subtype kSubtypeMessagePipePeerClosed = 0; typedef uint32_t EndpointId; // Never a valid endpoint ID. static const EndpointId kInvalidEndpointId = 0; // Messages (the header and data) must always be aligned to a multiple of this // quantity (which must be a power of 2). static const size_t kMessageAlignment = 8; // Creates a |MessageInTransit| of the given |type| and |subtype|, with the // data given by |bytes|/|num_bytes|. static MessageInTransit* Create(Type type, Subtype subtype, const void* bytes, uint32_t num_bytes); // Destroys a |MessageInTransit| created using |Create()|. inline void Destroy() { // No need to call the destructor, since we're POD. free(this); } // Gets the size of the data (in number of bytes). uint32_t data_size() const { return size_; } // Gets the data (of size |size()| bytes). const void* data() const { return reinterpret_cast<const char*>(this) + sizeof(*this); } size_t size_with_header_and_padding() const { return RoundUpMessageAlignment(sizeof(*this) + size_); } Type type() const { return type_; } Subtype subtype() const { return subtype_; } EndpointId source_id() const { return source_id_; } EndpointId destination_id() const { return destination_id_; } void set_source_id(EndpointId source_id) { source_id_ = source_id; } void set_destination_id(EndpointId destination_id) { destination_id_ = destination_id; } // TODO(vtl): Add whatever's necessary to transport handles. // Rounds |n| up to a multiple of |kMessageAlignment|. static inline size_t RoundUpMessageAlignment(size_t n) { return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1); } private: explicit MessageInTransit(uint32_t size, Type type, Subtype subtype) : size_(size), type_(type), subtype_(subtype), source_id_(kInvalidEndpointId), destination_id_(kInvalidEndpointId) {} // "Header" for the data. uint32_t size_; Type type_; Subtype subtype_; EndpointId source_id_; EndpointId destination_id_; // Intentionally unimplemented (and private): Use |Destroy()| instead (which // simply frees the memory). ~MessageInTransit(); DISALLOW_COPY_AND_ASSIGN(MessageInTransit); }; // The size of |MessageInTransit| must be appropriate to maintain alignment of // the following data. COMPILE_ASSERT(sizeof(MessageInTransit) == 16, MessageInTransit_has_wrong_size); } // namespace system } // namespace mojo #endif // MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_