• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkdegames/kggznet

kggzraw.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the kggznet library.
00003     Copyright (c) 2005 - 2007 Josef Spillner <josef@ggzgamingzone.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kggzraw.h"
00022 
00023 #include <kdebug.h>
00024 
00025 #include <qabstractsocket.h>
00026 #include <qdatastream.h>
00027 
00028 /*
00029 KGGZRaw provides a replacement for QDataStream when being used on an arbitrary
00030 file descriptor, such as within the kggzmod library or for those games
00031 which use a non-quantized binary protocol (i.e. blocking or in a thread).
00032 
00033 This class is necessary for two reasons:
00034 1) to ensure the QAbstractSocket is opened in unbuffered mode, so we can
00035    read ancillary data from the underlying fd as needed at any point in time
00036 2) to ensure that QDataStream will block until enough bytes are available
00037    for reading
00038 */
00039 
00040 /*
00041 FIXME: one open issue is that when the destructor of QAbstractSocket is
00042 called, the application will segfault!
00043 */
00044 
00045 /*
00046 FIXME: See qt-copy/doc/html/datastreamformat.html for compatibility with
00047 easysock and other implementations
00048 */
00049 
00050 KGGZRaw::KGGZRaw()
00051 {
00052     m_socket = NULL;
00053     m_net = NULL;
00054     m_format = EasysockFormat;
00055 }
00056 
00057 KGGZRaw::~KGGZRaw()
00058 {
00059     kDebug(11005) << "[raw] *destructor* net";
00060     delete m_net;
00061     kDebug(11005) << "[raw] *destructor* socket";
00062     delete m_socket;
00063     kDebug(11005) << "[raw] *destructor* done";
00064 }
00065 
00066 void KGGZRaw::setFormat(Format format)
00067 {
00068     m_format = format;
00069 }
00070 
00071 void KGGZRaw::setNetwork(int fd)
00072 {
00073     // Ensure this method gets called only once
00074     if(m_socket)
00075     {
00076         kError(11005) << "[raw] setNetwork called more than once";
00077         emit signalError();
00078         return;
00079     }
00080 
00081     // Create a datastream on an unbuffered TCP socket
00082     m_socket = new QAbstractSocket(QAbstractSocket::TcpSocket, this);
00083     m_socket->setSocketDescriptor(fd, QAbstractSocket::ConnectedState, QIODevice::ReadWrite | QIODevice::Unbuffered);
00084 
00085     m_net = new QDataStream(m_socket);
00086 }
00087 
00088 bool KGGZRaw::ensureBytes(int bytes)
00089 {
00090     // Ensure that kggzraw has been initialised properly
00091     if((!m_net) || (!m_socket))
00092     {
00093         kError(11005) << "[raw] setNetwork not called yet";
00094         emit signalError();
00095         return false;
00096     }
00097 
00098     // Shortcut for invalid dynamic sizes - signalError() was already sent
00099     if(bytes < 0) return false;
00100 
00101     // Shortcut for outgoing data (operator<<)
00102     if(bytes == 0) return true;
00103 
00104     // Ensure that this number of bytes is available
00105     while(m_socket->bytesAvailable() < bytes)
00106     {
00107         m_socket->waitForReadyRead(-1);
00108         kWarning(11005) << "[raw] bytesAvailable grows to:" << m_socket->bytesAvailable();
00109     }
00110 
00111     return true;
00112 }
00113 
00114 KGGZRaw& KGGZRaw::operator>>(qint32 &i)
00115 {
00116     kDebug(11005) << "[raw] bytesAvailable(i32):" << m_socket->bytesAvailable();
00117 
00118     if(!ensureBytes(4)) return *this;
00119     *m_net >> i;
00120 
00121     kDebug(11005) << "[raw] i32 is:" << i;
00122 
00123     return *this;
00124 }
00125 
00126 KGGZRaw& KGGZRaw::operator>>(qint8 &i)
00127 {
00128     kDebug(11005) << "[raw] bytesAvailable(i8):" << m_socket->bytesAvailable();
00129 
00130     if(!ensureBytes(1)) return *this;
00131     *m_net >> i;
00132 
00133     kDebug(11005) << "[raw] i8 is:" << i;
00134 
00135     return *this;
00136 }
00137 
00138 KGGZRaw& KGGZRaw::operator>>(QString &s)
00139 {
00140     char *tmp;
00141 
00142     kDebug(11005) << "[raw] bytesAvailable(qstring):" << m_socket->bytesAvailable();
00143 
00144     if(!ensureBytes(peekedStringBytes())) return *this;
00145     if(m_format == QtFormat)
00146     {
00147         *m_net >> s;
00148     }
00149     else
00150     {
00151         kDebug(11005) << "[raw] use easysock conversion";
00152         *m_net >> tmp;
00153         s = tmp;
00154         delete[] tmp;
00155     }
00156 
00157     kDebug(11005) << "[raw] qstring is:" << s;
00158 
00159     return *this;
00160 }
00161 
00162 KGGZRaw& KGGZRaw::operator<<(qint32 i)
00163 {
00164     kDebug(11005) << "[raw] out(i32):" << i;
00165 
00166     if(!ensureBytes(0)) return *this;
00167     *m_net << i;
00168 
00169     return *this;
00170 }
00171 
00172 KGGZRaw& KGGZRaw::operator<<(qint8 i)
00173 {
00174     kDebug(11005) << "[raw] out(i8):" << i;
00175 
00176     if(!ensureBytes(0)) return *this;
00177     *m_net << i;
00178 
00179     return *this;
00180 }
00181 
00182 KGGZRaw& KGGZRaw::operator<<(QString s)
00183 {
00184     kDebug(11005) << "[raw] out(qstring):" << s;
00185 
00186     if(!ensureBytes(0)) return *this;
00187     if(m_format == QtFormat)
00188     {
00189         *m_net << s;
00190     }
00191     else
00192     {
00193         kDebug(11005) << "[raw] use easysock conversion";
00194         *m_net << s.toUtf8().constData();
00195     }
00196 
00197     return *this;
00198 }
00199 
00200 int KGGZRaw::peekedStringBytes()
00201 {
00202     int strsize;
00203 
00204     if(!ensureBytes(4)) return -1;
00205 
00206     QByteArray strsizear = m_socket->peek(4);
00207     QDataStream strsizestream(strsizear);
00208     strsizestream >> strsize;
00209     kDebug(11005) << "[raw] string length is" << strsize;
00210 
00211     if(m_format == QtFormat)
00212     {
00213         // an empty QString()
00214         if(strsize == -1) strsize = 0;
00215     }
00216 
00217     return strsize + 4;
00218 }
00219 
00220 #include "kggzraw.moc"

libkdegames/kggznet

Skip menu "libkdegames/kggznet"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

API Reference

Skip menu "API Reference"
  • kblackbox
  • kgoldrunner
  • kmahjongg
  • ksquares
  • libkdegames
  •   highscore
  •   kgame
  •   kggzgames
  •   kggzmod
  •   kggznet
  • libkmahjongg
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal