1// Copyright (c) 2012 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_MESSAGE_DECODER_H_
6#define REMOTING_PROTOCOL_MESSAGE_DECODER_H_
7
8#include <deque>
9#include <list>
10
11#include "base/memory/ref_counted.h"
12#include "net/base/io_buffer.h"
13#include "remoting/base/compound_buffer.h"
14
15#if defined(USE_SYSTEM_PROTOBUF)
16#include <google/protobuf/message_lite.h>
17#else
18#include "third_party/protobuf/src/google/protobuf/message_lite.h"
19#endif
20
21namespace remoting {
22namespace protocol {
23
24// MessageDecoder uses CompoundBuffer to split the data received from
25// the network into separate messages. Each message is expected to be
26// decoded in the stream as follows:
27//   +--------------+--------------+
28//   | message_size | message_data |
29//   +--------------+--------------+
30//
31// Here, message_size is 4-byte integer that represents size of
32// message_data in bytes. message_data - content of the message.
33class MessageDecoder {
34 public:
35  MessageDecoder();
36  virtual ~MessageDecoder();
37
38  // Add next chunk of data. MessageDecoder retains |data| until all
39  // its bytes are consumed.
40  void AddData(scoped_refptr<net::IOBuffer> data, int data_size);
41
42  // Returns next message from the stream. Ownership of the result is
43  // passed to the caller. Returns NULL if there are no complete
44  // messages yet, otherwise returns a buffer that contains one
45  // message.
46  CompoundBuffer* GetNextMessage();
47
48 private:
49  // Retrieves the read payload size of the current protocol buffer via |size|.
50  // Returns false and leaves |size| unmodified, if we do not have enough data
51  // to retrieve the current size.
52  bool GetPayloadSize(int* size);
53
54  CompoundBuffer buffer_;
55
56  // |next_payload_| stores the size of the next payload if known.
57  // |next_payload_known_| is true if the size of the next payload is known.
58  // After one payload is read this is reset to false.
59  int next_payload_;
60  bool next_payload_known_;
61};
62
63}  // namespace protocol
64}  // namespace remoting
65
66#endif  // REMOTING_PROTOCOL_MESSAGE_DECODER_H_
67