1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef BACKENDS_NETWORKING_CURL_REQUEST_H 24 #define BACKENDS_NETWORKING_CURL_REQUEST_H 25 26 #include "common/callback.h" 27 #include "common/scummsys.h" 28 #include "common/str.h" 29 30 namespace Networking { 31 32 class Request; 33 34 /** 35 * Response<T> is a struct to be returned from Request 36 * to user's callbacks. It's a type safe way to indicate 37 * which "return value" Request has and user awaits. 38 * 39 * It just keeps a Request pointer together with 40 * some T value (which might be a pointer, a reference 41 * or a plain type (copied by value)). 42 * 43 * To make it more convenient, typedefs are used. 44 * For example, Response<void *> is called DataResponse 45 * and corresponding callback pointer is DataCallback. 46 */ 47 48 template<typename T> struct Response { 49 Request *request; 50 T value; 51 ResponseResponse52 Response(Request *rq, T v) : request(rq), value(v) {} 53 }; 54 55 /** 56 * ErrorResponse is a struct to be returned from Request 57 * to user's failure callbacks. 58 * 59 * It keeps a Request pointer together with some useful 60 * information fields, which would explain why failure 61 * callback was called. 62 * 63 * <interrupted> flag is set when Request was interrupted, 64 * i.e. finished by user with finish() call. 65 * 66 * <failed> flag is set when Request has failed because of 67 * some error (bad server response, for example). 68 * 69 * <response> contains server's original response. 70 * 71 * <httpResponseCode> contains server's HTTP response code. 72 */ 73 74 struct ErrorResponse { 75 Request *request; 76 bool interrupted; 77 bool failed; 78 Common::String response; 79 long httpResponseCode; 80 81 ErrorResponse(Request *rq, Common::String resp); 82 ErrorResponse(Request *rq, bool interrupt, bool failure, Common::String resp, long httpCode); 83 }; 84 85 typedef Response<void *> DataReponse; 86 typedef Common::BaseCallback<DataReponse> *DataCallback; 87 typedef Common::BaseCallback<ErrorResponse> *ErrorCallback; 88 89 /** 90 * RequestState is used to indicate current Request state. 91 * ConnectionManager uses it to decide what to do with the Request. 92 * 93 * PROCESSING state indicates that Request is working. 94 * ConnectionManager calls handle() method of Requests in that state. 95 * 96 * PAUSED state indicates that Request is not working. 97 * ConnectionManager keeps Requests in that state and doesn't call any methods of those. 98 * 99 * RETRY state indicates that Request must restart after a few seconds. 100 * ConnectionManager calls handleRetry() method of Requests in that state. 101 * Default handleRetry() implementation decreases _retryInSeconds value 102 * until it reaches zero. When it does, Request's restart() method is called. 103 * 104 * FINISHED state indicates that Request did the work and might be deleted. 105 * ConnectionManager deletes Requests in that state. 106 * After this state is set, but before ConnectionManager deletes the Request, 107 * Request calls user's callback. User can ask Request to change its state 108 * by calling retry() or pause() methods and Request won't be deleted. 109 * 110 * Request get a success and failure callbacks. Request must call one 111 * (and only one!) of these callbacks when it sets FINISHED state. 112 */ 113 enum RequestState { 114 PROCESSING, 115 PAUSED, 116 RETRY, 117 FINISHED 118 }; 119 120 class Request { 121 protected: 122 /** 123 * Callback, which should be called when Request is finished. 124 * That's the way Requests pass the result to the code which asked to create this request. 125 * 126 * @note some Requests use their own callbacks to return something but void *. 127 * @note callback must be called in finish() or similar method. 128 */ 129 DataCallback _callback; 130 131 /** 132 * Callback, which should be called when Request is failed/interrupted. 133 * That's the way Requests pass error information to the code which asked to create this request. 134 * @note callback must be called in finish() or similar method. 135 */ 136 ErrorCallback _errorCallback; 137 138 /** 139 * Request state, which is used by ConnectionManager to determine 140 * whether request might be deleted or it's still working. 141 * 142 * State might be changed from outside with finish(), pause() or 143 * retry() methods. Override these if you want to react to these 144 * changes correctly. 145 */ 146 RequestState _state; 147 148 /** In RETRY state this indicates whether it's time to call restart(). */ 149 uint32 _retryInSeconds; 150 151 /** Sets FINISHED state and calls the _errorCallback with given error. */ 152 virtual void finishError(ErrorResponse error); 153 154 /** Sets FINISHED state. Implementations might extend it if needed. */ 155 virtual void finishSuccess(); 156 157 public: 158 Request(DataCallback cb, ErrorCallback ecb); 159 virtual ~Request(); 160 161 /** Method, which does actual work. Depends on what this Request is doing. */ 162 virtual void handle() = 0; 163 164 /** Method, which is called by ConnectionManager when Request's state is RETRY. */ 165 virtual void handleRetry(); 166 167 /** Method, which is used to restart the Request. */ 168 virtual void restart() = 0; 169 170 /** Method, which is called to pause the Request. */ 171 virtual void pause(); 172 173 /** 174 * Method, which is called to *interrupt* the Request. 175 * When it's called, Request must stop its work and 176 * call the failure callback to notify user. 177 */ 178 virtual void finish(); 179 180 /** Method, which is called to retry the Request. */ 181 virtual void retry(uint32 seconds); 182 183 /** Returns Request's current state. */ 184 RequestState state() const; 185 186 /** 187 * Return date this Request received from server. 188 * It could be extracted from "Date" header, 189 * which is kept in NetworkReadStream. 190 * 191 * @note not all Requests do that, so "" is returned 192 * to indicate the date is unknown. That's also true 193 * if no server response available or no "Date" header 194 * was passed. 195 * 196 * @returns date from "Date" response header. 197 */ 198 virtual Common::String date() const; 199 }; 200 201 } // End of namespace Networking 202 203 #endif 204