Improved socket read/write
[dashstudio.git] / src / dash / network / socket.cpp
blob989552cadbfec34bf1c20df4ca78580b34343d60
1 /***************************************************************************
2 * Copyright (C) 2006 by David Cuadrado *
3 * krawek@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "socket.h"
23 #include <QTextStream>
24 #include <QQueue>
26 #include <dcore/debug.h>
29 // Dash
30 #include "socketobserver.h"
32 namespace Dash {
33 namespace Network {
35 struct Socket::Private
37 Private() : format(Text) {}
39 QQueue<QByteArray> queue;
40 QList<SocketObserver *> observers;
42 Format format;
44 QString readed;
47 Socket::Socket(QObject *parent)
48 : /*QSslSocket*/QTcpSocket(parent), d(new Private)
50 connect(this, SIGNAL(readyRead ()), this, SLOT(readFromServer()) );
51 connect(this, SIGNAL(connected()), this, SLOT(sendQueue()));
52 connect(this, SIGNAL(disconnected()), this, SLOT(clearQueue()));
56 Socket::~Socket()
58 delete d;
61 void Socket::setFormat(Format format)
63 d->format = format;
66 Socket::Format Socket::format() const
68 return d->format;
71 void Socket::addObserver(SocketObserver *observer)
73 d->observers << observer;
76 void Socket::removeObserver(SocketObserver *observer)
78 d->observers.removeAll(observer);
81 void Socket::sendQueue()
83 while( d->queue.count() > 0 )
85 if ( state() == QAbstractSocket::ConnectedState )
87 send(d->queue.dequeue());
89 else break;
93 void Socket::clearQueue()
95 d->queue.clear();
98 bool Socket::send(const QByteArray &data)
100 if( state() == QAbstractSocket::ConnectedState )
102 switch(d->format)
104 case Text:
106 QByteArray toSend = data.toBase64()+"%%\n";
107 QByteArray block;
109 for(int i = 0; i < toSend.size(); i++)
111 block += toSend[i];
112 if( i % 1024 == 0 )
114 if( write(block) == -1 )
116 return false;
118 block = QByteArray();
122 if( !block.isEmpty() )
124 return write(block) != -1;
127 return true;
129 break;
130 case Binary:
132 return write(data) != -1;
134 break;
137 else
139 d->queue.enqueue(data);
143 bool Socket::send(const QDomDocument &doc)
145 return send(doc.toString(0).toLocal8Bit());
148 void Socket::readFromServer()
150 switch(d->format)
152 case Text:
154 while(bytesAvailable() > 0 )
156 int bytes = bytesAvailable();
158 bool process = false;
160 QString line = this->readLine();
162 if( line.isEmpty() )
164 d->readed += this->read(1024);
166 else
168 d->readed += line;
171 if ( d->readed.endsWith("%%\n") )
173 d->readed.remove(d->readed.lastIndexOf("%%"), 2);
174 process = true;
177 if( process && !d->readed.isEmpty() )
179 d->readed = QByteArray::fromBase64(d->readed.toLocal8Bit());
181 foreach(SocketObserver *o, d->observers)
183 o->readed(d->readed);
185 d->readed = QString();
187 if( d->format != Text ) break;
191 break;
192 case Binary:
194 d->readed = QString();
195 while(bytesAvailable() > 0)
197 QByteArray data = this->read(1024);
198 foreach(SocketObserver *o, d->observers)
200 o->dataReaded(data);
204 break;
207 if (this->bytesAvailable() > 0) emit readyRead();