1 /***************************************************************************
2 buffer.cpp - description
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 *************************************************************************
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. *
17 *************************************************************************
31 Buffer::Buffer( const Buffer
& other
)
33 mBuffer
= other
.mBuffer
;
34 mReadPos
= other
.mReadPos
;
35 mBlockStack
= other
.mBlockStack
;
38 Buffer::Buffer(const char *b
, int len
)
40 mBuffer
= QByteArray::fromRawData( b
, len
);
44 Buffer::Buffer( const QByteArray
& data
)
56 int Buffer::addByte(Oscar::BYTE b
)
59 mBuffer
[mBuffer
.size()-1] = b
;
61 return mBuffer
.size();
64 int Buffer::addLEByte(Oscar::BYTE b
)
67 mBuffer
[mBuffer
.size()-1] = ((b
) & 0xff);
69 return mBuffer
.size();
73 int Buffer::addWord(Oscar::WORD w
)
76 mBuffer
[mBuffer
.size()-2] = ((w
& 0xff00) >> 8);
77 mBuffer
[mBuffer
.size()-1] = (w
& 0x00ff);
79 return mBuffer
.size();
82 int Buffer::addLEWord(Oscar::WORD w
)
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(Oscar::DWORD dw
)
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(Oscar::DWORD dw
)
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
)
117 return mBuffer
.size();
120 int Buffer::addString(QByteArray s
, Oscar::DWORD len
)
123 return addString( s
);
126 int Buffer::addString( const char* s
, Oscar::DWORD len
)
128 QByteArray
qba( s
, len
);
129 return addString( qba
);
132 int Buffer::addString(const unsigned char* s
, Oscar::DWORD len
)
134 QByteArray
qba( (const char*) s
, len
);
135 return addString( qba
);
138 int Buffer::addLEString(const char *s
, Oscar::DWORD len
)
140 unsigned int pos
= mBuffer
.size();
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();
153 mBuffer
.truncate( 0 );
157 int Buffer::addTLV( const TLV
& t
)
159 return addTLV( t
.type
, t
.data
);
162 int Buffer::addTLV( Oscar::WORD type
, const QByteArray
& data
)
165 addWord( data
.length() );
166 return addString( data
);
169 int Buffer::addLETLV( Oscar::WORD type
, const QByteArray
& data
)
172 addLEWord( data
.length() );
173 return addString( data
);
176 Oscar::BYTE
Buffer::getByte()
178 Oscar::BYTE thebyte
= 0x00;
180 if(mReadPos
< mBuffer
.size())
182 thebyte
= mBuffer
[mReadPos
];
186 kDebug(14150) << "Buffer::getByte(): mBuffer empty";
191 void Buffer::skipBytes( int bytesToSkip
)
193 if (mReadPos
< mBuffer
.size())
194 mReadPos
+= bytesToSkip
;
197 Oscar::BYTE
Buffer::getLEByte()
199 Oscar::BYTE b
= getByte();
203 Oscar::WORD
Buffer::getWord()
205 Oscar::WORD theword
, theword2
, retword
;
207 theword2
= getByte();
208 retword
= (theword
<< 8) | theword2
;
212 Oscar::WORD
Buffer::getLEWord()
214 Oscar::WORD theword1
, theword2
, retword
;
215 theword1
= getLEByte();
216 theword2
= getLEByte();
217 retword
= (theword2
<< 8) | theword1
;
221 Oscar::DWORD
Buffer::getDWord()
223 Oscar::DWORD word1
, word2
;
224 Oscar::DWORD retdword
;
227 retdword
= (word1
<< 16) | word2
;
231 Oscar::DWORD
Buffer::getLEDWord()
233 Oscar::DWORD word1
, word2
, retdword
;
236 retdword
= (word2
<< 16) | word1
;
240 void Buffer::setBuf(char *b
, Oscar::WORD len
)
242 mBuffer
= QByteArray::fromRawData(b
, len
);
246 QByteArray
Buffer::getBlock(Oscar::DWORD len
)
248 if ( len
> (Oscar::DWORD
)(mBuffer
.size() - mReadPos
) )
250 kDebug(14150) << "Buffer::getBlock(DWORD): mBuffer underflow!!!";
251 len
= mBuffer
.size() - mReadPos
;
257 for ( Oscar::DWORD i
= 0; i
< len
; i
++ )
265 QByteArray
Buffer::getBBlock(Oscar::WORD len
)
267 QByteArray data
= QByteArray::fromRawData( mBuffer
.data() + mReadPos
, len
);
273 Oscar::WORD
*Buffer::getWordBlock(Oscar::WORD len
)
275 kDebug(14150) << "of length " << len
;
276 Oscar::WORD
*ch
=new Oscar::WORD
[len
+1];
277 for (unsigned int i
=0; i
<len
; i
++)
286 QByteArray
Buffer::getLEBlock(Oscar::WORD len
)
289 for (unsigned int i
=0;i
<len
;i
++)
295 int Buffer::addTLV32(Oscar::WORD type
, Oscar::DWORD data
)
298 addWord(0x0004); //4 Oscar::BYTEs long
299 return addDWord(data
);
302 int Buffer::addLETLV32(Oscar::WORD type
, Oscar::DWORD data
)
305 addLEWord(0x0004); //4 Oscar::BYTEs long
306 return addLEDWord(data
);
309 int Buffer::addTLV16(Oscar::WORD type
, Oscar::WORD data
)
312 addWord(0x0002); //2 Oscar::BYTEs long
313 return addWord(data
);
316 int Buffer::addLETLV16(Oscar::WORD type
, Oscar::WORD data
)
319 addLEWord(0x0002); //2 Oscar::BYTEs long
320 return addLEWord(data
);
323 int Buffer::addTLV8(Oscar::WORD type
, Oscar::BYTE data
)
326 addWord(0x0001); //1 Oscar::BYTE long
327 return addByte(data
);
330 int Buffer::addLETLV8(Oscar::WORD type
, Oscar::BYTE data
)
333 addLEWord(0x0001); //1 Oscar::BYTE long
334 return addLEByte(data
);
340 if(bytesAvailable() >= 4)
343 t
.length
= getWord();
345 t
.data
= getBlock( t
.length
);
347 kDebug(OSCAR_RAW_DEBUG) << "Invalid TLV in buffer";*/
350 //kDebug(OSCAR_RAW_DEBUG) << "TLV data is " << t.data;
354 QList
<TLV
> Buffer::getTLVList()
358 while (mReadPos
< mBuffer
.size())
365 kDebug(14150) << "Invalid TLV found";
369 //kDebug(14150) << "got TLV(" << t.type << ")";
376 int Buffer::addChatTLV(Oscar::WORD type
, Oscar::WORD exchange
,
377 const QString
&roomname
, Oscar::WORD instance
)
380 addWord(0x0005 + roomname
.length());
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 Oscar::WORD len
= getWord();
399 qcs
= getBlock(len
- 1);
406 QByteArray
Buffer::getLELNTS()
408 Oscar::WORD len
= getLEWord();
412 qcs
= getBlock(len
- 1);
419 int Buffer::addLNTS(const char *s
)
421 unsigned int len
= strlen(s
);
426 int ret
= addByte(0x00);
430 int Buffer::addLELNTS(const char *s
)
432 unsigned int len
= strlen(s
);
433 int ret
= addLEWord(len
+1);
435 ret
= addLEString(s
, len
);
440 int Buffer::addBSTR(const char * s
)
442 unsigned int len
= strlen(s
);
443 int ret
= addWord(len
);
445 ret
= addString(s
, len
);
449 QByteArray
Buffer::getBSTR()
451 Oscar::WORD len
= getWord();
452 QByteArray
qba( getBlock(len
) );
456 int Buffer::addBUIN(const char * s
)
458 unsigned int len
= strlen(s
);
459 int ret
= addByte(len
);
460 ret
= addString(s
, len
);
464 QByteArray
Buffer::getBUIN()
466 Oscar::BYTE len
= getByte();
467 QByteArray
qba( getBlock(len
) );
471 QByteArray
Buffer::buffer() const
476 int Buffer::length() const
478 return mBuffer
.size();
481 int Buffer::bytesAvailable() const
483 return (mBuffer
.size() - mReadPos
);
488 QString
Buffer::toString() const
491 //00 03 00 0b 00 00 90 b8 f5 9f 09 31 31 33 37 38 |;tJ�..........|
494 QString output
= "\n";
497 QByteArray::ConstIterator it
;
498 for ( it
= mBuffer
.begin(); it
!= mBuffer
.end(); ++it
)
502 unsigned char c
= static_cast<unsigned char>(*it
);
506 hex
.append(QString("%1 ").arg(c
, 0, 16));
508 ascii
.append(isprint(c
) ? c
: '.');
512 output
+= hex
+ " |" + ascii
+ "|\n";
520 output
+= hex
.leftJustified(48, ' ') + " |" + ascii
.leftJustified(16, ' ') + '|';
526 QString
Buffer::peekBSTR()
528 int lastPos
= mReadPos
;
529 QByteArray qba
= getBSTR();
531 return QString( qba
);
533 QString
Buffer::peekBUIN()
535 int lastPos
= mReadPos
;
536 QByteArray qba
= getBUIN();
538 return QString( qba
);
542 int Buffer::addGuid( const Guid
& g
)
545 return addString( g
.data() );
546 return mBuffer
.size();
550 Guid
Buffer::getGuid()
552 return Guid(getBBlock(16)); //block or bblock?
555 int Buffer::addLEBlock( const QByteArray
& block
)
557 int ret
= addLEWord( block
.length() );
558 if ( block
.length() > 0 )
559 ret
= addString( block
);
564 QByteArray
Buffer::getLEBlock()
566 Oscar::DWORD len
= getLEWord();
567 return getBlock( len
);
570 int Buffer::addLEDBlock( const QByteArray
& block
)
572 int ret
= addLEDWord( block
.length() );
573 if ( block
.length() > 0 )
574 ret
= addString( block
);
579 QByteArray
Buffer::getLEDBlock()
581 Oscar::DWORD len
= getLEDWord();
582 return getBlock( len
);
585 void Buffer::startBlock( BlockType type
, ByteOrder byteOrder
)
587 Block block
= { type
, byteOrder
, mBuffer
.size() };
588 mBlockStack
.push( block
);
592 else if ( type
== BDWord
)
596 void Buffer::endBlock()
598 Q_ASSERT( mBlockStack
.size() > 0 );
599 Block block
= mBlockStack
.pop();
602 if ( block
.type
== BWord
)
603 size
= mBuffer
.size() - block
.pos
- 2;
604 else if ( block
.type
== BDWord
)
605 size
= mBuffer
.size() - block
.pos
- 4;
607 if ( block
.byteOrder
== BigEndian
)
609 if ( block
.type
== BWord
)
611 mBuffer
[block
.pos
++] = (unsigned char) (size
& 0x0000ff00) >> 8;
612 mBuffer
[block
.pos
++] = (unsigned char) (size
& 0x000000ff) >> 0;
614 else if ( block
.type
== BDWord
)
616 mBuffer
[block
.pos
++] = (unsigned char) (size
& 0xff000000) >> 24;
617 mBuffer
[block
.pos
++] = (unsigned char) (size
& 0x00ff0000) >> 16;
618 mBuffer
[block
.pos
++] = (unsigned char) (size
& 0x0000ff00) >> 8;
619 mBuffer
[block
.pos
++] = (unsigned char) (size
& 0x000000ff) >> 0;
624 if ( block
.type
== BWord
)
626 mBuffer
[block
.pos
++] = (unsigned char) ((size
>> 0) & 0xff);
627 mBuffer
[block
.pos
++] = (unsigned char) ((size
>> 8) & 0xff);
629 else if ( block
.type
== BDWord
)
631 mBuffer
[block
.pos
++] = (unsigned char) ((size
>> 0) & 0xff);
632 mBuffer
[block
.pos
++] = (unsigned char) ((size
>> 8) & 0xff);
633 mBuffer
[block
.pos
++] = (unsigned char) ((size
>> 16) & 0xff);
634 mBuffer
[block
.pos
++] = (unsigned char) ((size
>> 24) & 0xff);
639 Buffer::operator QByteArray() const
643 //kate: tab-width 4; indent-mode csands;