Use QByteArray::append instead of copying every byte with [] operator.
[kdenetwork.git] / kopete / protocols / oscar / liboscar / buffer.cpp
blob6a1b26a9a9275dc4d12fc53dd984d2614cc85ec5
1 /***************************************************************************
2 buffer.cpp - description
3 -------------------
4 begin : Thu Jun 6 2002
6 Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
7 Copyright (c) 2004,2005 by Matt Rogers <mattr@kde.org>
8 Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org>
10 *************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 *************************************************************************
20 #include "buffer.h"
22 #include <ctype.h>
23 #include <kdebug.h>
24 #include <kapplication.h>
27 Buffer::Buffer()
29 mReadPos=0;
32 Buffer::Buffer( const Buffer& other )
34 mBuffer = other.mBuffer;
35 mReadPos = other.mReadPos;
38 Buffer::Buffer(const char *b, int len)
40 mBuffer = QByteArray::fromRawData( b, len );
41 mReadPos = 0;
44 Buffer::Buffer( const QByteArray& data )
46 mBuffer = data;
47 mReadPos = 0;
51 Buffer::~Buffer()
56 int Buffer::addByte(const BYTE b)
58 expandBuffer(1);
59 mBuffer[mBuffer.size()-1] = b;
61 return mBuffer.size();
64 int Buffer::addLEByte(const BYTE b)
66 expandBuffer(1);
67 mBuffer[mBuffer.size()-1] = ((b) & 0xff);
69 return mBuffer.size();
73 int Buffer::addWord(const WORD w)
75 expandBuffer(2);
76 mBuffer[mBuffer.size()-2] = ((w & 0xff00) >> 8);
77 mBuffer[mBuffer.size()-1] = (w & 0x00ff);
79 return mBuffer.size();
82 int Buffer::addLEWord(const WORD w)
84 expandBuffer(2);
85 mBuffer[mBuffer.size()-2] = (unsigned char) ((w >> 0) & 0xff);
86 mBuffer[mBuffer.size()-1] = (unsigned char) ((w >> 8) & 0xff);
88 return mBuffer.size();
92 int Buffer::addDWord(const DWORD dw)
94 expandBuffer(4);
95 mBuffer[mBuffer.size()-4] = (dw & 0xff000000) >> 24;
96 mBuffer[mBuffer.size()-3] = (dw & 0x00ff0000) >> 16;
97 mBuffer[mBuffer.size()-2] = (dw & 0x0000ff00) >> 8;
98 mBuffer[mBuffer.size()-1] = (dw & 0x000000ff);
100 return mBuffer.size();
103 int Buffer::addLEDWord(const DWORD dw)
105 expandBuffer(4);
106 mBuffer[mBuffer.size()-4] = (unsigned char) ((dw >> 0) & 0xff);
107 mBuffer[mBuffer.size()-3] = (unsigned char) ((dw >> 8) & 0xff);
108 mBuffer[mBuffer.size()-2] = (unsigned char) ((dw >> 16) & 0xff);
109 mBuffer[mBuffer.size()-1] = (unsigned char) ((dw >> 24) & 0xff);
111 return mBuffer.size();
114 int Buffer::addString( const QByteArray& s )
116 mBuffer.append( s );
117 return mBuffer.size();
120 int Buffer::addString(QByteArray s, DWORD len)
122 Q_UNUSED( len );
123 return addString( s );
126 int Buffer::addString( const char* s, DWORD len )
128 QByteArray qba( s, len );
129 return addString( qba );
132 int Buffer::addString(const unsigned char* s, DWORD len)
134 QByteArray qba( (const char*) s, len );
135 return addString( qba );
138 int Buffer::addLEString(const char *s, const DWORD len)
140 unsigned int pos = mBuffer.size();
141 expandBuffer(len);
142 //concatenate the new string onto the buffer
143 for(unsigned int i=0; i<len; i++)
145 mBuffer[pos+i]=((s[i]) & 0xff);
147 return mBuffer.size();
151 void Buffer::clear()
153 mBuffer.truncate( 0 );
154 mReadPos=0;
157 int Buffer::addTLV( const TLV& t )
159 return addTLV( t.type, t.data );
162 int Buffer::addTLV( WORD type, const QByteArray& data )
164 addWord( type );
165 addWord( data.length() );
166 return addString( data );
169 int Buffer::addLETLV( WORD type, const QByteArray& data )
171 addLEWord( type );
172 addLEWord( data.length() );
173 return addString( data );
176 BYTE Buffer::getByte()
178 BYTE thebyte = 0x00;
180 if(mReadPos < mBuffer.size())
182 thebyte = mBuffer[mReadPos];
183 mReadPos++;
185 else
186 kDebug(14150) << "Buffer::getByte(): mBuffer empty" << endl;
188 return thebyte;
191 void Buffer::skipBytes( int bytesToSkip )
193 if (mReadPos < mBuffer.size())
194 mReadPos += bytesToSkip;
197 BYTE Buffer::getLEByte()
199 BYTE b = getByte();
200 return (b & 0xff);
203 WORD Buffer::getWord()
205 WORD theword, theword2, retword;
206 theword = getByte();
207 theword2 = getByte();
208 retword = (theword << 8) | theword2;
209 return retword;
212 WORD Buffer::getLEWord()
214 WORD theword1, theword2, retword;
215 theword1 = getLEByte();
216 theword2 = getLEByte();
217 retword = (theword2 << 8) | theword1;
218 return retword;
221 DWORD Buffer::getDWord()
223 DWORD word1, word2;
224 DWORD retdword;
225 word1 = getWord();
226 word2 = getWord();
227 retdword = (word1 << 16) | word2;
228 return retdword;
231 DWORD Buffer::getLEDWord()
233 DWORD word1, word2, retdword;
234 word1 = getLEWord();
235 word2 = getLEWord();
236 retdword = (word2 << 16) | word1;
237 return retdword;
240 void Buffer::setBuf(char *b, const WORD len)
242 mBuffer = QByteArray::fromRawData(b, len);
243 mReadPos = 0;
246 QByteArray Buffer::getBlock(WORD len)
248 QByteArray ch;
249 ch.resize( len );
251 for ( int i = 0; i < len; i++ )
253 ch[i] = getByte();
256 return ch;
259 QByteArray Buffer::getBBlock(WORD len)
261 QByteArray data = QByteArray::fromRawData( mBuffer.data() + mReadPos, len);
262 mReadPos += len;
263 return data;
267 WORD *Buffer::getWordBlock(WORD len)
269 kDebug(14150) << k_funcinfo << "of length " << len << endl;
270 WORD *ch=new WORD[len+1];
271 for (unsigned int i=0; i<len; i++)
273 ch[i]=getWord();
275 ch[len]=0;
276 return ch;
280 QByteArray Buffer::getLEBlock(WORD len)
282 QByteArray ch;
283 for (unsigned int i=0;i<len;i++)
284 ch += getLEByte();
286 return ch;
289 int Buffer::addTLV16(const WORD type, const WORD data)
291 addWord(type);
292 addWord(0x0002); //2 bytes long
293 return addWord(data);
296 int Buffer::addLETLV16(const WORD type, const WORD data)
298 addLEWord(type);
299 addLEWord(0x0002); //2 bytes long
300 return addLEWord(data);
303 int Buffer::addTLV8(const WORD type, const BYTE data)
305 addWord(type);
306 addWord(0x0001); //1 byte long
307 return addByte(data);
310 int Buffer::addLETLV8(const WORD type, const BYTE data)
312 addLEWord(type);
313 addLEWord(0x0001); //1 byte long
314 return addLEByte(data);
317 TLV Buffer::getTLV()
319 TLV t;
320 if(bytesAvailable() >= 4)
322 t.type = getWord();
323 t.length = getWord();
324 if ( t )
325 t.data = getBlock( t.length );
326 /*else
327 kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Invalid TLV in buffer" << endl;*/
330 //kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "TLV data is " << t.data << endl;
331 return t;
334 QList<TLV> Buffer::getTLVList()
336 QList<TLV> ql;
338 while (mReadPos < mBuffer.size())
340 TLV t;
342 t = getTLV();
343 if ( !t )
345 kDebug(14150) << k_funcinfo << "Invalid TLV found" << endl;
346 continue;
349 //kDebug(14150) << k_funcinfo << "got TLV(" << t.type << ")" << endl;
350 ql.append(t);
353 return ql;
356 int Buffer::addChatTLV(const WORD type, const WORD exchange,
357 const QString &roomname, const WORD instance)
359 addWord(type);
360 addWord(0x0005 + roomname.length());
361 addWord(exchange);
362 addByte(roomname.length());
363 addString(roomname.toLatin1(), roomname.length()); // TODO: check encoding
365 return addWord(instance);
368 void Buffer::expandBuffer(unsigned int inc)
370 mBuffer.resize(mBuffer.size()+inc);
373 QByteArray Buffer::getLNTS()
375 WORD len = getWord() - 1;
376 QByteArray qcs( getBlock(len) );
377 skipBytes( 1 );
378 return qcs;
381 QByteArray Buffer::getLELNTS()
383 WORD len = getLEWord() - 1;
384 QByteArray qcs( getBlock(len) );
385 skipBytes( 1 );
386 return qcs;
389 int Buffer::addLNTS(const char *s)
391 unsigned int len = strlen(s);
393 addLEWord(len+1);
394 if(len > 0)
395 addString(s, len);
396 int ret = addByte(0x00);
397 return ret;
400 int Buffer::addLELNTS(const char *s)
402 unsigned int len = strlen(s);
403 int ret = addLEWord(len+1);
404 if(len > 0)
405 ret = addLEString(s, len);
406 ret = addByte(0x00);
407 return ret;
410 int Buffer::addBSTR(const char * s)
412 unsigned int len = strlen(s);
413 int ret = addWord(len);
414 if(len > 0)
415 ret = addString(s, len);
416 return ret;
419 QByteArray Buffer::getBSTR()
421 WORD len = getWord();
422 QByteArray qba( getBlock(len) );
423 return qba;
426 int Buffer::addBUIN(const char * s)
428 unsigned int len = strlen(s);
429 int ret = addByte(len);
430 ret = addString(s, len);
431 return ret;
434 QByteArray Buffer::getBUIN()
436 BYTE len = getByte();
437 QByteArray qba( getBlock(len) );
438 return qba;
441 QByteArray Buffer::buffer() const
443 return mBuffer;
446 int Buffer::length() const
448 return mBuffer.size();
451 int Buffer::bytesAvailable() const
453 return (mBuffer.size() - mReadPos);
458 QString Buffer::toString() const
460 // line format:
461 //00 03 00 0b 00 00 90 b8 f5 9f 09 31 31 33 37 38 |;tJ�..........|
463 int i = 0;
464 QString output = "\n";
465 QString hex, ascii;
467 QByteArray::ConstIterator it;
468 for ( it = mBuffer.begin(); it != mBuffer.end(); ++it )
470 i++;
472 unsigned char c = static_cast<unsigned char>(*it);
474 if ( c < 0x10 )
475 hex.append("0");
476 hex.append(QString("%1 ").arg(c, 0, 16));
478 ascii.append(isprint(c) ? c : '.');
480 if (i == 16)
482 output += hex + " |" + ascii + "|\n";
483 i=0;
484 hex.clear();
485 ascii.clear();
489 if(!hex.isEmpty())
490 output += hex.leftJustified(48, ' ') + " |" + ascii.leftJustified(16, ' ') + '|';
491 output.append('\n');
493 return output;
496 QString Buffer::peekBSTR()
498 int lastPos = mReadPos;
499 QByteArray qba = getBSTR();
500 mReadPos = lastPos;
501 return QString( qba );
503 QString Buffer::peekBUIN()
505 int lastPos = mReadPos;
506 QByteArray qba = getBUIN();
507 mReadPos = lastPos;
508 return QString( qba );
512 int Buffer::addGuid( const Guid & g )
514 if (g.isValid())
515 return addString( g.data() );
516 return mBuffer.size();
520 Guid Buffer::getGuid()
522 return Guid(getBBlock(16)); //block or bblock?
526 Buffer::operator QByteArray() const
528 return mBuffer;
530 //kate: tab-width 4; indent-mode csands;