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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_ 6 #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_ 7 8 #include "base/basictypes.h" 9 #include "extensions/common/api/cast_channel.h" 10 #include "net/base/io_buffer.h" 11 12 namespace extensions { 13 namespace core_api { 14 namespace cast_channel { 15 class CastMessage; 16 17 // Class for constructing and parsing CastMessage packet data. 18 class MessageFramer { 19 public: 20 // |input_buffer|: The input buffer used by all socket read operations that 21 // feed data into the framer. 22 explicit MessageFramer(scoped_refptr<net::GrowableIOBuffer> input_buffer); 23 ~MessageFramer(); 24 25 // The number of bytes required from |input_buffer| to complete the 26 // CastMessage being read. 27 // Returns zero if |error_| is true (framer is in an invalid state.) 28 size_t BytesRequested(); 29 30 // Serializes |message_proto| into |message_data|. 31 // Returns true if the message was serialized successfully, false otherwise. 32 static bool Serialize(const CastMessage& message_proto, 33 std::string* message_data); 34 35 // Reads bytes from |input_buffer_| and returns a new CastMessage if one 36 // is fully read. 37 // 38 // |num_bytes| The number of bytes received by a read operation. 39 // Value must be <= BytesRequested(). 40 // |message_length| Size of the deserialized message object, in bytes. For 41 // logging purposes. Set to zero if no message was parsed. 42 // |error| The result of the ingest operation. Set to CHANNEL_ERROR_NONE 43 // if no error occurred. 44 // Returns A pointer to a parsed CastMessage if a message was received 45 // in its entirety, NULL otherwise. 46 scoped_ptr<CastMessage> Ingest(size_t num_bytes, 47 size_t* message_length, 48 ChannelError* error); 49 50 // Message header struct. If fields are added, be sure to update 51 // header_size(). Public to allow use of *_size() methods in unit tests. 52 struct MessageHeader { 53 MessageHeader(); 54 // Sets the message size. 55 void SetMessageSize(size_t message_size); 56 // Prepends this header to |str|. 57 void PrependToString(std::string* str); 58 // Reads |header| from the bytes specified by |data|. 59 static void Deserialize(char* data, MessageHeader* header); 60 // Size (in bytes) of the message header. 61 static size_t header_size(); 62 // Maximum size (in bytes) of a message payload on the wire (does not 63 // include header). 64 static size_t max_message_size(); 65 std::string ToString(); 66 // The size of the following protocol message in bytes, in host byte order. 67 size_t message_size; 68 }; 69 70 private: 71 enum MessageElement { HEADER, BODY }; 72 73 // Prepares the framer for ingesting a new message. 74 void Reset(); 75 76 // The element of the message that will be read on the next call to Ingest(). 77 MessageElement current_element_; 78 79 // Total size of the message, in bytes (head + body). 80 size_t message_bytes_received_; 81 82 // Size of the body alone, in bytes. 83 size_t body_size_; 84 85 // Input buffer which carries message data read from the socket. 86 // Caller is responsible for writing into this buffer. 87 scoped_refptr<net::GrowableIOBuffer> input_buffer_; 88 89 // Disables Ingest functionality is the parser receives invalid data. 90 bool error_; 91 92 DISALLOW_COPY_AND_ASSIGN(MessageFramer); 93 }; 94 } // namespace cast_channel 95 } // namespace core_api 96 } // namespace extensions 97 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_ 98