Home | History | Annotate | Download | only in ipc
      1 // Copyright 2014 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 #ifndef CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_H_
      6 #define CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_H_
      7 
      8 #include <stddef.h>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/callback.h"
     12 #include "base/macros.h"
     13 #include "base/memory/scoped_ptr.h"
     14 
     15 namespace chromecast {
     16 namespace media {
     17 class MediaMemoryChunk;
     18 
     19 // MediaMessage -
     20 // Represents a media message, including:
     21 // - a message header that gives for example the message size or its type,
     22 // - the content of the message,
     23 // - and some possible padding if the content does not occupy the whole
     24 //   reserved space.
     25 //
     26 class MediaMessage {
     27  public:
     28   // Memory allocator: given a number of bytes to allocate,
     29   // return the pointer to the allocated block if successful
     30   // or NULL if allocation failed.
     31   typedef base::Callback<scoped_ptr<MediaMemoryChunk>(size_t)>
     32       MemoryAllocatorCB;
     33 
     34   // Creates a message with no associated memory for its content, i.e.
     35   // each write on this message is a dummy operation.
     36   // This type of message can be useful to calculate first the size of the
     37   // message, before allocating the real message.
     38   static scoped_ptr<MediaMessage> CreateDummyMessage(uint32 type);
     39 
     40   // Creates a message with a capacity of at least |msg_content_capacity|
     41   // bytes. The actual content size can be smaller than its capacity.
     42   // The message can be populated with some Write functions.
     43   static scoped_ptr<MediaMessage> CreateMessage(
     44       uint32 type,
     45       const MemoryAllocatorCB& memory_allocator,
     46       size_t msg_content_capacity);
     47 
     48   // Creates a message of type |type| whose serialized structure is stored
     49   // in |mem|.
     50   static scoped_ptr<MediaMessage> CreateMessage(
     51       uint32 type,
     52       scoped_ptr<MediaMemoryChunk> mem);
     53 
     54   // Creates a message from a memory area which already contains
     55   // the serialized structure of the message.
     56   // Only Read functions can be invoked on this type of message.
     57   static scoped_ptr<MediaMessage> MapMessage(
     58       scoped_ptr<MediaMemoryChunk> mem);
     59 
     60   // Return the minimum size of a message.
     61   static size_t minimum_msg_size() {
     62     return offsetof(SerializedMsg, content);
     63   }
     64 
     65   ~MediaMessage();
     66 
     67   // Indicate whether the underlying serialized structure of the message is
     68   // available.
     69   // Note: the serialized structure might be unavailable in case of a dummy
     70   // message or if the underlying memory has been invalidated.
     71   bool IsSerializedMsgAvailable() const;
     72 
     73   // Return the message and the total size of the message
     74   // incuding the header, the content and the possible padding.
     75   const void* msg() const { return msg_read_only_; }
     76   size_t size() const { return cached_msg_.header.size; }
     77 
     78   // Return the size of the message without padding.
     79   size_t actual_size() const {
     80     return minimum_msg_size() + cached_msg_.header.content_size;
     81   }
     82 
     83   // Return the size of the content of the message.
     84   size_t content_size() const { return cached_msg_.header.content_size; }
     85 
     86   // Return the type of the message.
     87   uint32 type() const { return cached_msg_.header.type; }
     88 
     89   // Append a POD to the message.
     90   // Return true if the POD has been succesfully written.
     91   template<typename T> bool WritePod(T* const& pod);
     92   template<typename T> bool WritePod(const T& pod) {
     93     return WriteBuffer(&pod, sizeof(T));
     94   }
     95 
     96   // Append a raw buffer to the message.
     97   bool WriteBuffer(const void* src, size_t size);
     98 
     99   // Read a POD from the message.
    100   template<typename T> bool ReadPod(T* pod) {
    101     return ReadBuffer(pod, sizeof(T));
    102   }
    103 
    104   // Read |size| bytes from the message from the last read position
    105   // and write it to |dst|.
    106   bool ReadBuffer(void* dst, size_t size);
    107 
    108   // Return a pointer to a buffer of size |size|.
    109   // Return NULL if not successful.
    110   const void* GetBuffer(size_t size);
    111   void* GetWritableBuffer(size_t size);
    112 
    113  private:
    114   MediaMessage(uint32 type, size_t msg_size);
    115   MediaMessage(uint32 type, scoped_ptr<MediaMemoryChunk> memory);
    116   MediaMessage(scoped_ptr<MediaMemoryChunk> memory);
    117 
    118   struct Header {
    119     // Total size of the message (including both header & content).
    120     uint32 size;
    121     // Indicate the message type.
    122     uint32 type;
    123     // Actual size of the content in the message.
    124     uint32 content_size;
    125   };
    126 
    127   struct SerializedMsg {
    128     // Message header.
    129     Header header;
    130 
    131     // Start of the content of the message.
    132     // Use uint8_t since no special alignment is needed.
    133     uint8 content;
    134   };
    135 
    136   // Indicate whether the message is a dummy message, i.e. a message without
    137   // a complete underlying serialized structure: only the message header is
    138   // available.
    139   bool is_dummy_msg_;
    140 
    141   // |cached_msg_| is used for 2 purposes:
    142   // - to create a dummy message
    143   // - for security purpose: cache the msg header to avoid browser security
    144   // issues.
    145   SerializedMsg cached_msg_;
    146   Header* const cached_header_;
    147 
    148   SerializedMsg* msg_;
    149   SerializedMsg* msg_read_only_;
    150 
    151   // Memory allocated to store the underlying serialized structure into memory.
    152   // Note: a dummy message has no underlying serialized structure:
    153   // |mem_| is a null pointer in that case.
    154   scoped_ptr<MediaMemoryChunk> mem_;
    155 
    156   // Read iterator into the message.
    157   size_t rd_offset_;
    158 
    159   DISALLOW_COPY_AND_ASSIGN(MediaMessage);
    160 };
    161 
    162 }  // namespace media
    163 }  // namespace chromecast
    164 
    165 #endif
    166