OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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 REMOTING_PROTOCOL_MESSAGES_DECODER_H_ |
| 6 #define REMOTING_PROTOCOL_MESSAGES_DECODER_H_ |
| 7 |
| 8 #include <deque> |
| 9 #include <list> |
| 10 |
| 11 #include "base/ref_counted.h" |
| 12 #include "base/scoped_ptr.h" |
| 13 #include "google/protobuf/message_lite.h" |
| 14 |
| 15 namespace net { |
| 16 class DrainableIOBuffer; |
| 17 class IOBuffer; |
| 18 } // namespace net |
| 19 |
| 20 namespace remoting { |
| 21 |
| 22 class ChromotingClientMessage; |
| 23 class ChromotingHostMessage; |
| 24 class ClientControlMessage; |
| 25 class ClientEventMessage; |
| 26 class HostControlMessage; |
| 27 class HostEventMessage; |
| 28 class MultipleArrayInputStream; |
| 29 |
| 30 // MessageDecoder uses MultipleArrayInputStream to decode bytes into |
| 31 // protocol buffer messages. This can be used to decode bytes received from |
| 32 // the network. |
| 33 // |
| 34 // It provides ParseMessages() which accepts an IOBuffer. If enough bytes |
| 35 // are collected to produce protocol buffer messages then the bytes will be |
| 36 // consumed and the generated protocol buffer messages are added to the output |
| 37 // list. |
| 38 // |
| 39 // It retains ownership of IOBuffer given to this object and keeps it alive |
| 40 // until it is full consumed. |
| 41 class MessageDecoder { |
| 42 public: |
| 43 MessageDecoder(); |
| 44 virtual ~MessageDecoder(); |
| 45 |
| 46 // Parses the bytes in |data| into a protobuf of type MessageType. The bytes |
| 47 // in |data| are conceptually a stream of bytes to be parsed into a series of |
| 48 // protobufs. Each parsed protouf is appended into the |messages|. All calls |
| 49 // to ParseMessages should use same MessageType for any single instace of |
| 50 // MessageDecoder. |
| 51 |
| 52 // This function retains |data| until all its bytes are consumed. |
| 53 // Ownership of the produced protobufs is passed to the caller via the |
| 54 // |messages| list. |
| 55 template <class MessageType> |
| 56 void ParseMessages(scoped_refptr<net::IOBuffer> data, |
| 57 int data_size, std::list<MessageType*>* messages) { |
| 58 AddBuffer(data, data_size); |
| 59 |
| 60 // Then try to parse the next message until we can't parse anymore. |
| 61 MessageType* message; |
| 62 while (ParseOneMessage<MessageType>(&message)) { |
| 63 messages->push_back(message); |
| 64 } |
| 65 } |
| 66 |
| 67 private: |
| 68 // TODO(sergeyu): It might be more efficient to memcopy data to one big buffer |
| 69 // instead of storing chunks in dqueue. |
| 70 typedef std::deque<scoped_refptr<net::DrainableIOBuffer> > BufferList; |
| 71 |
| 72 // Parse one message from |buffer_list_|. Return true if sucessful. |
| 73 template <class MessageType> |
| 74 bool ParseOneMessage(MessageType** message) { |
| 75 scoped_ptr<MultipleArrayInputStream> stream(CreateInputStreamFromData()); |
| 76 if (!stream.get()) |
| 77 return false; |
| 78 |
| 79 *message = new MessageType(); |
| 80 bool ret = (*message)->ParseFromZeroCopyStream(stream.get()); |
| 81 if (!ret) { |
| 82 delete *message; |
| 83 } |
| 84 return ret; |
| 85 } |
| 86 |
| 87 void AddBuffer(scoped_refptr<net::IOBuffer> data, int data_size); |
| 88 |
| 89 MultipleArrayInputStream* CreateInputStreamFromData(); |
| 90 |
| 91 // Retrieves the read payload size of the current protocol buffer via |size|. |
| 92 // Returns false and leaves |size| unmodified, if we do not have enough data |
| 93 // to retrieve the current size. |
| 94 bool GetPayloadSize(int* size); |
| 95 |
| 96 BufferList buffer_list_; |
| 97 |
| 98 // The number of bytes in |buffer_list_| not consumed. |
| 99 int available_bytes_; |
| 100 |
| 101 // |next_payload_| stores the size of the next payload if known. |
| 102 // |next_payload_known_| is true if the size of the next payload is known. |
| 103 // After one payload is read this is reset to false. |
| 104 int next_payload_; |
| 105 bool next_payload_known_; |
| 106 }; |
| 107 |
| 108 } // namespace remoting |
| 109 |
| 110 #endif // REMOTING_PROTOCOL_MESSAGES_DECODER_H_ |
OLD | NEW |