Libgourou

Libgourou Git Source Tree

Root/src/bytearray.cpp

1/*
2 Copyright 2021 Grégory Soutadé
3
4 This file is part of libgourou.
5
6 libgourou is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 libgourou is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with libgourou. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include <string.h>
20#include <stdexcept>
21
22#include <Base64.h>
23
24#include <bytearray.h>
25
26namespace gourou
27{
28 std::map<unsigned char*, int> ByteArray::refCounter;
29
30 ByteArray::ByteArray(bool useMalloc):_useMalloc(useMalloc), _data(0), _length(0)
31 {}
32
33 ByteArray::ByteArray(unsigned int length, bool useMalloc):
34_useMalloc(useMalloc)
35 {
36initData(0, length);
37 }
38
39 ByteArray::ByteArray(const unsigned char* data, unsigned int length):
40_useMalloc(false)
41 {
42initData(data, length);
43 }
44
45 ByteArray::ByteArray(const char* data, int length):
46_useMalloc(false)
47 {
48if (length == -1)
49 length = strlen(data);
50
51initData((unsigned char*)data, (unsigned int) length);
52 }
53
54 ByteArray::ByteArray(const std::string& str):
55_useMalloc(false)
56 {
57initData((unsigned char*)str.c_str(), (unsigned int)str.length());
58 }
59
60 void ByteArray::initData(const unsigned char* data, unsigned int length)
61 {
62if (_useMalloc)
63 _data = (unsigned char*)malloc(length);
64else
65 _data = new unsigned char[length];
66
67if (data)
68 memcpy((void*)_data, data, length);
69
70_length = length;
71
72addRef();
73 }
74
75 ByteArray::ByteArray(const ByteArray& other)
76 {
77this->_useMalloc = other._useMalloc;
78this->_data = other._data;
79this->_length = other._length;
80
81addRef();
82 }
83
84 ByteArray& ByteArray::operator=(const ByteArray& other)
85 {
86delRef();
87
88this->_useMalloc = other._useMalloc;
89this->_data = other._data;
90this->_length = other._length;
91
92addRef();
93
94return *this;
95 }
96
97 ByteArray::~ByteArray()
98 {
99delRef();
100 }
101
102 void ByteArray::addRef()
103 {
104if (!_data) return;
105
106if (refCounter.count(_data) == 0)
107 refCounter[_data] = 1;
108else
109 refCounter[_data]++;
110 }
111
112 void ByteArray::delRef()
113 {
114if (!_data) return;
115
116if (refCounter[_data] == 1)
117{
118 if (_useMalloc)
119free(_data);
120 else
121delete[] _data;
122 refCounter.erase(_data);
123}
124else
125 refCounter[_data]--;
126 }
127
128 ByteArray ByteArray::fromBase64(const ByteArray& other)
129 {
130std::string b64;
131
132macaron::Base64::Decode(std::string((char*)other._data, other._length), b64);
133
134return ByteArray(b64);
135 }
136
137 ByteArray ByteArray::fromBase64(const char* data, int length)
138 {
139std::string b64;
140
141if (length == -1)
142 length = strlen(data);
143
144macaron::Base64::Decode(std::string(data, length), b64);
145
146return ByteArray(b64);
147 }
148
149 ByteArray ByteArray::fromBase64(const std::string& str)
150 {
151return ByteArray::fromBase64(str.c_str(), str.length());
152 }
153
154 std::string ByteArray::toBase64()
155 {
156return macaron::Base64::Encode(std::string((char*)_data, _length));
157 }
158
159 ByteArray ByteArray::fromHex(const std::string& str)
160 {
161if (str.size() % 2)
162 throw std::invalid_argument("Size of hex string not multiple of 2");
163
164ByteArray res((unsigned int)(str.size()/2));
165unsigned int i;
166
167unsigned char* data = res.data();
168unsigned char cur, tmp;
169
170for (i=0; i<str.size(); i+=2)
171{
172 cur = 0;
173
174 tmp = str[i];
175 if (tmp >= 'a' && tmp <= 'f')
176cur = (tmp - 'a' + 10) << 4;
177 else if (tmp >= 'A' && tmp <= 'F')
178cur = (tmp - 'A' + 10) << 4;
179 else if (tmp >= '0' && tmp <= '9')
180cur = (tmp - '0') << 4;
181 else
182throw std::invalid_argument("Invalid character in hex string");
183
184 tmp = str[i+1];
185 if (tmp >= 'a' && tmp <= 'f')
186cur += tmp - 'a' + 10;
187 else if (tmp >= 'A' && tmp <= 'F')
188cur += tmp - 'A' + 10;
189 else if (tmp >= '0' && tmp <= '9')
190cur += tmp - '0';
191 else
192throw std::invalid_argument("Invalid character in hex string");
193
194 data[i/2] = cur;
195}
196
197return res;
198 }
199
200 std::string ByteArray::toHex()
201 {
202char* tmp = new char[_length*2+1];
203
204for(int i=0; i<(int)_length; i++)
205 sprintf(&tmp[i*2], "%02x", _data[i]);
206
207tmp[_length*2] = 0;
208
209std::string res = tmp;
210delete[] tmp;
211
212return res;
213 }
214
215 void ByteArray::append(const unsigned char* data, unsigned int length)
216 {
217if (!length)
218 return;
219
220unsigned int oldLength = _length;
221
222resize(_length+length, true);
223
224memcpy(&_data[oldLength], data, length);
225 }
226
227 void ByteArray::append(unsigned char c) { append(&c, 1);}
228 void ByteArray::append(const char* str) { append((const unsigned char*)str, strlen(str));}
229 void ByteArray::append(const std::string& str) { append((const unsigned char*)str.c_str(), str.length()); }
230
231 void ByteArray::resize(unsigned length, bool keepData)
232 {
233if (length == _length)
234 return;
235else if (length < _length)
236 _length = length ; // Don't touch data
237else // New size >
238{
239 unsigned char* newData;
240
241 if (_useMalloc)
242newData = (unsigned char*)malloc(_length+length);
243 else
244newData = new unsigned char[_length+length];
245
246 if (keepData)
247memcpy(newData, _data, _length);
248
249 delRef();
250
251 _length = length;
252 _data = newData;
253
254 addRef();
255}
256 }
257}

Archive Download this file