2 * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 const static size_t DEFAULT_SIZE
= 0x1000;
35 ByteBuffer(): _rpos(0), _wpos(0)
37 _storage
.reserve(DEFAULT_SIZE
);
40 ByteBuffer(size_t res
): _rpos(0), _wpos(0)
42 _storage
.reserve(res
);
45 ByteBuffer(const ByteBuffer
&buf
): _rpos(buf
._rpos
), _wpos(buf
._wpos
), _storage(buf
._storage
) { }
53 template <typename T
> void append(T value
)
55 append((uint8
*)&value
, sizeof(value
));
57 template <typename T
> void put(size_t pos
,T value
)
59 put(pos
,(uint8
*)&value
,sizeof(value
));
62 ByteBuffer
&operator<<(bool value
)
64 append
<char>((char)value
);
67 ByteBuffer
&operator<<(uint8 value
)
72 ByteBuffer
&operator<<(uint16 value
)
74 append
<uint16
>(value
);
77 ByteBuffer
&operator<<(uint32 value
)
79 append
<uint32
>(value
);
82 ByteBuffer
&operator<<(uint64 value
)
84 append
<uint64
>(value
);
88 // signed as in 2e complement
89 ByteBuffer
&operator<<(int8 value
)
94 ByteBuffer
&operator<<(int16 value
)
99 ByteBuffer
&operator<<(int32 value
)
101 append
<int32
>(value
);
104 ByteBuffer
&operator<<(int64 value
)
106 append
<int64
>(value
);
111 ByteBuffer
&operator<<(float value
)
113 append
<float>(value
);
116 ByteBuffer
&operator<<(double value
)
118 append
<double>(value
);
121 ByteBuffer
&operator<<(const std::string
&value
)
123 append((uint8
*)value
.c_str(), value
.length());
127 ByteBuffer
&operator<<(const char *str
)
129 append((uint8
*)str
, str
? strlen(str
) : 0);
134 ByteBuffer
&operator>>(bool &value
)
136 value
= read
<char>() > 0 ? true : false;
139 ByteBuffer
&operator>>(uint8
&value
)
141 value
= read
<uint8
>();
144 ByteBuffer
&operator>>(uint16
&value
)
146 value
= read
<uint16
>();
149 ByteBuffer
&operator>>(uint32
&value
)
151 value
= read
<uint32
>();
154 ByteBuffer
&operator>>(uint64
&value
)
156 value
= read
<uint64
>();
160 //signed as in 2e complement
161 ByteBuffer
&operator>>(int8
&value
)
163 value
= read
<int8
>();
166 ByteBuffer
&operator>>(int16
&value
)
168 value
= read
<int16
>();
171 ByteBuffer
&operator>>(int32
&value
)
173 value
= read
<int32
>();
176 ByteBuffer
&operator>>(int64
&value
)
178 value
= read
<int64
>();
182 ByteBuffer
&operator>>(float &value
)
184 value
= read
<float>();
187 ByteBuffer
&operator>>(double &value
)
189 value
= read
<double>();
192 ByteBuffer
&operator>>(std::string
& value
)
195 while (rpos() < size()) // prevent crash at wrong string format in packet
205 uint8
operator[](size_t pos
)
207 return read
<uint8
>(pos
);
215 size_t rpos(size_t rpos
)
226 size_t wpos(size_t wpos
)
232 template <typename T
> T
read()
238 template <typename T
> T
read(size_t pos
) const
240 ASSERT(pos
+ sizeof(T
) <= size() || PrintPosError(false,pos
,sizeof(T
)));
241 return *((T
*)&_storage
[pos
]);
244 void read(uint8
*dest
, size_t len
)
246 ASSERT(_rpos
+ len
<= size() || PrintPosError(false,_rpos
,len
));
247 memcpy(dest
, &_storage
[_rpos
], len
);
251 const uint8
*contents() const { return &_storage
[0]; };
253 inline size_t size() const { return _storage
.size(); };
255 void resize(size_t newsize
)
257 _storage
.resize(newsize
);
261 void reserve(size_t ressize
)
263 if (ressize
> size()) _storage
.reserve(ressize
);
266 void append(const std::string
& str
)
268 append((uint8
*)str
.c_str(),str
.size() + 1);
270 void append(const char *src
, size_t cnt
)
272 return append((const uint8
*)src
, cnt
);
274 void append(const uint8
*src
, size_t cnt
)
278 ASSERT(size() < 10000000);
280 if (_storage
.size() < _wpos
+ cnt
)
281 _storage
.resize(_wpos
+ cnt
);
282 memcpy(&_storage
[_wpos
], src
, cnt
);
285 void append(const ByteBuffer
& buffer
)
287 if(buffer
.size()) append(buffer
.contents(),buffer
.size());
290 void put(size_t pos
, const uint8
*src
, size_t cnt
)
292 ASSERT(pos
+ cnt
<= size() || PrintPosError(true,pos
,cnt
));
293 memcpy(&_storage
[pos
], src
, cnt
);
297 printf("STORAGE_SIZE: %u\n", size() );
298 for(uint32 i
= 0; i
< size(); i
++)
299 printf("%u - ", read
<uint8
>(i
) );
305 printf("STORAGE_SIZE: %u\n", size() );
306 for(uint32 i
= 0; i
< size(); i
++)
307 printf("%c", read
<uint8
>(i
) );
315 printf("STORAGE_SIZE: %u\n", size() );
316 for(uint32 i
= 0; i
< size(); i
++)
318 if ((i
== (j
*8)) && ((i
!= (k
*16))))
320 if (read
<uint8
>(i
) < 0x0F)
322 printf("| 0%X ", read
<uint8
>(i
) );
326 printf("| %X ", read
<uint8
>(i
) );
330 else if (i
== (k
*16))
332 if (read
<uint8
>(i
) < 0x0F)
334 printf("\n0%X ", read
<uint8
>(i
) );
338 printf("\n%X ", read
<uint8
>(i
) );
346 if (read
<uint8
>(i
) < 0x0F)
348 printf("0%X ", read
<uint8
>(i
) );
352 printf("%X ", read
<uint8
>(i
) );
360 bool PrintPosError(bool add
, size_t pos
, size_t esize
) const
362 printf("ERROR: Attempt %s in ByteBuffer (pos: %u size: %u) value with size: %u",(add
? "put" : "get"),pos
, size(), esize
);
364 // assert must fail after function call
369 std::vector
<uint8
> _storage
;
372 template <typename T
> ByteBuffer
&operator<<(ByteBuffer
&b
, std::vector
<T
> v
)
374 b
<< (uint32
)v
.size();
375 for (typename
std::vector
<T
>::iterator i
= v
.begin(); i
!= v
.end(); i
++)
382 template <typename T
> ByteBuffer
&operator>>(ByteBuffer
&b
, std::vector
<T
> &v
)
396 template <typename T
> ByteBuffer
&operator<<(ByteBuffer
&b
, std::list
<T
> v
)
398 b
<< (uint32
)v
.size();
399 for (typename
std::list
<T
>::iterator i
= v
.begin(); i
!= v
.end(); i
++)
406 template <typename T
> ByteBuffer
&operator>>(ByteBuffer
&b
, std::list
<T
> &v
)
420 template <typename K
, typename V
> ByteBuffer
&operator<<(ByteBuffer
&b
, std::map
<K
, V
> &m
)
422 b
<< (uint32
)m
.size();
423 for (typename
std::map
<K
, V
>::iterator i
= m
.begin(); i
!= m
.end(); i
++)
425 b
<< i
->first
<< i
->second
;
430 template <typename K
, typename V
> ByteBuffer
&operator>>(ByteBuffer
&b
, std::map
<K
, V
> &m
)
440 m
.insert(make_pair(k
, v
));