length to size
[anytun.git] / buffer.cpp
blob675383b1c9d01cbceb35b2cf32070a2bcec3de1d
1 /*
2 * anytun
4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 * as published by the Free Software Foundation.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program (see the file COPYING included with this
27 * distribution); if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <stdexcept>
32 #include <string>
33 #include <sstream>
34 #include <iostream>
35 #include <boost/archive/text_oarchive.hpp>
36 #include <boost/archive/text_iarchive.hpp>
37 #include "datatypes.h"
38 #include "buffer.h"
40 Buffer::Buffer(bool allow_realloc) : buf_(0), length_(0), real_length_(0), allow_realloc_(allow_realloc)
44 Buffer::Buffer(u_int32_t length, bool allow_realloc) : length_(length), real_length_(length_ + Buffer::OVER_SIZE_),
45 allow_realloc_(allow_realloc)
47 buf_ = new u_int8_t[real_length_];
48 if(!buf_) {
49 length_ = 0;
50 real_length_ = 0;
51 throw std::bad_alloc();
53 std::memset(buf_, 0, real_length_);
56 Buffer::Buffer(u_int8_t* data, u_int32_t length, bool allow_realloc) : length_(length), real_length_(length + Buffer::OVER_SIZE_),
57 allow_realloc_(allow_realloc)
59 buf_ = new u_int8_t[real_length_];
60 if(!buf_) {
61 length_ = 0;
62 real_length_ = 0;
63 throw std::bad_alloc();
65 std::memcpy(buf_, data, length_);
68 Buffer::Buffer(std::string hex_data, bool allow_realloc) : length_(hex_data.size()/2),
69 real_length_(length_ + Buffer::OVER_SIZE_),
70 allow_realloc_(allow_realloc)
72 buf_ = new u_int8_t[real_length_];
73 if(!buf_) {
74 length_ = 0;
75 real_length_ = 0;
76 throw std::bad_alloc();
79 for(u_int32_t i=0; i<length_; ++i)
81 u_int32_t tmp;
82 std::istringstream ss(std::string(hex_data.c_str(), i*2, 2));
83 if(!(ss >> std::hex >> tmp)) tmp = 0;
84 buf_[i] = tmp;
88 Buffer::~Buffer()
90 if(buf_)
91 delete[] buf_;
94 Buffer::Buffer(const Buffer &src) : length_(src.length_), real_length_(src.real_length_), allow_realloc_(src.allow_realloc_)
96 buf_ = new u_int8_t[real_length_];
97 if(!buf_) {
98 length_ = 0;
99 real_length_ = 0;
100 throw std::bad_alloc();
102 std::memcpy(buf_, src.buf_, length_);
105 void Buffer::operator=(const Buffer &src)
107 if(buf_)
108 delete[] buf_;
110 length_ = src.length_;
111 real_length_ = src.real_length_;
112 allow_realloc_ = src.allow_realloc_;
114 buf_ = new u_int8_t[real_length_];
115 if(!buf_) {
116 length_ = 0;
117 real_length_ = 0;
118 throw std::bad_alloc();
120 std::memcpy(buf_, src.buf_, length_);
125 bool Buffer::operator==(const Buffer &cmp) const
127 if(length_ != cmp.length_)
128 return false;
130 if(!std::memcmp(buf_, cmp.buf_, length_))
131 return true;
133 return false;
136 Buffer Buffer::operator^(const Buffer &xor_by) const
138 u_int32_t res_length = (xor_by.length_ > length_) ? xor_by.length_ : length_;
139 u_int32_t min_length = (xor_by.length_ < length_) ? xor_by.length_ : length_;
140 Buffer res(res_length);
142 for( u_int32_t index = 0; index < min_length; index++ )
143 res[index] = buf_[index] ^ xor_by[index];
145 return res;
148 u_int32_t Buffer::getLength() const
150 return length_;
153 void Buffer::setLength(u_int32_t new_length)
155 if(new_length == length_)
156 return;
158 if(new_length > real_length_)
160 if(!allow_realloc_)
161 throw std::out_of_range("buffer::setLength() - reallocation not allowed for this Buffer");
163 u_int8_t* old_buf = buf_;
164 u_int32_t old_length = length_;
166 length_ = new_length;
167 real_length_ = length_ + Buffer::OVER_SIZE_;
169 buf_ = new u_int8_t[real_length_];
170 if(!buf_) {
171 length_ = 0;
172 real_length_ = 0;
173 if(old_buf)
174 delete[] old_buf;
176 throw std::bad_alloc();
178 std::memcpy(buf_, old_buf, old_length);
180 if(old_buf)
181 delete[] old_buf;
183 old_buf = &buf_[old_length];
184 std::memset(old_buf, 0, real_length_ - old_length);
186 reinit();
188 else
189 length_ = new_length;
193 u_int8_t* Buffer::getBuf()
195 return buf_;
198 u_int8_t& Buffer::operator[](u_int32_t index)
200 if(index >= length_)
201 throw std::out_of_range("buffer::operator[]");
203 return buf_[index];
206 u_int8_t Buffer::operator[](u_int32_t index) const
208 if(index >= length_)
209 throw std::out_of_range("buffer::operator[] const");
211 return buf_[index];
214 Buffer::operator u_int8_t*()
216 return buf_;
219 std::string Buffer::getHexDump() const
221 std::stringstream ss;
222 ss << "Length=" << length_ << std::endl << std::hex << std::uppercase;
223 for( u_int32_t index = 0; index < length_; index++ )
225 ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]) << " ";
226 if(!((index+1) % 16)) {
227 ss << std::endl;
228 continue;
230 if(!((index+1) % 8))
231 ss << " ";
233 return ss.str();
236 std::string Buffer::getHexDumpOneLine() const
238 std::stringstream ss;
239 ss << length_ << " Bytes,'" << std::hex << std::uppercase;
240 for( u_int32_t index = 0; index < length_; index++ )
242 ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]);
244 ss << "'";
245 return ss.str();
248 bool Buffer::isReallocAllowed() const
250 return allow_realloc_;