ksocketbuffer.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include <assert.h>
00028 #include <string.h>
00029
00030 #include "ksocketbase.h"
00031 #include "ksocketbuffer_p.h"
00032
00033 using namespace KNetwork;
00034 using namespace KNetwork::Internal;
00035
00036 KSocketBuffer::KSocketBuffer(Q_LONG size)
00037 : m_mutex(true), m_offset(0), m_size(size), m_length(0)
00038 {
00039 }
00040
00041 KSocketBuffer::KSocketBuffer(const KSocketBuffer& other)
00042 : KIOBufferBase(other), m_mutex(true)
00043 {
00044 *this = other;
00045 }
00046
00047 KSocketBuffer::~KSocketBuffer()
00048 {
00049
00050 }
00051
00052 KSocketBuffer& KSocketBuffer::operator=(const KSocketBuffer& other)
00053 {
00054 QMutexLocker locker1(&m_mutex);
00055 QMutexLocker locker2(&other.m_mutex);
00056
00057 KIOBufferBase::operator=(other);
00058
00059 m_list = other.m_list;
00060 m_offset = other.m_offset;
00061 m_size = other.m_size;
00062 m_length = other.m_length;
00063
00064 return *this;
00065 }
00066
00067 bool KSocketBuffer::canReadLine() const
00068 {
00069 QMutexLocker locker(&m_mutex);
00070
00071 QValueListConstIterator<QByteArray> it = m_list.constBegin(),
00072 end = m_list.constEnd();
00073 QIODevice::Offset offset = m_offset;
00074
00075
00076 for ( ; it != end; ++it)
00077 {
00078 if ((*it).find('\n', offset) != -1)
00079 return true;
00080 if ((*it).find('\r', offset) != -1)
00081 return true;
00082 offset = 0;
00083 }
00084
00085 return false;
00086 }
00087
00088 QCString KSocketBuffer::readLine()
00089 {
00090 if (!canReadLine())
00091 return QCString();
00092
00093 QMutexLocker locker(&m_mutex);
00094
00095
00096 int newline = 0;
00097 QValueListConstIterator<QByteArray> it = m_list.constBegin(),
00098 end = m_list.constEnd();
00099 QIODevice::Offset offset = m_offset;
00100
00101
00102 for ( ; it != end; ++it)
00103 {
00104 int posnl = (*it).find('\n', offset);
00105 if (posnl == -1)
00106 {
00107
00108 newline += (*it).size();
00109 offset = 0;
00110 continue;
00111 }
00112
00113
00114 newline += posnl;
00115 break;
00116 }
00117
00118 QCString result(newline + 2 - m_offset);
00119 consumeBuffer(result.data(), newline + 1 - m_offset);
00120 return result;
00121 }
00122
00123 Q_LONG KSocketBuffer::length() const
00124 {
00125 return m_length;
00126 }
00127
00128 Q_LONG KSocketBuffer::size() const
00129 {
00130 return m_size;
00131 }
00132
00133 bool KSocketBuffer::setSize(Q_LONG size)
00134 {
00135 m_size = size;
00136 if (size == -1 || m_length < m_size)
00137 return true;
00138
00139
00140 QMutexLocker locker(&m_mutex);
00141
00142
00143 if (m_length < m_size)
00144 return true;
00145
00146
00147 return (m_length - m_size) == consumeBuffer(0L, m_length - m_size, true);
00148 }
00149
00150 Q_LONG KSocketBuffer::feedBuffer(const char *data, Q_LONG len)
00151 {
00152 if (data == 0L || len == 0)
00153 return 0;
00154 if (isFull())
00155 return -1;
00156
00157 QMutexLocker locker(&m_mutex);
00158
00159
00160 if (m_size != -1 && (m_size - m_length) < len)
00161 len = m_size - m_length;
00162
00163 QByteArray a(len);
00164 a.duplicate(data, len);
00165 m_list.append(a);
00166
00167 m_length += len;
00168 return len;
00169 }
00170
00171 Q_LONG KSocketBuffer::consumeBuffer(char *destbuffer, Q_LONG maxlen, bool discard)
00172 {
00173 if (maxlen == 0 || isEmpty())
00174 return 0;
00175
00176 QValueListIterator<QByteArray> it = m_list.begin(),
00177 end = m_list.end();
00178 QIODevice::Offset offset = m_offset;
00179 Q_LONG copied = 0;
00180
00181
00182 while (it != end && maxlen)
00183 {
00184
00185 size_t to_copy = (*it).size() - offset;
00186 if (to_copy > maxlen)
00187 to_copy = maxlen;
00188
00189
00190 if (destbuffer)
00191 memcpy(destbuffer + copied, (*it).data() + offset, to_copy);
00192 maxlen -= to_copy;
00193 copied += to_copy;
00194
00195 if ((*it).size() - offset > to_copy)
00196 {
00197
00198 offset += to_copy;
00199 break;
00200 }
00201 else
00202 {
00203
00204
00205 offset = 0;
00206 if (discard)
00207 it = m_list.remove(it);
00208 else
00209 ++it;
00210 }
00211 }
00212
00213 if (discard)
00214 {
00215 m_offset = offset;
00216 m_length -= copied;
00217 assert(m_length >= 0);
00218 }
00219
00220 return copied;
00221 }
00222
00223 void KSocketBuffer::clear()
00224 {
00225 QMutexLocker locker(&m_mutex);
00226 m_list.clear();
00227 m_offset = 0;
00228 m_length = 0;
00229 }
00230
00231 Q_LONG KSocketBuffer::sendTo(KActiveSocketBase* dev, Q_LONG len)
00232 {
00233 if (len == 0 || isEmpty())
00234 return 0;
00235
00236 QMutexLocker locker(&m_mutex);
00237
00238 QValueListIterator<QByteArray> it = m_list.begin(),
00239 end = m_list.end();
00240 QIODevice::Offset offset = m_offset;
00241 Q_LONG written = 0;
00242
00243
00244 while (it != end && (len || len == -1))
00245 {
00246
00247
00248
00249
00250
00251 Q_ULONG bufsize = 1460;
00252 if (len != -1 && len < bufsize)
00253 bufsize = len;
00254 QByteArray buf(bufsize);
00255 Q_LONG count = 0;
00256
00257 while (it != end && count + ((*it).size() - offset) <= bufsize)
00258 {
00259 memcpy(buf.data() + count, (*it).data() + offset, (*it).size() - offset);
00260 count += (*it).size() - offset;
00261 offset = 0;
00262 ++it;
00263 }
00264
00265
00266 if (count < bufsize && it != end)
00267 {
00268
00269
00270 memcpy(buf.data() + count, (*it).data() + offset, bufsize - count);
00271 offset += bufsize - count;
00272 count = bufsize;
00273 }
00274
00275
00276 Q_LONG wrote = dev->writeBlock(buf, count);
00277
00278 if (wrote == -1)
00279
00280 break;
00281
00282 written += wrote;
00283 if (wrote != count)
00284
00285 break;
00286 }
00287
00288
00289
00290 if (written)
00291 consumeBuffer(0L, written);
00292
00293 return written;
00294 }
00295
00296 Q_LONG KSocketBuffer::receiveFrom(KActiveSocketBase* dev, Q_LONG len)
00297 {
00298 if (len == 0 || isFull())
00299 return 0;
00300
00301 QMutexLocker locker(&m_mutex);
00302
00303 if (len == -1)
00304 len = dev->bytesAvailable();
00305 if (len <= 0)
00306
00307 return len;
00308
00309
00310 if (m_size != -1 && len > (m_size - m_length))
00311 len = m_size - m_length;
00312
00313
00314
00315
00316 QByteArray a(len);
00317 len = dev->readBlock(a.data(), len);
00318
00319 if (len == -1)
00320
00321 return -1;
00322
00323
00324
00325 a.truncate(len);
00326 m_list.append(a);
00327 m_length += len;
00328 return len;
00329 }
|