Changeset 23:e3beb05af132 in xplra for src/client/c/hu
- Timestamp:
- 02/06/13 18:50:36 (12 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src/client/c/hu/varadiistvan/xplra
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/client/c/hu/varadiistvan/xplra/xplra.cc
r14 r23 34 34 #include "Exception.h" 35 35 36 #include <vector> 37 #include <memory> 38 36 39 #include <cstdio> 40 #include <cassert> 37 41 38 42 //------------------------------------------------------------------------------ … … 40 44 using hu::varadiistvan::xplra::XPlane; 41 45 using hu::varadiistvan::xplra::Exception; 46 using hu::varadiistvan::xplra::IOException; 47 using hu::varadiistvan::xplra::ProtocolException; 48 using hu::varadiistvan::xplra::NotConnectedException; 49 using hu::varadiistvan::xplra::TypeMismatchException; 50 using hu::varadiistvan::xplra::InvalidIDException; 51 52 using std::exception; 53 using std::string; 54 using std::vector; 55 using std::auto_ptr; 56 57 //------------------------------------------------------------------------------ 58 59 namespace { 60 61 //------------------------------------------------------------------------------ 62 63 /** 64 * Information about a connection. 65 */ 66 class Connection : public XPlane 67 { 68 private: 69 /** 70 * The last error code. 71 */ 72 int lastErrorCode; 73 74 /** 75 * The last error subcode. 76 */ 77 unsigned long lastErrorSubCode; 78 79 /** 80 * The string of the last error 81 */ 82 std::string lastErrorString; 83 84 public: 85 /** 86 * Construct the connection 87 */ 88 Connection() throw(); 89 90 /** 91 * Handle the currently pending exception. 92 */ 93 void handleException() throw(); 94 95 /** 96 * Get the last error code. 97 */ 98 int getLastError(unsigned long* lastErrorSubCode) const throw(); 99 100 /** 101 * Get the string representation of the last error code. 102 */ 103 const char* getLastErrorString() const throw(); 104 105 /** 106 * Clear the last error code. 107 */ 108 void clearLastError() throw(); 109 }; 110 111 //------------------------------------------------------------------------------ 112 113 inline Connection::Connection() throw() : 114 lastErrorCode(0), 115 lastErrorSubCode(0) 116 { 117 } 118 119 //------------------------------------------------------------------------------ 120 121 void Connection::handleException() throw() 122 { 123 try { 124 throw; 125 } catch(const IOException& e) { 126 lastErrorCode = ERROR_IO; 127 lastErrorSubCode = e.getErrorCode(); 128 lastErrorString = e.what(); 129 } catch(const ProtocolException& e) { 130 lastErrorCode = ERROR_PROTOCOL; 131 lastErrorSubCode = static_cast<unsigned long>(e.getErrorCode()); 132 lastErrorString = e.what(); 133 } catch(const NotConnectedException& e) { 134 lastErrorCode = ERROR_NOT_CONNECTED; 135 lastErrorSubCode = 0; 136 lastErrorString = e.what(); 137 } catch(const TypeMismatchException& e) { 138 lastErrorCode = ERROR_TYPE_MISMATCH; 139 lastErrorSubCode = 0; 140 lastErrorString = e.what(); 141 } catch(const InvalidIDException& e) { 142 lastErrorCode = ERROR_INVALID_ID; 143 lastErrorSubCode = 0; 144 lastErrorString = e.what(); 145 } catch(const exception& e) { 146 lastErrorCode = ERROR_OTHER; 147 lastErrorSubCode = 0; 148 lastErrorString = e.what(); 149 } catch(...) { 150 lastErrorCode = ERROR_OTHER; 151 lastErrorSubCode = 0; 152 lastErrorString = "<Exception of an unknown type>"; 153 } 154 } 155 156 //------------------------------------------------------------------------------ 157 158 inline int Connection::getLastError(unsigned long* lastErrorSubCode) 159 const throw() 160 { 161 if (lastErrorSubCode!=0) *lastErrorSubCode = this->lastErrorSubCode; 162 return lastErrorCode; 163 } 164 165 //------------------------------------------------------------------------------ 166 167 inline const char* Connection::getLastErrorString() const throw() 168 { 169 return (lastErrorCode==ERROR_NONE) ? 0 : lastErrorString.c_str(); 170 } 171 172 //------------------------------------------------------------------------------ 173 174 inline void Connection::clearLastError() throw() 175 { 176 lastErrorCode = ERROR_NONE; 177 lastErrorSubCode = 0; 178 lastErrorString.clear(); 179 } 180 181 //------------------------------------------------------------------------------ 182 //------------------------------------------------------------------------------ 183 184 /** 185 * Information about a connection slot in the vector of connections. 186 */ 187 struct Slot 188 { 189 private: 190 /** 191 * The slots. 192 */ 193 static std::vector<Slot> slots; 194 195 /** 196 * The index of the first free slot. 197 */ 198 static int firstFree; 199 200 public: 201 /** 202 * Add a new connection. 203 */ 204 static int addConnection(Connection* connection) throw(); 205 206 /** 207 * Get the connection with the given ID. 208 */ 209 static Connection* getConnection(int connectionID) throw(); 210 211 /** 212 * Clear the connection with the given ID. 213 */ 214 static void clearConnection(int connectionID) throw(); 215 216 // Indicate if the slot contains a valid connection or not 217 bool valid; 218 219 union { 220 // The connection, if it is a valid connection 221 Connection* connection; 222 223 // The index of the next free slot 224 int nextFreeIndex; 225 }; 226 227 /** 228 * Construct a slot with the given connection 229 */ 230 Slot(Connection* connection) throw(); 231 232 /** 233 * Set the connection and return the former next free index. It 234 * should be called for a slot with no connection. 235 */ 236 int setConnection(Connection* connection) throw(); 237 238 /** 239 * Get the connection if this slot contains a connection. 240 */ 241 Connection* getConnection() const throw(); 242 243 /** 244 * Clear the connection and set the given next free index. 245 */ 246 void clear(int nextFreeIndex) throw(); 247 }; 248 249 //------------------------------------------------------------------------------ 250 251 vector<Slot> Slot::slots; 252 253 //------------------------------------------------------------------------------ 254 255 int Slot::firstFree = -1; 256 257 //------------------------------------------------------------------------------ 258 259 inline Slot::Slot(Connection* connection) throw() : 260 valid(true) 261 { 262 this->connection = connection; 263 } 264 265 //------------------------------------------------------------------------------ 266 267 inline int Slot::setConnection(Connection* connection) throw() 268 { 269 assert(!valid); 270 int nextFreeIndex = this->nextFreeIndex; 271 this->connection = connection; 272 valid = true; 273 return nextFreeIndex; 274 } 275 276 //------------------------------------------------------------------------------ 277 278 inline Connection* Slot::getConnection() const throw() 279 { 280 return valid ? connection : 0; 281 } 282 283 //------------------------------------------------------------------------------ 284 285 inline void Slot::clear(int nextFreeIndex) throw() 286 { 287 assert(valid); 288 valid = false; 289 this->nextFreeIndex = nextFreeIndex; 290 } 291 292 //------------------------------------------------------------------------------ 293 294 int Slot::addConnection(Connection* connection) throw() 295 { 296 int id = firstFree; 297 if (id<0) { 298 id = slots.size(); 299 slots.push_back(Slot(connection)); 300 } else { 301 Slot& slot = slots[id]; 302 firstFree = slot.setConnection(connection); 303 } 304 305 return id; 306 } 307 308 //------------------------------------------------------------------------------ 309 310 Connection* Slot::getConnection(int connectionID) throw() 311 { 312 size_t index = static_cast<size_t>(connectionID); 313 return (index<slots.size()) ? slots[index].getConnection() : 0; 314 } 315 316 //------------------------------------------------------------------------------ 317 318 void Slot::clearConnection(int connectionID) throw() 319 { 320 size_t index = static_cast<size_t>(connectionID); 321 if (index<slots.size()) { 322 slots[index].clear(firstFree); 323 firstFree = index; 324 } 325 } 326 327 //------------------------------------------------------------------------------ 328 329 } /* anonymous namespace */ 330 331 //------------------------------------------------------------------------------ 332 333 extern "C" int xplra_get_last_error(int connectionID, unsigned long* subCode) 334 { 335 Connection* connection = Slot::getConnection(connectionID); 336 return (connection==0) ? -1 : connection->getLastError(subCode); 337 } 338 339 //------------------------------------------------------------------------------ 340 341 extern "C" const char* xplra_get_last_error_string(int connectionID) 342 { 343 Connection* connection = Slot::getConnection(connectionID); 344 return (connection==0) ? 0 : connection->getLastErrorString(); 345 } 346 347 //------------------------------------------------------------------------------ 348 349 extern "C" void xplra_clear_last_error(int connectionID) 350 { 351 Connection* connection = Slot::getConnection(connectionID); 352 if (connection!=0) connection->clearLastError(); 353 } 42 354 43 355 //------------------------------------------------------------------------------ … … 46 358 { 47 359 try { 48 XPlane xplane; 360 auto_ptr<Connection> connection(new Connection()); 361 connection->connect(); 362 return Slot::addConnection(connection.release()); 363 } catch(...) { 364 return -1; 365 } 366 } 367 368 //------------------------------------------------------------------------------ 369 370 extern "C" int xplra_get_int(int* value, int connectionID, const char* name) 371 { 372 Connection* connection = Slot::getConnection(connectionID); 373 if (connection==0) return -1; 374 try { 375 *value = connection->getInt(name); 49 376 return 0; 50 } catch (const Exception& e) {51 printf("xplra_connect failed: %s\n", e.what());377 } catch (...) { 378 connection->handleException(); 52 379 return -1; 53 380 } 381 } 382 383 //------------------------------------------------------------------------------ 384 385 extern "C" int xplra_get_float(float* value, int connectionID, const char* name) 386 { 387 Connection* connection = Slot::getConnection(connectionID); 388 if (connection==0) return -1; 389 try { 390 *value = connection->getFloat(name); 391 return 0; 392 } catch (...) { 393 connection->handleException(); 394 return -1; 395 } 396 } 397 398 //------------------------------------------------------------------------------ 399 400 extern "C" int xplra_get_double(double* value, 401 int connectionID, const char* name) 402 { 403 Connection* connection = Slot::getConnection(connectionID); 404 if (connection==0) return -1; 405 try { 406 *value = connection->getDouble(name); 407 return 0; 408 } catch (...) { 409 connection->handleException(); 410 return -1; 411 } 412 } 413 414 //------------------------------------------------------------------------------ 415 416 extern "C" int xplra_disconnect(int connectionID) 417 { 418 Connection* connection = Slot::getConnection(connectionID); 419 if (connection==0) return -1; 420 421 Slot::clearConnection(connectionID); 422 connection->disconnect(); 423 delete connection; 424 425 return 0; 54 426 } 55 427 -
src/client/c/hu/varadiistvan/xplra/xplra.h
r14 r23 38 38 /*----------------------------------------------------------------------------*/ 39 39 40 /** No error occured */ 41 #define ERROR_NONE 0 42 43 /** 44 * An I/O error has occured. The subcode is the errno value on Linux, or the 45 * Windows error code. 46 */ 47 #define ERROR_IO 1 48 49 /** 50 * A protocol error has occured. The subcode is one of the 51 * ERROR_PROTOCOL_XXX values. 52 */ 53 #define ERROR_PROTOCOL 2 54 55 /** Invalid command was passed to the plugin */ 56 #define ERROR_PROTOCOL_INVALID_COMMAND = 1 57 58 /** An unknown dataref was specified */ 59 #define ERROR_PROTOCOL_UNKNOWN_DATAREF = 2 60 61 /** An invalid type was specified */ 62 #define ERROR_PROTOCOL_INVALID_TYPE = 3 63 64 /** An invalid length was specified */ 65 #define ERROR_PROTOCOL_INVALID_LENGTH = 4 66 67 /** An invalid offset was specified */ 68 #define ERROR_PROTOCOL_INVALID_OFFSET = 5 69 70 /** An invalid count was specified */ 71 #define ERROR_PROTOCOL_INVALID_COUNT = 6 72 73 /** An invalid ID was specified */ 74 #define ERROR_PROTOCOL_INVALID_ID = 7 75 76 /** Other protocol error */ 77 #define ERROR_PROTOCOL_OTHER = 8 78 79 /** A function requiring a connection is called without a connection */ 80 #define ERROR_NOT_CONNECTED 3 81 82 /** A type-specific function was called for a dataref of a different type */ 83 #define ERROR_TYPE_MISMATCH 4 84 85 /** An invalid ID was passed to a function */ 86 #define ERROR_INVALID_ID 5 87 88 /** Some other error */ 89 #define ERROR_OTHER 255 90 91 /*----------------------------------------------------------------------------*/ 92 93 /** 94 * Get the last error code with the subcode. 95 * 96 * @return the last error code, or -1 if the given connection ID is invalid. 97 */ 98 int xplra_get_last_error(int connectionID, unsigned long* subCode); 99 100 /** 101 * Get a string representation of the last error. 102 * 103 * @return the string representation of the last error, or 0 if there 104 * was no last error, or the connection ID is invalid. 105 */ 106 const char* xplra_get_last_error_string(int connectionID); 107 108 /** 109 * Clear the last error. 110 */ 111 void xplra_clear_last_error(int connectionID); 112 113 /*----------------------------------------------------------------------------*/ 114 115 /** 116 * Connect to the simulator. 117 * 118 * @return an ID for the created connection, or -1 on error. 119 */ 40 120 int xplra_connect(); 121 122 /*----------------------------------------------------------------------------*/ 123 124 /** 125 * Get an integer value from the simulator. 126 * 127 * @return 0 on success, -1 on error 128 */ 129 int xplra_get_int(int* value, int connectionID, const char* name); 130 131 /*----------------------------------------------------------------------------*/ 132 133 /** 134 * Get a float value from the simulator. 135 * 136 * @return 0 on success, -1 on error 137 */ 138 int xplra_get_float(float* value, int connectionID, const char* name); 139 140 /*----------------------------------------------------------------------------*/ 141 142 /** 143 * Get a double value from the simulator. 144 * 145 * @return 0 on success, -1 on error 146 */ 147 int xplra_get_double(double* value, int connectionID, const char* name); 148 149 /*----------------------------------------------------------------------------*/ 150 151 /** 152 * Destroy the connection with the given ID. 153 * 154 * @return 0 on success, -1 on error. 155 */ 156 int xplra_disconnect(int connectionID); 41 157 42 158 /*----------------------------------------------------------------------------*/
Note:
See TracChangeset
for help on using the changeset viewer.