File indexing completed on 2025-01-12 04:19:46
0001 /* 0002 * Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library; if not, write to the Free Software 0016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 0017 * 0018 */ 0019 0020 #include "lineconverter.h" 0021 0022 namespace gpgQCAPlugin { 0023 0024 void LineConverter::setup(LineConverter::Mode m) 0025 { 0026 state = Normal; 0027 mode = m; 0028 prebytes = 0; 0029 list.clear(); 0030 } 0031 0032 QByteArray LineConverter::update(const QByteArray &buf) 0033 { 0034 if (mode == Read) { 0035 // Convert buf to UNIX line ending style 0036 // If buf ends with '\r' set state to Partival 0037 0038 QByteArray out; 0039 0040 if (state == Normal) { 0041 out = buf; 0042 } else { 0043 out.resize(buf.size() + 1); 0044 out[0] = '\r'; 0045 memcpy(out.data() + 1, buf.data(), buf.size()); 0046 } 0047 0048 int n = 0; 0049 while (true) { 0050 n = out.indexOf('\r', n); 0051 // not found 0052 if (n == -1) { 0053 break; 0054 } 0055 // found, not last character 0056 if (n < (buf.size() - 1)) { 0057 // found windows line ending "\r\n" 0058 if (out[n + 1] == '\n') { 0059 // clip out the '\r' 0060 memmove(out.data() + n, out.data() + n + 1, out.size() - n - 1); 0061 out.resize(out.size() - 1); 0062 } 0063 } 0064 // found, last character 0065 else { 0066 state = Partial; 0067 break; 0068 } 0069 ++n; 0070 } 0071 0072 return out; 0073 } else { 0074 // On Windows use DOS line ending style. 0075 // On UNIX don't do any convertation. Return buf as is. 0076 #ifdef Q_OS_WIN 0077 QByteArray out; 0078 int prev = 0; 0079 int at = 0; 0080 0081 while (1) { 0082 int n = buf.indexOf('\n', at); 0083 if (n == -1) 0084 break; 0085 0086 int chunksize = n - at; 0087 const int oldsize = out.size(); 0088 out.resize(oldsize + chunksize + 2); 0089 memcpy(out.data() + oldsize, buf.data() + at, chunksize); 0090 memcpy(out.data() + oldsize + chunksize, "\r\n", 2); 0091 0092 list.append(prebytes + n + 1 - prev); 0093 prebytes = 0; 0094 prev = n; 0095 0096 at = n + 1; 0097 } 0098 if (at < buf.size()) { 0099 const int chunksize = buf.size() - at; 0100 const int oldsize = out.size(); 0101 out.resize(oldsize + chunksize); 0102 memcpy(out.data() + oldsize, buf.data() + at, chunksize); 0103 } 0104 0105 prebytes += buf.size() - prev; 0106 return out; 0107 #else 0108 return buf; 0109 #endif 0110 } 0111 } 0112 0113 QByteArray LineConverter::final() 0114 { 0115 if (mode == Read) { 0116 QByteArray out; 0117 if (state == Partial) { 0118 out.resize(1); 0119 out[0] = '\n'; 0120 } 0121 return out; 0122 } else { 0123 return QByteArray(); 0124 } 0125 } 0126 0127 QByteArray LineConverter::process(const QByteArray &buf) 0128 { 0129 return update(buf) + final(); 0130 } 0131 0132 int LineConverter::writtenToActual(int bytes) 0133 { 0134 #ifdef Q_OS_WIN 0135 int n = 0; 0136 int counter = bytes; 0137 while (counter > 0) { 0138 if (!list.isEmpty() && bytes >= list.first()) { 0139 ++n; 0140 counter -= list.takeFirst(); 0141 } else { 0142 if (list.isEmpty()) 0143 prebytes -= counter; 0144 else 0145 list.first() -= counter; 0146 0147 if (prebytes < 0) { 0148 bytes += prebytes; 0149 prebytes = 0; 0150 } 0151 0152 break; 0153 } 0154 } 0155 return bytes - n; 0156 #else 0157 return bytes; 0158 #endif 0159 } 0160 0161 } // end namespace gpgQCAPlugin