00001
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 }