1/*
2 * Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 *
18 */
19
20#include "lineconverter.h"
21
22namespace gpgQCAPlugin {
23
24void LineConverter::setup(LineConverter::Mode m)
25{
26 state = Normal;
27 mode = m;
28 prebytes = 0;
29 list.clear();
30}
31
32QByteArray LineConverter::update(const QByteArray &buf)
33{
34 if (mode == Read) {
35 // Convert buf to UNIX line ending style
36 // If buf ends with '\r' set state to Partival
37
38 QByteArray out;
39
40 if (state == Normal) {
41 out = buf;
42 } else {
43 out.resize(size: buf.size() + 1);
44 out[0] = '\r';
45 memcpy(dest: out.data() + 1, src: buf.data(), n: buf.size());
46 }
47
48 int n = 0;
49 while (true) {
50 n = out.indexOf(c: '\r', from: n);
51 // not found
52 if (n == -1) {
53 break;
54 }
55 // found, not last character
56 if (n < (buf.size() - 1)) {
57 // found windows line ending "\r\n"
58 if (out[n + 1] == '\n') {
59 // clip out the '\r'
60 memmove(dest: out.data() + n, src: out.data() + n + 1, n: out.size() - n - 1);
61 out.resize(size: out.size() - 1);
62 }
63 }
64 // found, last character
65 else {
66 state = Partial;
67 break;
68 }
69 ++n;
70 }
71
72 return out;
73 } else {
74 // On Windows use DOS line ending style.
75 // On UNIX don't do any convertation. Return buf as is.
76#ifdef Q_OS_WIN
77 QByteArray out;
78 int prev = 0;
79 int at = 0;
80
81 while (1) {
82 int n = buf.indexOf('\n', at);
83 if (n == -1)
84 break;
85
86 int chunksize = n - at;
87 const int oldsize = out.size();
88 out.resize(oldsize + chunksize + 2);
89 memcpy(out.data() + oldsize, buf.data() + at, chunksize);
90 memcpy(out.data() + oldsize + chunksize, "\r\n", 2);
91
92 list.append(prebytes + n + 1 - prev);
93 prebytes = 0;
94 prev = n;
95
96 at = n + 1;
97 }
98 if (at < buf.size()) {
99 const int chunksize = buf.size() - at;
100 const int oldsize = out.size();
101 out.resize(oldsize + chunksize);
102 memcpy(out.data() + oldsize, buf.data() + at, chunksize);
103 }
104
105 prebytes += buf.size() - prev;
106 return out;
107#else
108 return buf;
109#endif
110 }
111}
112
113QByteArray LineConverter::final()
114{
115 if (mode == Read) {
116 QByteArray out;
117 if (state == Partial) {
118 out.resize(size: 1);
119 out[0] = '\n';
120 }
121 return out;
122 } else {
123 return QByteArray();
124 }
125}
126
127QByteArray LineConverter::process(const QByteArray &buf)
128{
129 return update(buf) + final();
130}
131
132int LineConverter::writtenToActual(int bytes)
133{
134#ifdef Q_OS_WIN
135 int n = 0;
136 int counter = bytes;
137 while (counter > 0) {
138 if (!list.isEmpty() && bytes >= list.first()) {
139 ++n;
140 counter -= list.takeFirst();
141 } else {
142 if (list.isEmpty())
143 prebytes -= counter;
144 else
145 list.first() -= counter;
146
147 if (prebytes < 0) {
148 bytes += prebytes;
149 prebytes = 0;
150 }
151
152 break;
153 }
154 }
155 return bytes - n;
156#else
157 return bytes;
158#endif
159}
160
161} // end namespace gpgQCAPlugin
162

source code of qca/plugins/qca-gnupg/lineconverter.cpp