// Copyright (c) 2013 by István Váradi // This file is part of XPLRA, a remote-access plugin for X-Plane // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // The views and conclusions contained in the software and documentation are those // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. //------------------------------------------------------------------------------ #include "xplra.h" #include "XPlane.h" #include "MultiGetter.h" #include "MultiSetter.h" #include "Exception.h" #include #include #include #include //------------------------------------------------------------------------------ using hu::varadiistvan::xplra::XPlane; using hu::varadiistvan::xplra::MultiBuffer; using hu::varadiistvan::xplra::MultiGetter; using hu::varadiistvan::xplra::MultiSetter; using hu::varadiistvan::xplra::Exception; using hu::varadiistvan::xplra::IOException; using hu::varadiistvan::xplra::ProtocolException; using hu::varadiistvan::xplra::NotConnectedException; using hu::varadiistvan::xplra::TypeMismatchException; using hu::varadiistvan::xplra::InvalidIDException; using std::exception; using std::string; using std::vector; using std::set; using std::auto_ptr; //------------------------------------------------------------------------------ namespace { //------------------------------------------------------------------------------ /** * Template for handling slots. */ template struct Slot { private: /** * The slots. */ static std::vector< Slot > slots; /** * The index of the first free slot. */ static int firstFree; public: /** * Add a new value. * * @return the ID of the new value */ static int addValue(Value value) throw(); /** * Get the value with the given ID. */ static Value getValue(int valueID) throw(); /** * Clear the value with the given ID. */ static void clearValue(int valueID) throw(); private: /** * Indicate if the slot contains a valid value or not. */ bool valid; union { // The value, if the slot contains a value Value value; // The index of the next free slot int nextFreeIndex; }; /** * Construct a slot with the given value */ Slot(Value value) throw(); /** * Set the value and return the former next free index. It * should be called for a slot with no value. */ int setValue(Value value) throw(); /** * Get the value if this slot contains a value. Otherwise 0 is * returned (converted to value). */ Value getValue() const throw(); /** * Clear the value and set the given next free index. */ void clear(int nextFreeIndex) throw(); }; //------------------------------------------------------------------------------ template vector< Slot > Slot::slots; //------------------------------------------------------------------------------ template int Slot::firstFree = -1; //------------------------------------------------------------------------------ template inline Slot::Slot(Value value) throw() : valid(true) { this->value = value; } //------------------------------------------------------------------------------ template inline int Slot::setValue(Value value) throw() { assert(!valid); int nextFreeIndex = this->nextFreeIndex; this->value = value; valid = true; return nextFreeIndex; } //------------------------------------------------------------------------------ template inline Value Slot::getValue() const throw() { return valid ? value : static_cast(0); } //------------------------------------------------------------------------------ template inline void Slot::clear(int nextFreeIndex) throw() { assert(valid); valid = false; this->nextFreeIndex = nextFreeIndex; } //------------------------------------------------------------------------------ template int Slot::addValue(Value value) throw() { int id = firstFree; if (id<0) { id = slots.size(); slots.push_back(Slot(value)); } else { Slot& slot = slots[id]; firstFree = slot.setValue(value); } return id; } //------------------------------------------------------------------------------ template Value Slot::getValue(int valueID) throw() { size_t index = static_cast(valueID); return (index(0); } //------------------------------------------------------------------------------ template void Slot::clearValue(int valueID) throw() { size_t index = static_cast(valueID); if (index MultiBufferSlot; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /** * Information about a connection. */ class Connection : public XPlane { private: /** * Type for the set of multi-dataref buffers belonging to this connection. */ typedef std::set multiBufferIDs_t; public: /** * Get the connection for the given multi-dataref buffer. */ static Connection& get(const MultiBuffer& buffer) throw(); private: /** * The last error code. */ int lastErrorCode; /** * The last error subcode. */ unsigned long lastErrorSubCode; /** * The string of the last error */ std::string lastErrorString; /** * The set of multi-dataref buffers belonging to this connection. */ multiBufferIDs_t multiBufferIDs; public: /** * Construct the connection */ Connection() throw(); /** * Destroy the connection. */ ~Connection() throw(); /** * Handle the currently pending exception. */ void handleException() throw(); /** * Get the last error code. */ int getLastError(unsigned long* lastErrorSubCode) const throw(); /** * Get the string representation of the last error code. */ const char* getLastErrorString() const throw(); /** * Clear the last error code. */ void clearLastError() throw(); /** * Create a multi-dataref getter object and register it in a slot. * * @return the ID of the new getter. */ int createMultiGetter() throw(); /** * Create a multi-dataref setter object and register it in a slot. * * @return the ID of the new setter. */ int createMultiSetter() throw(); /** * Destroy the multi-dataref buffer with the given ID. * * @param bufferID the ID of the buffer. It should be a valid ID, * that belongs to this connection. * * @return whether the buffer was found and could be destroyed. */ bool destroyMultiBuffer(int bufferID) throw(Exception); }; //------------------------------------------------------------------------------ inline Connection& Connection::get(const MultiBuffer& buffer) throw() { return static_cast(buffer.getXPlane()); } //------------------------------------------------------------------------------ inline Connection::Connection() throw() : lastErrorCode(0), lastErrorSubCode(0) { } //------------------------------------------------------------------------------ Connection::~Connection() throw() { for(multiBufferIDs_t::iterator i = multiBufferIDs.begin(); i!=multiBufferIDs.end(); ++i) { MultiBufferSlot::clearValue(*i); } } //------------------------------------------------------------------------------ void Connection::handleException() throw() { try { throw; } catch(const IOException& e) { lastErrorCode = ERROR_IO; lastErrorSubCode = e.getErrorCode(); lastErrorString = e.what(); } catch(const ProtocolException& e) { lastErrorCode = ERROR_PROTOCOL; lastErrorSubCode = static_cast(e.getErrorCode()); lastErrorString = e.what(); } catch(const NotConnectedException& e) { lastErrorCode = ERROR_NOT_CONNECTED; lastErrorSubCode = 0; lastErrorString = e.what(); } catch(const TypeMismatchException& e) { lastErrorCode = ERROR_TYPE_MISMATCH; lastErrorSubCode = 0; lastErrorString = e.what(); } catch(const InvalidIDException& e) { lastErrorCode = ERROR_INVALID_ID; lastErrorSubCode = 0; lastErrorString = e.what(); } catch(const exception& e) { lastErrorCode = ERROR_OTHER; lastErrorSubCode = 0; lastErrorString = e.what(); } catch(...) { lastErrorCode = ERROR_OTHER; lastErrorSubCode = 0; lastErrorString = ""; } } //------------------------------------------------------------------------------ inline int Connection::getLastError(unsigned long* lastErrorSubCode) const throw() { if (lastErrorSubCode!=0) *lastErrorSubCode = this->lastErrorSubCode; return lastErrorCode; } //------------------------------------------------------------------------------ inline const char* Connection::getLastErrorString() const throw() { return (lastErrorCode==ERROR_NONE) ? 0 : lastErrorString.c_str(); } //------------------------------------------------------------------------------ inline void Connection::clearLastError() throw() { lastErrorCode = ERROR_NONE; lastErrorSubCode = 0; lastErrorString.clear(); } //------------------------------------------------------------------------------ inline int Connection::createMultiGetter() throw() { MultiGetter& getter = XPlane::createMultiGetter(); return MultiBufferSlot::addValue(&getter); } //------------------------------------------------------------------------------ inline int Connection::createMultiSetter() throw() { MultiSetter& setter = XPlane::createMultiSetter(); return MultiBufferSlot::addValue(&setter); } //------------------------------------------------------------------------------ bool Connection::destroyMultiBuffer(int bufferID) throw(Exception) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return false; if (XPlane::destroyMultiBuffer(*buffer)) { multiBufferIDs.erase(bufferID); MultiBufferSlot::clearValue(bufferID); return true; } else { return false; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /** * Slot for connections. */ typedef Slot ConnectionSlot; //------------------------------------------------------------------------------ } /* anonymous namespace */ //------------------------------------------------------------------------------ extern "C" int xplra_get_last_error(int connectionID, unsigned long* subCode) { Connection* connection = ConnectionSlot::getValue(connectionID); return (connection==0) ? -1 : connection->getLastError(subCode); } //------------------------------------------------------------------------------ extern "C" const char* xplra_get_last_error_string(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); return (connection==0) ? 0 : connection->getLastErrorString(); } //------------------------------------------------------------------------------ extern "C" void xplra_clear_last_error(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection!=0) connection->clearLastError(); } //------------------------------------------------------------------------------ extern "C" int xplra_connect() { try { auto_ptr connection(new Connection()); connection->connect(); return ConnectionSlot::addValue(connection.release()); } catch(...) { return -1; } } //------------------------------------------------------------------------------ extern "C"int xplra_get_versions(int connectionID, int* xplaneVersion, int* xplmVersion, int* xplraVersion) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->getVersions(*xplaneVersion, *xplmVersion, *xplraVersion); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_reload_plugins(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->reloadPlugins(); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_get_int(int* value, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { *value = connection->getInt(name); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_get_float(float* value, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { *value = connection->getFloat(name); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_get_double(double* value, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { *value = connection->getDouble(name); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_get_float_array(float* dest, size_t length, size_t offset, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { return connection->getFloatArray(name, dest, length, offset); } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" float* xplra_get_float_array_new(size_t* length, size_t offset, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { return connection->getFloatArray(name, *length, offset); } catch (...) { connection->handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_get_int_array(int32_t* dest, size_t length, size_t offset, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { return connection->getIntArray(name, dest, length, offset); } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int32_t* xplra_get_int_array_new(size_t* length, size_t offset, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { return connection->getIntArray(name, *length, offset); } catch (...) { connection->handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_get_byte_array(void* dest, size_t length, size_t offset, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { return connection->getByteArray(name, reinterpret_cast(dest), length, offset); } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" uint8_t* xplra_get_byte_array_new(size_t* length, size_t offset, int connectionID, const char* name) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { return connection->getByteArray(name, *length, offset); } catch (...) { connection->handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" int xplra_set_int(int connectionID, const char* name, int value) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setInt(name, value); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_set_float(int connectionID, const char* name, float value) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setFloat(name, value); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_set_double(int connectionID, const char* name, double value) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setDouble(name, value); return 0; } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_set_float_array(int connectionID, const char* name, const float* values, size_t length, size_t offset) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setFloatArray(name, values, length, offset); return 0; } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_set_int_array(int connectionID, const char* name, const int32_t* values, size_t length, size_t offset) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setIntArray(name, values, length, offset); return 0; } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_set_byte_array(int connectionID, const char* name, const void* values, size_t length, size_t offset) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setByteArray(name, reinterpret_cast(values), length, offset); return 0; } catch (...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_set_string(int connectionID, const char* name, const char* value, size_t length, size_t offset) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return 0; try { connection->setString(name, value, length, offset); return 0; } catch (...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ extern "C" int xplra_multi_create_getter(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); return (connection==0) ? -1 : connection->createMultiGetter(); } //------------------------------------------------------------------------------ extern "C" int xplra_multi_create_setter(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); return (connection==0) ? -1 : connection->createMultiSetter(); } //------------------------------------------------------------------------------ extern "C" size_t xplra_multi_add_int(int bufferID, const char* name) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? INVALID_DATAREF_ID : buffer->addInt(name); } //------------------------------------------------------------------------------ extern "C" size_t xplra_multi_add_float(int bufferID, const char* name) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? INVALID_DATAREF_ID : buffer->addFloat(name); } //------------------------------------------------------------------------------ extern "C" size_t xplra_multi_add_double(int bufferID, const char* name) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? INVALID_DATAREF_ID : buffer->addDouble(name); } /*----------------------------------------------------------------------------*/ extern "C" size_t xplra_multi_add_float_array(int bufferID, const char* name, size_t length, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? INVALID_DATAREF_ID : buffer->addFloatArray(name, length, offset); } /*----------------------------------------------------------------------------*/ extern "C" size_t xplra_multi_add_int_array(int bufferID, const char* name, size_t length, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? INVALID_DATAREF_ID : buffer->addIntArray(name, length, offset); } /*----------------------------------------------------------------------------*/ extern "C" size_t xplra_multi_add_byte_array(int bufferID, const char* name, size_t length, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? INVALID_DATAREF_ID : buffer->addByteArray(name, length, offset); } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_finalize(int bufferID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? -1 : (buffer->finalize() ? 1 : 0); } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_register(int bufferID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { buffer->registerInXPlane(); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_unregister(int bufferID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { buffer->unregisterFromXPlane(); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_unregister_safely(int bufferID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); return (buffer==0) ? -1 : (buffer->unregisterSafelyFromXPlane() ? 1 : 0); } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_execute(int bufferID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { buffer->execute(); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } //------------------------------------------------------------------------------ extern "C" int xplra_multi_set_int(int bufferID, size_t datarefID, int value) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { buffer->setInt(datarefID, value); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_get_int(int* dest, int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { *dest = buffer->getInt(datarefID); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const int32_t* xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return &(buffer->getIntRef(datarefID)); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } /*----------------------------------------------------------------------------*/ extern "C" int32_t* xplra_multi_get_int_ptr(int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return &(buffer->getIntRef(datarefID)); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" int xplra_multi_set_float(int bufferID, size_t datarefID, float value) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { buffer->setFloat(datarefID, value); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_get_float(float* dest, int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { *dest = buffer->getFloat(datarefID); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const float* xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return &(buffer->getFloatRef(datarefID)); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } /*----------------------------------------------------------------------------*/ extern "C" float* xplra_multi_get_float_ptr(int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return &(buffer->getFloatRef(datarefID)); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" int xplra_multi_set_double(int bufferID, size_t datarefID, double value) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { buffer->setDouble(datarefID, value); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_multi_get_double(double* dest, int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { *dest = buffer->getDouble(datarefID); return 0; } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const double* xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return &(buffer->getDoubleRef(datarefID)); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } /*----------------------------------------------------------------------------*/ extern "C" double* xplra_multi_get_double_ptr(int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return &(buffer->getDoubleRef(datarefID)); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID, const float* value, size_t length, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->setFloatArray(datarefID, value, length, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" ssize_t xplra_multi_get_float_array(float* value, size_t length, size_t offset, int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->getFloatArray(datarefID, value, length, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const float* xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return buffer->getFloatArray(datarefID, offset); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID, const int32_t* value, size_t length, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->setIntArray(datarefID, value, length, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" ssize_t xplra_multi_get_int_array(int32_t* value, size_t length, size_t offset, int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->getIntArray(datarefID, value, length, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const int32_t* xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return buffer->getIntArray(datarefID, offset); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID, const void* value, size_t length, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->setByteArray(datarefID, reinterpret_cast(value), length, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" ssize_t xplra_multi_get_byte_array(void* value, size_t length, size_t offset, int bufferID, size_t datarefID) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->getByteArray(datarefID, reinterpret_cast(value), length, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const uint8_t* xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return buffer->getByteArray(datarefID, offset); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" ssize_t xplra_multi_set_string(int bufferID, size_t datarefID, const char* value, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return -1; try { return buffer->setString(datarefID, value, offset); } catch (...) { Connection::get(*buffer).handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" const char* xplra_multi_get_string_ptr(int bufferID, size_t datarefID, size_t offset) { MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID); if (buffer==0) return 0; try { return buffer->getStringPtr(datarefID, offset); } catch (...) { Connection::get(*buffer).handleException(); return 0; } } //------------------------------------------------------------------------------ extern "C" int xplra_multi_destroy_buffer(int connectionID, int bufferID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { return connection->destroyMultiBuffer(bufferID) ? 0 : -1; } catch(...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ extern "C" int xplra_show_message(int connectionID, const char* message, float duration) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->showMessage(message, duration); return 0; } catch(...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ extern "C" int xplra_register_hotkeys(int connectionID, const uint16_t* codes, size_t length) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->registerHotkeys(codes, length); return 0; } catch(...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_query_hotkeys(int connectionID, uint8_t* states, size_t length) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->queryHotkeys(states, length); return 0; } catch(...) { connection->handleException(); return -1; } } /*----------------------------------------------------------------------------*/ extern "C" int xplra_unregister_hotkeys(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->unregisterHotkeys(); return 0; } catch(...) { connection->handleException(); return -1; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ extern "C" int xplra_disconnect(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; connection->disconnect(); return 0; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ extern "C" int xplra_reconnect(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; try { connection->connect(); return 0; } catch(...) { return -1; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ extern "C" int xplra_destroy(int connectionID) { Connection* connection = ConnectionSlot::getValue(connectionID); if (connection==0) return -1; ConnectionSlot::clearValue(connectionID); delete connection; return 0; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Local Variables: // mode: C++ // c-basic-offset: 4 // indent-tabs-mode: nil // End: