Branch data Line data Source code
1 : : /*
2 : : *
3 : : * Copyright 2006 Savarese Software Research Corporation
4 : : *
5 : : * Licensed under the Apache License, Version 2.0 (the "License");
6 : : * you may not use this file except in compliance with the License.
7 : : * You may obtain a copy of the License at
8 : : *
9 : : * http://www.savarese.com/software/ApacheLicense-2.0
10 : : *
11 : : * Unless required by applicable law or agreed to in writing, software
12 : : * distributed under the License is distributed on an "AS IS" BASIS,
13 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : : * See the License for the specific language governing permissions and
15 : : * limitations under the License.
16 : : */
17 : :
18 : : /**
19 : : * @file
20 : : * This header defines the ByteBuffer class.
21 : : */
22 : :
23 : : #ifndef __SSRC_SPREAD_DETAIL_BYTE_BUFFER_H
24 : : #define __SSRC_SPREAD_DETAIL_BYTE_BUFFER_H
25 : :
26 : : #include <ssrc/spread/detail/Buffer.h>
27 : :
28 : : __BEGIN_NS_SSRC_SPREAD
29 : :
30 : : namespace detail {
31 : :
32 : : /**
33 : : * ByteBuffer provides the ability to write and read bytes to and
34 : : * from a buffer and reuse the buffer for input or output. The
35 : : * class is not meant to be subclassed by library users, but it
36 : : * needs to be documented publicly so you can use its methods in its
37 : : * subclasses.
38 : : *
39 : : * ByteBuffer maintains a current offset into the buffer where reads
40 : : * and writes will start. The offset is not updated when the buffer
41 : : * is resized.
42 : : */
43 : 23 : class ByteBuffer : public detail::Buffer<char> {
44 : : typedef detail::Buffer<char> super;
45 : :
46 : : unsigned int _offset;
47 : :
48 : : public:
49 : :
50 : : /**
51 : : * Creates a buffer with the specified capacity and sets its size
52 : : * and offset to zero.
53 : : *
54 : : * @param capacity The initial capacity of the buffer.
55 : : */
56 : 23 : explicit ByteBuffer(const unsigned int capacity) : super(0), _offset(0) {
57 [ + - ]: 23 : super::reserve(capacity);
58 : 23 : }
59 : :
60 : : /**
61 : : * Creates a copy of a ByteBuffer, including its contents, its
62 : : * read/write position, size, and its capacity.
63 : : *
64 : : * @param buffer The ByteBuffer to copy.
65 : : */
66 : : ByteBuffer(const ByteBuffer & buffer) : super(0), _offset(0) {
67 : : super::reserve(buffer.capacity());
68 : : write(&buffer[0], buffer.size());
69 : : seek(buffer.offset());
70 : : }
71 : :
72 : : /**
73 : : * Copies the contents of a ByteBuffer, its read/write position, and
74 : : * its size, but does not necessarily copy its capacity.
75 : : *
76 : : * @param buffer The ByteBuffer to copy.
77 : : * @return *this
78 : : */
79 : : ByteBuffer & operator=(const ByteBuffer & buffer) {
80 : : if(&buffer != this) {
81 : : clear();
82 : : write(&buffer[0], buffer.size());
83 : : seek(buffer.offset());
84 : : }
85 : : return *this;
86 : : }
87 : :
88 : : /**
89 : : * Returns the current read/write position.
90 : : *
91 : : * @return The current read/write position.
92 : : */
93 : 262147 : unsigned int offset() const {
94 : 262147 : return _offset;
95 : : }
96 : :
97 : : /**
98 : : * Sets the read/write position to the specified value if the
99 : : * value is less than or equal to the size of the buffer.
100 : : * Otherwise, the current offset is left unchanged.
101 : : *
102 : : * @param offset The buffer offset of the new read/write position.
103 : : * @return The new read/write position.
104 : : */
105 : 6 : unsigned int seek(const unsigned int offset) {
106 [ + - ]: 6 : if(offset <= size())
107 : 6 : _offset = offset;
108 : 6 : return _offset;
109 : : }
110 : :
111 : : /** Same as {@link #seek seek(0)}. */
112 : 6 : void rewind() {
113 : 6 : seek(0);
114 : 6 : }
115 : :
116 : : /**
117 : : * Rewinds the read/write position befor resizing the buffer to zero.
118 : : */
119 : 6 : void clear() {
120 : 6 : rewind();
121 : 6 : resize(0);
122 : 6 : }
123 : :
124 : : /**
125 : : * Writes the specified number of bytes from the provided data into
126 : : * the buffer at the current read/write position. If the buffer is
127 : : * not large enough to hold the data, it is resized automatically to
128 : : * the current offset plus the size of the data to be written.
129 : : * After writing the data, the read/write position is incremented by
130 : : * the size of the data written.
131 : : *
132 : : * @param data A pointer to the data to be written.
133 : : * @param size The number of bytes to write.
134 : : */
135 : 294932 : void write(const void *data, const unsigned int size) {
136 : 294932 : unsigned int total = _offset + size;
137 : :
138 [ + + ]: 294932 : if(total > ByteBuffer::size())
139 : 262161 : resize(total);
140 : :
141 : 294932 : std::memcpy(&(this->operator[](_offset)), data, size);
142 : :
143 : 294932 : _offset = total;
144 : 294932 : }
145 : :
146 : : /**
147 : : * Reads the specified number of bytes from the buffer into the
148 : : * provided destination starting from the current read/write
149 : : * position. If the number of bytes to be read would result in
150 : : * running off the end of the buffer, the read is truncated at the
151 : : * end of the buffer.
152 : : *
153 : : * @param data A pointer to the read destination.
154 : : * @param size The number of bytes to read.
155 : : * @return The number of bytes read.
156 : : */
157 : : unsigned int read(void *data, unsigned int size) {
158 : : if(_offset >= ByteBuffer::size())
159 : : return 0;
160 : :
161 : : unsigned int total = _offset + size;
162 : :
163 : : if(total > ByteBuffer::size()) {
164 : : total = ByteBuffer::size();
165 : : size = total - _offset;
166 : : }
167 : :
168 : : std::memcpy(data, &(this->operator[](_offset)), size);
169 : :
170 : : _offset = total;
171 : :
172 : : return size;
173 : : }
174 : :
175 : : };
176 : :
177 : : }
178 : :
179 : : __END_NS_SSRC_SPREAD
180 : :
181 : : #endif
|