/* -*- c++ -*- * * mmpacket.cpp * * Copyright (C) 2003 Petter E. Stokke * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include "mmpacket.h" #include #include #include #include #include #include #include #include #include #include QTextCodec* MMPacket::codec = 0; void MMPacket::initCodec() { if (!codec) { codec = QTextCodec::codecForName("UTF-8"); if (!codec) codec = QTextCodec::codecForLocale(); } } void MMPacket::setStringCodec(QTextCodec* newCodec) { codec = newCodec; } MMPacket::MMPacket( int8 opcode ) : QMemArray() { initCodec(); op = opcode; pos = 0; } MMPacket::MMPacket( const char* data, int len ) : QMemArray() { initCodec(); resize(len - 1); op = data[0]; char *p = (char*)data + 1; int i; for (i=0; i<(len-1); i++) (*this)[i] = p[i]; pos = 0; } MMPacket::MMPacket(int8 opcode, int len) : QMemArray(len) { initCodec(); op = opcode; pos = 0; } int8 MMPacket::opcode() const { return op; } void MMPacket::setOpcode(int8 opcode) { op = opcode; } inline void MMPacket::writeInt(int32 v, int sz) { int j; pos = size(); resize(pos + sz); for(j = 0; j < sz; j++) (*this)[pos + j] = (v & (-1)) >> (8 * j); pos += sz; } void MMPacket::writeByte(int8 v) { writeInt((int32)v, 1); } void MMPacket::writeShort(int16 v) { writeInt((int32)v, 2); } void MMPacket::writeInt(int32 v) { writeInt((int32)v, 4); } void MMPacket::writeString(const QString& v) { QCString s = codec->fromUnicode(v); if (s.isNull()) { kdDebug() << "Unable to convert string into charset " << codec->name() << "." << endl; writeString(""); } else writeString((const char*)s); } void MMPacket::writeString(const char* v) { int i,l = strlen(v); assert(l < 256); pos = size(); writeByte(l); resize(pos + l); for (i=0; i count()) { QString foo(kdBacktrace()); QString msg(dumpArray()); kdDebug() << "Position " << pos + sz << " exceeds buffer size " << count() << "\nMessage: " << msg << "\nBT: '" << foo << "'" << endl; kdFatal() << "Invalid index access."; } int i; int32 res = 0; for(i = 0; i < sz; i++) res += ((*this)[pos + i] & 0xFF) << (8 * i); pos += sz; return res; } int8 MMPacket::readByte() { return (int8)readInt(1); } int16 MMPacket::readShort() { return (int16)readInt(2); } int32 MMPacket::readInt() { return (int32)readInt(4); } QString MMPacket::readString() { return codec->toUnicode(readByteArray()); } QByteArray MMPacket::readByteArray() { int sz = (int)readByte(); if ((uint)pos + sz > count()) { QString foo(kdBacktrace()); QString msg(dumpArray()); kdDebug() << "Position " << pos + sz << " exceeds buffer size " << count() << "\nMessage: " << msg << "\nBT: '" << foo << "'" << endl; kdFatal() << "Invalid index access."; } QByteArray buf(sz); memcpy(buf.data(), *this + pos, sz); pos += sz; return buf; } QString MMPacket::dumpArray() const { QString out = "Opcode " + QString::number(op) + ", size " + QString::number(size()) + "\n"; int i; QString hex = "", asc = "", tmp; for (i=0; i<(int)size(); i++) { if (at(i) >= 32 && at(i) <= 127) asc += QChar(at(i)); else asc += "."; tmp.sprintf("%02x", at(i)); hex += tmp + " "; if (i % 16 == 15) { tmp.sprintf("%8d: ", i - 15); out += tmp + hex + " " + asc + "\n"; hex = ""; asc = ""; } } tmp.sprintf("%8d: ", i - (i % 16)); for (i %= 16; i < 16; i++) hex += " "; out += tmp + hex + " " + asc + "\n"; return out; } uint MMPacket::packetSize() const { return size() + 3; } bool MMPacket::specialHeader() const { return m_specialHeader; } void MMPacket::setSpecialHeader(bool sh) { m_specialHeader = sh; }