Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
459 andreas 1
/*
2
 * Copyright (C) 2024 by Andreas Theofilu <andreas@theosys.at>
3
 *
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 3 of the License, or
7
 * (at your option) any later version.
8
 *
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.
13
 *
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 Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <cstring>
20
 
21
#include "tbytearray.h"
22
#include "terror.h"
23
 
24
using std::string;
25
 
26
TByteArray::TByteArray()
27
{
28
    DECL_TRACER("TByteArray::TByteArray()");
29
}
30
 
31
TByteArray::TByteArray(TByteArray& arr)
32
{
33
    DECL_TRACER("TByteArray::TByteArray(TByteArray& arr)");
34
 
35
    if (!arr.mSize)
36
        return;
37
 
38
    mBuffer = new unsigned char[arr.mSize];
39
    memcpy(mBuffer, arr.mBuffer, arr.mSize);
40
    mSize = arr.mSize;
41
}
42
 
43
TByteArray::TByteArray(const unsigned char* data, size_t len)
44
{
45
    DECL_TRACER("TByteArray::TByteArray(const unsigned char* data, size_t len)");
46
 
47
    if (!len)
48
        return;
49
 
50
    mBuffer = new unsigned char[len];
51
    memcpy(mBuffer, data, len);
52
    mSize = len;
53
}
54
 
55
TByteArray::TByteArray(const string& data)
56
{
57
    DECL_TRACER("TByteArray::TByteArray(const string& data)");
58
 
59
    if (data.empty())
60
        return;
61
 
62
    mBuffer = new unsigned char[data.length()];
63
    memcpy(mBuffer, data.c_str(), data.length());
64
    mSize = data.length();
65
}
66
 
67
TByteArray::~TByteArray()
68
{
69
    DECL_TRACER("TByteArray::~TByteArray()");
70
 
71
    if (mBuffer)
72
        delete[] mBuffer;
73
}
74
 
75
void TByteArray::assign(unsigned char *data, size_t len)
76
{
77
    DECL_TRACER("TByteArray::assign(unsigned char *data, size_t len)");
78
 
79
    if (!data)
80
        return;
81
 
82
    if (mBuffer)
83
    {
84
        delete[] mBuffer;
85
        mBuffer = nullptr;
86
    }
87
 
88
    mSize = len;
89
 
90
    if (!len)
91
        return;
92
 
93
    mBuffer = new unsigned char[len];
94
    memcpy(mBuffer, data, len);
95
}
96
 
97
void TByteArray::assign(const string& data)
98
{
99
    DECL_TRACER("TByteArray::assign(const string& data)");
100
 
101
    assign((unsigned char *)data.c_str(), data.length());
102
}
103
 
104
void TByteArray::assign(const TByteArray& arr)
105
{
106
    DECL_TRACER("TByteArray::assign(const TByteArray& arr)");
107
 
108
    assign(arr.mBuffer, arr.mSize);
109
}
110
 
111
void TByteArray::append(unsigned char *data, size_t len)
112
{
113
    DECL_TRACER("TByteArray::append(unsigned char *data, size_t len)");
114
 
115
    if (!data)
116
        return;
117
 
118
    if (len == 0)
119
        return;
120
 
121
    if (!mSize)
122
    {
123
        assign(data, len);
124
        return;
125
    }
126
 
127
    size_t newLen = mSize + len;
128
    unsigned char *buf = new unsigned char[newLen];
129
 
130
    memcpy(buf, mBuffer, mSize);
131
    memcpy(buf+mSize, data, len);
132
    mSize = newLen;
133
    delete[] mBuffer;
134
    mBuffer = buf;
135
}
136
 
137
void TByteArray::append(const string& data)
138
{
139
    DECL_TRACER("TByteArray::append(const string& data)");
140
 
141
    append((unsigned char *)data.c_str(), data.length());
142
}
143
 
144
void TByteArray::append(const TByteArray& arr)
145
{
146
    DECL_TRACER("TByteArray::append(const TByteArray& arr)");
147
 
148
    append(arr.mBuffer, arr.mSize);
149
}
150
 
151
unsigned char *TByteArray::hexStrToByte(const string& hstr, size_t *size)
152
{
153
    DECL_TRACER("TByteArray::hexStrToByte(const string& hstr)");
154
 
155
    if (hstr.empty())
156
        return nullptr;
157
 
158
    // Test string for hex digits and determine the translateable length
159
    size_t len = 0;
160
 
161
    for (size_t i = 0; i < hstr.length(); ++i)
162
    {
163
        if (!isxdigit(hstr[i]))
164
            break;
165
 
166
        len++;
167
    }
168
 
169
    if (!len || (len % 2) != 0) // Is the number of digits an equal number?
170
        return nullptr;         // No, then return. We do no padding.
171
 
172
    unsigned char *bytes = new unsigned char[len / 2];
173
    size_t pos = 0;
174
 
175
    if (size)
176
        *size = len / 2;
177
 
178
    for (size_t i = 0; i < len; i += 2)
179
    {
180
        char *endptr;
181
        string sbyte = hstr.substr(i, 2);
182
        unsigned long ch = strtoul(sbyte.c_str(), &endptr, 16);
183
 
184
        if (errno != 0)
185
        {
186
            MSG_ERROR("Error interpreting number " << sbyte << " into hex: " << strerror(errno));
187
            delete[] bytes;
188
            return nullptr;
189
        }
190
 
191
        if (endptr == sbyte.c_str())
192
        {
193
            MSG_ERROR("No digits were found!");
194
            delete[] bytes;
195
            return nullptr;
196
        }
197
 
198
        *(bytes + pos) = static_cast<int>(ch);
199
        pos++;
200
    }
201
 
202
    return bytes;
203
}
204
 
205
string TByteArray::toString()
206
{
207
    DECL_TRACER("TByteArray::toString()");
208
 
209
    return string(reinterpret_cast<char *>(mBuffer), mSize);
210
}
211
 
212
unsigned char *TByteArray::toSerial(unsigned char *erg, bool bigEndian)
213
{
214
    DECL_TRACER("TByteArray::toSerial(unsigned char *erg)");
215
 
216
    if (!mSize)
217
        return nullptr;
218
 
219
    size_t len = mSize + 4;
220
    unsigned char *buf = nullptr;
221
 
222
    if (!erg)
223
        buf = new unsigned char[len];
224
    else
225
        buf = erg;
226
 
227
    u_int32_t bsize = static_cast<u_int32_t>(mSize);
228
 
229
    if (bigEndian && !isBigEndian())
230
        swapBytes(reinterpret_cast<unsigned char *>(&bsize), sizeof(bsize));
231
 
232
    memcpy(buf, &bsize, sizeof(bsize));
233
    memcpy(buf+sizeof(bsize), mBuffer, mSize);
234
    return buf;
235
}
236
 
237
size_t TByteArray::serialSize()
238
{
239
    DECL_TRACER("TByteArray::serialSize()");
240
 
241
    return mSize + sizeof(u_int32_t);
242
}
243
 
244
unsigned char TByteArray::at(size_t pos) const
245
{
246
    DECL_TRACER("TByteArray::at(size_t pos) const");
247
 
248
    if (pos >= mSize)
249
        return 0;
250
 
251
    return *(mBuffer+pos);
252
}
253
 
254
void TByteArray::clear()
255
{
256
    DECL_TRACER("TByteArray::clear()");
257
 
258
    if (mBuffer)
259
        delete[] mBuffer;
260
 
261
    mSize = 0;
262
    mBuffer = nullptr;
263
}
264
 
265
bool TByteArray::isBigEndian()
266
{
267
    DECL_TRACER("TByteArray::isBigEndian()");
268
 
269
    u_int16_t var = 1;
270
    unsigned char snum[2];
271
    memcpy(snum, &var, sizeof(snum));
272
 
273
    if (snum[0] == 1)
274
        return false;
275
 
276
    return true;
277
}
278
 
279
unsigned char *TByteArray::swapBytes(unsigned char* b, size_t size)
280
{
281
    DECL_TRACER("TByteArray::swapBytes(unsigned char* b, size_t size)");
282
 
283
    unsigned char *num = new unsigned char[size];
284
    size_t cnt = size - 1;
285
 
286
    for (size_t i = 0; i < size; ++i)
287
    {
288
        *(num+cnt) = *(b+i);
289
        cnt--;
290
    }
291
 
292
    memcpy(b, num, size);
293
    delete[] num;
294
    return b;
295
}
296
 
297
TByteArray& TByteArray::operator=(const TByteArray& other)
298
{
299
    DECL_TRACER("TByteArray::operator=(const TByteArray& other)");
300
 
301
    assign(other.mBuffer, other.mSize);
302
    return *this;
303
}
304
 
305
TByteArray& TByteArray::operator+=(const TByteArray& other)
306
{
307
    DECL_TRACER("TByteArray::operator+=(const TByteArray& other)");
308
 
309
    append(other.mBuffer, other.mSize);
310
    return *this;
311
}
312
 
313
bool TByteArray::operator==(const TByteArray& other) const
314
{
315
    DECL_TRACER("TByteArray::operator==(const TByteArray& other) const");
316
 
317
    if (other.mSize != mSize)
318
        return false;
319
 
320
    for (size_t i = 0; i < mSize; ++i)
321
    {
322
        if (*(mBuffer+i) != *(other.mBuffer+i))
323
            return false;
324
    }
325
 
326
    return true;
327
}
328
 
329
bool TByteArray::operator!=(const TByteArray& other) const
330
{
331
    DECL_TRACER("TByteArray::operator!=(const TByteArray& other) const");
332
 
333
    if (other.mSize != mSize)
334
        return true;
335
 
336
    for (size_t i = 0; i < mSize; ++i)
337
    {
338
        if (*(mBuffer+i) != *(other.mBuffer+i))
339
            return true;
340
    }
341
 
342
    return false;
343
}
344
 
345
unsigned char TByteArray::operator[](size_t pos) const
346
{
347
    DECL_TRACER("TByteArray::operator[](size_t pos) const");
348
 
349
    return at(pos);
350
}