source: xplra/src/client/c/hu/varadiistvan/xplra/xplra.cc@ 107:614b9ff033c1

Last change on this file since 107:614b9ff033c1 was 107:614b9ff033c1, checked in by István Váradi <ivaradi@…>, 17 months ago

Modernized the exception specifications in the C++ client

File size: 41.6 KB
Line 
1// Copyright (c) 2013 by István Váradi
2
3// This file is part of XPLRA, a remote-access plugin for X-Plane
4
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7
8// 1. Redistributions of source code must retain the above copyright notice, this
9// list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25// The views and conclusions contained in the software and documentation are those
26// of the authors and should not be interpreted as representing official policies,
27// either expressed or implied, of the FreeBSD Project.
28
29//------------------------------------------------------------------------------
30
31#include "xplra.h"
32
33#include "XPlane.h"
34#include "MultiGetter.h"
35#include "MultiSetter.h"
36#include "Exception.h"
37
38#include <vector>
39#include <memory>
40
41#include <cstdio>
42#include <cassert>
43
44//------------------------------------------------------------------------------
45
46using hu::varadiistvan::xplra::XPlane;
47using hu::varadiistvan::xplra::MultiBuffer;
48using hu::varadiistvan::xplra::MultiGetter;
49using hu::varadiistvan::xplra::MultiSetter;
50using hu::varadiistvan::xplra::Exception;
51using hu::varadiistvan::xplra::IOException;
52using hu::varadiistvan::xplra::ProtocolException;
53using hu::varadiistvan::xplra::NotConnectedException;
54using hu::varadiistvan::xplra::TypeMismatchException;
55using hu::varadiistvan::xplra::InvalidIDException;
56
57using std::exception;
58using std::string;
59using std::vector;
60using std::set;
61using std::unique_ptr;
62
63//------------------------------------------------------------------------------
64
65namespace {
66
67//------------------------------------------------------------------------------
68
69/**
70 * Template for handling slots.
71 */
72template <class Value>
73struct Slot
74{
75private:
76 /**
77 * The slots.
78 */
79 static std::vector< Slot<Value> > slots;
80
81 /**
82 * The index of the first free slot.
83 */
84 static int firstFree;
85
86public:
87 /**
88 * Add a new value.
89 *
90 * @return the ID of the new value
91 */
92 static int addValue(Value value) noexcept;
93
94 /**
95 * Get the value with the given ID.
96 */
97 static Value getValue(int valueID) noexcept;
98
99 /**
100 * Clear the value with the given ID.
101 */
102 static void clearValue(int valueID) noexcept;
103
104private:
105 /**
106 * Indicate if the slot contains a valid value or not.
107 */
108 bool valid;
109
110 union {
111 // The value, if the slot contains a value
112 Value value;
113
114 // The index of the next free slot
115 int nextFreeIndex;
116 };
117
118 /**
119 * Construct a slot with the given value
120 */
121 Slot(Value value) noexcept;
122
123 /**
124 * Set the value and return the former next free index. It
125 * should be called for a slot with no value.
126 */
127 int setValue(Value value) noexcept;
128
129 /**
130 * Get the value if this slot contains a value. Otherwise 0 is
131 * returned (converted to value).
132 */
133 Value getValue() const noexcept;
134
135 /**
136 * Clear the value and set the given next free index.
137 */
138 void clear(int nextFreeIndex) noexcept;
139};
140
141//------------------------------------------------------------------------------
142
143template <class Value> vector< Slot<Value> > Slot<Value>::slots;
144
145//------------------------------------------------------------------------------
146
147template <class Value> int Slot<Value>::firstFree = -1;
148
149//------------------------------------------------------------------------------
150
151template <class Value>
152inline Slot<Value>::Slot(Value value) noexcept :
153 valid(true)
154{
155 this->value = value;
156}
157
158//------------------------------------------------------------------------------
159
160template <class Value>
161inline int Slot<Value>::setValue(Value value) noexcept
162{
163 assert(!valid);
164 int nextFreeIndex = this->nextFreeIndex;
165 this->value = value;
166 valid = true;
167 return nextFreeIndex;
168}
169
170//------------------------------------------------------------------------------
171
172template <class Value>
173inline Value Slot<Value>::getValue() const noexcept
174{
175 return valid ? value : static_cast<Value>(0);
176}
177
178//------------------------------------------------------------------------------
179
180template <class Value>
181inline void Slot<Value>::clear(int nextFreeIndex) noexcept
182{
183 assert(valid);
184 valid = false;
185 this->nextFreeIndex = nextFreeIndex;
186}
187
188//------------------------------------------------------------------------------
189
190template <class Value>
191int Slot<Value>::addValue(Value value) noexcept
192{
193 int id = firstFree;
194 if (id<0) {
195 id = slots.size();
196 slots.push_back(Slot<Value>(value));
197 } else {
198 Slot& slot = slots[id];
199 firstFree = slot.setValue(value);
200 }
201
202 return id;
203}
204
205//------------------------------------------------------------------------------
206
207template <class Value>
208Value Slot<Value>::getValue(int valueID) noexcept
209{
210 size_t index = static_cast<size_t>(valueID);
211 return (index<slots.size()) ?
212 slots[index].getValue() : static_cast<Value>(0);
213}
214
215//------------------------------------------------------------------------------
216
217template <class Value>
218void Slot<Value>::clearValue(int valueID) noexcept
219{
220 size_t index = static_cast<size_t>(valueID);
221 if (index<slots.size()) {
222 slots[index].clear(firstFree);
223 firstFree = index;
224 }
225}
226
227//------------------------------------------------------------------------------
228//------------------------------------------------------------------------------
229
230typedef Slot<MultiBuffer*> MultiBufferSlot;
231
232//------------------------------------------------------------------------------
233//------------------------------------------------------------------------------
234
235/**
236 * Information about a connection.
237 */
238class Connection : public XPlane
239{
240private:
241 /**
242 * Type for the set of multi-dataref buffers belonging to this connection.
243 */
244 typedef std::set<int> multiBufferIDs_t;
245
246public:
247 /**
248 * Get the connection for the given multi-dataref buffer.
249 */
250 static Connection& get(const MultiBuffer& buffer) noexcept;
251
252private:
253 /**
254 * The last error code.
255 */
256 int lastErrorCode;
257
258 /**
259 * The last error subcode.
260 */
261 unsigned long lastErrorSubCode;
262
263 /**
264 * The string of the last error
265 */
266 std::string lastErrorString;
267
268 /**
269 * The set of multi-dataref buffers belonging to this connection.
270 */
271 multiBufferIDs_t multiBufferIDs;
272
273public:
274 /**
275 * Construct the connection
276 */
277 Connection() noexcept;
278
279 /**
280 * Destroy the connection.
281 */
282 ~Connection() noexcept;
283
284 /**
285 * Handle the currently pending exception.
286 */
287 void handleException() noexcept;
288
289 /**
290 * Get the last error code.
291 */
292 int getLastError(unsigned long* lastErrorSubCode) const noexcept;
293
294 /**
295 * Get the string representation of the last error code.
296 */
297 const char* getLastErrorString() const noexcept;
298
299 /**
300 * Clear the last error code.
301 */
302 void clearLastError() noexcept;
303
304 /**
305 * Create a multi-dataref getter object and register it in a slot.
306 *
307 * @return the ID of the new getter.
308 */
309 int createMultiGetter() noexcept;
310
311 /**
312 * Create a multi-dataref setter object and register it in a slot.
313 *
314 * @return the ID of the new setter.
315 */
316 int createMultiSetter() noexcept;
317
318 /**
319 * Destroy the multi-dataref buffer with the given ID.
320 *
321 * @param bufferID the ID of the buffer. It should be a valid ID,
322 * that belongs to this connection.
323 *
324 * @return whether the buffer was found and could be destroyed.
325 */
326 bool destroyMultiBuffer(int bufferID);
327};
328
329//------------------------------------------------------------------------------
330
331inline Connection& Connection::get(const MultiBuffer& buffer) noexcept
332{
333 return static_cast<Connection&>(buffer.getXPlane());
334}
335
336//------------------------------------------------------------------------------
337
338inline Connection::Connection() noexcept :
339 lastErrorCode(0),
340 lastErrorSubCode(0)
341{
342}
343
344//------------------------------------------------------------------------------
345
346Connection::~Connection() noexcept
347{
348 for(multiBufferIDs_t::iterator i = multiBufferIDs.begin();
349 i!=multiBufferIDs.end(); ++i)
350 {
351 MultiBufferSlot::clearValue(*i);
352 }
353}
354
355//------------------------------------------------------------------------------
356
357void Connection::handleException() noexcept
358{
359 try {
360 throw;
361 } catch(const IOException& e) {
362 lastErrorCode = ERROR_IO;
363 lastErrorSubCode = e.getErrorCode();
364 lastErrorString = e.what();
365 } catch(const ProtocolException& e) {
366 lastErrorCode = ERROR_PROTOCOL;
367 lastErrorSubCode = static_cast<unsigned long>(e.getErrorCode());
368 lastErrorString = e.what();
369 } catch(const NotConnectedException& e) {
370 lastErrorCode = ERROR_NOT_CONNECTED;
371 lastErrorSubCode = 0;
372 lastErrorString = e.what();
373 } catch(const TypeMismatchException& e) {
374 lastErrorCode = ERROR_TYPE_MISMATCH;
375 lastErrorSubCode = 0;
376 lastErrorString = e.what();
377 } catch(const InvalidIDException& e) {
378 lastErrorCode = ERROR_INVALID_ID;
379 lastErrorSubCode = 0;
380 lastErrorString = e.what();
381 } catch(const exception& e) {
382 lastErrorCode = ERROR_OTHER;
383 lastErrorSubCode = 0;
384 lastErrorString = e.what();
385 } catch(...) {
386 lastErrorCode = ERROR_OTHER;
387 lastErrorSubCode = 0;
388 lastErrorString = "<Exception of an unknown type>";
389 }
390}
391
392//------------------------------------------------------------------------------
393
394inline int Connection::getLastError(unsigned long* lastErrorSubCode)
395 const noexcept
396{
397 if (lastErrorSubCode!=0) *lastErrorSubCode = this->lastErrorSubCode;
398 return lastErrorCode;
399}
400
401//------------------------------------------------------------------------------
402
403inline const char* Connection::getLastErrorString() const noexcept
404{
405 return (lastErrorCode==ERROR_NONE) ? 0 : lastErrorString.c_str();
406}
407
408//------------------------------------------------------------------------------
409
410inline void Connection::clearLastError() noexcept
411{
412 lastErrorCode = ERROR_NONE;
413 lastErrorSubCode = 0;
414 lastErrorString.clear();
415}
416
417//------------------------------------------------------------------------------
418
419inline int Connection::createMultiGetter() noexcept
420{
421 MultiGetter& getter = XPlane::createMultiGetter();
422 return MultiBufferSlot::addValue(&getter);
423}
424
425//------------------------------------------------------------------------------
426
427inline int Connection::createMultiSetter() noexcept
428{
429 MultiSetter& setter = XPlane::createMultiSetter();
430 return MultiBufferSlot::addValue(&setter);
431}
432
433//------------------------------------------------------------------------------
434
435bool Connection::destroyMultiBuffer(int bufferID)
436{
437 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
438 if (buffer==0) return false;
439
440 if (XPlane::destroyMultiBuffer(*buffer)) {
441 multiBufferIDs.erase(bufferID);
442 MultiBufferSlot::clearValue(bufferID);
443 return true;
444 } else {
445 return false;
446 }
447}
448
449//------------------------------------------------------------------------------
450//------------------------------------------------------------------------------
451
452/**
453 * Slot for connections.
454 */
455typedef Slot<Connection*> ConnectionSlot;
456
457//------------------------------------------------------------------------------
458
459} /* anonymous namespace */
460
461//------------------------------------------------------------------------------
462
463extern "C" int xplra_get_last_error(int connectionID, unsigned long* subCode)
464{
465 Connection* connection = ConnectionSlot::getValue(connectionID);
466 return (connection==0) ? -1 : connection->getLastError(subCode);
467}
468
469//------------------------------------------------------------------------------
470
471extern "C" const char* xplra_get_last_error_string(int connectionID)
472{
473 Connection* connection = ConnectionSlot::getValue(connectionID);
474 return (connection==0) ? 0 : connection->getLastErrorString();
475}
476
477//------------------------------------------------------------------------------
478
479extern "C" void xplra_clear_last_error(int connectionID)
480{
481 Connection* connection = ConnectionSlot::getValue(connectionID);
482 if (connection!=0) connection->clearLastError();
483}
484
485//------------------------------------------------------------------------------
486
487extern "C" int xplra_connect()
488{
489 try {
490 unique_ptr<Connection> connection(new Connection());
491 connection->connect();
492 return ConnectionSlot::addValue(connection.release());
493 } catch(...) {
494 return -1;
495 }
496}
497
498//------------------------------------------------------------------------------
499
500extern "C" int xplra_get_versions(int connectionID,
501 int* xplaneVersion, int* xplmVersion,
502 int* xplraVersion)
503{
504 Connection* connection = ConnectionSlot::getValue(connectionID);
505 if (connection==0) return -1;
506 try {
507 connection->getVersions(*xplaneVersion, *xplmVersion, *xplraVersion);
508 return 0;
509 } catch (...) {
510 connection->handleException();
511 return -1;
512 }
513}
514
515//------------------------------------------------------------------------------
516
517extern "C" int xplra_reload_plugins(int connectionID)
518{
519 Connection* connection = ConnectionSlot::getValue(connectionID);
520 if (connection==0) return -1;
521 try {
522 connection->reloadPlugins();
523 return 0;
524 } catch (...) {
525 connection->handleException();
526 return -1;
527 }
528}
529
530//------------------------------------------------------------------------------
531
532extern "C" int xplra_save_situation(int connectionID, const char* path)
533{
534 Connection* connection = ConnectionSlot::getValue(connectionID);
535 if (connection==0) return -1;
536 try {
537 connection->saveSituation(path);
538 return 0;
539 } catch (...) {
540 connection->handleException();
541 return -1;
542 }
543}
544
545//------------------------------------------------------------------------------
546
547extern "C" int xplra_get_int(int* value, int connectionID, const char* name)
548{
549 Connection* connection = ConnectionSlot::getValue(connectionID);
550 if (connection==0) return -1;
551 try {
552 *value = connection->getInt(name);
553 return 0;
554 } catch (...) {
555 connection->handleException();
556 return -1;
557 }
558}
559
560//------------------------------------------------------------------------------
561
562extern "C" int xplra_get_float(float* value, int connectionID, const char* name)
563{
564 Connection* connection = ConnectionSlot::getValue(connectionID);
565 if (connection==0) return -1;
566 try {
567 *value = connection->getFloat(name);
568 return 0;
569 } catch (...) {
570 connection->handleException();
571 return -1;
572 }
573}
574
575//------------------------------------------------------------------------------
576
577extern "C" int xplra_get_double(double* value,
578 int connectionID, const char* name)
579{
580 Connection* connection = ConnectionSlot::getValue(connectionID);
581 if (connection==0) return -1;
582 try {
583 *value = connection->getDouble(name);
584 return 0;
585 } catch (...) {
586 connection->handleException();
587 return -1;
588 }
589}
590
591//------------------------------------------------------------------------------
592
593extern "C" ssize_t xplra_get_float_array(float* dest, size_t length, size_t offset,
594 int connectionID, const char* name)
595{
596 Connection* connection = ConnectionSlot::getValue(connectionID);
597 if (connection==0) return -1;
598 try {
599 return connection->getFloatArray(name, dest, length, offset);
600 } catch (...) {
601 connection->handleException();
602 return -1;
603 }
604}
605
606/*----------------------------------------------------------------------------*/
607
608extern "C" float* xplra_get_float_array_new(size_t* length, size_t offset,
609 int connectionID, const char* name)
610{
611 Connection* connection = ConnectionSlot::getValue(connectionID);
612 if (connection==0) return 0;
613 try {
614 return connection->getFloatArray(name, *length, offset);
615 } catch (...) {
616 connection->handleException();
617 return 0;
618 }
619}
620
621//------------------------------------------------------------------------------
622
623extern "C" ssize_t xplra_get_int_array(int32_t* dest, size_t length, size_t offset,
624 int connectionID, const char* name)
625{
626 Connection* connection = ConnectionSlot::getValue(connectionID);
627 if (connection==0) return -1;
628 try {
629 return connection->getIntArray(name, dest, length, offset);
630 } catch (...) {
631 connection->handleException();
632 return -1;
633 }
634}
635
636/*----------------------------------------------------------------------------*/
637
638extern "C" int32_t* xplra_get_int_array_new(size_t* length, size_t offset,
639 int connectionID, const char* name)
640{
641 Connection* connection = ConnectionSlot::getValue(connectionID);
642 if (connection==0) return 0;
643 try {
644 return connection->getIntArray(name, *length, offset);
645 } catch (...) {
646 connection->handleException();
647 return 0;
648 }
649}
650
651//------------------------------------------------------------------------------
652
653extern "C" ssize_t xplra_get_byte_array(void* dest, size_t length, size_t offset,
654 int connectionID, const char* name)
655{
656 Connection* connection = ConnectionSlot::getValue(connectionID);
657 if (connection==0) return -1;
658 try {
659 return connection->getByteArray(name, reinterpret_cast<uint8_t*>(dest),
660 length, offset);
661 } catch (...) {
662 connection->handleException();
663 return -1;
664 }
665}
666
667/*----------------------------------------------------------------------------*/
668
669extern "C" uint8_t* xplra_get_byte_array_new(size_t* length, size_t offset,
670 int connectionID, const char* name)
671{
672 Connection* connection = ConnectionSlot::getValue(connectionID);
673 if (connection==0) return 0;
674 try {
675 return connection->getByteArray(name, *length, offset);
676 } catch (...) {
677 connection->handleException();
678 return 0;
679 }
680}
681
682//------------------------------------------------------------------------------
683
684extern "C" int xplra_set_int(int connectionID, const char* name, int value)
685{
686 Connection* connection = ConnectionSlot::getValue(connectionID);
687 if (connection==0) return 0;
688 try {
689 connection->setInt(name, value);
690 return 0;
691 } catch (...) {
692 connection->handleException();
693 return -1;
694 }
695}
696
697//------------------------------------------------------------------------------
698
699extern "C" int xplra_set_float(int connectionID, const char* name, float value)
700{
701 Connection* connection = ConnectionSlot::getValue(connectionID);
702 if (connection==0) return 0;
703 try {
704 connection->setFloat(name, value);
705 return 0;
706 } catch (...) {
707 connection->handleException();
708 return -1;
709 }
710}
711
712//------------------------------------------------------------------------------
713
714extern "C" int xplra_set_double(int connectionID, const char* name,
715 double value)
716{
717 Connection* connection = ConnectionSlot::getValue(connectionID);
718 if (connection==0) return 0;
719 try {
720 connection->setDouble(name, value);
721 return 0;
722 } catch (...) {
723 connection->handleException();
724 return -1;
725 }
726}
727
728/*----------------------------------------------------------------------------*/
729
730extern "C" int xplra_set_float_array(int connectionID, const char* name,
731 const float* values,
732 size_t length, size_t offset)
733{
734 Connection* connection = ConnectionSlot::getValue(connectionID);
735 if (connection==0) return 0;
736 try {
737 connection->setFloatArray(name, values, length, offset);
738 return 0;
739 } catch (...) {
740 connection->handleException();
741 return -1;
742 }
743}
744
745/*----------------------------------------------------------------------------*/
746
747extern "C" int xplra_set_int_array(int connectionID, const char* name,
748 const int32_t* values,
749 size_t length, size_t offset)
750{
751 Connection* connection = ConnectionSlot::getValue(connectionID);
752 if (connection==0) return 0;
753 try {
754 connection->setIntArray(name, values, length, offset);
755 return 0;
756 } catch (...) {
757 connection->handleException();
758 return -1;
759 }
760}
761
762/*----------------------------------------------------------------------------*/
763
764extern "C" int xplra_set_byte_array(int connectionID, const char* name,
765 const void* values,
766 size_t length, size_t offset)
767{
768 Connection* connection = ConnectionSlot::getValue(connectionID);
769 if (connection==0) return 0;
770 try {
771 connection->setByteArray(name, reinterpret_cast<const uint8_t*>(values),
772 length, offset);
773 return 0;
774 } catch (...) {
775 connection->handleException();
776 return -1;
777 }
778}
779
780/*----------------------------------------------------------------------------*/
781
782extern "C" int xplra_set_string(int connectionID, const char* name,
783 const char* value,
784 size_t length, size_t offset)
785{
786 Connection* connection = ConnectionSlot::getValue(connectionID);
787 if (connection==0) return 0;
788 try {
789 connection->setString(name, value, length, offset);
790 return 0;
791 } catch (...) {
792 connection->handleException();
793 return -1;
794 }
795}
796
797//------------------------------------------------------------------------------
798//------------------------------------------------------------------------------
799
800extern "C" int xplra_multi_create_getter(int connectionID)
801{
802 Connection* connection = ConnectionSlot::getValue(connectionID);
803 return (connection==0) ? -1 : connection->createMultiGetter();
804}
805
806//------------------------------------------------------------------------------
807
808extern "C" int xplra_multi_create_setter(int connectionID)
809{
810 Connection* connection = ConnectionSlot::getValue(connectionID);
811 return (connection==0) ? -1 : connection->createMultiSetter();
812}
813
814//------------------------------------------------------------------------------
815
816extern "C" size_t xplra_multi_add_int(int bufferID, const char* name)
817{
818 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
819 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addInt(name);
820}
821
822//------------------------------------------------------------------------------
823
824extern "C" size_t xplra_multi_add_float(int bufferID, const char* name)
825{
826 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
827 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addFloat(name);
828}
829
830//------------------------------------------------------------------------------
831
832extern "C" size_t xplra_multi_add_double(int bufferID, const char* name)
833{
834 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
835 return (buffer==0) ? INVALID_DATAREF_ID : buffer->addDouble(name);
836}
837
838/*----------------------------------------------------------------------------*/
839
840extern "C" size_t xplra_multi_add_float_array(int bufferID, const char* name,
841 size_t length, size_t offset)
842{
843 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
844 return (buffer==0) ?
845 INVALID_DATAREF_ID : buffer->addFloatArray(name, length, offset);
846}
847
848/*----------------------------------------------------------------------------*/
849
850extern "C" size_t xplra_multi_add_int_array(int bufferID, const char* name,
851 size_t length, size_t offset)
852{
853 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
854 return (buffer==0) ?
855 INVALID_DATAREF_ID : buffer->addIntArray(name, length, offset);
856}
857
858/*----------------------------------------------------------------------------*/
859
860extern "C" size_t xplra_multi_add_byte_array(int bufferID, const char* name,
861 size_t length, size_t offset)
862{
863 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
864 return (buffer==0) ?
865 INVALID_DATAREF_ID : buffer->addByteArray(name, length, offset);
866}
867
868/*----------------------------------------------------------------------------*/
869
870extern "C" int xplra_multi_finalize(int bufferID)
871{
872 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
873 return (buffer==0) ? -1 : (buffer->finalize() ? 1 : 0);
874}
875
876/*----------------------------------------------------------------------------*/
877
878extern "C" int xplra_multi_register(int bufferID)
879{
880 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
881 if (buffer==0) return -1;
882 try {
883 buffer->registerInXPlane();
884 return 0;
885 } catch (...) {
886 Connection::get(*buffer).handleException();
887 return -1;
888 }
889}
890
891/*----------------------------------------------------------------------------*/
892
893extern "C" int xplra_multi_unregister(int bufferID)
894{
895 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
896 if (buffer==0) return -1;
897 try {
898 buffer->unregisterFromXPlane();
899 return 0;
900 } catch (...) {
901 Connection::get(*buffer).handleException();
902 return -1;
903 }
904}
905
906/*----------------------------------------------------------------------------*/
907
908extern "C" int xplra_multi_unregister_safely(int bufferID)
909{
910 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
911 return (buffer==0) ? -1 : (buffer->unregisterSafelyFromXPlane() ? 1 : 0);
912}
913
914/*----------------------------------------------------------------------------*/
915
916extern "C" int xplra_multi_execute(int bufferID)
917{
918 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
919 if (buffer==0) return -1;
920 try {
921 buffer->execute();
922 return 0;
923 } catch (...) {
924 Connection::get(*buffer).handleException();
925 return -1;
926 }
927}
928
929//------------------------------------------------------------------------------
930
931extern "C" int xplra_multi_set_int(int bufferID, size_t datarefID, int value)
932{
933 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
934 if (buffer==0) return -1;
935 try {
936 buffer->setInt(datarefID, value);
937 return 0;
938 } catch (...) {
939 Connection::get(*buffer).handleException();
940 return -1;
941 }
942}
943
944/*----------------------------------------------------------------------------*/
945
946extern "C" int xplra_multi_get_int(int* dest, int bufferID, size_t datarefID)
947{
948 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
949 if (buffer==0) return -1;
950 try {
951 *dest = buffer->getInt(datarefID);
952 return 0;
953 } catch (...) {
954 Connection::get(*buffer).handleException();
955 return -1;
956 }
957}
958
959/*----------------------------------------------------------------------------*/
960
961extern "C"
962const int32_t* xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID)
963{
964 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
965 if (buffer==0) return 0;
966 try {
967 return &(buffer->getIntRef(datarefID));
968 } catch (...) {
969 Connection::get(*buffer).handleException();
970 return 0;
971 }
972}
973
974/*----------------------------------------------------------------------------*/
975
976extern "C"
977int32_t* xplra_multi_get_int_ptr(int bufferID, size_t datarefID)
978{
979 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
980 if (buffer==0) return 0;
981 try {
982 return &(buffer->getIntRef(datarefID));
983 } catch (...) {
984 Connection::get(*buffer).handleException();
985 return 0;
986 }
987}
988
989//------------------------------------------------------------------------------
990
991extern "C"
992int xplra_multi_set_float(int bufferID, size_t datarefID, float value)
993{
994 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
995 if (buffer==0) return -1;
996 try {
997 buffer->setFloat(datarefID, value);
998 return 0;
999 } catch (...) {
1000 Connection::get(*buffer).handleException();
1001 return -1;
1002 }
1003}
1004
1005/*----------------------------------------------------------------------------*/
1006
1007extern "C"
1008int xplra_multi_get_float(float* dest, int bufferID, size_t datarefID)
1009{
1010 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1011 if (buffer==0) return -1;
1012 try {
1013 *dest = buffer->getFloat(datarefID);
1014 return 0;
1015 } catch (...) {
1016 Connection::get(*buffer).handleException();
1017 return -1;
1018 }
1019}
1020
1021/*----------------------------------------------------------------------------*/
1022
1023extern "C"
1024const float* xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID)
1025{
1026 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1027 if (buffer==0) return 0;
1028 try {
1029 return &(buffer->getFloatRef(datarefID));
1030 } catch (...) {
1031 Connection::get(*buffer).handleException();
1032 return 0;
1033 }
1034}
1035
1036/*----------------------------------------------------------------------------*/
1037
1038extern "C"
1039float* xplra_multi_get_float_ptr(int bufferID, size_t datarefID)
1040{
1041 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1042 if (buffer==0) return 0;
1043 try {
1044 return &(buffer->getFloatRef(datarefID));
1045 } catch (...) {
1046 Connection::get(*buffer).handleException();
1047 return 0;
1048 }
1049}
1050
1051//------------------------------------------------------------------------------
1052
1053extern "C"
1054int xplra_multi_set_double(int bufferID, size_t datarefID, double value)
1055{
1056 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1057 if (buffer==0) return -1;
1058 try {
1059 buffer->setDouble(datarefID, value);
1060 return 0;
1061 } catch (...) {
1062 Connection::get(*buffer).handleException();
1063 return -1;
1064 }
1065}
1066
1067/*----------------------------------------------------------------------------*/
1068
1069extern "C"
1070int xplra_multi_get_double(double* dest, int bufferID, size_t datarefID)
1071{
1072 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1073 if (buffer==0) return -1;
1074 try {
1075 *dest = buffer->getDouble(datarefID);
1076 return 0;
1077 } catch (...) {
1078 Connection::get(*buffer).handleException();
1079 return -1;
1080 }
1081}
1082
1083/*----------------------------------------------------------------------------*/
1084
1085extern "C"
1086const double* xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID)
1087{
1088 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1089 if (buffer==0) return 0;
1090 try {
1091 return &(buffer->getDoubleRef(datarefID));
1092 } catch (...) {
1093 Connection::get(*buffer).handleException();
1094 return 0;
1095 }
1096}
1097
1098/*----------------------------------------------------------------------------*/
1099
1100extern "C"
1101double* xplra_multi_get_double_ptr(int bufferID, size_t datarefID)
1102{
1103 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1104 if (buffer==0) return 0;
1105 try {
1106 return &(buffer->getDoubleRef(datarefID));
1107 } catch (...) {
1108 Connection::get(*buffer).handleException();
1109 return 0;
1110 }
1111}
1112
1113//------------------------------------------------------------------------------
1114
1115extern "C"
1116ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID,
1117 const float* value, size_t length,
1118 size_t offset)
1119{
1120 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1121 if (buffer==0) return -1;
1122 try {
1123 return buffer->setFloatArray(datarefID, value, length, offset);
1124 } catch (...) {
1125 Connection::get(*buffer).handleException();
1126 return -1;
1127 }
1128}
1129
1130/*----------------------------------------------------------------------------*/
1131
1132extern "C"
1133ssize_t xplra_multi_get_float_array(float* value,
1134 size_t length, size_t offset,
1135 int bufferID, size_t datarefID)
1136{
1137 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1138 if (buffer==0) return -1;
1139 try {
1140 return buffer->getFloatArray(datarefID, value, length, offset);
1141 } catch (...) {
1142 Connection::get(*buffer).handleException();
1143 return -1;
1144 }
1145}
1146
1147/*----------------------------------------------------------------------------*/
1148
1149extern "C"
1150const float* xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID,
1151 size_t offset)
1152{
1153 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1154 if (buffer==0) return 0;
1155 try {
1156 return buffer->getFloatArray(datarefID, offset);
1157 } catch (...) {
1158 Connection::get(*buffer).handleException();
1159 return 0;
1160 }
1161}
1162
1163//------------------------------------------------------------------------------
1164
1165extern "C"
1166ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID,
1167 const int32_t* value, size_t length,
1168 size_t offset)
1169{
1170 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1171 if (buffer==0) return -1;
1172 try {
1173 return buffer->setIntArray(datarefID, value, length, offset);
1174 } catch (...) {
1175 Connection::get(*buffer).handleException();
1176 return -1;
1177 }
1178}
1179
1180/*----------------------------------------------------------------------------*/
1181
1182extern "C"
1183ssize_t xplra_multi_get_int_array(int32_t* value,
1184 size_t length, size_t offset,
1185 int bufferID, size_t datarefID)
1186{
1187 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1188 if (buffer==0) return -1;
1189 try {
1190 return buffer->getIntArray(datarefID, value, length, offset);
1191 } catch (...) {
1192 Connection::get(*buffer).handleException();
1193 return -1;
1194 }
1195}
1196
1197/*----------------------------------------------------------------------------*/
1198
1199extern "C"
1200const int32_t* xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID,
1201 size_t offset)
1202{
1203 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1204 if (buffer==0) return 0;
1205 try {
1206 return buffer->getIntArray(datarefID, offset);
1207 } catch (...) {
1208 Connection::get(*buffer).handleException();
1209 return 0;
1210 }
1211}
1212
1213//------------------------------------------------------------------------------
1214
1215extern "C"
1216ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID,
1217 const void* value, size_t length,
1218 size_t offset)
1219{
1220 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1221 if (buffer==0) return -1;
1222 try {
1223 return buffer->setByteArray(datarefID,
1224 reinterpret_cast<const uint8_t*>(value),
1225 length, offset);
1226 } catch (...) {
1227 Connection::get(*buffer).handleException();
1228 return -1;
1229 }
1230}
1231
1232/*----------------------------------------------------------------------------*/
1233
1234extern "C"
1235ssize_t xplra_multi_get_byte_array(void* value,
1236 size_t length, size_t offset,
1237 int bufferID, size_t datarefID)
1238{
1239 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1240 if (buffer==0) return -1;
1241 try {
1242 return buffer->getByteArray(datarefID,
1243 reinterpret_cast<uint8_t*>(value),
1244 length, offset);
1245 } catch (...) {
1246 Connection::get(*buffer).handleException();
1247 return -1;
1248 }
1249}
1250
1251/*----------------------------------------------------------------------------*/
1252
1253extern "C"
1254const uint8_t* xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID,
1255 size_t offset)
1256{
1257 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1258 if (buffer==0) return 0;
1259 try {
1260 return buffer->getByteArray(datarefID, offset);
1261 } catch (...) {
1262 Connection::get(*buffer).handleException();
1263 return 0;
1264 }
1265}
1266
1267//------------------------------------------------------------------------------
1268
1269extern "C" ssize_t xplra_multi_set_string(int bufferID, size_t datarefID,
1270 const char* value, size_t offset)
1271{
1272 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1273 if (buffer==0) return -1;
1274 try {
1275 return buffer->setString(datarefID, value, offset);
1276 } catch (...) {
1277 Connection::get(*buffer).handleException();
1278 return -1;
1279 }
1280}
1281
1282/*----------------------------------------------------------------------------*/
1283
1284extern "C"
1285const char* xplra_multi_get_string_ptr(int bufferID, size_t datarefID,
1286 size_t offset)
1287{
1288 MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
1289 if (buffer==0) return 0;
1290 try {
1291 return buffer->getStringPtr(datarefID, offset);
1292 } catch (...) {
1293 Connection::get(*buffer).handleException();
1294 return 0;
1295 }
1296}
1297
1298//------------------------------------------------------------------------------
1299
1300extern "C" int xplra_multi_destroy_buffer(int connectionID, int bufferID)
1301{
1302 Connection* connection = ConnectionSlot::getValue(connectionID);
1303 if (connection==0) return -1;
1304
1305 try {
1306 return connection->destroyMultiBuffer(bufferID) ? 0 : -1;
1307 } catch(...) {
1308 connection->handleException();
1309 return -1;
1310 }
1311}
1312
1313//------------------------------------------------------------------------------
1314//------------------------------------------------------------------------------
1315
1316extern "C" int xplra_show_message(int connectionID,
1317 const char* message, float duration)
1318{
1319 Connection* connection = ConnectionSlot::getValue(connectionID);
1320 if (connection==0) return -1;
1321
1322 try {
1323 connection->showMessage(message, duration);
1324 return 0;
1325 } catch(...) {
1326 connection->handleException();
1327 return -1;
1328 }
1329}
1330
1331//------------------------------------------------------------------------------
1332//------------------------------------------------------------------------------
1333
1334extern "C" int xplra_register_hotkeys(int connectionID,
1335 const uint16_t* codes, size_t length)
1336{
1337 Connection* connection = ConnectionSlot::getValue(connectionID);
1338 if (connection==0) return -1;
1339
1340 try {
1341 connection->registerHotkeys(codes, length);
1342 return 0;
1343 } catch(...) {
1344 connection->handleException();
1345 return -1;
1346 }
1347}
1348
1349/*----------------------------------------------------------------------------*/
1350
1351extern "C" int xplra_query_hotkeys(int connectionID,
1352 uint8_t* states, size_t length)
1353{
1354 Connection* connection = ConnectionSlot::getValue(connectionID);
1355 if (connection==0) return -1;
1356
1357 try {
1358 connection->queryHotkeys(states, length);
1359 return 0;
1360 } catch(...) {
1361 connection->handleException();
1362 return -1;
1363 }
1364}
1365
1366/*----------------------------------------------------------------------------*/
1367
1368extern "C" int xplra_unregister_hotkeys(int connectionID)
1369{
1370 Connection* connection = ConnectionSlot::getValue(connectionID);
1371 if (connection==0) return -1;
1372
1373 try {
1374 connection->unregisterHotkeys();
1375 return 0;
1376 } catch(...) {
1377 connection->handleException();
1378 return -1;
1379 }
1380}
1381
1382//------------------------------------------------------------------------------
1383//------------------------------------------------------------------------------
1384
1385extern "C" int xplra_disconnect(int connectionID)
1386{
1387 Connection* connection = ConnectionSlot::getValue(connectionID);
1388 if (connection==0) return -1;
1389
1390 connection->disconnect();
1391
1392 return 0;
1393}
1394
1395//------------------------------------------------------------------------------
1396//------------------------------------------------------------------------------
1397
1398extern "C" int xplra_reconnect(int connectionID)
1399{
1400 Connection* connection = ConnectionSlot::getValue(connectionID);
1401 if (connection==0) return -1;
1402
1403 try {
1404 connection->connect();
1405 return 0;
1406 } catch(...) {
1407 return -1;
1408 }
1409}
1410
1411//------------------------------------------------------------------------------
1412//------------------------------------------------------------------------------
1413
1414extern "C" int xplra_destroy(int connectionID)
1415{
1416 Connection* connection = ConnectionSlot::getValue(connectionID);
1417 if (connection==0) return -1;
1418
1419 ConnectionSlot::clearValue(connectionID);
1420 delete connection;
1421
1422 return 0;
1423}
1424
1425//------------------------------------------------------------------------------
1426//------------------------------------------------------------------------------
1427
1428// Local Variables:
1429// mode: C++
1430// c-basic-offset: 4
1431// indent-tabs-mode: nil
1432// End:
Note: See TracBrowser for help on using the repository browser.