/* messageformatter.cpp - msn p2p protocol Copyright (c) 2005 by Gregg Edghill ************************************************************************* * * * 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 "messageformatter.h" #include "p2p.h" // TQt includes #include #include // Kde includes #include using P2P::MessageFormatter; using P2P::Message; MessageFormatter::MessageFormatter(TQObject *parent, const char *name) : TQObject(parent, name) {} MessageFormatter::~MessageFormatter() {} Message MessageFormatter::readMessage(const TQByteArray& stream, bool compact) { Message inbound; TQ_UINT32 index = 0; if(compact == false) { // Determine the end position of the message header. while(index < stream.size()) { if(stream[index++] == '\n'){ if(stream[index - 3] == '\n') break; } } // Retrieve the message header. TQString messageHeader = TQCString(stream.data(), index); // Retrieve the message mime version, content type, // and p2p destination. TQRegExp regex("Content-Type: ([A-Za-z0-9$!*/\\-]*)"); regex.search(messageHeader); TQString contentType = regex.cap(1); if(contentType != "application/x-msnmsgrp2p") return inbound; // kdDebug(14140) << k_funcinfo << endl; regex = TQRegExp("MIME-Version: (\\d.\\d)"); regex.search(messageHeader); inbound.mimeVersion = regex.cap(1); inbound.contentType = contentType; regex = TQRegExp("P2P-Dest: ([^\r\n]*)"); regex.search(messageHeader); TQString destination = regex.cap(1); } TQDataStream reader(stream, IO_ReadOnly); reader.setByteOrder(TQDataStream::LittleEndian); // Seek to the start position of the message // transport header. reader.tqdevice()->tqat(index); // Read the message transport headers from the stream. reader >> inbound.header.sessionId; reader >> inbound.header.identifier; reader >> inbound.header.dataOffset; reader >> inbound.header.totalDataSize; reader >> inbound.header.dataSize; reader >> inbound.header.flag; reader >> inbound.header.ackSessionIdentifier; reader >> inbound.header.ackUniqueIdentifier; reader >> inbound.header.ackDataSize; /*kdDebug(14140) << "session id, " << inbound.header.sessionId << endl << "identifier, " << inbound.header.identifier << endl << "data offset, " << inbound.header.dataOffset << endl << "total size, " << inbound.header.totalDataSize << endl << "data size, " << inbound.header.dataSize << endl << "flag, " << inbound.header.flag << endl << "ack session identifier, " << inbound.header.ackSessionIdentifier << endl << "ack unique identifier, " << inbound.header.ackUniqueIdentifier << endl << "ack data size, " << inbound.header.ackDataSize << endl;*/ // Read the message body from the stream. if(inbound.header.dataSize > 0){ inbound.body.resize(inbound.header.dataSize); reader.readRawBytes(inbound.body.data(), inbound.header.dataSize); } if(compact == false) { reader.setByteOrder(TQDataStream::BigEndian); // Read the message application identifier from the stream. reader >> inbound.applicationIdentifier; /* kdDebug(14140) << "application identifier, " << inbound.applicationIdentifier << endl;*/ } return inbound; } void MessageFormatter::writeMessage(const Message& message, TQByteArray& stream, bool compact) { // kdDebug(14140) << k_funcinfo << endl; TQDataStream writer(stream, IO_WriteOnly); writer.setByteOrder(TQDataStream::LittleEndian); if(compact == false) { const TQCString messageHeader = TQString("MIME-Version: 1.0\r\n" "Content-Type: application/x-msnmsgrp2p\r\n" "P2P-Dest: " + message.destination + "\r\n" "\r\n").utf8(); // Set the capacity of the message buffer. stream.resize(messageHeader.length() + 48 + message.body.size() + 4); // Write the message header to the stream writer.writeRawBytes(messageHeader.data(), messageHeader.length()); } else { // Set the capacity of the message buffer. stream.resize(4 + 48 + message.body.size()); // Write the message size to the stream. writer << (TQ_INT32)(48+message.body.size()); } // Write the transport headers to the stream. writer << message.header.sessionId; writer << message.header.identifier; writer << message.header.dataOffset; writer << message.header.totalDataSize; writer << message.header.dataSize; writer << message.header.flag; writer << message.header.ackSessionIdentifier; writer << message.header.ackUniqueIdentifier; writer << message.header.ackDataSize; /* kdDebug(14140) << "session id, " << message.header.sessionId << endl << "identifier, " << message.header.identifier << endl << "data offset, " << message.header.dataOffset << endl << "total size, " << message.header.totalDataSize << endl << "data size, " << message.header.dataSize << endl << "flag, " << message.header.flag << endl << "ack session identifier, " << message.header.ackSessionIdentifier << endl << "ack unique identifier, " << message.header.ackUniqueIdentifier << endl << "ack data size, " << message.header.ackDataSize << endl; */ if(message.body.size() > 0){ // Write the messge body to the stream. writer.writeRawBytes(message.body.data(), message.body.size()); } if(compact == false) { // Seek to the message application identifier section. writer.setByteOrder(TQDataStream::BigEndian); // Write the message application identifier to the stream. writer << message.applicationIdentifier; /* kdDebug(14140) << "application identifier, " << message.applicationIdentifier << endl; */ } } #include "messageformatter.moc"