1 /**
2  * @file
3  */
4 
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23 */
24 
25 #include "common.h"
26 
dbuffer(int reserve)27 dbuffer::dbuffer (int reserve) : _length(0)
28 {
29 	_data.reserve(reserve);
30 }
31 
dbuffer(const dbuffer & other)32 dbuffer::dbuffer (const dbuffer &other)
33 {
34 	_data = other._data;
35 	_length = other._length;
36 }
37 
~dbuffer()38 dbuffer::~dbuffer ()
39 {
40 }
41 
add(const char * data,size_t len)42 void dbuffer::add (const char* data, size_t len)
43 {
44 	_data.insert(_data.begin() + _length, data, data + len);
45 	_length += len;
46 }
47 
48 /**
49  * @brief Read data from a dbuffer
50  * @param[out] data pointer to where the data should be copied
51  * @param[in] len maximum number of bytes to copy
52  * @return number of bytes copied
53  *
54  * @par
55  * Copies up to @c len bytes into @c data
56  *
57  * @par
58  * If the buffer does not contain at least @c len bytes, then as many
59  * bytes as are present will be copied.
60  */
get(char * data,size_t len) const61 size_t dbuffer::get (char* data, size_t len) const
62 {
63 	if (len > _length) {
64 		len = _length;
65 	}
66 	std::vector<char>::const_iterator copyEnd = _data.begin() + len;
67 	std::copy(_data.begin(), copyEnd, data);
68 
69 	return len;
70 }
71 
72 /**
73  * @brief Read data from a dbuffer
74  * @param[in] offset the offset in the source buffer where data should be copied from
75  * @param[out] data pointer to where the data should be copied
76  * @param[in] len maximum number of bytes to copy
77  * @return number of bytes copied
78  *
79  * @par
80  * Copies up to @c len bytes into @c data
81  *
82  * @par
83  * If the buffer does not contain at least @c len bytes after offset,
84  * then as many bytes as are present will be copied.
85  */
getAt(size_t offset,char * data,size_t len) const86 size_t dbuffer::getAt (size_t offset, char* data, size_t len) const
87 {
88 	if (offset > _length)
89 		return 0;
90 
91 	std::vector<char>::const_iterator copyBegin = _data.begin() + offset;
92 	len = std::min(len, _length - offset);
93 	std::vector<char>::const_iterator copyEnd = copyBegin + len;
94 	std::copy(copyBegin, copyEnd, data);
95 
96 	return len;
97 }
98 
99 /**
100  * @brief Deletes data from a dbuffer
101  * @param[in] len number of bytes to delete
102  * Deletes the given number of bytes from the start of the dbuffer
103  */
remove(size_t len)104 size_t dbuffer::remove (size_t len)
105 {
106 	if (len <= 0) {
107 		return 0;
108 	}
109 
110 	if (len > _length) {
111 		len = _length;
112 	}
113 	std::vector<char>::iterator eraseEnd = _data.begin() + len;
114 	_data.erase(_data.begin(), eraseEnd);
115 	_length -= len;
116 	return len;
117 }
118 
119 /**
120  * @brief Read and delete data from a dbuffer
121  * @param[out] data pointer to where the data should be copied
122  * @param[in] len maximum number of bytes to copy
123  * @return number of bytes copied
124  *
125  * @par
126  * Copies up to @c len bytes into @c data, and removes them from the dbuffer
127  *
128  * @par
129  * If the buffer does not contain at least @c len bytes, then as many
130  * bytes as are present will be copied.
131  *
132  * @par
133  * However many bytes are copied, exactly that many will be removed
134  * from the start of the dbuffer.
135  */
extract(char * data,size_t len)136 size_t dbuffer::extract (char* data, size_t len)
137 {
138 	len = get(data, len);
139 	remove(len);
140 	return len;
141 }
142