Add support for sending and receiving ICQ plugin messages.
[kdenetwork.git] / kopete / protocols / oscar / liboscar / buffer.cpp
blobe2ad30893c042441994544549004ac4f595eead0
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(DWORD len)
248 if ( len > (DWORD)(mBuffer.size() - mReadPos) )
250 kDebug(14150) << "Buffer::getBlock(DWORD): mBuffer underflow!!!" << endl;
251 len = mBuffer.size() - mReadPos;
254 QByteArray ch;
255 ch.resize( len );
257 for ( DWORD i = 0; i < len; i++ )
259 ch[i] = getByte();
262 return ch;
265 QByteArray Buffer::getBBlock(WORD len)
267 QByteArray data = QByteArray::fromRawData( mBuffer.data() + mReadPos, len);
268 mReadPos += len;
269 return data;
273 WORD *Buffer::getWordBlock(WORD len)
275 kDebug(14150) << k_funcinfo << "of length " << len << endl;
276 WORD *ch=new WORD[len+1];
277 for (unsigned int i=0; i<len; i++)
279 ch[i]=getWord();
281 ch[len]=0;
282 return ch;
286 QByteArray Buffer::getLEBlock(WORD len)
288 QByteArray ch;
289 for (unsigned int i=0;i<len;i++)
290 ch += getLEByte();
292 return ch;
295 int Buffer::addTLV32(const WORD type, const DWORD data)
297 addWord(type);
298 addWord(0x0004); //4 bytes long
299 return addDWord(data);
302 int Buffer::addLETLV32(const WORD type, const DWORD data)
304 addLEWord(type);
305 addLEWord(0x0004); //4 bytes long
306 return addLEDWord(data);
309 int Buffer::addTLV16(const WORD type, const WORD data)
311 addWord(type);
312 addWord(0x0002); //2 bytes long
313 return addWord(data);
316 int Buffer::addLETLV16(const WORD type, const WORD data)
318 addLEWord(type);
319 addLEWord(0x0002); //2 bytes long
320 return addLEWord(data);
323 int Buffer::addTLV8(const WORD type, const BYTE data)
325 addWord(type);
326 addWord(0x0001); //1 byte long
327 return addByte(data);
330 int Buffer::addLETLV8(const WORD type, const BYTE data)
332 addLEWord(type);
333 addLEWord(0x0001); //1 byte long
334 return addLEByte(data);
337 TLV Buffer::getTLV()
339 TLV t;
340 if(bytesAvailable() >= 4)
342 t.type = getWord();
343 t.length = getWord();
344 if ( t )
345 t.data = getBlock( t.length );
346 /*else
347 kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Invalid TLV in buffer" << endl;*/
350 //kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "TLV data is " << t.data << endl;
351 return t;
354 QList<TLV> Buffer::getTLVList()
356 QList<TLV> ql;
358 while (mReadPos < mBuffer.size())
360 TLV t;
362 t = getTLV();
363 if ( !t )
365 kDebug(14150) << k_funcinfo << "Invalid TLV found" << endl;
366 continue;
369 //kDebug(14150) << k_funcinfo << "got TLV(" << t.type << ")" << endl;
370 ql.append(t);
373 return ql;
376 int Buffer::addChatTLV(const WORD type, const WORD exchange,
377 const QString &roomname, const WORD instance)
379 addWord(type);
380 addWord(0x0005 + roomname.length());
381 addWord(exchange);
382 addByte(roomname.length());
383 addString(roomname.toLatin1()); // TODO: check encoding
385 return addWord(instance);
388 void Buffer::expandBuffer(unsigned int inc)
390 mBuffer.resize(mBuffer.size()+inc);
393 QByteArray Buffer::getLNTS()
395 WORD len = getWord() - 1;
396 QByteArray qcs( getBlock(len) );
397 skipBytes( 1 );
398 return qcs;
401 QByteArray Buffer::getLELNTS()
403 WORD len = getLEWord() - 1;
404 QByteArray qcs( getBlock(len) );
405 skipBytes( 1 );
406 return qcs;
409 int Buffer::addLNTS(const char *s)
411 unsigned int len = strlen(s);
413 addLEWord(len+1);
414 if(len > 0)
415 addString(s, len);
416 int ret = addByte(0x00);
417 return ret;
420 int Buffer::addLELNTS(const char *s)
422 unsigned int len = strlen(s);
423 int ret = addLEWord(len+1);
424 if(len > 0)
425 ret = addLEString(s, len);
426 ret = addByte(0x00);
427 return ret;
430 int Buffer::addBSTR(const char * s)
432 unsigned int len = strlen(s);
433 int ret = addWord(len);
434 if(len > 0)
435 ret = addString(s, len);
436 return ret;
439 QByteArray Buffer::getBSTR()
441 WORD len = getWord();
442 QByteArray qba( getBlock(len) );
443 return qba;
446 int Buffer::addBUIN(const char * s)
448 unsigned int len = strlen(s);
449 int ret = addByte(len);
450 ret = addString(s, len);
451 return ret;
454 QByteArray Buffer::getBUIN()
456 BYTE len = getByte();
457 QByteArray qba( getBlock(len) );
458 return qba;
461 QByteArray Buffer::buffer() const
463 return mBuffer;
466 int Buffer::length() const
468 return mBuffer.size();
471 int Buffer::bytesAvailable() const
473 return (mBuffer.size() - mReadPos);
478 QString Buffer::toString() const
480 // line format:
481 //00 03 00 0b 00 00 90 b8 f5 9f 09 31 31 33 37 38 |;tJ�..........|
483 int i = 0;
484 QString output = "\n";
485 QString hex, ascii;
487 QByteArray::ConstIterator it;
488 for ( it = mBuffer.begin(); it != mBuffer.end(); ++it )
490 i++;
492 unsigned char c = static_cast<unsigned char>(*it);
494 if ( c < 0x10 )
495 hex.append("0");
496 hex.append(QString("%1 ").arg(c, 0, 16));
498 ascii.append(isprint(c) ? c : '.');
500 if (i == 16)
502 output += hex + " |" + ascii + "|\n";
503 i=0;
504 hex.clear();
505 ascii.clear();
509 if(!hex.isEmpty())
510 output += hex.leftJustified(48, ' ') + " |" + ascii.leftJustified(16, ' ') + '|';
511 output.append('\n');
513 return output;
516 QString Buffer::peekBSTR()
518 int lastPos = mReadPos;
519 QByteArray qba = getBSTR();
520 mReadPos = lastPos;
521 return QString( qba );
523 QString Buffer::peekBUIN()
525 int lastPos = mReadPos;
526 QByteArray qba = getBUIN();
527 mReadPos = lastPos;
528 return QString( qba );
532 int Buffer::addGuid( const Guid & g )
534 if (g.isValid())
535 return addString( g.data() );
536 return mBuffer.size();
540 Guid Buffer::getGuid()
542 return Guid(getBBlock(16)); //block or bblock?
545 int Buffer::addLEBlock( const QByteArray& block )
547 int ret = addLEWord( block.length() );
548 if ( block.length() > 0 )
549 ret = addString( block );
551 return ret;
554 QByteArray Buffer::addLEBlock()
556 DWORD len = getLEWord();
557 return getBlock( len );
560 int Buffer::addLEDBlock( const QByteArray& block )
562 int ret = addLEDWord( block.length() );
563 if ( block.length() > 0 )
564 ret = addString( block );
566 return ret;
569 QByteArray Buffer::getLEDBlock()
571 DWORD len = getLEDWord();
572 return getBlock( len );
575 Buffer::operator QByteArray() const
577 return mBuffer;
579 //kate: tab-width 4; indent-mode csands;