/* -*- c++ -*- * * donkeysocket.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 #include #include "donkeysocket.h" #include "donkeysocket.moc" DonkeySocket::DonkeySocket( QObject *parent, const char *name ) : QSocket( parent, name) { fifo.setAutoDelete(TRUE); mlHost = QString::null; mlPort = 4001; connect(this, SIGNAL(readyRead()), SLOT(readMessage())); } DonkeySocket::~DonkeySocket() { } void DonkeySocket::connectDonkey() { rstate = 0; ct = 0; sz = 0; kdDebug() << "Connecting to " << mlHost << ":" << mlPort << endl; connectToHost(mlHost, mlPort); } void DonkeySocket::connectDonkey(const QString& host, Q_UINT16 port) { mlHost = host; mlPort = port; connectDonkey(); } int DonkeySocket::sendMessage(const DonkeyMessage& msg) { unsigned char op[4]; int sz = msg.size() + 2; op[0] = (unsigned char)(sz & 0xff); op[1] = (unsigned char)((sz >> 8) & 0xff); op[2] = (unsigned char)((sz >> 16) & 0xff); op[3] = (unsigned char)((sz >> 24) & 0xff); Q_LONG r = writeBlock((const char *)op, 4); if (r != 4) return 0; op[0] = (unsigned char)(msg.opcode() & 0xff); op[1] = (unsigned char)((msg.opcode() >> 8) & 0xff); r = writeBlock((const char *)op, 2); if (r != 2) return 0; r = writeBlock((const char*)msg.data(), msg.size()); return r == (Q_LONG)msg.size(); } void DonkeySocket::readMessage() { int done = 1; while (bytesAvailable() && done) { done = 0; if (!rstate && bytesAvailable() >= 4) { ct = 0; rstate = 1; sz = getch(); sz |= getch() << 8; sz |= getch() << 16; sz |= getch() << 24; sz -= 2; done = 1; } if (rstate == 1 && (int)bytesAvailable() >= 2) { int opcode = getch(); opcode |= getch() << 8; cur = new DonkeyMessage(opcode, sz); rstate = 2; done = 1; } if (rstate == 2 && (int)bytesAvailable()) { int a = (int)bytesAvailable() > (sz - ct) ? sz - ct : bytesAvailable(); char* data = (char*)malloc(bytesAvailable()); if (!data) exit(1); int r = (int)readBlock(data, a); if (r < 0) { rstate = 0; free(data); delete cur; kdDebug() << "Read error!" << endl; return; } cur->feedBuffer(data, r); free(data); ct += r; if (ct >= sz) { cur->resetPosition(); fifo.enqueue(cur); cur = NULL; rstate = sz = ct = 0; } done = 1; } } if (!fifo.isEmpty()) emit readyMessage(); } uint DonkeySocket::queueSize() { return fifo.count(); } DonkeyMessage* DonkeySocket::popMessage() { return fifo.dequeue(); }