You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/kopete/protocols/oscar/liboscar/buffer.cpp

519 lines
9.5 KiB

/***************************************************************************
buffer.cpp - description
-------------------
begin : Thu Jun 6 2002
Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
Copyright (c) 2004 by Matt Rogers <mattr@kde.org>
Kopete (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
*************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
*************************************************************************
*/
#include <kdebug.h>
#include <tdeapplication.h>
#include "buffer.h"
#include <ctype.h>
Buffer::Buffer()
{
mReadPos=0;
}
Buffer::Buffer( const Buffer& other )
{
mBuffer.duplicate( other.mBuffer );
mReadPos = other.mReadPos;
}
Buffer::Buffer(const char *b, TQ_ULONG len)
{
mBuffer.duplicate(b, len);
mReadPos=0;
}
Buffer::Buffer( const TQByteArray& data )
{
mBuffer.duplicate( data );
mReadPos = 0;
}
Buffer::~Buffer()
{
}
int Buffer::addByte(const BYTE b)
{
expandBuffer(1);
mBuffer[mBuffer.size()-1] = b;
return mBuffer.size();
}
int Buffer::addLEByte(const BYTE b)
{
expandBuffer(1);
mBuffer[mBuffer.size()-1] = ((b) & 0xff);
return mBuffer.size();
}
int Buffer::addWord(const WORD w)
{
expandBuffer(2);
mBuffer[mBuffer.size()-2] = ((w & 0xff00) >> 8);
mBuffer[mBuffer.size()-1] = (w & 0x00ff);
return mBuffer.size();
}
int Buffer::addLEWord(const WORD w)
{
expandBuffer(2);
mBuffer[mBuffer.size()-2] = (unsigned char) ((w >> 0) & 0xff);
mBuffer[mBuffer.size()-1] = (unsigned char) ((w >> 8) & 0xff);
return mBuffer.size();
}
int Buffer::addDWord(const DWORD dw)
{
expandBuffer(4);
mBuffer[mBuffer.size()-4] = (dw & 0xff000000) >> 24;
mBuffer[mBuffer.size()-3] = (dw & 0x00ff0000) >> 16;
mBuffer[mBuffer.size()-2] = (dw & 0x0000ff00) >> 8;
mBuffer[mBuffer.size()-1] = (dw & 0x000000ff);
return mBuffer.size();
}
int Buffer::addLEDWord(const DWORD dw)
{
expandBuffer(4);
mBuffer[mBuffer.size()-4] = (unsigned char) ((dw >> 0) & 0xff);
mBuffer[mBuffer.size()-3] = (unsigned char) ((dw >> 8) & 0xff);
mBuffer[mBuffer.size()-2] = (unsigned char) ((dw >> 16) & 0xff);
mBuffer[mBuffer.size()-1] = (unsigned char) ((dw >> 24) & 0xff);
return mBuffer.size();
}
int Buffer::addString(TQByteArray s)
{
unsigned int pos = mBuffer.size();
int len = s.size();
expandBuffer(len);
for ( int i = 0; i < len; i++ )
mBuffer[pos + i] = s[i];
return mBuffer.size();
}
int Buffer::addString(TQByteArray s, DWORD len)
{
Q_UNUSED( len );
return addString( s );
}
int Buffer::addString( const char* s, DWORD len )
{
TQByteArray qba;
qba.duplicate( s, len );
return addString( qba );
}
int Buffer::addString(const unsigned char* s, DWORD len)
{
TQByteArray qba;
qba.duplicate( (const char*) s, len );
return addString( qba );
}
int Buffer::addLEString(const char *s, const DWORD len)
{
unsigned int pos = mBuffer.size();
expandBuffer(len);
//concatenate the new string onto the buffer
for(unsigned int i=0; i<len; i++)
{
mBuffer[pos+i]=((s[i]) & 0xff);
}
return mBuffer.size();
}
void Buffer::clear()
{
mBuffer.truncate( 0 );
mReadPos=0;
}
int Buffer::addTLV( const TLV& t )
{
return addTLV( t.type, t.length, t.data );
}
int Buffer::addTLV(WORD type, WORD len, const char *data)
{
addWord(type);
addWord(len);
return addString(data,len);
}
int Buffer::addLETLV(WORD type, WORD len, const char *data)
{
addLEWord( type );
addLEWord( len );
return addString( data, len );
}
BYTE Buffer::getByte()
{
BYTE thebyte = 0x00;
if(mReadPos < mBuffer.size())
{
thebyte = mBuffer[mReadPos];
mReadPos++;
}
else
kdDebug(14150) << "Buffer::getByte(): mBuffer empty" << endl;
return thebyte;
}
void Buffer::skipBytes( int bytesToSkip )
{
if (mReadPos < mBuffer.size())
mReadPos += bytesToSkip;
}
BYTE Buffer::getLEByte()
{
BYTE b = getByte();
return (b & 0xff);
}
WORD Buffer::getWord()
{
WORD theword, theword2, retword;
theword = getByte();
theword2 = getByte();
retword = (theword << 8) | theword2;
return retword;
}
WORD Buffer::getLEWord()
{
WORD theword1, theword2, retword;
theword1 = getLEByte();
theword2 = getLEByte();
retword = (theword2 << 8) | theword1;
return retword;
}
DWORD Buffer::getDWord()
{
DWORD word1, word2;
DWORD retdword;
word1 = getWord();
word2 = getWord();
retdword = (word1 << 16) | word2;
return retdword;
}
DWORD Buffer::getLEDWord()
{
DWORD word1, word2, retdword;
word1 = getLEWord();
word2 = getLEWord();
retdword = (word2 << 16) | word1;
return retdword;
}
void Buffer::setBuf(char *b, const WORD len)
{
kdDebug(14150) << k_funcinfo << "Called." << endl;
mBuffer.duplicate(b, len);
mReadPos = 0;
}
TQByteArray Buffer::getBlock(WORD len)
{
TQByteArray ch( len );
for ( int i = 0; i < len; i++ )
{
ch[i] = getByte();
}
return ch;
}
TQByteArray Buffer::getBBlock(WORD len)
{
TQByteArray data;
data.duplicate(mBuffer.data() + mReadPos, len);
mReadPos += len;
return data;
}
WORD *Buffer::getWordBlock(WORD len)
{
kdDebug(14150) << k_funcinfo << "of length " << len << endl;
WORD *ch=new WORD[len+1];
for (unsigned int i=0; i<len; i++)
{
ch[i]=getWord();
}
ch[len]=0;
return ch;
}
TQCString Buffer::getLEBlock(WORD len)
{
TQCString ch;
for (unsigned int i=0;i<len;i++)
ch += getLEByte();
return ch;
}
int Buffer::addTLV16(const WORD type, const WORD data)
{
addWord(type);
addWord(0x0002); //2 bytes long
return addWord(data);
}
int Buffer::addLETLV16(const WORD type, const WORD data)
{
addLEWord(type);
addLEWord(0x0002); //2 bytes long
return addLEWord(data);
}
int Buffer::addTLV8(const WORD type, const BYTE data)
{
addWord(type);
addWord(0x0001); //1 byte long
return addByte(data);
}
int Buffer::addLETLV8(const WORD type, const BYTE data)
{
addLEWord(type);
addLEWord(0x0001); //1 byte long
return addLEByte(data);
}
TLV Buffer::getTLV()
{
TLV t;
if(length() >= 4)
{
t.type = getWord();
t.length = getWord();
if ( t )
t.data = getBlock( t.length );
/*else
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Invalid TLV in buffer" << endl;*/
}
//kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "TLV data is " << t.data << endl;
return t;
}
TQValueList<TLV> Buffer::getTLVList()
{
TQValueList<TLV> ql;
while (mReadPos < mBuffer.size())
{
TLV t;
t = getTLV();
if ( !t )
{
kdDebug(14150) << k_funcinfo << "Invalid TLV found" << endl;
continue;
}
//kdDebug(14150) << k_funcinfo << "got TLV(" << t.type << ")" << endl;
ql.append(t);
}
return ql;
}
int Buffer::addChatTLV(const WORD type, const WORD exchange,
const TQString &roomname, const WORD instance)
{
addWord(type);
addWord(0x0005 + roomname.length());
addWord(exchange);
addByte(roomname.length());
addString(roomname.latin1(), roomname.length()); // TODO: check encoding
return addWord(instance);
}
void Buffer::expandBuffer(unsigned int inc)
{
mBuffer.resize(mBuffer.size()+inc, TQGArray::SpeedOptim);
}
TQCString Buffer::getLNTS()
{
WORD len = getLEWord();
TQCString qcs;
qcs.duplicate( getBlock(len) );
return qcs;
}
TQCString Buffer::getLELNTS()
{
WORD len = getLEWord();
TQCString qcs;
qcs.duplicate( getBlock(len) );
return qcs;
}
int Buffer::addLNTS(const char *s)
{
unsigned int len = strlen(s);
addLEWord(len+1);
if(len > 0)
addString(s, len);
int ret = addByte(0x00);
return ret;
}
int Buffer::addLELNTS(const char *s)
{
unsigned int len = strlen(s);
int ret = addLEWord(len+1);
if(len > 0)
ret = addLEString(s, len);
ret = addByte(0x00);
return ret;
}
int Buffer::addBSTR(const char * s)
{
unsigned int len = strlen(s);
int ret = addWord(len);
if(len > 0)
ret = addString(s, len);
return ret;
}
TQByteArray Buffer::getBSTR()
{
WORD len = getWord();
TQByteArray qba;
qba.duplicate( getBlock(len) );
return qba;
}
int Buffer::addBUIN(const char * s)
{
unsigned int len = strlen(s);
int ret = addByte(len);
ret = addString(s, len);
return ret;
}
TQByteArray Buffer::getBUIN()
{
BYTE len = getByte();
TQByteArray qba;
qba.duplicate( getBlock(len) );
return qba;
}
char *Buffer::buffer() const
{
return const_cast<char*>(mBuffer.data());
}
int Buffer::length() const
{
return (mBuffer.size() - mReadPos);
}
TQString Buffer::toString() const
{
// line format:
//00 03 00 0b 00 00 90 b8 f5 9f 09 31 31 33 37 38 |;tJ<74>..........|
int i = 0;
TQString output = "\n";
TQString hex, ascii;
TQByteArray::ConstIterator it;
for ( it = mBuffer.begin(); it != mBuffer.end(); ++it )
{
i++;
unsigned char c = static_cast<unsigned char>(*it);
if ( c < 0x10 )
hex.append("0");
hex.append(TQString("%1 ").arg(c, 0, 16));
ascii.append(isprint(c) ? c : '.');
if (i == 16)
{
output += hex + " |" + ascii + "|\n";
i=0;
hex=TQString();
ascii=TQString();
}
}
if(!hex.isEmpty())
output += hex.leftJustify(48, ' ') + " |" + ascii.leftJustify(16, ' ') + '|';
output.append('\n');
return output;
}
TQString Buffer::peekBSTR()
{
int lastPos = mReadPos;
TQByteArray qba = getBSTR();
mReadPos = lastPos;
return TQString( qba );
}
TQString Buffer::peekBUIN()
{
int lastPos = mReadPos;
TQByteArray qba = getBUIN();
mReadPos = lastPos;
return TQString( qba );
}
Buffer::operator TQByteArray() const
{
return mBuffer;
}