ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

client.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00024 
00025 #include "backends/networking/sdl_net/client.h"
00026 #include "backends/networking/sdl_net/localwebserver.h"
00027 #include "common/memstream.h"
00028 #include <SDL_net.h>
00029 
00030 namespace Networking {
00031 
00032 Client::Client():
00033     _state(INVALID), _set(nullptr), _socket(nullptr), _handler(nullptr),
00034     _previousHandler(nullptr), _stream(nullptr), _buffer(new byte[CLIENT_BUFFER_SIZE]) {}
00035 
00036 Client::Client(SDLNet_SocketSet set, TCPsocket socket):
00037     _state(INVALID), _set(nullptr), _socket(nullptr), _handler(nullptr),
00038     _previousHandler(nullptr), _stream(nullptr), _buffer(new byte[CLIENT_BUFFER_SIZE]) {
00039     open(set, socket);
00040 }
00041 
00042 Client::~Client() {
00043     close();
00044     delete[] _buffer;
00045 }
00046 
00047 void Client::open(SDLNet_SocketSet set, TCPsocket socket) {
00048     if (_state != INVALID)
00049         close();
00050     _state = READING_HEADERS;
00051     _socket = socket;
00052     _set = set;
00053     Reader cleanReader;
00054     _reader = cleanReader;
00055     if (_handler)
00056         delete _handler;
00057     _handler = nullptr;
00058     if (_previousHandler)
00059         delete _previousHandler;
00060     _previousHandler = nullptr;
00061     _stream = new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
00062     if (set) {
00063         int numused = SDLNet_TCP_AddSocket(set, socket);
00064         if (numused == -1) {
00065             error("Client: SDLNet_AddSocket: %s\n", SDLNet_GetError());
00066         }
00067     }
00068 }
00069 
00070 bool Client::readMoreIfNeeded() {
00071     if (_stream == nullptr)
00072         return false; //nothing to read into
00073     if (_stream->size() - _stream->pos() > 0)
00074         return true; //not needed, some data left in the stream
00075     if (!_socket)
00076         return false;
00077     if (!SDLNet_SocketReady(_socket))
00078         return false;
00079 
00080     int bytes = SDLNet_TCP_Recv(_socket, _buffer, CLIENT_BUFFER_SIZE);
00081     if (bytes <= 0) {
00082         warning("Client::readMoreIfNeeded: recv fail");
00083         close();
00084         return false;
00085     }
00086 
00087     if (_stream->write(_buffer, bytes) != (uint32)bytes) {
00088         warning("Client::readMoreIfNeeded: failed to write() into MemoryReadWriteStream");
00089         close();
00090         return false;
00091     }
00092 
00093     return true;
00094 }
00095 
00096 void Client::readHeaders() {
00097     if (!readMoreIfNeeded())
00098         return;
00099     _reader.setContent(_stream);
00100     if (_reader.readFirstHeaders())
00101         _state = (_reader.badRequest() ? BAD_REQUEST : READ_HEADERS);
00102 }
00103 
00104 bool Client::readContent(Common::WriteStream *stream) {
00105     if (!readMoreIfNeeded())
00106         return false;
00107     _reader.setContent(_stream);
00108     return _reader.readFirstContent(stream);
00109 }
00110 
00111 bool Client::readBlockHeaders(Common::WriteStream *stream) {
00112     if (!readMoreIfNeeded())
00113         return false;
00114     _reader.setContent(_stream);
00115     return _reader.readBlockHeaders(stream);
00116 }
00117 
00118 bool Client::readBlockContent(Common::WriteStream *stream) {
00119     if (!readMoreIfNeeded())
00120         return false;
00121     _reader.setContent(_stream);
00122     return _reader.readBlockContent(stream);
00123 }
00124 
00125 void Client::setHandler(ClientHandler *handler) {
00126     if (_handler) {
00127         if (_previousHandler)
00128             delete _previousHandler;
00129         _previousHandler = _handler; //can't just delete it, as setHandler() could've been called by handler itself
00130     }
00131     _state = BEING_HANDLED;
00132     _handler = handler;
00133 }
00134 
00135 void Client::handle() {
00136     if (_state != BEING_HANDLED)
00137         warning("handle() called in a wrong Client's state");
00138     if (!_handler)
00139         warning("Client doesn't have handler to be handled by");
00140     if (_handler)
00141         _handler->handle(this);
00142 }
00143 
00144 void Client::close() {
00145     if (_set) {
00146         if (_socket) {
00147             int numused = SDLNet_TCP_DelSocket(_set, _socket);
00148             if (numused == -1)
00149                 error("Client: SDLNet_DelSocket: %s\n", SDLNet_GetError());
00150         }
00151         _set = nullptr;
00152     }
00153 
00154     if (_socket) {
00155         SDLNet_TCP_Close(_socket);
00156         _socket = nullptr;
00157     }
00158 
00159     if (_stream) {
00160         delete _stream;
00161         _stream = nullptr;
00162     }
00163 
00164     _state = INVALID;
00165 }
00166 
00167 
00168 ClientState Client::state() const { return _state; }
00169 
00170 Common::String Client::headers() const { return _reader.headers(); }
00171 
00172 Common::String Client::method() const { return _reader.method(); }
00173 
00174 Common::String Client::path() const { return _reader.path(); }
00175 
00176 Common::String Client::query() const { return _reader.query(); }
00177 
00178 Common::String Client::queryParameter(Common::String name) const { return _reader.queryParameter(name); }
00179 
00180 Common::String Client::anchor() const { return _reader.anchor(); }
00181 
00182 bool Client::noMoreContent() const { return _reader.noMoreContent(); }
00183 
00184 bool Client::socketIsReady() { return SDLNet_SocketReady(_socket); }
00185 
00186 int Client::recv(void *data, int maxlen) { return SDLNet_TCP_Recv(_socket, data, maxlen); }
00187 
00188 int Client::send(void *data, int len) { return SDLNet_TCP_Send(_socket, data, len); }
00189 
00190 } // End of namespace Networking


Generated on Sat Feb 16 2019 05:00:47 for ResidualVM by doxygen 1.7.1
curved edge   curved edge