2
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
3
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21
#include "qca_textfilter.h"
25
//----------------------------------------------------------------------------
27
//----------------------------------------------------------------------------
28
TextFilter::TextFilter(Direction dir)
33
void TextFilter::setup(Direction dir)
38
Direction TextFilter::direction() const
43
MemoryRegion TextFilter::encode(const MemoryRegion &a)
49
MemoryRegion TextFilter::decode(const MemoryRegion &a)
55
QString TextFilter::arrayToString(const MemoryRegion &a)
57
return QString::fromLatin1(encode(a).toByteArray());
60
MemoryRegion TextFilter::stringToArray(const QString &s)
63
return MemoryRegion();
64
return decode(s.toLatin1());
67
QString TextFilter::encodeString(const QString &s)
69
return arrayToString(s.toUtf8());
72
QString TextFilter::decodeString(const QString &s)
74
return QString::fromUtf8(stringToArray(s).toByteArray());
77
//----------------------------------------------------------------------------
79
//----------------------------------------------------------------------------
80
static int enhex(uchar c)
90
static int dehex(char c)
92
if(c >= 'a' && c <= 'f')
94
else if(c >= 'A' && c <= 'F')
96
else if(c >= '0' && c <= '9')
102
Hex::Hex(Direction dir)
114
MemoryRegion Hex::update(const MemoryRegion &m)
116
QByteArray a = m.toByteArray();
119
QByteArray out(a.size() * 2, 0);
122
for(int n = 0; n < (int)a.size(); ++n)
124
uchar lo = (uchar)a[n] & 0x0f;
125
uchar hi = (uchar)a[n] >> 4;
142
return MemoryRegion();
157
QByteArray out(a.size() / 2, 0);
160
for(int n = 0; n < (int)a.size(); ++n)
162
c = dehex((char)a[n]);
171
uchar full = ((hi & 0x0f) << 4) + (lo & 0x0f);
182
return MemoryRegion();
193
MemoryRegion Hex::final()
197
return MemoryRegion();
205
//----------------------------------------------------------------------------
207
//----------------------------------------------------------------------------
208
Base64::Base64(Direction dir)
222
bool Base64::lineBreaksEnabled() const
227
int Base64::lineBreaksColumn() const
232
void Base64::setLineBreaksEnabled(bool b)
237
void Base64::setLineBreaksColumn(int column)
245
static QByteArray b64encode(const QByteArray &s)
261
QByteArray p((len + 2) / 3 * 4, 0);
263
for(i = 0; i < len; i += 3)
265
a = ((unsigned char)s[i] & 3) << 4;
268
a += (unsigned char)s[i + 1] >> 4;
269
b = ((unsigned char)s[i + 1] & 0xf) << 2;
272
b += (unsigned char)s[i + 2] >> 6;
273
c = (unsigned char)s[i + 2] & 0x3f;
281
p[at++] = tbl[(unsigned char)s[i] >> 2];
289
static QByteArray b64decode(const QByteArray &s, bool *ok)
291
// -1 specifies invalid
293
// everything else specifies data
297
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
298
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
299
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
300
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,
301
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
302
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
303
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
304
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
305
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
306
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
307
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
308
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
309
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
310
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
311
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
312
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
319
// this should be a multiple of 4
327
p.resize(len / 4 * 3);
335
for(i = 0; i < len; i += 4)
338
b = tbl[(int)s[i + 1]];
339
c = tbl[(int)s[i + 2]];
340
d = tbl[(int)s[i + 3]];
341
if((a == 64 || b == 64) || (a < 0 || b < 0 || c < 0 || d < 0))
347
p[at++] = ((a & 0x3F) << 2) | ((b >> 4) & 0x03);
348
p[at++] = ((b & 0x0F) << 4) | ((c >> 2) & 0x0F);
349
p[at++] = ((c & 0x03) << 6) | ((d >> 0) & 0x3F);
360
static int findLF(const QByteArray &in, int offset)
362
for(int n = offset; n < in.size(); ++n)
370
static QByteArray insert_linebreaks(const QByteArray &s, int *col, int lfAt)
374
int needed = (out.size() + *col) / lfAt; // how many newlines needed?
377
int firstlen = lfAt - *col; // length of first chunk
378
int at = firstlen + (lfAt * (needed - 1)); // position of last newline
379
int lastlen = out.size() - at; // length of last chunk
381
//printf("size=%d,needed=%d,firstlen=%d,at=%d,lastlen=%d\n", out.size(), needed, firstlen, at, lastlen);
384
out.resize(out.size() + needed);
387
for(int n = 0; n < needed; ++n)
389
char *p = out.data() + at;
395
memmove(p + needed - n, p, len);
396
p[needed - n - 1] = '\n';
408
static QByteArray remove_linebreaks(const QByteArray &s)
413
int at = findLF(out, 0);
416
int next = findLF(out, at + 1);
421
len = out.size() - at;
425
char *p = out.data() + at;
426
memmove(p - removed, p + 1, len - 1);
431
out.resize(out.size() - removed);
436
static void appendArray(QByteArray *a, const QByteArray &b)
441
MemoryRegion Base64::update(const MemoryRegion &m)
444
if(_dir == Decode && _lb_enabled)
445
in = remove_linebreaks(m.toByteArray());
447
in = m.toByteArray();
450
return MemoryRegion();
458
int size = partial.size() + in.size();
461
appendArray(&partial, in);
462
return MemoryRegion();
465
int eat = size % chunk;
467
// s = partial + a - eat
468
QByteArray s(partial.size() + in.size() - eat, 0);
469
memcpy(s.data(), partial.data(), partial.size());
470
memcpy(s.data() + partial.size(), in.data(), in.size() - eat);
473
memcpy(partial.data(), in.data() + in.size() - eat, eat);
478
return insert_linebreaks(b64encode(s), &col, _lb_column);
485
QByteArray out = b64decode(s, &ok);
492
MemoryRegion Base64::final()
497
return insert_linebreaks(b64encode(partial), &col, _lb_column);
499
return b64encode(partial);
504
QByteArray out = b64decode(partial, &ok);
511
bool Base64::ok() const