1 // Copyright (c) 2011 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.
5 // CompoundBuffer implements a data buffer that is composed of several pieces,
6 // each stored in a refcounted IOBuffer. It is needed for encoding/decoding
7 // video pipeline to represent data packet and minimize data copying.
8 // It is particularly useful for splitting data between multiple RTP packets
9 // and assembling them into one buffer on the receiving side.
11 // CompoundBufferInputStream implements ZeroCopyInputStream interface
12 // to be used by protobuf to decode data stored in CompoundBuffer into
13 // a protocol buffer message.
15 // Mutations to the buffer are not thread-safe. Immutability can be ensured
16 // with the Lock() method.
18 #ifndef REMOTING_BASE_COMPOUND_BUFFER_H_
19 #define REMOTING_BASE_COMPOUND_BUFFER_H_
23 #include "base/basictypes.h"
24 #include "base/memory/ref_counted.h"
25 #include "google/protobuf/io/zero_copy_stream.h"
29 class IOBufferWithSize
;
34 class CompoundBuffer
{
41 // Adds new chunk to the buffer. |start| defines position of the chunk
42 // within the |buffer|. |size| is the size of the chunk that is being
43 // added, not size of the |buffer|.
44 void Append(net::IOBuffer
* buffer
, int size
);
45 void Append(net::IOBuffer
* buffer
, const char* start
, int size
);
46 void Append(const CompoundBuffer
& buffer
);
47 void Prepend(net::IOBuffer
* buffer
, int size
);
48 void Prepend(net::IOBuffer
* buffer
, const char* start
, int size
);
49 void Prepend(const CompoundBuffer
& buffer
);
51 // Same as above, but creates new IOBuffer and copies the data.
52 void AppendCopyOf(const char* data
, int data_size
);
53 void PrependCopyOf(const char* data
, int data_size
);
55 // Drop |bytes| bytes from the beginning or the end of the buffer.
56 void CropFront(int bytes
);
57 void CropBack(int bytes
);
59 // Current size of the buffer.
60 int total_bytes() const { return total_bytes_
; }
62 // Locks the buffer. After the buffer is locked, no data can be
63 // added or removed (content can still be changed if some other
64 // object holds reference to the IOBuffer objects).
67 // Returns true if content is locked.
68 bool locked() const { return locked_
; }
70 // Creates new IOBufferWithSize object and copies all data into it.
71 // Ownership of the result is given to the caller.
72 net::IOBufferWithSize
* ToIOBufferWithSize() const;
74 // Copies all data into given location.
75 void CopyTo(char* data
, int data_size
) const;
77 // Clears the buffer, and initializes it with the interval from |buffer|
78 // starting at |start| and ending at |end|. The data itself isn't copied.
79 void CopyFrom(const CompoundBuffer
& source
, int start
, int end
);
82 friend class CompoundBufferInputStream
;
85 DataChunk(net::IOBuffer
* buffer
, const char* start
, int size
);
88 scoped_refptr
<net::IOBuffer
> buffer
;
92 typedef std::deque
<DataChunk
> DataChunkList
;
94 DataChunkList chunks_
;
98 DISALLOW_COPY_AND_ASSIGN(CompoundBuffer
);
101 class CompoundBufferInputStream
102 : public google::protobuf::io::ZeroCopyInputStream
{
104 // Caller keeps ownership of |buffer|. |buffer| must be locked.
105 explicit CompoundBufferInputStream(const CompoundBuffer
* buffer
);
106 ~CompoundBufferInputStream() override
;
108 int position() const { return position_
; }
110 // google::protobuf::io::ZeroCopyInputStream interface.
111 bool Next(const void** data
, int* size
) override
;
112 void BackUp(int count
) override
;
113 bool Skip(int count
) override
;
114 int64
ByteCount() const override
;
117 const CompoundBuffer
* buffer_
;
119 size_t current_chunk_
;
120 int current_chunk_position_
;
122 int last_returned_size_
;
125 } // namespace remoting
127 #endif // REMOTING_BASE_COMPOUND_BUFFER_H_