Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 13)
+++ src/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=plugin client
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=plugin client
Index: src/client/Makefile.am
===================================================================
--- src/client/Makefile.am	(revision 13)
+++ src/client/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=c
Index: src/client/Makefile.am
===================================================================
--- src/client/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=c
Index: src/client/c/Makefile.am
===================================================================
--- src/client/c/Makefile.am	(revision 13)
+++ src/client/c/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=hu
Index: src/client/c/Makefile.am
===================================================================
--- src/client/c/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=hu
Index: src/client/c/hu/Makefile.am
===================================================================
--- src/client/c/hu/Makefile.am	(revision 13)
+++ src/client/c/hu/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=varadiistvan
Index: src/client/c/hu/Makefile.am
===================================================================
--- src/client/c/hu/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=varadiistvan
Index: src/client/c/hu/varadiistvan/Makefile.am
===================================================================
--- src/client/c/hu/varadiistvan/Makefile.am	(revision 13)
+++ src/client/c/hu/varadiistvan/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=xplra
Index: src/client/c/hu/varadiistvan/Makefile.am
===================================================================
--- src/client/c/hu/varadiistvan/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=xplra
Index: src/client/c/hu/varadiistvan/xplra/.copyright
===================================================================
--- src/client/c/hu/varadiistvan/xplra/.copyright	(revision 13)
+++ src/client/c/hu/varadiistvan/xplra/.copyright	(revision 13)
@@ -0,0 +1,23 @@
+// 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.
Index: src/client/c/hu/varadiistvan/xplra/.copyright
===================================================================
--- src/client/c/hu/varadiistvan/xplra/.copyright	(revision 13)
+++ 	(revision )
@@ -1,23 +1,0 @@
-// 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.
Index: src/client/c/hu/varadiistvan/xplra/.namespace
===================================================================
--- src/client/c/hu/varadiistvan/xplra/.namespace	(revision 13)
+++ src/client/c/hu/varadiistvan/xplra/.namespace	(revision 13)
@@ -0,0 +1,3 @@
+hu
+varadiistvan
+xplra
Index: src/client/c/hu/varadiistvan/xplra/.namespace
===================================================================
--- src/client/c/hu/varadiistvan/xplra/.namespace	(revision 13)
+++ 	(revision )
@@ -1,3 +1,0 @@
-hu
-varadiistvan
-xplra
Index: src/client/c/hu/varadiistvan/xplra/.srcmessage
===================================================================
--- src/client/c/hu/varadiistvan/xplra/.srcmessage	(revision 13)
+++ src/client/c/hu/varadiistvan/xplra/.srcmessage	(revision 13)
@@ -0,0 +1,1 @@
+// This file is part of XPLRA, a remote-access plugin for X-Plane
Index: src/client/c/hu/varadiistvan/xplra/.srcmessage
===================================================================
--- src/client/c/hu/varadiistvan/xplra/.srcmessage	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-// This file is part of XPLRA, a remote-access plugin for X-Plane
Index: src/client/c/hu/varadiistvan/xplra/Exception.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/Exception.cc	(revision 40)
+++ src/client/c/hu/varadiistvan/xplra/Exception.cc	(revision 40)
@@ -0,0 +1,114 @@
+// 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 "Exception.h"
+
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using hu::varadiistvan::xplra::Exception;
+using hu::varadiistvan::xplra::IOException;
+using hu::varadiistvan::xplra::ProtocolException;
+
+//------------------------------------------------------------------------------
+
+const char* Exception::what() const throw()
+{
+    return message.c_str();
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+IOException::IOException(errorCode_t errorCode) throw() :
+    errorCode(errorCode)
+{
+    char buf[256];
+    snprintf(buf, sizeof(buf), "xplra::IOException: error code=%lu",
+             errorCode);
+    message = buf;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+ProtocolException::ProtocolException(errorCode_t errorCode, bool hasParameter,
+                                     long parameter) throw() :
+    errorCode(errorCode),
+    hasParameter(parameter),
+    parameter(parameter)
+{
+    switch (errorCode) {
+      case INVALID_COMMAND:
+        message = "xplra::ProtocolException: invalid command";
+        break;
+      case UNKNOWN_DATAREF:
+        message = "xplra::ProtocolException: unknown dataref";
+        if (hasParameter) {
+            char buf[32];
+            snprintf(buf, sizeof(buf), " (# %ld)", parameter);
+            message += buf;
+        }
+        break;
+      case INVALID_TYPE:
+        message = "xplra::ProtocolException: invalid type";
+        break;
+      case INVALID_LENGTH:
+        message = "xplra::ProtocolException: invalid length";
+        break;
+      case INVALID_OFFSET:
+        message = "xplra::ProtocolException: invalid offset";
+        break;
+      case INVALID_COUNT:
+        message = "xplra::ProtocolException: invalid count";
+        break;
+      case INVALID_ID:
+        message = "xplra::ProtocolException: invalid ID";
+        break;
+      case INVALID_DURATION:
+        message = "xplra::ProtocolException: invalid duration";
+        break;
+      case OTHER:
+        message = "xplra::ProtocolException: other error";
+        break;
+      default:
+        message = "xplra::ProtocolException: unknown error";
+        break;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/Exception.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/Exception.cc	(revision 40)
+++ 	(revision )
@@ -1,114 +1,0 @@
-// 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 "Exception.h"
-
-#include <cstdio>
-
-//------------------------------------------------------------------------------
-
-using hu::varadiistvan::xplra::Exception;
-using hu::varadiistvan::xplra::IOException;
-using hu::varadiistvan::xplra::ProtocolException;
-
-//------------------------------------------------------------------------------
-
-const char* Exception::what() const throw()
-{
-    return message.c_str();
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-IOException::IOException(errorCode_t errorCode) throw() :
-    errorCode(errorCode)
-{
-    char buf[256];
-    snprintf(buf, sizeof(buf), "xplra::IOException: error code=%lu",
-             errorCode);
-    message = buf;
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-ProtocolException::ProtocolException(errorCode_t errorCode, bool hasParameter,
-                                     long parameter) throw() :
-    errorCode(errorCode),
-    hasParameter(parameter),
-    parameter(parameter)
-{
-    switch (errorCode) {
-      case INVALID_COMMAND:
-        message = "xplra::ProtocolException: invalid command";
-        break;
-      case UNKNOWN_DATAREF:
-        message = "xplra::ProtocolException: unknown dataref";
-        if (hasParameter) {
-            char buf[32];
-            snprintf(buf, sizeof(buf), " (# %ld)", parameter);
-            message += buf;
-        }
-        break;
-      case INVALID_TYPE:
-        message = "xplra::ProtocolException: invalid type";
-        break;
-      case INVALID_LENGTH:
-        message = "xplra::ProtocolException: invalid length";
-        break;
-      case INVALID_OFFSET:
-        message = "xplra::ProtocolException: invalid offset";
-        break;
-      case INVALID_COUNT:
-        message = "xplra::ProtocolException: invalid count";
-        break;
-      case INVALID_ID:
-        message = "xplra::ProtocolException: invalid ID";
-        break;
-      case INVALID_DURATION:
-        message = "xplra::ProtocolException: invalid duration";
-        break;
-      case OTHER:
-        message = "xplra::ProtocolException: other error";
-        break;
-      default:
-        message = "xplra::ProtocolException: unknown error";
-        break;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/Exception.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/Exception.h	(revision 40)
+++ src/client/c/hu/varadiistvan/xplra/Exception.h	(revision 40)
@@ -0,0 +1,312 @@
+// 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.
+
+#ifndef HU_VARADIISTVAN_XPLRA_EXCEPTION_H
+#define HU_VARADIISTVAN_XPLRA_EXCEPTION_H
+//------------------------------------------------------------------------------
+
+#include <exception>
+
+#include <string>
+
+//------------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for exceptions that can be thrown by the client.
+ */
+class Exception : public std::exception
+{
+protected:
+    /**
+     * The string representation of the error message.
+     */
+    std::string message;
+
+public:
+    /**
+     * Construct the exception with the given message.
+     */
+    Exception(const char* message) throw();
+
+protected:
+    /**
+     * Default constructor for children.
+     */
+    Exception() throw();
+
+public:
+    /**
+     * Destroy the exception
+     */
+    virtual ~Exception() throw();
+
+public:
+    /**
+     * Get a message.
+     */
+    virtual const char* what() const throw();
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * An I/O exception.
+ */
+class IOException : public Exception
+{
+public:
+    /**
+     * Type for the error code.
+     */
+    typedef unsigned long errorCode_t;
+
+private:
+    /**
+     * The error code.
+     */
+    errorCode_t errorCode;
+
+public:
+    /**
+     * Construct the exception.
+     */
+    IOException(errorCode_t errorCode) throw();
+
+
+    /**
+     * Get the error code.
+     */
+    errorCode_t getErrorCode() const throw();
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * An exception arising from the invalid use of the protocol, e.g. an
+ * invalid dataref.
+ */
+class ProtocolException : public Exception
+{
+public:
+    /**
+     * Type for the error codes.
+     */
+    typedef enum {
+        /// Invalid command issued
+        INVALID_COMMAND = 1,
+
+        /// Unknown dataref
+        UNKNOWN_DATAREF = 2,
+
+        /// Invalid type
+        INVALID_TYPE = 3,
+
+        /// Invalid length
+        INVALID_LENGTH = 4,
+
+        /// Invalid offset
+        INVALID_OFFSET = 5,
+
+        /// Invalid count
+        INVALID_COUNT = 6,
+
+        /// Invalid ID
+        INVALID_ID = 7,
+
+        /// Invalid duration
+        INVALID_DURATION = 8,
+
+        /// Other error
+        OTHER = 255
+    } errorCode_t;
+
+private:
+    /**
+     * The error code.
+     */
+    errorCode_t errorCode;
+
+    /**
+     * Indicate if the parameter is valid.
+     */
+    bool hasParameter;
+
+    /**
+     * Parameter of the error.
+     */
+    long parameter;
+
+public:
+    /**
+     * Construct the exception.
+     */
+    ProtocolException(errorCode_t errorCode,
+                      bool hasParameter = false, long parameter = 0) throw();
+
+    /**
+     * Get the error code.
+     */
+    errorCode_t getErrorCode() const throw();
+
+    /**
+     * Get the value of the parameter and whether it is valid or not.
+     */
+    bool getParameter(long& param) const throw();
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * Exception to signify the fact the we are not connected to the
+ * simulator.
+ */
+class NotConnectedException : public Exception
+{
+public:
+    /**
+     * Construct the exception
+     */
+    NotConnectedException() throw();
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * Exception thrown when we want to get or set a dataref in a
+ * MultiBuffer into or from a value of the wrong type.
+ */
+class TypeMismatchException : public Exception
+{
+public:
+    /**
+     * Construct the exception
+     */
+    TypeMismatchException() throw();
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * Exception thrown when we want to get or set a dataref with an
+ * invalid ID.
+ */
+class InvalidIDException : public Exception
+{
+public:
+    /**
+     * Construct the exception
+     */
+    InvalidIDException() throw();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline Exception::Exception(const char* message) throw() :
+    message(message)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline Exception::Exception() throw()
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline Exception::~Exception() throw()
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline IOException::errorCode_t IOException::getErrorCode() const throw()
+{
+    return errorCode;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline ProtocolException::errorCode_t
+ProtocolException::getErrorCode() const throw()
+{
+    return errorCode;
+}
+
+//------------------------------------------------------------------------------
+
+inline bool ProtocolException::getParameter(long& param) const throw()
+{
+    if (hasParameter) param = parameter;
+    return hasParameter;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline NotConnectedException::NotConnectedException() throw() :
+    Exception("xplra::NotConnectedException: not connected to the simulator")
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline TypeMismatchException::TypeMismatchException() throw() :
+    Exception("xplra::TypeMismatchException")
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline InvalidIDException::InvalidIDException() throw() :
+    Exception("xplra::InvalidIDException")
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
+
+//------------------------------------------------------------------------------
+#endif // HU_VARADIISTVAN_XPLRA_EXCEPTION_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/Exception.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/Exception.h	(revision 40)
+++ 	(revision )
@@ -1,312 +1,0 @@
-// 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.
-
-#ifndef HU_VARADIISTVAN_XPLRA_EXCEPTION_H
-#define HU_VARADIISTVAN_XPLRA_EXCEPTION_H
-//------------------------------------------------------------------------------
-
-#include <exception>
-
-#include <string>
-
-//------------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Base class for exceptions that can be thrown by the client.
- */
-class Exception : public std::exception
-{
-protected:
-    /**
-     * The string representation of the error message.
-     */
-    std::string message;
-
-public:
-    /**
-     * Construct the exception with the given message.
-     */
-    Exception(const char* message) throw();
-
-protected:
-    /**
-     * Default constructor for children.
-     */
-    Exception() throw();
-
-public:
-    /**
-     * Destroy the exception
-     */
-    virtual ~Exception() throw();
-
-public:
-    /**
-     * Get a message.
-     */
-    virtual const char* what() const throw();
-};
-
-//------------------------------------------------------------------------------
-
-/**
- * An I/O exception.
- */
-class IOException : public Exception
-{
-public:
-    /**
-     * Type for the error code.
-     */
-    typedef unsigned long errorCode_t;
-
-private:
-    /**
-     * The error code.
-     */
-    errorCode_t errorCode;
-
-public:
-    /**
-     * Construct the exception.
-     */
-    IOException(errorCode_t errorCode) throw();
-
-
-    /**
-     * Get the error code.
-     */
-    errorCode_t getErrorCode() const throw();
-};
-
-//------------------------------------------------------------------------------
-
-/**
- * An exception arising from the invalid use of the protocol, e.g. an
- * invalid dataref.
- */
-class ProtocolException : public Exception
-{
-public:
-    /**
-     * Type for the error codes.
-     */
-    typedef enum {
-        /// Invalid command issued
-        INVALID_COMMAND = 1,
-
-        /// Unknown dataref
-        UNKNOWN_DATAREF = 2,
-
-        /// Invalid type
-        INVALID_TYPE = 3,
-
-        /// Invalid length
-        INVALID_LENGTH = 4,
-
-        /// Invalid offset
-        INVALID_OFFSET = 5,
-
-        /// Invalid count
-        INVALID_COUNT = 6,
-
-        /// Invalid ID
-        INVALID_ID = 7,
-
-        /// Invalid duration
-        INVALID_DURATION = 8,
-
-        /// Other error
-        OTHER = 255
-    } errorCode_t;
-
-private:
-    /**
-     * The error code.
-     */
-    errorCode_t errorCode;
-
-    /**
-     * Indicate if the parameter is valid.
-     */
-    bool hasParameter;
-
-    /**
-     * Parameter of the error.
-     */
-    long parameter;
-
-public:
-    /**
-     * Construct the exception.
-     */
-    ProtocolException(errorCode_t errorCode,
-                      bool hasParameter = false, long parameter = 0) throw();
-
-    /**
-     * Get the error code.
-     */
-    errorCode_t getErrorCode() const throw();
-
-    /**
-     * Get the value of the parameter and whether it is valid or not.
-     */
-    bool getParameter(long& param) const throw();
-};
-
-//------------------------------------------------------------------------------
-
-/**
- * Exception to signify the fact the we are not connected to the
- * simulator.
- */
-class NotConnectedException : public Exception
-{
-public:
-    /**
-     * Construct the exception
-     */
-    NotConnectedException() throw();
-};
-
-//------------------------------------------------------------------------------
-
-/**
- * Exception thrown when we want to get or set a dataref in a
- * MultiBuffer into or from a value of the wrong type.
- */
-class TypeMismatchException : public Exception
-{
-public:
-    /**
-     * Construct the exception
-     */
-    TypeMismatchException() throw();
-};
-
-//------------------------------------------------------------------------------
-
-/**
- * Exception thrown when we want to get or set a dataref with an
- * invalid ID.
- */
-class InvalidIDException : public Exception
-{
-public:
-    /**
-     * Construct the exception
-     */
-    InvalidIDException() throw();
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline Exception::Exception(const char* message) throw() :
-    message(message)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline Exception::Exception() throw()
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline Exception::~Exception() throw()
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline IOException::errorCode_t IOException::getErrorCode() const throw()
-{
-    return errorCode;
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline ProtocolException::errorCode_t
-ProtocolException::getErrorCode() const throw()
-{
-    return errorCode;
-}
-
-//------------------------------------------------------------------------------
-
-inline bool ProtocolException::getParameter(long& param) const throw()
-{
-    if (hasParameter) param = parameter;
-    return hasParameter;
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline NotConnectedException::NotConnectedException() throw() :
-    Exception("xplra::NotConnectedException: not connected to the simulator")
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline TypeMismatchException::TypeMismatchException() throw() :
-    Exception("xplra::TypeMismatchException")
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline InvalidIDException::InvalidIDException() throw() :
-    Exception("xplra::InvalidIDException")
-{
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
-
-//------------------------------------------------------------------------------
-#endif // HU_VARADIISTVAN_XPLRA_EXCEPTION_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/Makefile.am
===================================================================
--- src/client/c/hu/varadiistvan/xplra/Makefile.am	(revision 21)
+++ src/client/c/hu/varadiistvan/xplra/Makefile.am	(revision 21)
@@ -0,0 +1,26 @@
+AM_CXXFLAGS=$(VSCPL_CFLAGS) -I$(top_srcdir)/src/plugin/src
+
+lib_LTLIBRARIES=libxplra.la
+
+libxplra_la_SOURCES=\
+        Exception.cc    \
+        XPlane.cc       \
+        MultiBuffer.cc  \
+        MultiGetter.cc  \
+        MultiSetter.cc  \
+        xplra.cc
+
+libxplra_la_LIBADD=$(VSCPL_LIBS)
+
+if TARGET_API_WIN32
+libxplra_la_LDFLAGS=-no-undefined
+endif
+
+include_xplradir=$(includedir)/hu/varadiistvan/xplra
+include_xplra_HEADERS=\
+        Exception.h     \
+        XPlane.h        \
+        MultiBuffer.h   \
+        MultiGetter.h   \
+        MultiSetter.h   \
+        xplra.h
Index: src/client/c/hu/varadiistvan/xplra/Makefile.am
===================================================================
--- src/client/c/hu/varadiistvan/xplra/Makefile.am	(revision 21)
+++ 	(revision )
@@ -1,26 +1,0 @@
-AM_CXXFLAGS=$(VSCPL_CFLAGS) -I$(top_srcdir)/src/plugin/src
-
-lib_LTLIBRARIES=libxplra.la
-
-libxplra_la_SOURCES=\
-        Exception.cc    \
-        XPlane.cc       \
-        MultiBuffer.cc  \
-        MultiGetter.cc  \
-        MultiSetter.cc  \
-        xplra.cc
-
-libxplra_la_LIBADD=$(VSCPL_LIBS)
-
-if TARGET_API_WIN32
-libxplra_la_LDFLAGS=-no-undefined
-endif
-
-include_xplradir=$(includedir)/hu/varadiistvan/xplra
-include_xplra_HEADERS=\
-        Exception.h     \
-        XPlane.h        \
-        MultiBuffer.h   \
-        MultiGetter.h   \
-        MultiSetter.h   \
-        xplra.h
Index: src/client/c/hu/varadiistvan/xplra/MultiBuffer.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiBuffer.cc	(revision 66)
+++ src/client/c/hu/varadiistvan/xplra/MultiBuffer.cc	(revision 66)
@@ -0,0 +1,650 @@
+// 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 "MultiBuffer.h"
+
+#include "XPlane.h"
+
+#include <xplra/Protocol.h>
+
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+#include <cstring>
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using hu::varadiistvan::xplra::MultiBuffer;
+
+using xplra::Protocol;
+
+using std::vector;
+using std::string;
+using std::min;
+
+//------------------------------------------------------------------------------
+
+inline MultiBuffer::DataRef::DataRef(const string& name, uint8_t type,
+                                     const DataRef* previous,
+                                     size_t length, size_t offset) throw() :
+    name(name),
+    type(type),
+    length(length),
+    offset(offset),
+    dataOffset(0)
+{
+    if (previous!=0) {
+        size_t alignment = getAlignment();
+        dataOffset = previous->dataOffset + previous->getSize();
+        dataOffset += alignment - 1;
+        dataOffset &= ~(alignment-1);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+inline size_t MultiBuffer::DataRef::getSize() const throw()
+{
+    switch (type) {
+      case Protocol::TYPE_INT:
+        return sizeof(int32_t);
+      case Protocol::TYPE_FLOAT:
+        return sizeof(float);
+      case Protocol::TYPE_DOUBLE:
+        return sizeof(double);
+      case Protocol::TYPE_FLOAT_ARRAY:
+        return sizeof(float) * length;
+      case Protocol::TYPE_INT_ARRAY:
+        return sizeof(int32_t) * length;
+      case Protocol::TYPE_BYTE_ARRAY:
+        return sizeof(uint8_t) * length;
+      default:
+        return 0;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+inline size_t MultiBuffer::DataRef::getAlignment() const throw()
+{
+    switch (type) {
+      case Protocol::TYPE_INT:
+      case Protocol::TYPE_INT_ARRAY:
+        return sizeof(int32_t);
+      case Protocol::TYPE_FLOAT:
+      case Protocol::TYPE_FLOAT_ARRAY:
+        return sizeof(float);
+      case Protocol::TYPE_DOUBLE:
+        return sizeof(double);
+      case Protocol::TYPE_BYTE_ARRAY:
+      default:
+        return sizeof(uint8_t);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+bool MultiBuffer::DataRef::isArray() const throw()
+{
+    return
+        type==Protocol::TYPE_FLOAT_ARRAY ||
+        type==Protocol::TYPE_INT_ARRAY ||
+        type==Protocol::TYPE_BYTE_ARRAY;
+}
+
+//------------------------------------------------------------------------------
+
+inline size_t
+MultiBuffer::DataRef::getCopyLength(size_t userLength, size_t userOffset)
+    const throw()
+{
+    size_t maxLength =
+        (userOffset>length) ? 0 : (length - userOffset);
+    return (userLength==0) ? maxLength : min(userLength, maxLength);
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void MultiBuffer::unfinalize() throw()
+{
+    delete data; data = 0;
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::forgetRegistration() throw()
+{
+    registeredID = -1;
+}
+
+//------------------------------------------------------------------------------
+
+inline const MultiBuffer::DataRef* MultiBuffer::getLastDataRef() const throw()
+{
+    return dataRefs.empty() ? 0 : &(dataRefs.back());
+}
+
+//------------------------------------------------------------------------------
+
+inline const MultiBuffer::DataRef& MultiBuffer::getDataRef(size_t id, uint8_t type) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    if (id>=dataRefs.size()) throw InvalidIDException();
+    const DataRef& dataRef = dataRefs[id];
+    if (dataRef.type!=type) throw TypeMismatchException();
+    return dataRef;
+}
+
+//------------------------------------------------------------------------------
+
+inline void* MultiBuffer::getData(size_t id, uint8_t type)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    const DataRef& dataRef = getDataRef(id, type);
+    finalize();
+    return data + dataRef.dataOffset;
+}
+
+//------------------------------------------------------------------------------
+
+inline const void* MultiBuffer::getData(size_t id, uint8_t type) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    const DataRef& dataRef = getDataRef(id, type);
+    finalize();
+    return data + dataRef.dataOffset;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, uint8_t type> size_t
+inline MultiBuffer::setArray(size_t id, const T* value,
+                             size_t length, size_t offset)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    const DataRef& dataRef = getDataRef(id, type);
+    finalize();
+
+    size_t toCopy = dataRef.getCopyLength(length, offset);
+
+    if (toCopy>0) {
+        memcpy( data + dataRef.dataOffset + offset * sizeof(T),
+                value, toCopy * sizeof(T) );
+    }
+
+    return toCopy;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, uint8_t type>
+inline size_t MultiBuffer::getArray(size_t id, T* value,
+                                    size_t length, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    const DataRef& dataRef = getDataRef(id, type);
+    finalize();
+
+    size_t toCopy = dataRef.getCopyLength(length, offset);
+
+    if (toCopy>0) {
+        memcpy( value, data + dataRef.dataOffset + offset * sizeof(T),
+                toCopy * sizeof(T) );
+    }
+
+    return toCopy;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, uint8_t type>
+inline const T* MultiBuffer::getArray(size_t id, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    const DataRef& dataRef = getDataRef(id, type);
+    finalize();
+    return (offset<dataRef.length) ?
+        reinterpret_cast<const T*>(data + dataRef.dataOffset +
+                                   offset * sizeof(T)) : 0;
+}
+
+//------------------------------------------------------------------------------
+
+MultiBuffer::MultiBuffer(XPlane& xplane, uint8_t registerCommand,
+                         uint8_t unregisterCommand) throw() :
+    data(0),
+    xplane(xplane),
+    registerCommand(registerCommand),
+    unregisterCommand(unregisterCommand),
+    registeredID(-1)
+{
+}
+
+//------------------------------------------------------------------------------
+
+MultiBuffer::~MultiBuffer() throw()
+{
+    unregisterSafelyFromXPlane();
+    delete[] data;
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::addInt(const std::string& name) throw()
+{
+    unfinalize();
+    dataRefs.push_back(DataRef(name, Protocol::TYPE_INT, getLastDataRef()));
+    return dataRefs.size() - 1;
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::addFloat(const std::string& name) throw()
+{
+    unfinalize();
+    dataRefs.push_back(DataRef(name, Protocol::TYPE_FLOAT, getLastDataRef()));
+    return dataRefs.size() - 1;
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::addDouble(const std::string& name) throw()
+{
+    unfinalize();
+    dataRefs.push_back(DataRef(name, Protocol::TYPE_DOUBLE, getLastDataRef()));
+    return dataRefs.size() - 1;
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::addFloatArray(const std::string& name, size_t length,
+                                  size_t offset) throw()
+{
+    unfinalize();
+    dataRefs.push_back(DataRef(name, Protocol::TYPE_FLOAT_ARRAY,
+                               getLastDataRef(), length, offset));
+    return dataRefs.size() - 1;
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::addIntArray(const std::string& name, size_t length,
+                                size_t offset) throw()
+{
+    unfinalize();
+    dataRefs.push_back(DataRef(name, Protocol::TYPE_INT_ARRAY,
+                               getLastDataRef(), length, offset));
+    return dataRefs.size() - 1;
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::addByteArray(const std::string& name, size_t length,
+                                 size_t offset) throw()
+{
+    unfinalize();
+    dataRefs.push_back(DataRef(name, Protocol::TYPE_BYTE_ARRAY,
+                               getLastDataRef(), length, offset));
+    return dataRefs.size() - 1;
+}
+
+//------------------------------------------------------------------------------
+
+bool MultiBuffer::finalize() const
+{
+    if (data==0 && !dataRefs.empty()) {
+        const DataRef* lastDataRef = getLastDataRef();
+        size_t dataSize = lastDataRef->dataOffset + lastDataRef->getSize();
+        data = new unsigned char[dataSize];
+        memset(data, 0, dataSize);
+        return true;
+    } else {
+        return data!=0;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::registerInXPlane() throw(Exception)
+{
+    if (finalize() && registeredID<0) {
+        xplane.checkStream();
+
+        writeSpec(registerCommand);
+
+        uint32_t id = xplane.stream->readU32();
+        xplane.checkStream();
+
+        registeredID = static_cast<int>(id);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::unregisterFromXPlane() throw(Exception)
+{
+    if (registeredID>=0) {
+        xplane.stream->writeU8(unregisterCommand);
+        xplane.stream->writeU32(static_cast<uint32_t>(registeredID));
+        xplane.stream->flush();
+        xplane.checkResult();
+        registeredID = -1;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+bool MultiBuffer::unregisterSafelyFromXPlane() throw()
+{
+    try {
+        unregisterFromXPlane();
+        return true;
+    } catch(...) {
+        registeredID = -1;
+        return false;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::execute() throw(Exception)
+{
+    if (data==0 && registeredID>=0) {
+        unregisterFromXPlane();
+        registerInXPlane();
+    } else {
+        finalize();
+    }
+
+    if (registeredID>=0) {
+        doExecute();
+    } else {
+        doExecuteUnregistered();
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::setInt(size_t id, int value)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    *reinterpret_cast<int32_t*>(getData(id, Protocol::TYPE_INT)) = value;
+}
+
+//------------------------------------------------------------------------------
+
+int MultiBuffer::getInt(size_t id) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<const int32_t*>(getData(id, Protocol::TYPE_INT));
+}
+
+//------------------------------------------------------------------------------
+
+const int32_t& MultiBuffer::getIntRef(size_t id) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<const int32_t*>(getData(id, Protocol::TYPE_INT));
+}
+
+//------------------------------------------------------------------------------
+
+int32_t& MultiBuffer::getIntRef(size_t id)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<int32_t*>(getData(id, Protocol::TYPE_INT));
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::setFloat(size_t id, float value)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    *reinterpret_cast<float*>(getData(id, Protocol::TYPE_FLOAT)) = value;
+}
+
+//------------------------------------------------------------------------------
+
+float MultiBuffer::getFloat(size_t id) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<const float*>(getData(id, Protocol::TYPE_FLOAT));
+}
+
+//------------------------------------------------------------------------------
+
+const float& MultiBuffer::getFloatRef(size_t id) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<const float*>(getData(id, Protocol::TYPE_FLOAT));
+}
+
+//------------------------------------------------------------------------------
+
+float& MultiBuffer::getFloatRef(size_t id)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<float*>(getData(id, Protocol::TYPE_FLOAT));
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::setDouble(size_t id, double value)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    *reinterpret_cast<double*>(getData(id, Protocol::TYPE_DOUBLE)) = value;
+}
+
+//------------------------------------------------------------------------------
+
+double MultiBuffer::getDouble(size_t id) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<const double*>(getData(id, Protocol::TYPE_DOUBLE));
+}
+
+//------------------------------------------------------------------------------
+
+const double& MultiBuffer::getDoubleRef(size_t id) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<const double*>(getData(id, Protocol::TYPE_DOUBLE));
+}
+
+//------------------------------------------------------------------------------
+
+double& MultiBuffer::getDoubleRef(size_t id)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return *reinterpret_cast<double*>(getData(id, Protocol::TYPE_DOUBLE));
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::setFloatArray(size_t id, const float* value,
+                                  size_t length, size_t offset)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return setArray<float, Protocol::TYPE_FLOAT_ARRAY>(id, value, length, offset);
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::getFloatArray(size_t id, float* value,
+                                  size_t length, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return getArray<float, Protocol::TYPE_FLOAT_ARRAY>(id, value, length, offset);
+}
+
+//------------------------------------------------------------------------------
+
+const float* MultiBuffer::getFloatArray(size_t id, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return getArray<float, Protocol::TYPE_FLOAT_ARRAY>(id, offset);
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::setIntArray(size_t id, const int32_t* value,
+                                size_t length, size_t offset)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return setArray<int32_t, Protocol::TYPE_INT_ARRAY>(id, value, length, offset);
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::getIntArray(size_t id, int32_t* value,
+                                size_t length, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return getArray<int32_t, Protocol::TYPE_INT_ARRAY>(id, value, length, offset);
+}
+
+//------------------------------------------------------------------------------
+
+const int32_t* MultiBuffer::getIntArray(size_t id, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return getArray<int32_t, Protocol::TYPE_INT_ARRAY>(id, offset);
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::setByteArray(size_t id, const uint8_t* value,
+                                size_t length, size_t offset)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return setArray<uint8_t, Protocol::TYPE_BYTE_ARRAY>(id, value, length, offset);
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::getByteArray(size_t id, uint8_t* value,
+                                size_t length, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return getArray<uint8_t, Protocol::TYPE_BYTE_ARRAY>(id, value, length, offset);
+}
+
+//------------------------------------------------------------------------------
+
+const uint8_t* MultiBuffer::getByteArray(size_t id, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return getArray<uint8_t, Protocol::TYPE_BYTE_ARRAY>(id, offset);
+}
+
+//------------------------------------------------------------------------------
+
+size_t MultiBuffer::setString(size_t id, const string& value,
+                              size_t offset)
+    throw(InvalidIDException, TypeMismatchException)
+{
+    return setByteArray(id, reinterpret_cast<const uint8_t*>(value.c_str()),
+                        value.length(), offset);
+}
+
+//------------------------------------------------------------------------------
+
+string MultiBuffer::getString(size_t id, size_t offset) const
+    throw(InvalidIDException, TypeMismatchException)
+{
+    const DataRef& dataRef = getDataRef(id, Protocol::TYPE_BYTE_ARRAY);
+    finalize();
+
+    size_t toCopy = dataRef.getCopyLength(0, offset);
+    const uint8_t* str = data + dataRef.dataOffset + offset;
+
+    size_t length = 0;
+    if (toCopy!=0) {
+        while(length<toCopy && str[length]!=0) ++length;
+    }
+
+    return string(reinterpret_cast<const char*>(str), length);
+}
+
+//------------------------------------------------------------------------------
+
+const char* MultiBuffer::getStringPtr(size_t id, size_t offset) const
+        throw(InvalidIDException, TypeMismatchException)
+{
+    return reinterpret_cast<const char*>(getByteArray(id, offset));
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::writeSpec(uint8_t command) const throw(Exception)
+{
+    xplane.stream->writeU8(command);
+    xplane.stream->writeU32(dataRefs.size());
+
+    for(vector<DataRef>::const_iterator i = dataRefs.begin();
+        i!=dataRefs.end(); ++i)
+    {
+        const DataRef& dataRef = *i;
+        xplane.stream->writeString(dataRef.name);
+        xplane.stream->writeU8(dataRef.type);
+        if (dataRef.isArray()) {
+            xplane.stream->writeS32(dataRef.length);
+            xplane.stream->writeS32(dataRef.offset);
+        }
+    }
+
+    xplane.stream->flush();
+    xplane.checkResult(true);
+}
+
+//------------------------------------------------------------------------------
+
+void MultiBuffer::reregisterInXPlane() throw(Exception)
+{
+    if (registeredID>=0) {
+        int origRegisteredID = registeredID;
+        try {
+            registeredID = -1;
+            registerInXPlane();
+        } catch(...) {
+            registeredID = origRegisteredID;
+            throw;
+        }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiBuffer.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiBuffer.cc	(revision 57)
+++ 	(revision )
@@ -1,650 +1,0 @@
-// 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 "MultiBuffer.h"
-
-#include "XPlane.h"
-
-#include <xplra/Protocol.h>
-
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-#include <cstring>
-#include <cstdio>
-
-//------------------------------------------------------------------------------
-
-using hu::varadiistvan::xplra::MultiBuffer;
-
-using xplra::Protocol;
-
-using std::vector;
-using std::string;
-using std::min;
-
-//------------------------------------------------------------------------------
-
-inline MultiBuffer::DataRef::DataRef(const string& name, uint8_t type,
-                                     const DataRef* previous,
-                                     size_t length, size_t offset) throw() :
-    name(name),
-    type(type),
-    length(length),
-    offset(offset),
-    dataOffset(0)
-{
-    if (previous!=0) {
-        size_t alignment = getAlignment();
-        dataOffset = previous->dataOffset + previous->getSize();
-        dataOffset += alignment - 1;
-        dataOffset &= ~(alignment-1);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-inline size_t MultiBuffer::DataRef::getSize() const throw()
-{
-    switch (type) {
-      case Protocol::TYPE_INT:
-        return sizeof(int32_t);
-      case Protocol::TYPE_FLOAT:
-        return sizeof(float);
-      case Protocol::TYPE_DOUBLE:
-        return sizeof(double);
-      case Protocol::TYPE_FLOAT_ARRAY:
-        return sizeof(float) * length;
-      case Protocol::TYPE_INT_ARRAY:
-        return sizeof(int32_t) * length;
-      case Protocol::TYPE_BYTE_ARRAY:
-        return sizeof(uint8_t) * length;
-      default:
-        return 0;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-inline size_t MultiBuffer::DataRef::getAlignment() const throw()
-{
-    switch (type) {
-      case Protocol::TYPE_INT:
-      case Protocol::TYPE_INT_ARRAY:
-        return sizeof(int32_t);
-      case Protocol::TYPE_FLOAT:
-      case Protocol::TYPE_FLOAT_ARRAY:
-        return sizeof(float);
-      case Protocol::TYPE_DOUBLE:
-        return sizeof(double);
-      case Protocol::TYPE_BYTE_ARRAY:
-      default:
-        return sizeof(uint8_t);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-bool MultiBuffer::DataRef::isArray() const throw()
-{
-    return
-        type==Protocol::TYPE_FLOAT_ARRAY ||
-        type==Protocol::TYPE_INT_ARRAY ||
-        type==Protocol::TYPE_BYTE_ARRAY;
-}
-
-//------------------------------------------------------------------------------
-
-inline size_t
-MultiBuffer::DataRef::getCopyLength(size_t userLength, size_t userOffset)
-    const throw()
-{
-    size_t maxLength =
-        (userOffset>length) ? 0 : (length - userOffset);
-    return (userLength==0) ? maxLength : min(userLength, maxLength);
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void MultiBuffer::unfinalize() throw()
-{
-    delete data; data = 0;
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::forgetRegistration() throw()
-{
-    registeredID = -1;
-}
-
-//------------------------------------------------------------------------------
-
-inline const MultiBuffer::DataRef* MultiBuffer::getLastDataRef() const throw()
-{
-    return dataRefs.empty() ? 0 : &(dataRefs.back());
-}
-
-//------------------------------------------------------------------------------
-
-inline const MultiBuffer::DataRef& MultiBuffer::getDataRef(size_t id, uint8_t type) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    if (id>=dataRefs.size()) throw InvalidIDException();
-    const DataRef& dataRef = dataRefs[id];
-    if (dataRef.type!=type) throw TypeMismatchException();
-    return dataRef;
-}
-
-//------------------------------------------------------------------------------
-
-inline void* MultiBuffer::getData(size_t id, uint8_t type)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    const DataRef& dataRef = getDataRef(id, type);
-    finalize();
-    return data + dataRef.dataOffset;
-}
-
-//------------------------------------------------------------------------------
-
-inline const void* MultiBuffer::getData(size_t id, uint8_t type) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    const DataRef& dataRef = getDataRef(id, type);
-    finalize();
-    return data + dataRef.dataOffset;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, uint8_t type> size_t
-inline MultiBuffer::setArray(size_t id, const T* value,
-                             size_t length, size_t offset)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    const DataRef& dataRef = getDataRef(id, type);
-    finalize();
-
-    size_t toCopy = dataRef.getCopyLength(length, offset);
-
-    if (toCopy>0) {
-        memcpy( data + dataRef.dataOffset + offset * sizeof(T),
-                value, toCopy * sizeof(T) );
-    }
-
-    return toCopy;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, uint8_t type>
-inline size_t MultiBuffer::getArray(size_t id, T* value,
-                                    size_t length, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    const DataRef& dataRef = getDataRef(id, type);
-    finalize();
-
-    size_t toCopy = dataRef.getCopyLength(length, offset);
-
-    if (toCopy>0) {
-        memcpy( value, data + dataRef.dataOffset + offset * sizeof(T),
-                toCopy * sizeof(T) );
-    }
-
-    return toCopy;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, uint8_t type>
-inline const T* MultiBuffer::getArray(size_t id, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    const DataRef& dataRef = getDataRef(id, type);
-    finalize();
-    return (offset<dataRef.length) ?
-        reinterpret_cast<const T*>(data + dataRef.dataOffset +
-                                   offset * sizeof(T)) : 0;
-}
-
-//------------------------------------------------------------------------------
-
-MultiBuffer::MultiBuffer(XPlane& xplane, uint8_t registerCommand,
-                         uint8_t unregisterCommand) throw() :
-    data(0),
-    xplane(xplane),
-    registerCommand(registerCommand),
-    unregisterCommand(unregisterCommand),
-    registeredID(-1)
-{
-}
-
-//------------------------------------------------------------------------------
-
-MultiBuffer::~MultiBuffer() throw()
-{
-    unregisterSafelyFromXPlane();
-    delete[] data;
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::addInt(const string& name) throw()
-{
-    unfinalize();
-    dataRefs.push_back(DataRef(name, Protocol::TYPE_INT, getLastDataRef()));
-    return dataRefs.size() - 1;
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::addFloat(const string& name) throw()
-{
-    unfinalize();
-    dataRefs.push_back(DataRef(name, Protocol::TYPE_FLOAT, getLastDataRef()));
-    return dataRefs.size() - 1;
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::addDouble(const string& name) throw()
-{
-    unfinalize();
-    dataRefs.push_back(DataRef(name, Protocol::TYPE_DOUBLE, getLastDataRef()));
-    return dataRefs.size() - 1;
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::addFloatArray(const string& name, size_t length,
-                                  size_t offset) throw()
-{
-    unfinalize();
-    dataRefs.push_back(DataRef(name, Protocol::TYPE_FLOAT_ARRAY,
-                               getLastDataRef(), length, offset));
-    return dataRefs.size() - 1;
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::addIntArray(const string& name, size_t length,
-                                size_t offset) throw()
-{
-    unfinalize();
-    dataRefs.push_back(DataRef(name, Protocol::TYPE_INT_ARRAY,
-                               getLastDataRef(), length, offset));
-    return dataRefs.size() - 1;
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::addByteArray(const string& name, size_t length,
-                                 size_t offset) throw()
-{
-    unfinalize();
-    dataRefs.push_back(DataRef(name, Protocol::TYPE_BYTE_ARRAY,
-                               getLastDataRef(), length, offset));
-    return dataRefs.size() - 1;
-}
-
-//------------------------------------------------------------------------------
-
-bool MultiBuffer::finalize() const
-{
-    if (data==0 && !dataRefs.empty()) {
-        const DataRef* lastDataRef = getLastDataRef();
-        size_t dataSize = lastDataRef->dataOffset + lastDataRef->getSize();
-        data = new unsigned char[dataSize];
-        memset(data, 0, dataSize);
-        return true;
-    } else {
-        return data!=0;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::registerInXPlane() throw(Exception)
-{
-    if (finalize() && registeredID<0) {
-        xplane.checkStream();
-
-        writeSpec(registerCommand);
-
-        uint32_t id = xplane.stream->readU32();
-        xplane.checkStream();
-
-        registeredID = static_cast<int>(id);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::unregisterFromXPlane() throw(Exception)
-{
-    if (registeredID>=0) {
-        xplane.stream->writeU8(unregisterCommand);
-        xplane.stream->writeU32(static_cast<uint32_t>(registeredID));
-        xplane.stream->flush();
-        xplane.checkResult();
-        registeredID = -1;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-bool MultiBuffer::unregisterSafelyFromXPlane() throw()
-{
-    try {
-        unregisterFromXPlane();
-        return true;
-    } catch(...) {
-        registeredID = -1;
-        return false;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::execute() throw(Exception)
-{
-    if (data==0 && registeredID>=0) {
-        unregisterFromXPlane();
-        registerInXPlane();
-    } else {
-        finalize();
-    }
-
-    if (registeredID>=0) {
-        doExecute();
-    } else {
-        doExecuteUnregistered();
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::setInt(size_t id, int value)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    *reinterpret_cast<int32_t*>(getData(id, Protocol::TYPE_INT)) = value;
-}
-
-//------------------------------------------------------------------------------
-
-int MultiBuffer::getInt(size_t id) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<const int32_t*>(getData(id, Protocol::TYPE_INT));
-}
-
-//------------------------------------------------------------------------------
-
-const int32_t& MultiBuffer::getIntRef(size_t id) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<const int32_t*>(getData(id, Protocol::TYPE_INT));
-}
-
-//------------------------------------------------------------------------------
-
-int32_t& MultiBuffer::getIntRef(size_t id)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<int32_t*>(getData(id, Protocol::TYPE_INT));
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::setFloat(size_t id, float value)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    *reinterpret_cast<float*>(getData(id, Protocol::TYPE_FLOAT)) = value;
-}
-
-//------------------------------------------------------------------------------
-
-float MultiBuffer::getFloat(size_t id) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<const float*>(getData(id, Protocol::TYPE_FLOAT));
-}
-
-//------------------------------------------------------------------------------
-
-const float& MultiBuffer::getFloatRef(size_t id) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<const float*>(getData(id, Protocol::TYPE_FLOAT));
-}
-
-//------------------------------------------------------------------------------
-
-float& MultiBuffer::getFloatRef(size_t id)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<float*>(getData(id, Protocol::TYPE_FLOAT));
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::setDouble(size_t id, double value)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    *reinterpret_cast<double*>(getData(id, Protocol::TYPE_DOUBLE)) = value;
-}
-
-//------------------------------------------------------------------------------
-
-double MultiBuffer::getDouble(size_t id) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<const double*>(getData(id, Protocol::TYPE_DOUBLE));
-}
-
-//------------------------------------------------------------------------------
-
-const double& MultiBuffer::getDoubleRef(size_t id) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<const double*>(getData(id, Protocol::TYPE_DOUBLE));
-}
-
-//------------------------------------------------------------------------------
-
-double& MultiBuffer::getDoubleRef(size_t id)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return *reinterpret_cast<double*>(getData(id, Protocol::TYPE_DOUBLE));
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::setFloatArray(size_t id, const float* value,
-                                  size_t length, size_t offset)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return setArray<float, Protocol::TYPE_FLOAT_ARRAY>(id, value, length, offset);
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::getFloatArray(size_t id, float* value,
-                                  size_t length, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return getArray<float, Protocol::TYPE_FLOAT_ARRAY>(id, value, length, offset);
-}
-
-//------------------------------------------------------------------------------
-
-const float* MultiBuffer::getFloatArray(size_t id, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return getArray<float, Protocol::TYPE_FLOAT_ARRAY>(id, offset);
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::setIntArray(size_t id, const int32_t* value,
-                                size_t length, size_t offset)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return setArray<int32_t, Protocol::TYPE_INT_ARRAY>(id, value, length, offset);
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::getIntArray(size_t id, int32_t* value,
-                                size_t length, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return getArray<int32_t, Protocol::TYPE_INT_ARRAY>(id, value, length, offset);
-}
-
-//------------------------------------------------------------------------------
-
-const int32_t* MultiBuffer::getIntArray(size_t id, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return getArray<int32_t, Protocol::TYPE_INT_ARRAY>(id, offset);
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::setByteArray(size_t id, const uint8_t* value,
-                                size_t length, size_t offset)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return setArray<uint8_t, Protocol::TYPE_BYTE_ARRAY>(id, value, length, offset);
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::getByteArray(size_t id, uint8_t* value,
-                                size_t length, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return getArray<uint8_t, Protocol::TYPE_BYTE_ARRAY>(id, value, length, offset);
-}
-
-//------------------------------------------------------------------------------
-
-const uint8_t* MultiBuffer::getByteArray(size_t id, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return getArray<uint8_t, Protocol::TYPE_BYTE_ARRAY>(id, offset);
-}
-
-//------------------------------------------------------------------------------
-
-size_t MultiBuffer::setString(size_t id, const string& value,
-                              size_t offset)
-    throw(InvalidIDException, TypeMismatchException)
-{
-    return setByteArray(id, reinterpret_cast<const uint8_t*>(value.c_str()),
-                        value.length(), offset);
-}
-
-//------------------------------------------------------------------------------
-
-string MultiBuffer::getString(size_t id, size_t offset) const
-    throw(InvalidIDException, TypeMismatchException)
-{
-    const DataRef& dataRef = getDataRef(id, Protocol::TYPE_BYTE_ARRAY);
-    finalize();
-
-    size_t toCopy = dataRef.getCopyLength(0, offset);
-    const uint8_t* str = data + dataRef.dataOffset + offset;
-
-    size_t length = 0;
-    if (toCopy!=0) {
-        while(length<toCopy && str[length]!=0) ++length;
-    }
-
-    return string(reinterpret_cast<const char*>(str), length);
-}
-
-//------------------------------------------------------------------------------
-
-const char* MultiBuffer::getStringPtr(size_t id, size_t offset) const
-        throw(InvalidIDException, TypeMismatchException)
-{
-    return reinterpret_cast<const char*>(getByteArray(id, offset));
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::writeSpec(uint8_t command) const throw(Exception)
-{
-    xplane.stream->writeU8(command);
-    xplane.stream->writeU32(dataRefs.size());
-
-    for(vector<DataRef>::const_iterator i = dataRefs.begin();
-        i!=dataRefs.end(); ++i)
-    {
-        const DataRef& dataRef = *i;
-        xplane.stream->writeString(dataRef.name);
-        xplane.stream->writeU8(dataRef.type);
-        if (dataRef.isArray()) {
-            xplane.stream->writeS32(dataRef.length);
-            xplane.stream->writeS32(dataRef.offset);
-        }
-    }
-
-    xplane.stream->flush();
-    xplane.checkResult(true);
-}
-
-//------------------------------------------------------------------------------
-
-void MultiBuffer::reregisterInXPlane() throw(Exception)
-{
-    if (registeredID>=0) {
-        int origRegisteredID = registeredID;
-        try {
-            registeredID = -1;
-            registerInXPlane();
-        } catch(...) {
-            registeredID = origRegisteredID;
-            throw;
-        }
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiBuffer.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiBuffer.h	(revision 66)
+++ src/client/c/hu/varadiistvan/xplra/MultiBuffer.h	(revision 66)
@@ -0,0 +1,606 @@
+// 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.
+
+#ifndef HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
+#define HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
+//------------------------------------------------------------------------------
+
+#include "Exception.h"
+
+#include <string>
+#include <vector>
+
+#include <inttypes.h>
+
+//------------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class XPlane;
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for the multi-get and multi-set handlers. It contains
+ * the meta-data of the datarefs as well as a buffer for storing the
+ * data.
+ */
+class MultiBuffer
+{
+protected:
+    /**
+     * Information about a dataref.
+     */
+    class DataRef
+    {
+    public:
+        /**
+         * The name.
+         */
+        std::string name;
+
+        /**
+         * The type (the protocol constant).
+         */
+        uint8_t type;
+
+        /**
+         * The length in case of array types.
+         */
+        size_t length;
+
+        /**
+         * The offset in case of array types.
+         */
+        size_t offset;
+
+        /**
+         * The offset within the data buffer.
+         */
+        size_t dataOffset;
+
+        /**
+         * Construct the dataref with the given data.
+         */
+        DataRef(const std::string& name, uint8_t type,
+                const DataRef* previous = 0,
+                size_t length = 0, size_t offset = 0) throw();
+
+        /**
+         * Get the size of the data represented by this object.
+         */
+        size_t getSize() const throw();
+
+        /**
+         * Get the alignment requirement of the data represented by
+         * this dataref.
+         */
+        size_t getAlignment() const throw();
+
+        /**
+         * Determine if the dataref is an array.
+         */
+        bool isArray() const throw();
+
+        /**
+         * Get the length of the data the can be copied for the given
+         * user parameters.
+         */
+        size_t getCopyLength(size_t userLength, size_t userOffset) const throw();
+    };
+
+    /**
+     * The datarefs.
+     */
+    std::vector<DataRef> dataRefs;
+
+    /**
+     * The data buffer.
+     */
+    mutable unsigned char* data;
+
+    /**
+     * The XPlane object this buffer belongs to.
+     */
+    XPlane& xplane;
+
+    /**
+     * The command to use for registering the buffer.
+     */
+    uint8_t registerCommand;
+
+    /**
+     * The command to unregister the buffer.
+     */
+    uint8_t unregisterCommand;
+
+    /**
+     * The ID with which this buffer is registered in the plugin. If
+     * negative, the buffer is not registerd yet.
+     */
+    int registeredID;
+
+protected:
+    /**
+     * Construct an empty buffer for the given XPlane instance.
+     */
+    MultiBuffer(XPlane& xplane, uint8_t registerCommand,
+                uint8_t unregisterCommand) throw();
+
+    /**
+     * Destroy the buffer. If it is registered, an attempt will be
+     * made to unregister it.
+     */
+    virtual ~MultiBuffer() throw();
+
+public:
+    /**
+     * Get the X-Plane object this buffer belongs to.
+     */
+    XPlane& getXPlane() const throw();
+
+    /**
+     * Add an integer dataref.
+     *
+     * @return the ID of the dataref, that can be used later to set or
+     * get the value.
+     */
+    size_t addInt(const std::string& name) throw();
+
+    /**
+     * Add a float dataref.
+     *
+     * @return the ID of the dataref, that can be used later to set or
+     * get the value.
+     */
+    size_t addFloat(const std::string& name) throw();
+
+    /**
+     * Add a double dataref.
+     *
+     * @return the ID of the dataref, that can be used later to set or
+     * get the value.
+     */
+    size_t addDouble(const std::string& name) throw();
+
+    /**
+     * Add a float array dataref.
+     *
+     * @return the ID of the dataref, that can be used later to set or
+     * get the value.
+     */
+    size_t addFloatArray(const std::string& name, size_t length,
+                         size_t offset = 0) throw();
+
+    /**
+     * Add an integer array dataref.
+     *
+     * @return the ID of the dataref, that can be used later to set or
+     * get the value.
+     */
+    size_t addIntArray(const std::string& name, size_t length,
+                       size_t offset = 0) throw();
+
+    /**
+     * Add a byte array dataref.
+     *
+     * @return the ID of the dataref, that can be used later to set or
+     * get the value.
+     */
+    size_t addByteArray(const std::string& name, size_t length,
+                        size_t offset = 0) throw();
+
+    /**
+     * Finalize the buffer, if not finalized yet.
+     *
+     * @return if there is any data in it
+     */
+    bool finalize() const;
+
+    /**
+     * Register this buffer in X-Plane the for either getting or
+     * setting, depending on the actual subclass. It will be finalized
+     * too.
+     */
+    void registerInXPlane() throw(Exception);
+
+    /**
+     * Unregister this buffer from X-Plane.
+     */
+    void unregisterFromXPlane() throw(Exception);
+
+    /**
+     * Unregister this buffer from X-Plane safely, i.e. without
+     * throwing any exceptions. If unregistration fails, the
+     * registered ID will be cleared anyway.
+     *
+     * @return whether unregistration succeeded.
+     */
+    bool unregisterSafelyFromXPlane() throw();
+
+    /**
+     * Execute the buffer by either reading or writing it. If the
+     * buffer is not finalized, it will be finalized. If it is not
+     * finalized, but registered, the registration will be cleared,
+     * and it will be re-registered after finalizing.
+     */
+    void execute() throw(Exception);
+
+    /**
+     * Set the value of an integer dataref with the given ID.
+     */
+    void setInt(size_t id, int value)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of an integer dataref with the given ID.
+     */
+    int getInt(size_t id) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a reference to the integer dataref with the given ID
+     */
+    const int32_t& getIntRef(size_t id) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a reference to the integer dataref with the given ID
+     */
+    int32_t& getIntRef(size_t id)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Set the value of a float dataref with the given ID.
+     */
+    void setFloat(size_t id, float value)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of a float dataref with the given ID.
+     */
+    float getFloat(size_t id) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a reference to the float dataref with the given ID
+     */
+    const float& getFloatRef(size_t id) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a reference to the integer dataref with the given ID
+     */
+    float& getFloatRef(size_t id)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Set the value of a double dataref with the given ID.
+     */
+    void setDouble(size_t id, double value)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of a double dataref with the given ID.
+     */
+    double getDouble(size_t id) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a reference to the double dataref with the given ID
+     */
+    const double& getDoubleRef(size_t id) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a reference to the double dataref with the given ID
+     */
+    double& getDoubleRef(size_t id)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Set the value of the float array dataref with the given ID.
+     *
+     * @param id the ID of the float array dataref
+     * @param value the source buffer
+     * @param length the amount of data, i.e. you can set only a part
+     * of the data in the buffer. If 0, it is assumed to be the length
+     * of the data in the buffer minus the offset (see below).
+     *
+     * @param offset the offset within the buffer to set the data from
+     *
+     * @return the number of data items set
+     */
+    size_t setFloatArray(size_t id, const float* value,
+                         size_t length = 0, size_t offset = 0)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of the float array dataref with the given ID
+     *
+     * @param id the ID of the float array dataref
+     * @param value the destination buffer
+     * @param length the size of the buffer. If 0, it is assumed to be
+     * the length of the data in the buffer minus the offset (see
+     * below).
+     *
+     * @param offset the offset within the buffer to get the data from
+     *
+     * @return the number of data items retrieved.
+     */
+    size_t getFloatArray(size_t id, float* value,
+                         size_t length = 0, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the array of floating point values as a directly readable
+     * buffer.
+     *
+     * @param id the ID of the float array dataref
+     * @param offset the offset within the buffer. If it is not less
+     * than the length of the buffer, 0 is returned.
+     */
+    const float* getFloatArray(size_t id, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Set the value of the integer array dataref with the given ID.
+     *
+     * @param id the ID of the integer array dataref
+     * @param value the source buffer
+     * @param length the amount of data, i.e. you can set only a part
+     * of the data in the buffer. If 0, it is assumed to be the length
+     * of the data in the buffer minus the offset (see below).
+     *
+     * @param offset the offset within the buffer to set the data from
+     *
+     * @return the number of data items set
+     */
+    size_t setIntArray(size_t id, const int32_t* value,
+                       size_t length = 0, size_t offset = 0)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of the integer array dataref with the given ID
+     *
+     * @param id the ID of the integer array dataref
+     * @param value the destination buffer
+     * @param length the size of the buffer. If 0, it is assumed to be
+     * the length of the data in the buffer minus the offset (see
+     * below).
+     *
+     * @param offset the offset within the buffer to get the data from
+     *
+     * @return the number of data items retrieved.
+     */
+    size_t getIntArray(size_t id, int32_t* value,
+                       size_t length = 0, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the array of integer values as a directly readable buffer.
+     *
+     * @param id the ID of the float array dataref
+     * @param offset the offset within the buffer. If it is not less
+     * than the length of the buffer, 0 is returned.
+     */
+    const int32_t* getIntArray(size_t id, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+
+    /**
+     * Set the value of the byte array dataref with the given ID.
+     *
+     * @param id the ID of the byte array dataref
+     * @param value the source buffer
+     * @param length the amount of data, i.e. you can set only a part
+     * of the data in the buffer. If 0, it is assumed to be the length
+     * of the data in the buffer minus the offset (see below).
+     *
+     * @param offset the offset within the buffer to set the data from
+     *
+     * @return the number of data items set
+     */
+    size_t setByteArray(size_t id, const uint8_t* value,
+                        size_t length = 0, size_t offset = 0)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of the byte array dataref with the given ID
+     *
+     * @param id the ID of the byte array dataref
+     * @param value the destination buffer
+     * @param length the size of the buffer. If 0, it is assumed to be
+     * the length of the data in the buffer minus the offset (see
+     * below).
+     *
+     * @param offset the offset within the buffer to get the data from
+     *
+     * @return the number of data items retrieved.
+     */
+    size_t getByteArray(size_t id, uint8_t* value,
+                        size_t length = 0, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the array of byte values as a directly readable buffer.
+     *
+     * @param id the ID of the byte array dataref
+     * @param offset the offset within the buffer. If it is not less
+     * than the length of the buffer, 0 is returned.
+     */
+    const uint8_t* getByteArray(size_t id, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+
+    /**
+     * Set the value of the byte array dataref with the given ID
+     * from the given string. If the string contains less characters
+     * than the array's length, the rest will be filled with 0s.
+     *
+     * @return the number of bytes set
+     */
+    size_t setString(size_t id, const std::string& value,
+                     size_t offset = 0)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the value of the byte array dataref with the given ID as
+     * a string.
+     */
+    std::string getString(size_t id, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get a string pointer to the value of the byte array dataref
+     * with the given ID.
+     */
+    const char* getStringPtr(size_t id, size_t offset = 0) const
+        throw(InvalidIDException, TypeMismatchException);
+
+protected:
+    /**
+     * Perform the main part of the execution if the buffer is
+     * registered.
+     */
+    virtual void doExecute() throw(Exception) = 0;
+
+    /**
+     * Perform the main part of the execution if the buffer is
+     * not registered.
+     */
+    virtual void doExecuteUnregistered() throw(Exception) = 0;
+
+    /**
+     * Write the data specification with the given command. It also
+     * checks the result
+     */
+    void writeSpec(uint8_t command) const throw(Exception);
+
+    /**
+     * Re-register the buffer in X-Plane, if it has been registered
+     * earlier.
+     *
+     * it has not been registered, nothing is done. Otherwise the
+     * buffer gets registered, and the old ID is forgotten. This
+     * function is meant to be used by the XPlane object when it
+     * creates a new connection. If the registration fails, the
+     * original ID is restored, so that this function could be called
+     * again
+     */
+    void reregisterInXPlane() throw(Exception);
+
+private:
+    /**
+     * Unfinalize the buffer, if it is finalized.
+     */
+    void unfinalize() throw();
+
+    /**
+     * Forget the registration of this buffer. This is called from the
+     * destructor of the XPlane object, since that closes the
+     * connection anyway, so there is no need to unregister the
+     * multi-buffers.
+     */
+    void forgetRegistration() throw();
+
+    /**
+     * Get the last dataref, or 0 if there are not datarefs yet.
+     */
+    const DataRef* getLastDataRef() const throw();
+
+    /**
+     * Get the dataref with the given ID if it is of the given
+     * type. Otherwise throw an exception.
+     */
+    const DataRef& getDataRef(size_t id, uint8_t type) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the data area belonging to the given dataref it is of the
+     * given type. If the buffer is not finalized yet, it will be.
+     */
+    void* getData(size_t id, uint8_t type)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Get the data area belonging to the given dataref it is of the
+     * given type. If the buffer is not finalized yet, it will be.
+     */
+    const void* getData(size_t id, uint8_t type) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Template function for setting an array of a certain type.
+     */
+    template <typename T, uint8_t type> size_t
+    setArray(size_t id, const T* value, size_t length, size_t offset)
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Template function for getting the elements of an array of a
+     * certain type.
+     */
+    template <typename T, uint8_t type> size_t
+    getArray(size_t id, T* value, size_t length, size_t offset) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    /**
+     * Template function for getting the elements of an array of a
+     * certain type.
+     */
+    template <typename T, uint8_t type> const T*
+    getArray(size_t id, size_t offset) const
+        throw(InvalidIDException, TypeMismatchException);
+
+    friend class XPlane;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline XPlane& MultiBuffer::getXPlane() const throw()
+{
+    return xplane;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
+
+//------------------------------------------------------------------------------
+#endif // HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiBuffer.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiBuffer.h	(revision 57)
+++ 	(revision )
@@ -1,591 +1,0 @@
-// 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.
-
-#ifndef HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
-#define HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
-//------------------------------------------------------------------------------
-
-#include "Exception.h"
-
-#include <string>
-#include <vector>
-
-#include <inttypes.h>
-
-//------------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class XPlane;
-
-//------------------------------------------------------------------------------
-
-/**
- * Base class for the multi-get and multi-set handlers. It contains
- * the meta-data of the datarefs as well as a buffer for storing the
- * data.
- */
-class MultiBuffer
-{
-protected:
-    /**
-     * Information about a dataref.
-     */
-    class DataRef
-    {
-    public:
-        /**
-         * The name.
-         */
-        std::string name;
-
-        /**
-         * The type (the protocol constant).
-         */
-        uint8_t type;
-
-        /**
-         * The length in case of array types.
-         */
-        size_t length;
-
-        /**
-         * The offset in case of array types.
-         */
-        size_t offset;
-
-        /**
-         * The offset within the data buffer.
-         */
-        size_t dataOffset;
-
-        /**
-         * Construct the dataref with the given data.
-         */
-        DataRef(const std::string& name, uint8_t type,
-                const DataRef* previous = 0,
-                size_t length = 0, size_t offset = 0) throw();
-
-        /**
-         * Get the size of the data represented by this object.
-         */
-        size_t getSize() const throw();
-
-        /**
-         * Get the alignment requirement of the data represented by
-         * this dataref.
-         */
-        size_t getAlignment() const throw();
-
-        /**
-         * Determine if the dataref is an array.
-         */
-        bool isArray() const throw();
-
-        /**
-         * Get the length of the data the can be copied for the given
-         * user parameters.
-         */
-        size_t getCopyLength(size_t userLength, size_t userOffset) const throw();
-    };
-
-    /**
-     * The datarefs.
-     */
-    std::vector<DataRef> dataRefs;
-
-    /**
-     * The data buffer.
-     */
-    mutable unsigned char* data;
-
-    /**
-     * The XPlane object this buffer belongs to.
-     */
-    XPlane& xplane;
-
-    /**
-     * The command to use for registering the buffer.
-     */
-    uint8_t registerCommand;
-
-    /**
-     * The command to unregister the buffer.
-     */
-    uint8_t unregisterCommand;
-
-    /**
-     * The ID with which this buffer is registered in the plugin. If
-     * negative, the buffer is not registerd yet.
-     */
-    int registeredID;
-
-protected:
-    /**
-     * Construct an empty buffer for the given XPlane instance.
-     */
-    MultiBuffer(XPlane& xplane, uint8_t registerCommand,
-                uint8_t unregisterCommand) throw();
-
-    /**
-     * Destroy the buffer. If it is registered, an attempt will be
-     * made to unregister it.
-     */
-    virtual ~MultiBuffer() throw();
-
-public:
-    /**
-     * Get the X-Plane object this buffer belongs to.
-     */
-    XPlane& getXPlane() const throw();
-
-    /**
-     * Add an integer dataref.
-     *
-     * @return the ID of the dataref, that can be used later to set or
-     * get the value.
-     */
-    size_t addInt(const std::string& name) throw();
-
-    /**
-     * Add a float dataref.
-     *
-     * @return the ID of the dataref, that can be used later to set or
-     * get the value.
-     */
-    size_t addFloat(const std::string& name) throw();
-
-    /**
-     * Add a double dataref.
-     *
-     * @return the ID of the dataref, that can be used later to set or
-     * get the value.
-     */
-    size_t addDouble(const std::string& name) throw();
-
-    /**
-     * Add a float array dataref.
-     *
-     * @return the ID of the dataref, that can be used later to set or
-     * get the value.
-     */
-    size_t addFloatArray(const std::string& name, size_t length,
-                         size_t offset = 0) throw();
-
-    /**
-     * Add an integer array dataref.
-     *
-     * @return the ID of the dataref, that can be used later to set or
-     * get the value.
-     */
-    size_t addIntArray(const std::string& name, size_t length,
-                       size_t offset = 0) throw();
-
-    /**
-     * Add a byte array dataref.
-     *
-     * @return the ID of the dataref, that can be used later to set or
-     * get the value.
-     */
-    size_t addByteArray(const std::string& name, size_t length,
-                        size_t offset = 0) throw();
-
-    /**
-     * Finalize the buffer, if not finalized yet.
-     *
-     * @return if there is any data in it
-     */
-    bool finalize() const;
-
-    /**
-     * Register this buffer in X-Plane the for either getting or
-     * setting, depending on the actual subclass. It will be finalized
-     * too.
-     */
-    void registerInXPlane() throw(Exception);
-
-    /**
-     * Unregister this buffer from X-Plane.
-     */
-    void unregisterFromXPlane() throw(Exception);
-
-    /**
-     * Unregister this buffer from X-Plane safely, i.e. without
-     * throwing any exceptions. If unregistration fails, the
-     * registered ID will be cleared anyway.
-     *
-     * @return whether unregistration succeeded.
-     */
-    bool unregisterSafelyFromXPlane() throw();
-
-    /**
-     * Execute the buffer by either reading or writing it. If the
-     * buffer is not finalized, it will be finalized. If it is not
-     * finalized, but registered, the registration will be cleared,
-     * and it will be re-registered after finalizing.
-     */
-    void execute() throw(Exception);
-
-    /**
-     * Set the value of an integer dataref with the given ID.
-     */
-    void setInt(size_t id, int value)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of an integer dataref with the given ID.
-     */
-    int getInt(size_t id) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a reference to the integer dataref with the given ID
-     */
-    const int32_t& getIntRef(size_t id) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a reference to the integer dataref with the given ID
-     */
-    int32_t& getIntRef(size_t id)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Set the value of a float dataref with the given ID.
-     */
-    void setFloat(size_t id, float value)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of a float dataref with the given ID.
-     */
-    float getFloat(size_t id) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a reference to the float dataref with the given ID
-     */
-    const float& getFloatRef(size_t id) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a reference to the integer dataref with the given ID
-     */
-    float& getFloatRef(size_t id)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Set the value of a double dataref with the given ID.
-     */
-    void setDouble(size_t id, double value)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of a double dataref with the given ID.
-     */
-    double getDouble(size_t id) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a reference to the double dataref with the given ID
-     */
-    const double& getDoubleRef(size_t id) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a reference to the double dataref with the given ID
-     */
-    double& getDoubleRef(size_t id)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Set the value of the float array dataref with the given ID.
-     *
-     * @param length the amount of data, i.e. you can set only a part
-     * of the data in the buffer. If 0, it is assumed to be the length
-     * of the data in the buffer minus the offset (see below).
-     *
-     * @param offset the offset within the buffer to set the data from
-     *
-     * @return the number of data items set
-     */
-    size_t setFloatArray(size_t id, const float* value,
-                         size_t length = 0, size_t offset = 0)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of the float array dataref with the given ID
-     *
-     * @param length the size of the buffer. If 0, it is assumed to be
-     * the length of the data in the buffer minus the offset (see
-     * below).
-     *
-     * @param offset the offset within the buffer to get the data from
-     *
-     * @return the number of data items retrieved.
-     */
-    size_t getFloatArray(size_t id, float* value,
-                         size_t length = 0, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the array of floating point values as a directly readable
-     * buffer.
-     *
-     * @param offset the offset within the buffer. If it is not less
-     * than the length of the buffer, 0 is returned.
-     */
-    const float* getFloatArray(size_t id, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Set the value of the integer array dataref with the given ID.
-     *
-     * @param length the amount of data, i.e. you can set only a part
-     * of the data in the buffer. If 0, it is assumed to be the length
-     * of the data in the buffer minus the offset (see below).
-     *
-     * @param offset the offset within the buffer to set the data from
-     *
-     * @return the number of data items set
-     */
-    size_t setIntArray(size_t id, const int32_t* value,
-                       size_t length = 0, size_t offset = 0)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of the integer array dataref with the given ID
-     *
-     * @param length the size of the buffer. If 0, it is assumed to be
-     * the length of the data in the buffer minus the offset (see
-     * below).
-     *
-     * @param offset the offset within the buffer to get the data from
-     *
-     * @return the number of data items retrieved.
-     */
-    size_t getIntArray(size_t id, int32_t* value,
-                       size_t length = 0, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the array of integer values as a directly readable buffer.
-     *
-     * @param offset the offset within the buffer. If it is not less
-     * than the length of the buffer, 0 is returned.
-     */
-    const int32_t* getIntArray(size_t id, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-
-    /**
-     * Set the value of the byte array dataref with the given ID.
-     *
-     * @param length the amount of data, i.e. you can set only a part
-     * of the data in the buffer. If 0, it is assumed to be the length
-     * of the data in the buffer minus the offset (see below).
-     *
-     * @param offset the offset within the buffer to set the data from
-     *
-     * @return the number of data items set
-     */
-    size_t setByteArray(size_t id, const uint8_t* value,
-                        size_t length = 0, size_t offset = 0)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of the byte array dataref with the given ID
-     *
-     * @param length the size of the buffer. If 0, it is assumed to be
-     * the length of the data in the buffer minus the offset (see
-     * below).
-     *
-     * @param offset the offset within the buffer to get the data from
-     *
-     * @return the number of data items retrieved.
-     */
-    size_t getByteArray(size_t id, uint8_t* value,
-                       size_t length = 0, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the array of byte values as a directly readable buffer.
-     *
-     * @param offset the offset within the buffer. If it is not less
-     * than the length of the buffer, 0 is returned.
-     */
-    const uint8_t* getByteArray(size_t id, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-
-    /**
-     * Set the value of the byte array dataref with the given ID
-     * from the given string. If the string contains less characters
-     * than the array's length, the rest will be filled with 0s.
-     *
-     * @return the number of bytes set
-     */
-    size_t setString(size_t id, const std::string& value,
-                     size_t offset = 0)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the value of the byte array dataref with the given ID as
-     * a string.
-     */
-    std::string getString(size_t id, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get a string pointer to the value of the byte array dataref
-     * with the given ID.
-     */
-    const char* getStringPtr(size_t id, size_t offset = 0) const
-        throw(InvalidIDException, TypeMismatchException);
-
-protected:
-    /**
-     * Perform the main part of the execution if the buffer is
-     * registered.
-     */
-    virtual void doExecute() throw(Exception) = 0;
-
-    /**
-     * Perform the main part of the execution if the buffer is
-     * not registered.
-     */
-    virtual void doExecuteUnregistered() throw(Exception) = 0;
-
-    /**
-     * Write the data specification with the given command. It also
-     * checks the result
-     */
-    void writeSpec(uint8_t command) const throw(Exception);
-
-    /**
-     * Re-register the buffer in X-Plane, if it has been registered
-     * earlier.
-     *
-     * it has not been registered, nothing is done. Otherwise the
-     * buffer gets registered, and the old ID is forgotten. This
-     * function is meant to be used by the XPlane object when it
-     * creates a new connection. If the registration fails, the
-     * original ID is restored, so that this function could be called
-     * again
-     */
-    void reregisterInXPlane() throw(Exception);
-
-private:
-    /**
-     * Unfinalize the buffer, if it is finalized.
-     */
-    void unfinalize() throw();
-
-    /**
-     * Forget the registration of this buffer. This is called from the
-     * destructor of the XPlane object, since that closes the
-     * connection anyway, so there is no need to unregister the
-     * multi-buffers.
-     */
-    void forgetRegistration() throw();
-
-    /**
-     * Get the last dataref, or 0 if there are not datarefs yet.
-     */
-    const DataRef* getLastDataRef() const throw();
-
-    /**
-     * Get the dataref with the given ID if it is of the given
-     * type. Otherwise throw an exception.
-     */
-    const DataRef& getDataRef(size_t id, uint8_t type) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the data area belonging to the given dataref it is of the
-     * given type. If the buffer is not finalized yet, it will be.
-     */
-    void* getData(size_t id, uint8_t type)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Get the data area belonging to the given dataref it is of the
-     * given type. If the buffer is not finalized yet, it will be.
-     */
-    const void* getData(size_t id, uint8_t type) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Template function for setting an array of a certain type.
-     */
-    template <typename T, uint8_t type> size_t
-    setArray(size_t id, const T* value, size_t length, size_t offset)
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Template function for getting the elements of an array of a
-     * certain type.
-     */
-    template <typename T, uint8_t type> size_t
-    getArray(size_t id, T* value, size_t length, size_t offset) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    /**
-     * Template function for getting the elements of an array of a
-     * certain type.
-     */
-    template <typename T, uint8_t type> const T*
-    getArray(size_t id, size_t offset) const
-        throw(InvalidIDException, TypeMismatchException);
-
-    friend class XPlane;
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline XPlane& MultiBuffer::getXPlane() const throw()
-{
-    return xplane;
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
-
-//------------------------------------------------------------------------------
-#endif // HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiGetter.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiGetter.cc	(revision 40)
+++ src/client/c/hu/varadiistvan/xplra/MultiGetter.cc	(revision 40)
@@ -0,0 +1,133 @@
+// 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 "MultiGetter.h"
+
+#include "XPlane.h"
+
+#include <xplra/Protocol.h>
+
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using hu::varadiistvan::xplra::MultiGetter;
+
+using xplra::Protocol;
+
+using std::vector;
+using std::min;
+
+//------------------------------------------------------------------------------
+
+MultiGetter::MultiGetter(XPlane& xplane) throw() :
+    MultiBuffer(xplane, Protocol::COMMAND_REGISTER_GET_MULTI,
+                Protocol::COMMAND_UNREGISTER_GET_MULTI)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline void MultiGetter::read(const DataRef& dataRef) throw(Exception)
+{
+    switch (dataRef.type) {
+      case Protocol::TYPE_INT:
+        *reinterpret_cast<int32_t*>(data + dataRef.dataOffset) =
+            xplane.stream->readS32();
+        break;
+      case Protocol::TYPE_FLOAT:
+        *reinterpret_cast<float*>(data + dataRef.dataOffset) =
+            xplane.stream->readFloat();
+        break;
+      case Protocol::TYPE_DOUBLE:
+        *reinterpret_cast<double*>(data + dataRef.dataOffset) =
+            xplane.stream->readDouble();
+        break;
+      case Protocol::TYPE_FLOAT_ARRAY:
+      case Protocol::TYPE_INT_ARRAY:
+      case Protocol::TYPE_BYTE_ARRAY:
+      {
+          size_t length = xplane.stream->readS32();
+          xplane.checkStream();
+          length = min(length, dataRef.length);
+          size_t elementSize =
+              (dataRef.type==Protocol::TYPE_FLOAT_ARRAY) ? sizeof(float) :
+              ((dataRef.type==Protocol::TYPE_INT_ARRAY) ?
+               sizeof(int32_t) : sizeof(uint8_t));
+          xplane.stream->read(data + dataRef.dataOffset, length * elementSize);
+      }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiGetter::doExecute() throw(Exception)
+{
+    xplane.checkStream();
+    xplane.stream->writeU8(Protocol::COMMAND_EXECUTE_GET_MULTI);
+    xplane.stream->writeU32(registeredID);
+    xplane.stream->flush();
+    xplane.checkResult(true);
+
+    readValues();
+}
+
+
+//------------------------------------------------------------------------------
+
+void MultiGetter::doExecuteUnregistered() throw(Exception)
+{
+    writeSpec(Protocol::COMMAND_GET_MULTI);
+
+    readValues();
+}
+
+//------------------------------------------------------------------------------
+
+void MultiGetter::readValues() throw(Exception)
+{
+    for(vector<DataRef>::const_iterator i = dataRefs.begin();
+        i!=dataRefs.end(); ++i)
+    {
+        xplane.checkStream();
+        const DataRef& dataRef = *i;
+        read(dataRef);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiGetter.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiGetter.cc	(revision 40)
+++ 	(revision )
@@ -1,133 +1,0 @@
-// 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 "MultiGetter.h"
-
-#include "XPlane.h"
-
-#include <xplra/Protocol.h>
-
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-#include <cstdio>
-
-//------------------------------------------------------------------------------
-
-using hu::varadiistvan::xplra::MultiGetter;
-
-using xplra::Protocol;
-
-using std::vector;
-using std::min;
-
-//------------------------------------------------------------------------------
-
-MultiGetter::MultiGetter(XPlane& xplane) throw() :
-    MultiBuffer(xplane, Protocol::COMMAND_REGISTER_GET_MULTI,
-                Protocol::COMMAND_UNREGISTER_GET_MULTI)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline void MultiGetter::read(const DataRef& dataRef) throw(Exception)
-{
-    switch (dataRef.type) {
-      case Protocol::TYPE_INT:
-        *reinterpret_cast<int32_t*>(data + dataRef.dataOffset) =
-            xplane.stream->readS32();
-        break;
-      case Protocol::TYPE_FLOAT:
-        *reinterpret_cast<float*>(data + dataRef.dataOffset) =
-            xplane.stream->readFloat();
-        break;
-      case Protocol::TYPE_DOUBLE:
-        *reinterpret_cast<double*>(data + dataRef.dataOffset) =
-            xplane.stream->readDouble();
-        break;
-      case Protocol::TYPE_FLOAT_ARRAY:
-      case Protocol::TYPE_INT_ARRAY:
-      case Protocol::TYPE_BYTE_ARRAY:
-      {
-          size_t length = xplane.stream->readS32();
-          xplane.checkStream();
-          length = min(length, dataRef.length);
-          size_t elementSize =
-              (dataRef.type==Protocol::TYPE_FLOAT_ARRAY) ? sizeof(float) :
-              ((dataRef.type==Protocol::TYPE_INT_ARRAY) ?
-               sizeof(int32_t) : sizeof(uint8_t));
-          xplane.stream->read(data + dataRef.dataOffset, length * elementSize);
-      }
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiGetter::doExecute() throw(Exception)
-{
-    xplane.checkStream();
-    xplane.stream->writeU8(Protocol::COMMAND_EXECUTE_GET_MULTI);
-    xplane.stream->writeU32(registeredID);
-    xplane.stream->flush();
-    xplane.checkResult(true);
-
-    readValues();
-}
-
-
-//------------------------------------------------------------------------------
-
-void MultiGetter::doExecuteUnregistered() throw(Exception)
-{
-    writeSpec(Protocol::COMMAND_GET_MULTI);
-
-    readValues();
-}
-
-//------------------------------------------------------------------------------
-
-void MultiGetter::readValues() throw(Exception)
-{
-    for(vector<DataRef>::const_iterator i = dataRefs.begin();
-        i!=dataRefs.end(); ++i)
-    {
-        xplane.checkStream();
-        const DataRef& dataRef = *i;
-        read(dataRef);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiGetter.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiGetter.h	(revision 33)
+++ src/client/c/hu/varadiistvan/xplra/MultiGetter.h	(revision 33)
@@ -0,0 +1,89 @@
+// 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.
+
+#ifndef HU_VARADIISTVAN_XPLRA_MULTIGETTER_H
+#define HU_VARADIISTVAN_XPLRA_MULTIGETTER_H
+//------------------------------------------------------------------------------
+
+#include "MultiBuffer.h"
+
+//------------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A multi-dataref buffer used to query those data.
+ */
+class MultiGetter : public MultiBuffer
+{
+private:
+    /**
+     * Construct the object for the given XPlane instance.
+     */
+    MultiGetter(XPlane& xplane) throw();
+
+protected:
+    /**
+     * @see MultiBuffer::doExecute
+     */
+    virtual void doExecute() throw(Exception);
+
+    /**
+     * @see MultiBuffer::doExecuteUnregistered
+     */
+    virtual void doExecuteUnregistered() throw(Exception);
+
+private:
+    /**
+     * Read the value of the given dataref from the stream into the
+     * buffer.
+     */
+    void read(const DataRef& dataRef) throw(Exception);
+
+    /**
+     * Read all the values.
+     */
+    void readValues() throw(Exception);
+
+    friend class XPlane;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
+
+//------------------------------------------------------------------------------
+#endif // HU_VARADIISTVAN_XPLRA_MULTIGETTER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiGetter.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiGetter.h	(revision 33)
+++ 	(revision )
@@ -1,89 +1,0 @@
-// 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.
-
-#ifndef HU_VARADIISTVAN_XPLRA_MULTIGETTER_H
-#define HU_VARADIISTVAN_XPLRA_MULTIGETTER_H
-//------------------------------------------------------------------------------
-
-#include "MultiBuffer.h"
-
-//------------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A multi-dataref buffer used to query those data.
- */
-class MultiGetter : public MultiBuffer
-{
-private:
-    /**
-     * Construct the object for the given XPlane instance.
-     */
-    MultiGetter(XPlane& xplane) throw();
-
-protected:
-    /**
-     * @see MultiBuffer::doExecute
-     */
-    virtual void doExecute() throw(Exception);
-
-    /**
-     * @see MultiBuffer::doExecuteUnregistered
-     */
-    virtual void doExecuteUnregistered() throw(Exception);
-
-private:
-    /**
-     * Read the value of the given dataref from the stream into the
-     * buffer.
-     */
-    void read(const DataRef& dataRef) throw(Exception);
-
-    /**
-     * Read all the values.
-     */
-    void readValues() throw(Exception);
-
-    friend class XPlane;
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
-
-//------------------------------------------------------------------------------
-#endif // HU_VARADIISTVAN_XPLRA_MULTIGETTER_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiSetter.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiSetter.cc	(revision 40)
+++ src/client/c/hu/varadiistvan/xplra/MultiSetter.cc	(revision 40)
@@ -0,0 +1,132 @@
+// 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 "MultiSetter.h"
+
+#include "XPlane.h"
+
+#include <xplra/Protocol.h>
+
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+//------------------------------------------------------------------------------
+
+using hu::varadiistvan::xplra::MultiSetter;
+
+using xplra::Protocol;
+
+using std::vector;
+using std::min;
+
+//------------------------------------------------------------------------------
+
+MultiSetter::MultiSetter(XPlane& xplane) throw() :
+    MultiBuffer(xplane, Protocol::COMMAND_REGISTER_SET_MULTI,
+                Protocol::COMMAND_UNREGISTER_SET_MULTI)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline void MultiSetter::write(const DataRef& dataRef) const throw(Exception)
+{
+    switch (dataRef.type) {
+      case Protocol::TYPE_INT:
+        xplane.stream->writeS32(*reinterpret_cast<const int32_t*>
+                                (data + dataRef.dataOffset));
+        break;
+      case Protocol::TYPE_FLOAT:
+        xplane.stream->writeFloat(*reinterpret_cast<const float*>
+                                (data + dataRef.dataOffset));
+        break;
+      case Protocol::TYPE_DOUBLE:
+        xplane.stream->writeDouble(*reinterpret_cast<const double*>
+                                   (data + dataRef.dataOffset));
+        break;
+      case Protocol::TYPE_FLOAT_ARRAY:
+      case Protocol::TYPE_INT_ARRAY:
+      case Protocol::TYPE_BYTE_ARRAY:
+      {
+          size_t elementSize =
+              (dataRef.type==Protocol::TYPE_FLOAT_ARRAY) ? sizeof(float) :
+              ((dataRef.type==Protocol::TYPE_INT_ARRAY) ?
+               sizeof(int32_t) : sizeof(uint8_t));
+          xplane.stream->write(data + dataRef.dataOffset,
+                               dataRef.length * elementSize);
+      }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiSetter::doExecute() throw(Exception)
+{
+    xplane.checkStream();
+    xplane.stream->writeU8(Protocol::COMMAND_EXECUTE_SET_MULTI);
+    xplane.stream->writeU32(registeredID);
+    for(vector<DataRef>::const_iterator i = dataRefs.begin();
+        i!=dataRefs.end(); ++i)
+    {
+        const DataRef& dataRef = *i;
+        write(dataRef);
+    }
+    xplane.stream->flush();
+    xplane.checkResult(true);
+}
+
+//------------------------------------------------------------------------------
+
+void MultiSetter::doExecuteUnregistered() throw(Exception)
+{
+    xplane.stream->writeU8(Protocol::COMMAND_SET_MULTI);
+    xplane.stream->writeU32(dataRefs.size());
+    for(vector<DataRef>::const_iterator i = dataRefs.begin();
+        i!=dataRefs.end(); ++i)
+    {
+        const DataRef& dataRef = *i;
+        xplane.stream->writeString(dataRef.name);
+        xplane.stream->writeU8(dataRef.type);
+        if (dataRef.isArray()) {
+            xplane.stream->writeS32(dataRef.length);
+            xplane.stream->writeS32(dataRef.offset);
+        }
+        write(dataRef);
+    }
+    xplane.stream->flush();
+    xplane.checkResult(true);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiSetter.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiSetter.cc	(revision 40)
+++ 	(revision )
@@ -1,132 +1,0 @@
-// 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 "MultiSetter.h"
-
-#include "XPlane.h"
-
-#include <xplra/Protocol.h>
-
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-//------------------------------------------------------------------------------
-
-using hu::varadiistvan::xplra::MultiSetter;
-
-using xplra::Protocol;
-
-using std::vector;
-using std::min;
-
-//------------------------------------------------------------------------------
-
-MultiSetter::MultiSetter(XPlane& xplane) throw() :
-    MultiBuffer(xplane, Protocol::COMMAND_REGISTER_SET_MULTI,
-                Protocol::COMMAND_UNREGISTER_SET_MULTI)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline void MultiSetter::write(const DataRef& dataRef) const throw(Exception)
-{
-    switch (dataRef.type) {
-      case Protocol::TYPE_INT:
-        xplane.stream->writeS32(*reinterpret_cast<const int32_t*>
-                                (data + dataRef.dataOffset));
-        break;
-      case Protocol::TYPE_FLOAT:
-        xplane.stream->writeFloat(*reinterpret_cast<const float*>
-                                (data + dataRef.dataOffset));
-        break;
-      case Protocol::TYPE_DOUBLE:
-        xplane.stream->writeDouble(*reinterpret_cast<const double*>
-                                   (data + dataRef.dataOffset));
-        break;
-      case Protocol::TYPE_FLOAT_ARRAY:
-      case Protocol::TYPE_INT_ARRAY:
-      case Protocol::TYPE_BYTE_ARRAY:
-      {
-          size_t elementSize =
-              (dataRef.type==Protocol::TYPE_FLOAT_ARRAY) ? sizeof(float) :
-              ((dataRef.type==Protocol::TYPE_INT_ARRAY) ?
-               sizeof(int32_t) : sizeof(uint8_t));
-          xplane.stream->write(data + dataRef.dataOffset,
-                               dataRef.length * elementSize);
-      }
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiSetter::doExecute() throw(Exception)
-{
-    xplane.checkStream();
-    xplane.stream->writeU8(Protocol::COMMAND_EXECUTE_SET_MULTI);
-    xplane.stream->writeU32(registeredID);
-    for(vector<DataRef>::const_iterator i = dataRefs.begin();
-        i!=dataRefs.end(); ++i)
-    {
-        const DataRef& dataRef = *i;
-        write(dataRef);
-    }
-    xplane.stream->flush();
-    xplane.checkResult(true);
-}
-
-//------------------------------------------------------------------------------
-
-void MultiSetter::doExecuteUnregistered() throw(Exception)
-{
-    xplane.stream->writeU8(Protocol::COMMAND_SET_MULTI);
-    xplane.stream->writeU32(dataRefs.size());
-    for(vector<DataRef>::const_iterator i = dataRefs.begin();
-        i!=dataRefs.end(); ++i)
-    {
-        const DataRef& dataRef = *i;
-        xplane.stream->writeString(dataRef.name);
-        xplane.stream->writeU8(dataRef.type);
-        if (dataRef.isArray()) {
-            xplane.stream->writeS32(dataRef.length);
-            xplane.stream->writeS32(dataRef.offset);
-        }
-        write(dataRef);
-    }
-    xplane.stream->flush();
-    xplane.checkResult(true);
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiSetter.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiSetter.h	(revision 26)
+++ src/client/c/hu/varadiistvan/xplra/MultiSetter.h	(revision 26)
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef HU_VARADIISTVAN_XPLRA_MULTISETTER_H
+#define HU_VARADIISTVAN_XPLRA_MULTISETTER_H
+//------------------------------------------------------------------------------
+
+#include "MultiBuffer.h"
+
+//------------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A multi-dataref buffer used to set those data.
+ */
+class MultiSetter : public MultiBuffer
+{
+private:
+    /**
+     * Construct the object for the given XPlane instance.
+     */
+    MultiSetter(XPlane& xplane) throw();
+
+protected:
+    /**
+     * @see MultiBuffer::doExecute
+     */
+    virtual void doExecute() throw(Exception);
+
+    /**
+     * @see MultiBuffer::doExecuteUnregistered
+     */
+    virtual void doExecuteUnregistered() throw(Exception);
+
+private:
+    /**
+     * Write the value of the given dataref from the buffer into the
+     * stream.
+     */
+    void write(const DataRef& dataRef) const throw(Exception);
+
+    friend class XPlane;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
+
+//------------------------------------------------------------------------------
+#endif // HU_VARADIISTVAN_XPLRA_MULTISETTER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/MultiSetter.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/MultiSetter.h	(revision 26)
+++ 	(revision )
@@ -1,84 +1,0 @@
-// 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.
-
-#ifndef HU_VARADIISTVAN_XPLRA_MULTISETTER_H
-#define HU_VARADIISTVAN_XPLRA_MULTISETTER_H
-//------------------------------------------------------------------------------
-
-#include "MultiBuffer.h"
-
-//------------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A multi-dataref buffer used to set those data.
- */
-class MultiSetter : public MultiBuffer
-{
-private:
-    /**
-     * Construct the object for the given XPlane instance.
-     */
-    MultiSetter(XPlane& xplane) throw();
-
-protected:
-    /**
-     * @see MultiBuffer::doExecute
-     */
-    virtual void doExecute() throw(Exception);
-
-    /**
-     * @see MultiBuffer::doExecuteUnregistered
-     */
-    virtual void doExecuteUnregistered() throw(Exception);
-
-private:
-    /**
-     * Write the value of the given dataref from the buffer into the
-     * stream.
-     */
-    void write(const DataRef& dataRef) const throw(Exception);
-
-    friend class XPlane;
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
-
-//------------------------------------------------------------------------------
-#endif // HU_VARADIISTVAN_XPLRA_MULTISETTER_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/XPlane.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/XPlane.cc	(revision 57)
+++ src/client/c/hu/varadiistvan/xplra/XPlane.cc	(revision 57)
@@ -0,0 +1,557 @@
+// 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 "XPlane.h"
+
+#include "MultiGetter.h"
+#include "MultiSetter.h"
+
+#include <hu/varadiistvan/scpl/io/LocalClientSocket.h>
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+#include <xplra/Protocol.h>
+
+#include <memory>
+
+#ifndef _WIN32
+#include <signal.h>
+#endif
+
+//------------------------------------------------------------------------------
+
+using hu::varadiistvan::xplra::XPlane;
+using hu::varadiistvan::xplra::MultiGetter;
+using hu::varadiistvan::xplra::MultiSetter;
+
+using hu::varadiistvan::scpl::io::LocalClientSocket;
+using hu::varadiistvan::scpl::io::LocalConnector;
+using hu::varadiistvan::scpl::io::DataStream;
+
+using xplra::Protocol;
+
+using std::auto_ptr;
+using std::string;
+using std::min;
+
+//------------------------------------------------------------------------------
+
+void XPlane::checkStream() throw(NotConnectedException, IOException)
+{
+    if (stream==0) {
+        throw NotConnectedException();
+    } else if (stream->failed()) {
+        throw IOException(stream->getErrorCode());
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::checkResult(uint8_t result, bool hasParameter, long parameter)
+    throw(ProtocolException)
+{
+    switch(result) {
+      case Protocol::RESULT_OK:
+        return;
+      case Protocol::RESULT_INVALID_COMMAND:
+        throw ProtocolException(ProtocolException::INVALID_COMMAND,
+                                hasParameter, parameter);
+      case Protocol::RESULT_UNKNOWN_DATAREF:
+        throw ProtocolException(ProtocolException::UNKNOWN_DATAREF,
+                                hasParameter, parameter);
+      case Protocol::RESULT_INVALID_TYPE:
+        throw ProtocolException(ProtocolException::INVALID_TYPE,
+                                hasParameter, parameter);
+      case Protocol::RESULT_INVALID_LENGTH:
+        throw ProtocolException(ProtocolException::INVALID_LENGTH,
+                                hasParameter, parameter);
+      case Protocol::RESULT_INVALID_OFFSET:
+        throw ProtocolException(ProtocolException::INVALID_OFFSET,
+                                hasParameter, parameter);
+      case Protocol::RESULT_INVALID_COUNT:
+        throw ProtocolException(ProtocolException::INVALID_COUNT,
+                                hasParameter, parameter);
+      case Protocol::RESULT_INVALID_ID:
+        throw ProtocolException(ProtocolException::INVALID_ID,
+                                hasParameter, parameter);
+      case Protocol::RESULT_INVALID_DURATION:
+        throw ProtocolException(ProtocolException::INVALID_DURATION,
+                                hasParameter, parameter);
+      case Protocol::RESULT_OTHER_ERROR:
+      default:
+        throw ProtocolException(ProtocolException::OTHER,
+                                hasParameter, parameter);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::checkResult(bool multi) throw(ProtocolException, IOException)
+{
+    uint8_t result = stream->readU8();
+    bool hasParameter = false;
+    long parameter = 0;
+    if (multi) {
+        if (result==Protocol::RESULT_UNKNOWN_DATAREF) {
+            parameter = stream->readU32();
+            hasParameter = true;
+        }
+    }
+    checkStream();
+    checkResult(result, hasParameter, parameter);
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+XPlane::~XPlane() throw()
+{
+    disconnect();
+    for(multiBuffers_t::iterator i = multiBuffers.begin();
+        i!=multiBuffers.end(); ++i)
+    {
+        MultiBuffer* buffer = *i;
+        buffer->forgetRegistration();
+        delete buffer;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::connect() throw(IOException)
+{
+    if (socket!=0) return;
+
+    auto_ptr<LocalClientSocket> clientSocket(new LocalClientSocket("xplra",
+                                                                   &waiter));
+    LocalConnector& connector = clientSocket->getConnector();
+
+    while (!connector.connect()) {
+        if (connector.failed()) {
+            throw IOException(connector.getErrorCode());
+        }
+        waiter.wait();
+        if (waiter.failed()) {
+            throw IOException(waiter.getErrorCode());
+        }
+    }
+
+#ifndef _WIN32
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
+    socket = clientSocket.release();
+    stream = new DataStream(*socket);
+
+    for(multiBuffers_t::iterator i = multiBuffers.begin();
+        i!=multiBuffers.end(); ++i)
+    {
+        MultiBuffer* buffer = *i;
+        buffer->reregisterInXPlane();
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::disconnect() throw()
+{
+    if (socket==0) return;
+
+    delete stream; stream = 0;
+    delete socket; socket = 0;
+}
+
+//------------------------------------------------------------------------------
+
+MultiGetter& XPlane::createMultiGetter() throw()
+{
+    MultiGetter* getter = new MultiGetter(*this);
+    multiBuffers.insert(getter);
+    return *getter;
+}
+
+//------------------------------------------------------------------------------
+
+MultiSetter& XPlane::createMultiSetter() throw()
+{
+    MultiSetter* setter = new MultiSetter(*this);
+    multiBuffers.insert(setter);
+    return *setter;
+}
+
+//------------------------------------------------------------------------------
+
+bool XPlane::destroyMultiBuffer(MultiBuffer& buffer) throw(Exception)
+{
+    multiBuffers_t::iterator i = multiBuffers.find(&buffer);
+    if (i==multiBuffers.end()) return false;
+
+    multiBuffers.erase(i);
+    delete &buffer;
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::getVersions(int& xplaneVersion, int& xplmVersion, int& xplraVersion)
+    throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_GET_VERSIONS);
+    stream->flush();
+    checkResult();
+
+    xplaneVersion = stream->readS32();
+    xplmVersion = stream->readS32();
+    xplraVersion = stream->readS32();
+
+    checkStream();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::reloadPlugins() throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_RELOAD_PLUGINS);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::getScalar(const char* name, uint8_t type) throw(Exception)
+{
+    checkStream();
+
+    stream->writeU8(Protocol::COMMAND_GET_SINGLE);
+    stream->writeString(name, strlen(name));
+    stream->writeU8(type);
+    if (!stream->flush()) checkStream();
+
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+int XPlane::getInt(const char* name) throw(Exception)
+{
+    getScalar(name, Protocol::TYPE_INT);
+
+    int value = stream->readS32();
+    checkStream();
+    return value;
+}
+
+//------------------------------------------------------------------------------
+
+float XPlane::getFloat(const char* name) throw(Exception)
+{
+    getScalar(name, Protocol::TYPE_FLOAT);
+
+    float value = stream->readFloat();
+    checkStream();
+    return value;
+}
+
+//------------------------------------------------------------------------------
+
+double XPlane::getDouble(const char* name) throw(Exception)
+{
+    getScalar(name, Protocol::TYPE_DOUBLE);
+
+    double value = stream->readDouble();
+    checkStream();
+    return value;
+}
+
+//------------------------------------------------------------------------------
+
+size_t XPlane::getArray(const char* name, uint8_t type,
+                        ssize_t length, size_t offset) throw(Exception)
+{
+    checkStream();
+
+    stream->writeU8(Protocol::COMMAND_GET_SINGLE);
+    stream->writeString(name, strlen(name));
+    stream->writeU8(type);
+    stream->writeS32(static_cast<int32_t>(length));
+    stream->writeS32(static_cast<int32_t>(offset));
+    if (!stream->flush()) checkStream();
+
+    uint8_t result = stream->readU8();
+    length = stream->readS32();
+    checkStream();
+    checkResult(result);
+
+    return length;
+}
+
+//------------------------------------------------------------------------------
+
+size_t XPlane::getFloatArray(const char* name, float* dest,
+                             size_t length, size_t offset) throw(Exception)
+{
+    length = getArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
+
+    if (!stream->read(dest, length*sizeof(float))) checkStream();
+
+    return length;
+}
+
+//------------------------------------------------------------------------------
+
+float* XPlane::getFloatArray(const char* name, size_t& length,
+                             size_t offset) throw(Exception)
+{
+    length = getArray(name, Protocol::TYPE_FLOAT_ARRAY, -1, offset);
+
+    auto_ptr<float> data(new float[length]);
+    if (!stream->read(data.get(), length*sizeof(float))) checkStream();
+    return data.release();
+}
+
+//------------------------------------------------------------------------------
+
+size_t XPlane::getIntArray(const char* name, int32_t* dest,
+                           size_t length, size_t offset) throw(Exception)
+{
+    length = getArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
+
+    if (!stream->read(dest, length*sizeof(int32_t))) checkStream();
+
+    return length;
+}
+
+//------------------------------------------------------------------------------
+
+int32_t* XPlane::getIntArray(const char* name, size_t& length,
+                             size_t offset) throw(Exception)
+{
+    length = getArray(name, Protocol::TYPE_INT_ARRAY, -1, offset);
+
+    auto_ptr<int32_t> data(new int32_t[length]);
+    if (!stream->read(data.get(), length*sizeof(int32_t))) checkStream();
+    return data.release();
+}
+
+//------------------------------------------------------------------------------
+
+size_t XPlane::getByteArray(const char* name, uint8_t* dest,
+                            size_t length, size_t offset) throw(Exception)
+{
+    length = getArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
+
+    if (!stream->read(dest, length*sizeof(uint8_t))) checkStream();
+
+    return length;
+}
+
+//------------------------------------------------------------------------------
+
+uint8_t* XPlane::getByteArray(const char* name, size_t& length,
+                              size_t offset) throw(Exception)
+{
+    length = getArray(name, Protocol::TYPE_BYTE_ARRAY, -1, offset);
+
+    auto_ptr<uint8_t> data(new uint8_t[length]);
+    if (!stream->read(data.get(), length*sizeof(uint8_t))) checkStream();
+    return data.release();
+}
+
+//------------------------------------------------------------------------------
+
+string XPlane::getString(const char* name, size_t offset) throw(Exception)
+{
+    size_t length = 0;
+    auto_ptr<uint8_t> data(getByteArray(name, length, offset));
+    return string(reinterpret_cast<char*>(data.get()));
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setScalar(const char* name, uint8_t type) throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_SET_SINGLE);
+    stream->writeString(name, strlen(name));
+    stream->writeU8(type);
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setInt(const char* name, int value) throw(Exception)
+{
+    setScalar(name, Protocol::TYPE_INT);
+    stream->writeS32(value);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setFloat(const char* name, float value) throw(Exception)
+{
+    setScalar(name, Protocol::TYPE_FLOAT);
+    stream->writeFloat(value);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setDouble(const char* name, double value) throw(Exception)
+{
+    setScalar(name, Protocol::TYPE_DOUBLE);
+    stream->writeDouble(value);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setArray(const char* name, uint8_t type, size_t length,
+                      size_t offset) throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_SET_SINGLE);
+    stream->writeString(name, strlen(name));
+    stream->writeU8(type);
+    stream->writeS32(static_cast<int32_t>(length));
+    stream->writeS32(static_cast<int32_t>(offset));
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setFloatArray(const char* name, const float* values, size_t length,
+                           size_t offset) throw(Exception)
+{
+    setArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
+    stream->write(values, length*sizeof(*values));
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setIntArray(const char* name, const int32_t* values, size_t length,
+                         size_t offset) throw(Exception)
+{
+    setArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
+    stream->write(values, length*sizeof(*values));
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setByteArray(const char* name, const uint8_t* values, size_t length,
+                          size_t offset) throw(Exception)
+{
+    setArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
+    stream->write(values, length*sizeof(*values));
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::setString(const char* name, const char* value, size_t length,
+                       size_t offset) throw(Exception)
+{
+    size_t valueLength = strlen(value);
+    if ((valueLength+1)>=length) {
+        setByteArray(name, reinterpret_cast<const uint8_t*>(value),
+                     length, offset);
+    } else {
+        auto_ptr<uint8_t> buffer(new uint8_t[length]);
+        memcpy(buffer.get(), value, valueLength);
+        memset(buffer.get() + valueLength, 0, length - valueLength);
+        setByteArray(name, buffer.get(), length, offset);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::showMessage(const char* message, float duration) throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_SHOW_MESSAGE);
+    stream->writeString(message);
+    stream->writeFloat(duration);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::registerHotkeys(const uint16_t* codes, size_t length)
+    throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_REGISTER_HOTKEYS);
+    stream->writeU32(length);
+    stream->write(codes, sizeof(uint16_t)*length);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::queryHotkeys(uint8_t* states, size_t length) throw(Exception)
+{
+    stream->writeU8(Protocol::COMMAND_QUERY_HOTKEYS);
+    stream->flush();
+    checkResult();
+
+    size_t count = stream->readU32();
+    checkStream();
+    stream->read(states, min(length, count));
+    if (length<count) {
+        while(length<count) {
+            stream->readU8();
+            ++length;
+        }
+    } else if (length>count) {
+        memset(states + count, 0, length - count);
+    }
+    checkStream();
+}
+
+//------------------------------------------------------------------------------
+
+void XPlane::unregisterHotkeys()
+{
+    stream->writeU8(Protocol::COMMAND_UNREGISTER_HOTKEYS);
+    stream->flush();
+    checkResult();
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/XPlane.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/XPlane.cc	(revision 57)
+++ 	(revision )
@@ -1,557 +1,0 @@
-// 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 "XPlane.h"
-
-#include "MultiGetter.h"
-#include "MultiSetter.h"
-
-#include <hu/varadiistvan/scpl/io/LocalClientSocket.h>
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-#include <xplra/Protocol.h>
-
-#include <memory>
-
-#ifndef _WIN32
-#include <signal.h>
-#endif
-
-//------------------------------------------------------------------------------
-
-using hu::varadiistvan::xplra::XPlane;
-using hu::varadiistvan::xplra::MultiGetter;
-using hu::varadiistvan::xplra::MultiSetter;
-
-using hu::varadiistvan::scpl::io::LocalClientSocket;
-using hu::varadiistvan::scpl::io::LocalConnector;
-using hu::varadiistvan::scpl::io::DataStream;
-
-using xplra::Protocol;
-
-using std::auto_ptr;
-using std::string;
-using std::min;
-
-//------------------------------------------------------------------------------
-
-void XPlane::checkStream() throw(NotConnectedException, IOException)
-{
-    if (stream==0) {
-        throw NotConnectedException();
-    } else if (stream->failed()) {
-        throw IOException(stream->getErrorCode());
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::checkResult(uint8_t result, bool hasParameter, long parameter)
-    throw(ProtocolException)
-{
-    switch(result) {
-      case Protocol::RESULT_OK:
-        return;
-      case Protocol::RESULT_INVALID_COMMAND:
-        throw ProtocolException(ProtocolException::INVALID_COMMAND,
-                                hasParameter, parameter);
-      case Protocol::RESULT_UNKNOWN_DATAREF:
-        throw ProtocolException(ProtocolException::UNKNOWN_DATAREF,
-                                hasParameter, parameter);
-      case Protocol::RESULT_INVALID_TYPE:
-        throw ProtocolException(ProtocolException::INVALID_TYPE,
-                                hasParameter, parameter);
-      case Protocol::RESULT_INVALID_LENGTH:
-        throw ProtocolException(ProtocolException::INVALID_LENGTH,
-                                hasParameter, parameter);
-      case Protocol::RESULT_INVALID_OFFSET:
-        throw ProtocolException(ProtocolException::INVALID_OFFSET,
-                                hasParameter, parameter);
-      case Protocol::RESULT_INVALID_COUNT:
-        throw ProtocolException(ProtocolException::INVALID_COUNT,
-                                hasParameter, parameter);
-      case Protocol::RESULT_INVALID_ID:
-        throw ProtocolException(ProtocolException::INVALID_ID,
-                                hasParameter, parameter);
-      case Protocol::RESULT_INVALID_DURATION:
-        throw ProtocolException(ProtocolException::INVALID_DURATION,
-                                hasParameter, parameter);
-      case Protocol::RESULT_OTHER_ERROR:
-      default:
-        throw ProtocolException(ProtocolException::OTHER,
-                                hasParameter, parameter);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::checkResult(bool multi) throw(ProtocolException, IOException)
-{
-    uint8_t result = stream->readU8();
-    bool hasParameter = false;
-    long parameter = 0;
-    if (multi) {
-        if (result==Protocol::RESULT_UNKNOWN_DATAREF) {
-            parameter = stream->readU32();
-            hasParameter = true;
-        }
-    }
-    checkStream();
-    checkResult(result, hasParameter, parameter);
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-XPlane::~XPlane() throw()
-{
-    disconnect();
-    for(multiBuffers_t::iterator i = multiBuffers.begin();
-        i!=multiBuffers.end(); ++i)
-    {
-        MultiBuffer* buffer = *i;
-        buffer->forgetRegistration();
-        delete buffer;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::connect() throw(IOException)
-{
-    if (socket!=0) return;
-
-    auto_ptr<LocalClientSocket> clientSocket(new LocalClientSocket("xplra",
-                                                                   &waiter));
-    LocalConnector& connector = clientSocket->getConnector();
-
-    while (!connector.connect()) {
-        if (connector.failed()) {
-            throw IOException(connector.getErrorCode());
-        }
-        waiter.wait();
-        if (waiter.failed()) {
-            throw IOException(waiter.getErrorCode());
-        }
-    }
-
-#ifndef _WIN32
-    signal(SIGPIPE, SIG_IGN);
-#endif
-
-    socket = clientSocket.release();
-    stream = new DataStream(*socket);
-
-    for(multiBuffers_t::iterator i = multiBuffers.begin();
-        i!=multiBuffers.end(); ++i)
-    {
-        MultiBuffer* buffer = *i;
-        buffer->reregisterInXPlane();
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::disconnect() throw()
-{
-    if (socket==0) return;
-
-    delete stream; stream = 0;
-    delete socket; socket = 0;
-}
-
-//------------------------------------------------------------------------------
-
-MultiGetter& XPlane::createMultiGetter() throw()
-{
-    MultiGetter* getter = new MultiGetter(*this);
-    multiBuffers.insert(getter);
-    return *getter;
-}
-
-//------------------------------------------------------------------------------
-
-MultiSetter& XPlane::createMultiSetter() throw()
-{
-    MultiSetter* setter = new MultiSetter(*this);
-    multiBuffers.insert(setter);
-    return *setter;
-}
-
-//------------------------------------------------------------------------------
-
-bool XPlane::destroyMultiBuffer(MultiBuffer& buffer) throw(Exception)
-{
-    multiBuffers_t::iterator i = multiBuffers.find(&buffer);
-    if (i==multiBuffers.end()) return false;
-
-    multiBuffers.erase(i);
-    delete &buffer;
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::getVersions(int& xplaneVersion, int& xplmVersion, int& xplraVersion)
-    throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_GET_VERSIONS);
-    stream->flush();
-    checkResult();
-
-    xplaneVersion = stream->readS32();
-    xplmVersion = stream->readS32();
-    xplraVersion = stream->readS32();
-
-    checkStream();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::reloadPlugins() throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_RELOAD_PLUGINS);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::getScalar(const char* name, uint8_t type) throw(Exception)
-{
-    checkStream();
-
-    stream->writeU8(Protocol::COMMAND_GET_SINGLE);
-    stream->writeString(name, strlen(name));
-    stream->writeU8(type);
-    if (!stream->flush()) checkStream();
-
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-int XPlane::getInt(const char* name) throw(Exception)
-{
-    getScalar(name, Protocol::TYPE_INT);
-
-    int value = stream->readS32();
-    checkStream();
-    return value;
-}
-
-//------------------------------------------------------------------------------
-
-float XPlane::getFloat(const char* name) throw(Exception)
-{
-    getScalar(name, Protocol::TYPE_FLOAT);
-
-    float value = stream->readFloat();
-    checkStream();
-    return value;
-}
-
-//------------------------------------------------------------------------------
-
-double XPlane::getDouble(const char* name) throw(Exception)
-{
-    getScalar(name, Protocol::TYPE_DOUBLE);
-
-    double value = stream->readDouble();
-    checkStream();
-    return value;
-}
-
-//------------------------------------------------------------------------------
-
-size_t XPlane::getArray(const char* name, uint8_t type,
-                        ssize_t length, size_t offset) throw(Exception)
-{
-    checkStream();
-
-    stream->writeU8(Protocol::COMMAND_GET_SINGLE);
-    stream->writeString(name, strlen(name));
-    stream->writeU8(type);
-    stream->writeS32(static_cast<int32_t>(length));
-    stream->writeS32(static_cast<int32_t>(offset));
-    if (!stream->flush()) checkStream();
-
-    uint8_t result = stream->readU8();
-    length = stream->readS32();
-    checkStream();
-    checkResult(result);
-
-    return length;
-}
-
-//------------------------------------------------------------------------------
-
-size_t XPlane::getFloatArray(const char* name, float* dest,
-                             size_t length, size_t offset) throw(Exception)
-{
-    length = getArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
-
-    if (!stream->read(dest, length*sizeof(float))) checkStream();
-
-    return length;
-}
-
-//------------------------------------------------------------------------------
-
-float* XPlane::getFloatArray(const char* name, size_t& length,
-                             size_t offset) throw(Exception)
-{
-    length = getArray(name, Protocol::TYPE_FLOAT_ARRAY, -1, offset);
-
-    auto_ptr<float> data(new float[length]);
-    if (!stream->read(data.get(), length*sizeof(float))) checkStream();
-    return data.release();
-}
-
-//------------------------------------------------------------------------------
-
-size_t XPlane::getIntArray(const char* name, int32_t* dest,
-                           size_t length, size_t offset) throw(Exception)
-{
-    length = getArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
-
-    if (!stream->read(dest, length*sizeof(int32_t))) checkStream();
-
-    return length;
-}
-
-//------------------------------------------------------------------------------
-
-int32_t* XPlane::getIntArray(const char* name, size_t& length,
-                             size_t offset) throw(Exception)
-{
-    length = getArray(name, Protocol::TYPE_INT_ARRAY, -1, offset);
-
-    auto_ptr<int32_t> data(new int32_t[length]);
-    if (!stream->read(data.get(), length*sizeof(int32_t))) checkStream();
-    return data.release();
-}
-
-//------------------------------------------------------------------------------
-
-size_t XPlane::getByteArray(const char* name, uint8_t* dest,
-                            size_t length, size_t offset) throw(Exception)
-{
-    length = getArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
-
-    if (!stream->read(dest, length*sizeof(uint8_t))) checkStream();
-
-    return length;
-}
-
-//------------------------------------------------------------------------------
-
-uint8_t* XPlane::getByteArray(const char* name, size_t& length,
-                              size_t offset) throw(Exception)
-{
-    length = getArray(name, Protocol::TYPE_BYTE_ARRAY, -1, offset);
-
-    auto_ptr<uint8_t> data(new uint8_t[length]);
-    if (!stream->read(data.get(), length*sizeof(uint8_t))) checkStream();
-    return data.release();
-}
-
-//------------------------------------------------------------------------------
-
-string XPlane::getString(const char* name, size_t offset) throw(Exception)
-{
-    size_t length = 0;
-    auto_ptr<uint8_t> data(getByteArray(name, length, offset));
-    return string(reinterpret_cast<char*>(data.get()));
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setScalar(const char* name, uint8_t type) throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_SET_SINGLE);
-    stream->writeString(name, strlen(name));
-    stream->writeU8(type);
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setInt(const char* name, int value) throw(Exception)
-{
-    setScalar(name, Protocol::TYPE_INT);
-    stream->writeS32(value);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setFloat(const char* name, float value) throw(Exception)
-{
-    setScalar(name, Protocol::TYPE_FLOAT);
-    stream->writeFloat(value);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setDouble(const char* name, double value) throw(Exception)
-{
-    setScalar(name, Protocol::TYPE_DOUBLE);
-    stream->writeDouble(value);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setArray(const char* name, uint8_t type, size_t length,
-                      size_t offset) throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_SET_SINGLE);
-    stream->writeString(name, strlen(name));
-    stream->writeU8(type);
-    stream->writeS32(static_cast<int32_t>(length));
-    stream->writeS32(static_cast<int32_t>(offset));
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setFloatArray(const char* name, const float* values, size_t length,
-                           size_t offset) throw(Exception)
-{
-    setArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
-    stream->write(values, length*sizeof(*values));
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setIntArray(const char* name, const int32_t* values, size_t length,
-                         size_t offset) throw(Exception)
-{
-    setArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
-    stream->write(values, length*sizeof(*values));
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setByteArray(const char* name, const uint8_t* values, size_t length,
-                          size_t offset) throw(Exception)
-{
-    setArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
-    stream->write(values, length*sizeof(*values));
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::setString(const char* name, const char* value, size_t length,
-                       size_t offset) throw(Exception)
-{
-    size_t valueLength = strlen(value);
-    if ((valueLength+1)>=length) {
-        setByteArray(name, reinterpret_cast<const uint8_t*>(value),
-                     length, offset);
-    } else {
-        auto_ptr<uint8_t> buffer(new uint8_t[length]);
-        memcpy(buffer.get(), value, valueLength);
-        memset(buffer.get() + valueLength, 0, length - valueLength);
-        setByteArray(name, buffer.get(), length, offset);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::showMessage(const char* message, float duration) throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_SHOW_MESSAGE);
-    stream->writeString(message);
-    stream->writeFloat(duration);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::registerHotkeys(const uint16_t* codes, size_t length)
-    throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_REGISTER_HOTKEYS);
-    stream->writeU32(length);
-    stream->write(codes, sizeof(uint16_t)*length);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::queryHotkeys(uint8_t* states, size_t length) throw(Exception)
-{
-    stream->writeU8(Protocol::COMMAND_QUERY_HOTKEYS);
-    stream->flush();
-    checkResult();
-
-    size_t count = stream->readU32();
-    checkStream();
-    stream->read(states, min(length, count));
-    if (length<count) {
-        while(length<count) {
-            stream->readU8();
-            ++length;
-        }
-    } else if (length>count) {
-        memset(states + count, 0, length - count);
-    }
-    checkStream();
-}
-
-//------------------------------------------------------------------------------
-
-void XPlane::unregisterHotkeys()
-{
-    stream->writeU8(Protocol::COMMAND_UNREGISTER_HOTKEYS);
-    stream->flush();
-    checkResult();
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/XPlane.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/XPlane.h	(revision 66)
+++ src/client/c/hu/varadiistvan/xplra/XPlane.h	(revision 66)
@@ -0,0 +1,393 @@
+// 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.
+
+#ifndef HU_VARADIISTVAN_XPLRA_XPLANE_H
+#define HU_VARADIISTVAN_XPLRA_XPLANE_H
+//-----------------------------------------------------------------------------
+
+#include "Exception.h"
+
+#include <hu/varadiistvan/scpl/io/Waiter.h>
+
+#include <set>
+
+#include <inttypes.h>
+
+//-----------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace scpl { namespace io {
+
+class LocalClientSocket;
+class DataStream;
+
+} /* namespace hu::varadiistvan::scpl::io */ } /* namespace hu::varadiistvan::scpl */ } /* namespace hu::varadiistvan */ } /* namespace hu */
+
+//------------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class MultiBuffer;
+class MultiGetter;
+class MultiSetter;
+
+//------------------------------------------------------------------------------
+
+/**
+ * The main class to access X-Plane.
+ *
+ * The calls are synchronous and not thread-safe.
+ */
+class XPlane
+{
+private:
+    /**
+     * Type for the set of multi-dataref buffers.
+     */
+    typedef std::set<MultiBuffer*> multiBuffers_t;
+
+    /**
+     * The waiter to use.
+     */
+    scpl::io::Waiter waiter;
+
+    /**
+     * The local client socket over which we are communicating with X-Plane.
+     */
+    scpl::io::LocalClientSocket* socket;
+
+    /**
+     * The data stream to handle the data conversions.
+     */
+    scpl::io::DataStream* stream;
+
+    /**
+     * The buffers created by this object.
+     */
+    multiBuffers_t multiBuffers;
+
+public:
+    /**
+     * Construct the object. It will not be connected to the simulator
+     * yet.
+     */
+    XPlane() throw();
+
+    /**
+     * Destroy the object. If connected, the connection will be
+     * closed. It destroys all existing buffers, so their references
+     * become invalid.
+     */
+    ~XPlane() throw();
+
+    /**
+     * Connect to the simulator.
+     */
+    void connect() throw(IOException);
+
+    /**
+     * Check if we are connected to the simulator.
+     */
+    bool isConnected() const throw();
+
+    /**
+     * Disconnect from the simulator.
+     */
+    void disconnect() throw();
+
+    /**
+     * Create a new getter of multiple datarefs and return a reference
+     * to it.
+     */
+    MultiGetter& createMultiGetter() throw();
+
+    /**
+     * Create a new setter of multiple datarefs and return a reference
+     * to it.
+     */
+    MultiSetter& createMultiSetter() throw();
+
+    /**
+     * Destroy the given getter or setter of multiple datarefs. As the
+     * buffer is unregistered, if it has been registered previously,
+     * and  unregistration may fail, this function might throw an
+     * exception.
+     *
+     * @return if the buffer was found and could be destroyed
+     */
+    bool destroyMultiBuffer(MultiBuffer& buffer) throw(Exception);
+
+    /**
+     * Get the versions of X-Plane, XPLM and the XPLRA plugin.
+     */
+    void getVersions(int& xplaneVersion, int& xplmVersion, int& xplraVersion) throw(Exception);
+
+    /**
+     * Reload the plugins loaded in X-Plane. After this the connection
+     * fails.
+     */
+    void reloadPlugins() throw(Exception);
+
+    /**
+     * Get the integer value of the dataref with the given name.
+     */
+    int getInt(const char* name) throw(Exception);
+
+    /**
+     * Get a float value.
+     */
+    float getFloat(const char* name) throw(Exception);
+
+    /**
+     * Get a double value.
+     */
+    double getDouble(const char* name) throw(Exception);
+
+    /**
+     * Get a possibly partial array of floats.
+     *
+     * @param name the name of the dataref
+     * @param dest the destination buffer
+     * @param length the length of the destination buffer
+     * @param offset the offset from which to get the array
+     *
+     * @return the number of values acquired actually
+     */
+    size_t getFloatArray(const char* name, float* dest,
+                         size_t length, size_t offset = 0) throw(Exception);
+
+    /**
+     * Get a possibly partial array of floats. The result array will
+     * be created with a length needed to hold the returned value.
+     *
+     * @param name the name of the dataref
+     * @param length will contain the number of floats read
+     * @param offset the offset from which to get the array
+     */
+    float* getFloatArray(const char* name, size_t& length,
+                         size_t offset = 0) throw(Exception);
+
+    /**
+     * Get a possibly partial array of integers.
+     *
+     * @param name the name of the dataref
+     * @param dest the destination buffer
+     * @param length the length of the destination buffer
+     * @param offset the offset from which to get the array
+     *
+     * @return the number of values acquired actually
+     */
+    size_t getIntArray(const char* name, int32_t* dest,
+                       size_t length, size_t offset = 0) throw(Exception);
+
+    /**
+     * Get a possibly partial array of integers. The result array will
+     * be created with a length needed to hold the returned value.
+     *
+     * @param name the name of the dataref
+     * @param length will contain the number of integers read
+     * @param offset the offset from which to get the array
+     */
+    int32_t* getIntArray(const char* name, size_t& length,
+                         size_t offset = 0) throw(Exception);
+
+    /**
+     * Get a possibly partial array of bytes.
+     *
+     * @param name the name of the dataref
+     * @param dest the destination buffer
+     * @param length the length of the destination buffer
+     * @param offset the offset from which to get the array
+     *
+     * @return the number of values acquired actually
+     */
+    size_t getByteArray(const char* name, uint8_t* dest,
+                        size_t length, size_t offset = 0) throw(Exception);
+
+    /**
+     * Get a possibly partial array of bytes. The result array will
+     * be created with a length needed to hold the returned value.
+     *
+     * @param name the name of the dataref
+     * @param length will contain the number of bytes read on return
+     * @param offset the offset from which to get the array
+     */
+    uint8_t* getByteArray(const char* name, size_t& length,
+                          size_t offset = 0) throw(Exception);
+
+    /**
+     * Get a string. A string is a byte array.
+     */
+    std::string getString(const char* name, size_t offset = 0) throw(Exception);
+
+    /**
+     * Set the given dataref to the given integer value.
+     */
+    void setInt(const char* name, int value) throw(Exception);
+
+    /**
+     * Set the given dataref to the given float value.
+     */
+    void setFloat(const char* name, float value) throw(Exception);
+
+    /**
+     * Set the given dataref to the given double value.
+     */
+    void setDouble(const char* name, double value) throw(Exception);
+
+    /**
+     * Set the given float array to values in the given buffer.
+     */
+    void setFloatArray(const char* name, const float* values, size_t length,
+                       size_t offset = 0) throw(Exception);
+
+    /**
+     * Set the given integer array to values in the given buffer.
+     */
+    void setIntArray(const char* name, const int32_t* values, size_t length,
+                     size_t offset = 0) throw(Exception);
+
+    /**
+     * Set the given byte array to values in the given buffer.
+     */
+    void setByteArray(const char* name, const uint8_t* values, size_t length,
+                      size_t offset = 0) throw(Exception);
+
+    /**
+     * Set the given string to the given value. Since strings are byte
+     * arrays, and the bytes after the string should be zeroed, the
+     * length must be given. The string will be converted to a byte
+     * array of the given length, padded with 0s.
+     */
+    void setString(const char* name, const char* value, size_t length,
+                   size_t offset = 0) throw(Exception);
+
+    /**
+     * Show a textual message for a certain duration.
+     */
+    void showMessage(const char* message, float duration) throw(Exception);
+
+    /**
+     * Register the given hotkey codes for listening. If there is an
+     * existing set of hotkeys registered, those will be overwritten.
+     */
+    void registerHotkeys(const uint16_t* codes, size_t length) throw(Exception);
+
+    /**
+     * Query the registered hotkeys whether they were pressed.
+     */
+    void queryHotkeys(uint8_t* states, size_t length) throw(Exception);
+
+    /**
+     * Unregister the hotkeys.
+     */
+    void unregisterHotkeys();
+
+private:
+    /**
+     * Check if we have a stream and if it has not failed.
+     */
+    void checkStream() throw(NotConnectedException, IOException);
+
+    /**
+     * Check the given protocol result. If it signifies an error,
+     * throw a ProtocolException with the correct error code.
+     */
+    void checkResult(uint8_t result, bool hasParameter = false,
+                     long parameter = 0) throw(ProtocolException);
+
+    /**
+     * Read and check the result.  If it signifies an error,
+     * throw a ProtocolException with the correct error code. If there
+     * is some problem with the stream, an IOException is thrown.
+     */
+    void checkResult(bool multi = false) throw(ProtocolException, IOException);
+
+    /**
+     * Issue the command to get a single, scalar value. The result is
+     * also checked, but the value should be read by the caller.
+     */
+    void getScalar(const char* name, uint8_t type) throw(Exception);
+
+    /**
+     * Issue the command to get an array of values of the given
+     * type. It checks the result and retrieves the number of value
+     * items available.
+     *
+     * @return the number of value items available
+     */
+    size_t getArray(const char* name, uint8_t type,
+                    ssize_t length, size_t offset) throw(Exception);
+
+
+    /**
+     * Issue the command to set a scalar value of the given type.
+     */
+    void setScalar(const char* name, uint8_t type) throw(Exception);
+
+    /**
+     * Issue the command to set an array value of the given type.
+     */
+    void setArray(const char* name, uint8_t type, size_t length,
+                  size_t offset) throw(Exception);
+
+    friend class MultiBuffer;
+    friend class MultiGetter;
+    friend class MultiSetter;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline XPlane::XPlane() throw() :
+    socket(0),
+    stream(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline bool XPlane::isConnected() const throw()
+{
+    return socket!=0;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
+
+//------------------------------------------------------------------------------
+#endif // HU_VARADIISTVAN_XPLRA_XPLANE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/XPlane.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/XPlane.h	(revision 54)
+++ 	(revision )
@@ -1,381 +1,0 @@
-// 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.
-
-#ifndef HU_VARADIISTVAN_XPLRA_XPLANE_H
-#define HU_VARADIISTVAN_XPLRA_XPLANE_H
-//-----------------------------------------------------------------------------
-
-#include "Exception.h"
-
-#include <hu/varadiistvan/scpl/io/Waiter.h>
-
-#include <set>
-
-#include <inttypes.h>
-
-//-----------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace scpl { namespace io {
-
-class LocalClientSocket;
-class DataStream;
-
-} /* namespace hu::varadiistvan::scpl::io */ } /* namespace hu::varadiistvan::scpl */ } /* namespace hu::varadiistvan */ } /* namespace hu */
-
-//------------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class MultiBuffer;
-class MultiGetter;
-class MultiSetter;
-
-//------------------------------------------------------------------------------
-
-/**
- * The main class to access X-Plane.
- *
- * The calls are synchronous and not thread-safe.
- */
-class XPlane
-{
-private:
-    /**
-     * Type for the set of multi-dataref buffers.
-     */
-    typedef std::set<MultiBuffer*> multiBuffers_t;
-
-    /**
-     * The waiter to use.
-     */
-    scpl::io::Waiter waiter;
-
-    /**
-     * The local client socket over which we are communicating with X-Plane.
-     */
-    scpl::io::LocalClientSocket* socket;
-
-    /**
-     * The data stream to handle the data conversions.
-     */
-    scpl::io::DataStream* stream;
-
-    /**
-     * The buffers created by this object.
-     */
-    multiBuffers_t multiBuffers;
-
-public:
-    /**
-     * Construct the object. It will not be connected to the simulator
-     * yet.
-     */
-    XPlane() throw();
-
-    /**
-     * Destroy the object. If connected, the connection will be
-     * closed. It destroys all existing buffers, so their references
-     * become invalid.
-     */
-    ~XPlane() throw();
-
-    /**
-     * Connect to the simulator.
-     */
-    void connect() throw(IOException);
-
-    /**
-     * Check if we are connected to the simulator.
-     */
-    bool isConnected() const throw();
-
-    /**
-     * Disconnect from the simulator.
-     */
-    void disconnect() throw();
-
-    /**
-     * Create a new getter of multiple datarefs and return a reference
-     * to it.
-     */
-    MultiGetter& createMultiGetter() throw();
-
-    /**
-     * Create a new setter of multiple datarefs and return a reference
-     * to it.
-     */
-    MultiSetter& createMultiSetter() throw();
-
-    /**
-     * Destroy the given getter or setter of multiple datarefs. As the
-     * buffer is unregistered, if it has been registered previously,
-     * and  unregistration may fail, this function might throw an
-     * exception.
-     *
-     * @return if the buffer was found and could be destroyed
-     */
-    bool destroyMultiBuffer(MultiBuffer& buffer) throw(Exception);
-
-    /**
-     * Get the versions of X-Plane, XPLM and the XPLRA plugin.
-     */
-    void getVersions(int& xplaneVersion, int& xplmVersion, int& xplraVersion) throw(Exception);
-
-    /**
-     * Reload the plugins loaded in X-Plane. After this the connection
-     * fails.
-     */
-    void reloadPlugins() throw(Exception);
-
-    /**
-     * Get the integer value of the dataref with the given name.
-     */
-    int getInt(const char* name) throw(Exception);
-
-    /**
-     * Get a float value.
-     */
-    float getFloat(const char* name) throw(Exception);
-
-    /**
-     * Get a double value.
-     */
-    double getDouble(const char* name) throw(Exception);
-
-    /**
-     * Get a possibly partial array of floats.
-     *
-     * @param length the length of the destination buffer
-     * @param offset the offset from which to get the array
-     *
-     * @return the number of values acquired actually
-     */
-    size_t getFloatArray(const char* name, float* dest,
-                         size_t length, size_t offset = 0) throw(Exception);
-
-    /**
-     * Get a possibly partial array of floats. The result array will
-     * be created with a length needed to hold the returned value.
-     *
-     * @param offset the offset from which to get the array
-     */
-    float* getFloatArray(const char* name, size_t& length,
-                         size_t offset = 0) throw(Exception);
-
-    /**
-     * Get a possibly partial array of integers.
-     *
-     * @param length the length of the destination buffer
-     * @param offset the offset from which to get the array
-     *
-     * @return the number of values acquired actually
-     */
-    size_t getIntArray(const char* name, int32_t* dest,
-                       size_t length, size_t offset = 0) throw(Exception);
-
-    /**
-     * Get a possibly partial array of integers. The result array will
-     * be created with a length needed to hold the returned value.
-     *
-     * @param offset the offset from which to get the array
-     */
-    int32_t* getIntArray(const char* name, size_t& length,
-                         size_t offset = 0) throw(Exception);
-
-    /**
-     * Get a possibly partial array of bytes.
-     *
-     * @param length the length of the destination buffer
-     * @param offset the offset from which to get the array
-     *
-     * @return the number of values acquired actually
-     */
-    size_t getByteArray(const char* name, uint8_t* dest,
-                        size_t length, size_t offset = 0) throw(Exception);
-
-    /**
-     * Get a possibly partial array of bytes. The result array will
-     * be created with a length needed to hold the returned value.
-     *
-     * @param offset the offset from which to get the array
-     */
-    uint8_t* getByteArray(const char* name, size_t& lengyh,
-                          size_t offset = 0) throw(Exception);
-
-    /**
-     * Get a string. A string is a byte array.
-     */
-    std::string getString(const char* name, size_t offset = 0) throw(Exception);
-
-    /**
-     * Set the given dataref to the given integer value.
-     */
-    void setInt(const char* name, int value) throw(Exception);
-
-    /**
-     * Set the given dataref to the given float value.
-     */
-    void setFloat(const char* name, float value) throw(Exception);
-
-    /**
-     * Set the given dataref to the given double value.
-     */
-    void setDouble(const char* name, double value) throw(Exception);
-
-    /**
-     * Set the given float array to values in the given buffer.
-     */
-    void setFloatArray(const char* name, const float* values, size_t length,
-                       size_t offset = 0) throw(Exception);
-
-    /**
-     * Set the given integer array to values in the given buffer.
-     */
-    void setIntArray(const char* name, const int32_t* values, size_t length,
-                     size_t offset = 0) throw(Exception);
-
-    /**
-     * Set the given byte array to values in the given buffer.
-     */
-    void setByteArray(const char* name, const uint8_t* values, size_t length,
-                      size_t offset = 0) throw(Exception);
-
-    /**
-     * Set the given string to the given value. Since strings are byte
-     * arrays, and the bytes after the string should be zeroed, the
-     * length must be given. The string will be converted to a byte
-     * array of the given length, padded with 0s.
-     */
-    void setString(const char* name, const char* value, size_t length,
-                   size_t offset = 0) throw(Exception);
-
-    /**
-     * Show a textual message for a certain duration.
-     */
-    void showMessage(const char* message, float duration) throw(Exception);
-
-    /**
-     * Register the given hotkey codes for listening. If there is an
-     * existing set of hotkeys registered, those will be overwritten.
-     */
-    void registerHotkeys(const uint16_t* codes, size_t length) throw(Exception);
-
-    /**
-     * Query the registered hotkeys whether they were pressed.
-     */
-    void queryHotkeys(uint8_t* states, size_t length) throw(Exception);
-
-    /**
-     * Unregister the hotkeys.
-     */
-    void unregisterHotkeys();
-
-private:
-    /**
-     * Check if we have a stream and if it has not failed.
-     */
-    void checkStream() throw(NotConnectedException, IOException);
-
-    /**
-     * Check the given protocol result. If it signifies an error,
-     * throw a ProtocolException with the correct error code.
-     */
-    void checkResult(uint8_t result, bool hasParameter = false,
-                     long parameter = 0) throw(ProtocolException);
-
-    /**
-     * Read and check the result.  If it signifies an error,
-     * throw a ProtocolException with the correct error code. If there
-     * is some problem with the stream, an IOException is thrown.
-     */
-    void checkResult(bool multi = false) throw(ProtocolException, IOException);
-
-    /**
-     * Issue the command to get a single, scalar value. The result is
-     * also checked, but the value should be read by the caller.
-     */
-    void getScalar(const char* name, uint8_t type) throw(Exception);
-
-    /**
-     * Issue the command to get an array of values of the given
-     * type. It checks the result and retrieves the number of value
-     * items available.
-     *
-     * @return the number of value items available
-     */
-    size_t getArray(const char* name, uint8_t type,
-                    ssize_t length, size_t offset) throw(Exception);
-
-
-    /**
-     * Issue the command to set a scalar value of the given type.
-     */
-    void setScalar(const char* name, uint8_t type) throw(Exception);
-
-    /**
-     * Issue the command to set an array value of the given type.
-     */
-    void setArray(const char* name, uint8_t type, size_t length,
-                  size_t offset) throw(Exception);
-
-    friend class MultiBuffer;
-    friend class MultiGetter;
-    friend class MultiSetter;
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline XPlane::XPlane() throw() :
-    socket(0),
-    stream(0)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline bool XPlane::isConnected() const throw()
-{
-    return socket!=0;
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
-
-//------------------------------------------------------------------------------
-#endif // HU_VARADIISTVAN_XPLRA_XPLANE_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/xplra.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/xplra.cc	(revision 58)
+++ src/client/c/hu/varadiistvan/xplra/xplra.cc	(revision 58)
@@ -0,0 +1,1389 @@
+// 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 <vector>
+#include <memory>
+
+#include <cstdio>
+#include <cassert>
+
+//------------------------------------------------------------------------------
+
+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 <class Value>
+struct Slot
+{
+private:
+    /**
+     * The slots.
+     */
+    static std::vector< Slot<Value> > 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 <class Value> vector< Slot<Value> > Slot<Value>::slots;
+
+//------------------------------------------------------------------------------
+
+template <class Value> int Slot<Value>::firstFree = -1;
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+inline Slot<Value>::Slot(Value value) throw() :
+    valid(true)
+{
+    this->value = value;
+}
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+inline int Slot<Value>::setValue(Value value) throw()
+{
+    assert(!valid);
+    int nextFreeIndex = this->nextFreeIndex;
+    this->value = value;
+    valid = true;
+    return nextFreeIndex;
+}
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+inline Value Slot<Value>::getValue() const throw()
+{
+    return valid ? value : static_cast<Value>(0);
+}
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+inline void Slot<Value>::clear(int nextFreeIndex) throw()
+{
+    assert(valid);
+    valid = false;
+    this->nextFreeIndex = nextFreeIndex;
+}
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+int Slot<Value>::addValue(Value value) throw()
+{
+    int id = firstFree;
+    if (id<0) {
+        id = slots.size();
+        slots.push_back(Slot<Value>(value));
+    } else {
+        Slot& slot = slots[id];
+        firstFree = slot.setValue(value);
+    }
+
+    return id;
+}
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+Value Slot<Value>::getValue(int valueID) throw()
+{
+    size_t index = static_cast<size_t>(valueID);
+    return (index<slots.size()) ?
+        slots[index].getValue() : static_cast<Value>(0);
+}
+
+//------------------------------------------------------------------------------
+
+template <class Value>
+void Slot<Value>::clearValue(int valueID) throw()
+{
+    size_t index = static_cast<size_t>(valueID);
+    if (index<slots.size()) {
+        slots[index].clear(firstFree);
+        firstFree = index;
+    }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+typedef Slot<MultiBuffer*> 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<int> 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<Connection&>(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<unsigned long>(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 = "<Exception of an unknown type>";
+    }
+}
+
+//------------------------------------------------------------------------------
+
+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<Connection*> 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> 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<uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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<uint8_t*>(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;
+
+    ConnectionSlot::clearValue(connectionID);
+    connection->disconnect();
+    delete connection;
+
+    return 0;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/client/c/hu/varadiistvan/xplra/xplra.cc
===================================================================
--- src/client/c/hu/varadiistvan/xplra/xplra.cc	(revision 58)
+++ 	(revision )
@@ -1,1389 +1,0 @@
-// 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 <vector>
-#include <memory>
-
-#include <cstdio>
-#include <cassert>
-
-//------------------------------------------------------------------------------
-
-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 <class Value>
-struct Slot
-{
-private:
-    /**
-     * The slots.
-     */
-    static std::vector< Slot<Value> > 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 <class Value> vector< Slot<Value> > Slot<Value>::slots;
-
-//------------------------------------------------------------------------------
-
-template <class Value> int Slot<Value>::firstFree = -1;
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-inline Slot<Value>::Slot(Value value) throw() :
-    valid(true)
-{
-    this->value = value;
-}
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-inline int Slot<Value>::setValue(Value value) throw()
-{
-    assert(!valid);
-    int nextFreeIndex = this->nextFreeIndex;
-    this->value = value;
-    valid = true;
-    return nextFreeIndex;
-}
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-inline Value Slot<Value>::getValue() const throw()
-{
-    return valid ? value : static_cast<Value>(0);
-}
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-inline void Slot<Value>::clear(int nextFreeIndex) throw()
-{
-    assert(valid);
-    valid = false;
-    this->nextFreeIndex = nextFreeIndex;
-}
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-int Slot<Value>::addValue(Value value) throw()
-{
-    int id = firstFree;
-    if (id<0) {
-        id = slots.size();
-        slots.push_back(Slot<Value>(value));
-    } else {
-        Slot& slot = slots[id];
-        firstFree = slot.setValue(value);
-    }
-
-    return id;
-}
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-Value Slot<Value>::getValue(int valueID) throw()
-{
-    size_t index = static_cast<size_t>(valueID);
-    return (index<slots.size()) ?
-        slots[index].getValue() : static_cast<Value>(0);
-}
-
-//------------------------------------------------------------------------------
-
-template <class Value>
-void Slot<Value>::clearValue(int valueID) throw()
-{
-    size_t index = static_cast<size_t>(valueID);
-    if (index<slots.size()) {
-        slots[index].clear(firstFree);
-        firstFree = index;
-    }
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-typedef Slot<MultiBuffer*> 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<int> 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<Connection&>(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<unsigned long>(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 = "<Exception of an unknown type>";
-    }
-}
-
-//------------------------------------------------------------------------------
-
-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<Connection*> 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> 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<uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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<uint8_t*>(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;
-
-    ConnectionSlot::clearValue(connectionID);
-    connection->disconnect();
-    delete connection;
-
-    return 0;
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/client/c/hu/varadiistvan/xplra/xplra.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/xplra.h	(revision 58)
+++ src/client/c/hu/varadiistvan/xplra/xplra.h	(revision 58)
@@ -0,0 +1,808 @@
+/* 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.
+ */
+
+#ifndef HU_VARADIISTVAN_XPLRA_XPLRA_H
+#define HU_VARADIISTVAN_XPLRA_XPLRA_H
+/*----------------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+/*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------*/
+
+/** No error occured */
+#define ERROR_NONE 0
+
+/**
+ * An I/O error has occured. The subcode is the errno value on Linux, or the
+ * Windows error code.
+ */
+#define ERROR_IO 1
+
+/**
+ * A protocol error has occured. The subcode is one of the
+ * ERROR_PROTOCOL_XXX values.
+ */
+#define ERROR_PROTOCOL 2
+
+/** Invalid command was passed to the plugin */
+#define ERROR_PROTOCOL_INVALID_COMMAND = 1
+
+/** An unknown dataref was specified */
+#define ERROR_PROTOCOL_UNKNOWN_DATAREF = 2
+
+/** An invalid type was specified */
+#define ERROR_PROTOCOL_INVALID_TYPE = 3
+
+/** An invalid length was specified */
+#define ERROR_PROTOCOL_INVALID_LENGTH = 4
+
+/** An invalid offset was specified */
+#define ERROR_PROTOCOL_INVALID_OFFSET = 5
+
+/** An invalid count was specified */
+#define ERROR_PROTOCOL_INVALID_COUNT = 6
+
+/** An invalid ID was specified */
+#define ERROR_PROTOCOL_INVALID_ID = 7
+
+/** An invalid duration was specified */
+#define ERROR_PROTOCOL_INVALID_DURATION = 8
+
+/** Other protocol error  */
+#define ERROR_PROTOCOL_OTHER = 255
+
+/** A function requiring a connection is called without a connection */
+#define ERROR_NOT_CONNECTED 3
+
+/** A type-specific function was called for a dataref of a different type */
+#define ERROR_TYPE_MISMATCH 4
+
+/** An invalid ID was passed to a function */
+#define ERROR_INVALID_ID 5
+
+/** Some other error */
+#define ERROR_OTHER 255
+
+/*----------------------------------------------------------------------------*/
+
+/** Hotkey modifier: Shift */
+#define HOTKEY_MODIFIER_SHIFT 0x01
+
+/** Hotkey modifier: Control */
+#define HOTKEY_MODIFIER_CONTROL 0x02
+
+/*----------------------------------------------------------------------------*/
+
+#define INVALID_DATAREF_ID ((size_t)-1)
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the last error code with the subcode.
+ *
+ * @return the last error code, or -1 if the given connection ID is invalid.
+ */
+int xplra_get_last_error(int connectionID, unsigned long* subCode);
+
+/**
+ * Get a string representation of the last error.
+ *
+ * @return the string representation of the last error, or 0 if there
+ * was no last error, or the connection ID is invalid.
+ */
+const char* xplra_get_last_error_string(int connectionID);
+
+/**
+ * Clear the last error.
+ */
+void xplra_clear_last_error(int connectionID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Connect to the simulator.
+ *
+ * @return an ID for the created connection, or -1 on error.
+ */
+int xplra_connect();
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the versions of X-Plane, the XPLM library and XPLRA
+ */
+int xplra_get_versions(int connectionID,
+                       int* xplaneVersion, int* xplmVersion,
+                       int* xplraVersion);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Reload the plugins in X-Plane. After this the connection fails.
+ */
+int xplra_reload_plugins(int connectionID);
+
+/*----------------------------------------------------------------------------*/
+/* Single dataref support                                                     */
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an integer value from the simulator.
+ *
+ * @return 0 on success, -1 on error
+ */
+int xplra_get_int(int* value, int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a float value from the simulator.
+ *
+ * @return 0 on success, -1 on error
+ */
+int xplra_get_float(float* value, int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a double value from the simulator.
+ *
+ * @return 0 on success, -1 on error
+ */
+int xplra_get_double(double* value, int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an array of floats into a buffer.
+ *
+ * @param dest the array into which to get the data
+ * @param length the length of the destination buffer
+ * @param offset the offset from which to query the array
+ *
+ * @return the actual number of elements returned in case of success,
+ * -1 on error
+ */
+ssize_t xplra_get_float_array(float* dest, size_t length, size_t offset,
+                              int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an array of floats into a newly allocated buffer.
+ *
+ * @param length pointer to a variable containing the length to
+ * query. On return it will be set to the actual length, which can be
+ * less than or equal to the input value.
+ * @param offset the offset from which to query the array
+ *
+ * @return the new array on success, 0 on error
+ */
+float* xplra_get_float_array_new(size_t* length, size_t offset,
+                                 int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an array of integers into a buffer.
+ *
+ * @param dest the array into which to get the data
+ * @param length the length of the destination buffer
+ * @param offset the offset from which to query the array
+ *
+ * @return the actual number of elements returned in case of success,
+ * -1 on error
+ */
+ssize_t xplra_get_int_array(int32_t* dest, size_t length, size_t offset,
+                            int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an array of integers into a newly allocated buffer.
+ *
+ * @param length pointer to a variable containing the length to
+ * query. On return it will be set to the actual length, which can be
+ * less than or equal to the input value.
+ * @param offset the offset from which to query the array
+ *
+ * @return the new array on success, 0 on error
+ */
+int32_t* xplra_get_int_array_new(size_t* length, size_t offset,
+                                 int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an array of bytes into a buffer.
+ *
+ * @param dest the array into which to get the data
+ * @param length the length of the destination buffer
+ * @param offset the offset from which to query the array
+ *
+ * @return the actual number of elements returned in case of success,
+ * -1 on error
+ */
+ssize_t xplra_get_byte_array(void* dest, size_t length, size_t offset,
+                             int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get an array of bytes into a newly allocated buffer.
+ *
+ * @param length pointer to a variable containing the length to
+ * query. On return it will be set to the actual length, which can be
+ * less than or equal to the input value.
+ * @param offset the offset from which to query the array
+ *
+ * @return the new array on success, 0 on error
+ */
+uint8_t* xplra_get_byte_array_new(size_t* length, size_t offset,
+                                  int connectionID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the integer dataref with the given name to the given value.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_int(int connectionID, const char* name, int value);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the float dataref with the given name to the given value.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_float(int connectionID, const char* name, float value);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the double dataref with the given name to the given value.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_double(int connectionID, const char* name, double value);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the array of float values with the given name from the given
+ * buffer.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_float_array(int connectionID, const char* name,
+                          const float* values, size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the array of integer values with the given name from the given
+ * buffer.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_int_array(int connectionID, const char* name,
+                        const int32_t* values, size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the array of byte values with the given name from the given
+ * buffer.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_byte_array(int connectionID, const char* name,
+                         const void* values, size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the array of byte values with the given name from the given
+ * string. The string will be padded with 0 if it has a length less
+ * than the given length.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_set_string(int connectionID, const char* name,
+                     const char* value, size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+/* Multi-dataref support                                                      */
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Create a multi-dataref getter for the given connection.
+ *
+ * @return the ID of the new getter, or -1 on error
+ */
+int xplra_multi_create_getter(int connectionID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Create a multi-dataref setter for the given connection.
+ *
+ * @return the ID of the new setter, or -1 on error
+ */
+int xplra_multi_create_setter(int connectionID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Add an integer dataref to a multi-dataref buffer.
+ *
+ * @return the ID of the dataref that can be used later. If the buffer
+ * ID is invalid, INVALID_DATAREF_ID is returned.
+ */
+size_t xplra_multi_add_int(int bufferID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Add a float dataref to a multi-dataref buffer.
+ *
+ * @return the ID of the dataref that can be used later. If the buffer
+ * ID is invalid, INVALID_DATAREF_ID is returned.
+ */
+size_t xplra_multi_add_float(int bufferID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Add a double dataref to a multi-dataref buffer.
+ *
+ * @return the ID of the dataref that can be used later. If the buffer
+ * ID is invalid, INVALID_DATAREF_ID is returned.
+ */
+size_t xplra_multi_add_double(int bufferID, const char* name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Add a float array dataref to a multi-dataref buffer.
+ *
+ * @return the ID of the dataref that can be used later. If the buffer
+ * ID is invalid, INVALID_DATAREF_ID is returned.
+ */
+size_t xplra_multi_add_float_array(int bufferID, const char* name,
+                                   size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Add an integer array dataref to a multi-dataref buffer.
+ *
+ * @return the ID of the dataref that can be used later. If the buffer
+ * ID is invalid, INVALID_DATAREF_ID is returned.
+ */
+size_t xplra_multi_add_int_array(int bufferID, const char* name,
+                                 size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Add a byte array dataref to a multi-dataref buffer.
+ *
+ * @return the ID of the dataref that can be used later. If the buffer
+ * ID is invalid, INVALID_DATAREF_ID is returned.
+ */
+size_t xplra_multi_add_byte_array(int bufferID, const char* name,
+                                  size_t length, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Finalize the given buffer, if not finalized yet.
+ *
+ * @return -1 on error (if the buffer ID is invalid), 0 if there is no
+ * data in the buffer, 1 if there is data in it.
+ */
+int xplra_multi_finalize(int bufferID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Register the buffer with the given ID in X-Plane. If needed, it
+ * will be finalized too.
+ *
+ * @return 0 on success, -1 on error
+ */
+int xplra_multi_register(int bufferID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Unregister the buffer with the given ID from X-Plane.
+ *
+ * @return 0 on success, -1 on error
+ */
+int xplra_multi_unregister(int bufferID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Unregister the buffer with the given ID from X-Plane safely,
+ * i.e. the registration ID will be cleared anyway to support re-registration.
+ *
+ * @return -1 if the buffer ID is invalid, 0 if the unregistration
+ * call failed, 1 if it was successful.
+ */
+int xplra_multi_unregister_safely(int bufferID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Execute the buffer with the given ID. If the buffer is not
+ * finalized, it will be finalized. If it is not finalized, but
+ * registered, the registration will be cleared, and it will be
+ * re-registered after finalizing.
+ *
+ * @return 0 on success, -1 on error
+ */
+int xplra_multi_execute(int bufferID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the value of an integer dataref with the given ID.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_set_int(int bufferID, size_t datarefID, int value);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the value of an integer dataref with the given ID.
+ *
+ * @param dest pointer to the variable that will receive the value
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_get_int(int* dest, int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a const pointer to the integer dataref with the given ID
+ *
+ * @return the pointer or success, 0 on error.
+ */
+const int32_t* xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer to the integer dataref with the given ID
+ *
+ * @return the pointer or success, 0 on error.
+ */
+int32_t* xplra_multi_get_int_ptr(int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the value of a float dataref with the given ID.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_set_float(int bufferID, size_t datarefID, float value);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the value of a float dataref with the given ID.
+ *
+ * @param dest pointer to the variable that will receive the value
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_get_float(float* dest, int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a const pointer to the float dataref with the given ID
+ *
+ * @return the pointer or success, 0 on error.
+ */
+const float* xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer to the float dataref with the given ID
+ *
+ * @return the pointer or success, 0 on error.
+ */
+float* xplra_multi_get_float_ptr(int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the value of a double dataref with the given ID.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_set_double(int bufferID, size_t datarefID, double value);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the value of a double dataref with the given ID.
+ *
+ * @param dest pointer to the variable that will receive the value
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_get_double(double* dest, int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a const pointer to the double dataref with the given ID
+ *
+ * @return the pointer or success, 0 on error.
+ */
+const double* xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer to the double dataref with the given ID
+ *
+ * @return the pointer or success, 0 on error.
+ */
+double* xplra_multi_get_double_ptr(int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the contents of the float array dataref with the given ID.
+ *
+ * @param length the amount of data. If 0, it is assumed to be the
+ * length of the data in the buffer minus the offset.
+ * @param offset the offset within the buffer to set the data from
+ *
+ * @return the number of data items set, or -1 on error.
+ */
+ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID,
+                                    const float* value, size_t length,
+                                    size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the contents of the float array with the given ID.
+ *
+ * @param length the amount of data. If 0, it is assumed to be the
+ * length of the data in the buffer minus the offset.
+ * @param offset the offset within the buffer to get the data from
+ *
+ * @return the number of data items retrieved, or -1 on error.
+ */
+ssize_t xplra_multi_get_float_array(float* value,
+                                    size_t length, size_t offset,
+                                    int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer to the float array with the given ID.
+ *
+ * @param offset the offset within the buffer.
+ *
+ * @return the pointer on success, 0 on error.
+ */
+const float* xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID,
+                                             size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the contents of the integer array dataref with the given ID.
+ *
+ * @param length the amount of data. If 0, it is assumed to be the
+ * length of the data in the buffer minus the offset.
+ * @param offset the offset within the buffer to set the data from
+ *
+ * @return the number of data items set, or -1 on error.
+ */
+ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID,
+                                  const int32_t* value, size_t length,
+                                  size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the contents of the integer array with the given ID.
+ *
+ * @param length the amount of data. If 0, it is assumed to be the
+ * length of the data in the buffer minus the offset.
+ * @param offset the offset within the buffer to get the data from
+ *
+ * @return the number of data items retrieved, or -1 on error.
+ */
+ssize_t xplra_multi_get_int_array(int32_t* value,
+                                  size_t length, size_t offset,
+                                  int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer to the integer array with the given ID.
+ *
+ * @param offset the offset within the buffer.
+ *
+ * @return the pointer on success, 0 on error.
+ */
+const int32_t* xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID,
+                                             size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the contents of the byte array dataref with the given ID.
+ *
+ * @param length the amount of data. If 0, it is assumed to be the
+ * length of the data in the buffer minus the offset.
+ * @param offset the offset within the buffer to set the data from
+ *
+ * @return the number of data items set, or -1 on error.
+ */
+ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID,
+                                   const void* value, size_t length,
+                                   size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get the contents of the byte array with the given ID.
+ *
+ * @param length the amount of data. If 0, it is assumed to be the
+ * length of the data in the buffer minus the offset.
+ * @param offset the offset within the buffer to get the data from
+ *
+ * @return the number of data items retrieved, or -1 on error.
+ */
+ssize_t xplra_multi_get_byte_array(void* value,
+                                   size_t length, size_t offset,
+                                   int bufferID, size_t datarefID);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer to the byte array with the given ID.
+ *
+ * @param offset the offset within the buffer.
+ *
+ * @return the pointer on success, 0 on error.
+ */
+const uint8_t* xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID,
+                                              size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Set the value of the byte array with the given ID from the given
+ * string. If the string is shorter than the array, the rest will be
+ * filled with 0s.
+ *
+ * @return the number of bytes set, or -1 on error
+ */
+ssize_t xplra_multi_set_string(int bufferID, size_t datarefID,
+                               const char* value, size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Get a pointer as a string pointer to the byte array with the given
+ * ID.
+ *
+ * @return the pointer on success, 0 on error.
+ */
+const char* xplra_multi_get_string_ptr(int bufferID, size_t datarefID,
+                                       size_t offset);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Destroy a multi-dataref buffer for the given connection.
+ *
+ * @param connectionID the ID of the connection for which the buffer
+ * has been created.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_multi_destroy_buffer(int connectionID, int bufferID);
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Show a message in the simulator window for the given duration.
+ */
+int xplra_show_message(int connectionID, const char* message, float duration);
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Register the given hotkey codes for listening. If there is an
+ * existing set of hotkeys registered, those will be overwritten.
+ */
+int xplra_register_hotkeys(int connectionID,
+                           const uint16_t* codes, size_t length);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Query the registered hotkeys whether they were pressed.
+ */
+int xplra_query_hotkeys(int connectionID, uint8_t* states, size_t length);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Unregister the hotkeys.
+ */
+int xplra_unregister_hotkeys(int connectionID);
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Destroy the connection with the given ID.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int xplra_disconnect(int connectionID);
+
+/*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+/*----------------------------------------------------------------------------*/
+#endif // HU_VARADIISTVAN_XPLRA_XPLRA_H
Index: src/client/c/hu/varadiistvan/xplra/xplra.h
===================================================================
--- src/client/c/hu/varadiistvan/xplra/xplra.h	(revision 58)
+++ 	(revision )
@@ -1,808 +1,0 @@
-/* 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.
- */
-
-#ifndef HU_VARADIISTVAN_XPLRA_XPLRA_H
-#define HU_VARADIISTVAN_XPLRA_XPLRA_H
-/*----------------------------------------------------------------------------*/
-
-#include <stdlib.h>
-#include <inttypes.h>
-
-/*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*----------------------------------------------------------------------------*/
-
-/** No error occured */
-#define ERROR_NONE 0
-
-/**
- * An I/O error has occured. The subcode is the errno value on Linux, or the
- * Windows error code.
- */
-#define ERROR_IO 1
-
-/**
- * A protocol error has occured. The subcode is one of the
- * ERROR_PROTOCOL_XXX values.
- */
-#define ERROR_PROTOCOL 2
-
-/** Invalid command was passed to the plugin */
-#define ERROR_PROTOCOL_INVALID_COMMAND = 1
-
-/** An unknown dataref was specified */
-#define ERROR_PROTOCOL_UNKNOWN_DATAREF = 2
-
-/** An invalid type was specified */
-#define ERROR_PROTOCOL_INVALID_TYPE = 3
-
-/** An invalid length was specified */
-#define ERROR_PROTOCOL_INVALID_LENGTH = 4
-
-/** An invalid offset was specified */
-#define ERROR_PROTOCOL_INVALID_OFFSET = 5
-
-/** An invalid count was specified */
-#define ERROR_PROTOCOL_INVALID_COUNT = 6
-
-/** An invalid ID was specified */
-#define ERROR_PROTOCOL_INVALID_ID = 7
-
-/** An invalid duration was specified */
-#define ERROR_PROTOCOL_INVALID_DURATION = 8
-
-/** Other protocol error  */
-#define ERROR_PROTOCOL_OTHER = 255
-
-/** A function requiring a connection is called without a connection */
-#define ERROR_NOT_CONNECTED 3
-
-/** A type-specific function was called for a dataref of a different type */
-#define ERROR_TYPE_MISMATCH 4
-
-/** An invalid ID was passed to a function */
-#define ERROR_INVALID_ID 5
-
-/** Some other error */
-#define ERROR_OTHER 255
-
-/*----------------------------------------------------------------------------*/
-
-/** Hotkey modifier: Shift */
-#define HOTKEY_MODIFIER_SHIFT 0x01
-
-/** Hotkey modifier: Control */
-#define HOTKEY_MODIFIER_CONTROL 0x02
-
-/*----------------------------------------------------------------------------*/
-
-#define INVALID_DATAREF_ID ((size_t)-1)
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the last error code with the subcode.
- *
- * @return the last error code, or -1 if the given connection ID is invalid.
- */
-int xplra_get_last_error(int connectionID, unsigned long* subCode);
-
-/**
- * Get a string representation of the last error.
- *
- * @return the string representation of the last error, or 0 if there
- * was no last error, or the connection ID is invalid.
- */
-const char* xplra_get_last_error_string(int connectionID);
-
-/**
- * Clear the last error.
- */
-void xplra_clear_last_error(int connectionID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Connect to the simulator.
- *
- * @return an ID for the created connection, or -1 on error.
- */
-int xplra_connect();
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the versions of X-Plane, the XPLM library and XPLRA
- */
-int xplra_get_versions(int connectionID,
-                       int* xplaneVersion, int* xplmVersion,
-                       int* xplraVersion);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Reload the plugins in X-Plane. After this the connection fails.
- */
-int xplra_reload_plugins(int connectionID);
-
-/*----------------------------------------------------------------------------*/
-/* Single dataref support                                                     */
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an integer value from the simulator.
- *
- * @return 0 on success, -1 on error
- */
-int xplra_get_int(int* value, int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a float value from the simulator.
- *
- * @return 0 on success, -1 on error
- */
-int xplra_get_float(float* value, int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a double value from the simulator.
- *
- * @return 0 on success, -1 on error
- */
-int xplra_get_double(double* value, int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an array of floats into a buffer.
- *
- * @param dest the array into which to get the data
- * @param length the length of the destination buffer
- * @param offset the offset from which to query the array
- *
- * @return the actual number of elements returned in case of success,
- * -1 on error
- */
-ssize_t xplra_get_float_array(float* dest, size_t length, size_t offset,
-                              int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an array of floats into a newly allocated buffer.
- *
- * @param length pointer to a variable containing the length to
- * query. On return it will be set to the actual length, which can be
- * less than or equal to the input value.
- * @param offset the offset from which to query the array
- *
- * @return the new array on success, 0 on error
- */
-float* xplra_get_float_array_new(size_t* length, size_t offset,
-                                 int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an array of integers into a buffer.
- *
- * @param dest the array into which to get the data
- * @param length the length of the destination buffer
- * @param offset the offset from which to query the array
- *
- * @return the actual number of elements returned in case of success,
- * -1 on error
- */
-ssize_t xplra_get_int_array(int32_t* dest, size_t length, size_t offset,
-                            int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an array of integers into a newly allocated buffer.
- *
- * @param length pointer to a variable containing the length to
- * query. On return it will be set to the actual length, which can be
- * less than or equal to the input value.
- * @param offset the offset from which to query the array
- *
- * @return the new array on success, 0 on error
- */
-int32_t* xplra_get_int_array_new(size_t* length, size_t offset,
-                                 int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an array of bytes into a buffer.
- *
- * @param dest the array into which to get the data
- * @param length the length of the destination buffer
- * @param offset the offset from which to query the array
- *
- * @return the actual number of elements returned in case of success,
- * -1 on error
- */
-ssize_t xplra_get_byte_array(void* dest, size_t length, size_t offset,
-                             int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get an array of bytes into a newly allocated buffer.
- *
- * @param length pointer to a variable containing the length to
- * query. On return it will be set to the actual length, which can be
- * less than or equal to the input value.
- * @param offset the offset from which to query the array
- *
- * @return the new array on success, 0 on error
- */
-uint8_t* xplra_get_byte_array_new(size_t* length, size_t offset,
-                                  int connectionID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the integer dataref with the given name to the given value.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_int(int connectionID, const char* name, int value);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the float dataref with the given name to the given value.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_float(int connectionID, const char* name, float value);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the double dataref with the given name to the given value.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_double(int connectionID, const char* name, double value);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the array of float values with the given name from the given
- * buffer.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_float_array(int connectionID, const char* name,
-                          const float* values, size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the array of integer values with the given name from the given
- * buffer.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_int_array(int connectionID, const char* name,
-                        const int32_t* values, size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the array of byte values with the given name from the given
- * buffer.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_byte_array(int connectionID, const char* name,
-                         const void* values, size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the array of byte values with the given name from the given
- * string. The string will be padded with 0 if it has a length less
- * than the given length.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_set_string(int connectionID, const char* name,
-                     const char* value, size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-/* Multi-dataref support                                                      */
-/*----------------------------------------------------------------------------*/
-
-/**
- * Create a multi-dataref getter for the given connection.
- *
- * @return the ID of the new getter, or -1 on error
- */
-int xplra_multi_create_getter(int connectionID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Create a multi-dataref setter for the given connection.
- *
- * @return the ID of the new setter, or -1 on error
- */
-int xplra_multi_create_setter(int connectionID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Add an integer dataref to a multi-dataref buffer.
- *
- * @return the ID of the dataref that can be used later. If the buffer
- * ID is invalid, INVALID_DATAREF_ID is returned.
- */
-size_t xplra_multi_add_int(int bufferID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Add a float dataref to a multi-dataref buffer.
- *
- * @return the ID of the dataref that can be used later. If the buffer
- * ID is invalid, INVALID_DATAREF_ID is returned.
- */
-size_t xplra_multi_add_float(int bufferID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Add a double dataref to a multi-dataref buffer.
- *
- * @return the ID of the dataref that can be used later. If the buffer
- * ID is invalid, INVALID_DATAREF_ID is returned.
- */
-size_t xplra_multi_add_double(int bufferID, const char* name);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Add a float array dataref to a multi-dataref buffer.
- *
- * @return the ID of the dataref that can be used later. If the buffer
- * ID is invalid, INVALID_DATAREF_ID is returned.
- */
-size_t xplra_multi_add_float_array(int bufferID, const char* name,
-                                   size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Add an integer array dataref to a multi-dataref buffer.
- *
- * @return the ID of the dataref that can be used later. If the buffer
- * ID is invalid, INVALID_DATAREF_ID is returned.
- */
-size_t xplra_multi_add_int_array(int bufferID, const char* name,
-                                 size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Add a byte array dataref to a multi-dataref buffer.
- *
- * @return the ID of the dataref that can be used later. If the buffer
- * ID is invalid, INVALID_DATAREF_ID is returned.
- */
-size_t xplra_multi_add_byte_array(int bufferID, const char* name,
-                                  size_t length, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Finalize the given buffer, if not finalized yet.
- *
- * @return -1 on error (if the buffer ID is invalid), 0 if there is no
- * data in the buffer, 1 if there is data in it.
- */
-int xplra_multi_finalize(int bufferID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Register the buffer with the given ID in X-Plane. If needed, it
- * will be finalized too.
- *
- * @return 0 on success, -1 on error
- */
-int xplra_multi_register(int bufferID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Unregister the buffer with the given ID from X-Plane.
- *
- * @return 0 on success, -1 on error
- */
-int xplra_multi_unregister(int bufferID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Unregister the buffer with the given ID from X-Plane safely,
- * i.e. the registration ID will be cleared anyway to support re-registration.
- *
- * @return -1 if the buffer ID is invalid, 0 if the unregistration
- * call failed, 1 if it was successful.
- */
-int xplra_multi_unregister_safely(int bufferID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Execute the buffer with the given ID. If the buffer is not
- * finalized, it will be finalized. If it is not finalized, but
- * registered, the registration will be cleared, and it will be
- * re-registered after finalizing.
- *
- * @return 0 on success, -1 on error
- */
-int xplra_multi_execute(int bufferID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the value of an integer dataref with the given ID.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_set_int(int bufferID, size_t datarefID, int value);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the value of an integer dataref with the given ID.
- *
- * @param dest pointer to the variable that will receive the value
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_get_int(int* dest, int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a const pointer to the integer dataref with the given ID
- *
- * @return the pointer or success, 0 on error.
- */
-const int32_t* xplra_multi_get_int_const_ptr(int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer to the integer dataref with the given ID
- *
- * @return the pointer or success, 0 on error.
- */
-int32_t* xplra_multi_get_int_ptr(int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the value of a float dataref with the given ID.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_set_float(int bufferID, size_t datarefID, float value);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the value of a float dataref with the given ID.
- *
- * @param dest pointer to the variable that will receive the value
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_get_float(float* dest, int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a const pointer to the float dataref with the given ID
- *
- * @return the pointer or success, 0 on error.
- */
-const float* xplra_multi_get_float_const_ptr(int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer to the float dataref with the given ID
- *
- * @return the pointer or success, 0 on error.
- */
-float* xplra_multi_get_float_ptr(int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the value of a double dataref with the given ID.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_set_double(int bufferID, size_t datarefID, double value);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the value of a double dataref with the given ID.
- *
- * @param dest pointer to the variable that will receive the value
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_get_double(double* dest, int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a const pointer to the double dataref with the given ID
- *
- * @return the pointer or success, 0 on error.
- */
-const double* xplra_multi_get_double_const_ptr(int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer to the double dataref with the given ID
- *
- * @return the pointer or success, 0 on error.
- */
-double* xplra_multi_get_double_ptr(int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the contents of the float array dataref with the given ID.
- *
- * @param length the amount of data. If 0, it is assumed to be the
- * length of the data in the buffer minus the offset.
- * @param offset the offset within the buffer to set the data from
- *
- * @return the number of data items set, or -1 on error.
- */
-ssize_t xplra_multi_set_float_array(int bufferID, size_t datarefID,
-                                    const float* value, size_t length,
-                                    size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the contents of the float array with the given ID.
- *
- * @param length the amount of data. If 0, it is assumed to be the
- * length of the data in the buffer minus the offset.
- * @param offset the offset within the buffer to get the data from
- *
- * @return the number of data items retrieved, or -1 on error.
- */
-ssize_t xplra_multi_get_float_array(float* value,
-                                    size_t length, size_t offset,
-                                    int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer to the float array with the given ID.
- *
- * @param offset the offset within the buffer.
- *
- * @return the pointer on success, 0 on error.
- */
-const float* xplra_multi_get_float_array_ptr(int bufferID, size_t datarefID,
-                                             size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the contents of the integer array dataref with the given ID.
- *
- * @param length the amount of data. If 0, it is assumed to be the
- * length of the data in the buffer minus the offset.
- * @param offset the offset within the buffer to set the data from
- *
- * @return the number of data items set, or -1 on error.
- */
-ssize_t xplra_multi_set_int_array(int bufferID, size_t datarefID,
-                                  const int32_t* value, size_t length,
-                                  size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the contents of the integer array with the given ID.
- *
- * @param length the amount of data. If 0, it is assumed to be the
- * length of the data in the buffer minus the offset.
- * @param offset the offset within the buffer to get the data from
- *
- * @return the number of data items retrieved, or -1 on error.
- */
-ssize_t xplra_multi_get_int_array(int32_t* value,
-                                  size_t length, size_t offset,
-                                  int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer to the integer array with the given ID.
- *
- * @param offset the offset within the buffer.
- *
- * @return the pointer on success, 0 on error.
- */
-const int32_t* xplra_multi_get_int_array_ptr(int bufferID, size_t datarefID,
-                                             size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the contents of the byte array dataref with the given ID.
- *
- * @param length the amount of data. If 0, it is assumed to be the
- * length of the data in the buffer minus the offset.
- * @param offset the offset within the buffer to set the data from
- *
- * @return the number of data items set, or -1 on error.
- */
-ssize_t xplra_multi_set_byte_array(int bufferID, size_t datarefID,
-                                   const void* value, size_t length,
-                                   size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get the contents of the byte array with the given ID.
- *
- * @param length the amount of data. If 0, it is assumed to be the
- * length of the data in the buffer minus the offset.
- * @param offset the offset within the buffer to get the data from
- *
- * @return the number of data items retrieved, or -1 on error.
- */
-ssize_t xplra_multi_get_byte_array(void* value,
-                                   size_t length, size_t offset,
-                                   int bufferID, size_t datarefID);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer to the byte array with the given ID.
- *
- * @param offset the offset within the buffer.
- *
- * @return the pointer on success, 0 on error.
- */
-const uint8_t* xplra_multi_get_byte_array_ptr(int bufferID, size_t datarefID,
-                                              size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Set the value of the byte array with the given ID from the given
- * string. If the string is shorter than the array, the rest will be
- * filled with 0s.
- *
- * @return the number of bytes set, or -1 on error
- */
-ssize_t xplra_multi_set_string(int bufferID, size_t datarefID,
-                               const char* value, size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Get a pointer as a string pointer to the byte array with the given
- * ID.
- *
- * @return the pointer on success, 0 on error.
- */
-const char* xplra_multi_get_string_ptr(int bufferID, size_t datarefID,
-                                       size_t offset);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Destroy a multi-dataref buffer for the given connection.
- *
- * @param connectionID the ID of the connection for which the buffer
- * has been created.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_multi_destroy_buffer(int connectionID, int bufferID);
-
-/*----------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-
-/**
- * Show a message in the simulator window for the given duration.
- */
-int xplra_show_message(int connectionID, const char* message, float duration);
-
-/*----------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-
-/**
- * Register the given hotkey codes for listening. If there is an
- * existing set of hotkeys registered, those will be overwritten.
- */
-int xplra_register_hotkeys(int connectionID,
-                           const uint16_t* codes, size_t length);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Query the registered hotkeys whether they were pressed.
- */
-int xplra_query_hotkeys(int connectionID, uint8_t* states, size_t length);
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * Unregister the hotkeys.
- */
-int xplra_unregister_hotkeys(int connectionID);
-
-/*----------------------------------------------------------------------------*/
-/*----------------------------------------------------------------------------*/
-
-/**
- * Destroy the connection with the given ID.
- *
- * @return 0 on success, -1 on error.
- */
-int xplra_disconnect(int connectionID);
-
-/*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-/*----------------------------------------------------------------------------*/
-#endif // HU_VARADIISTVAN_XPLRA_XPLRA_H
Index: src/client/python/xplra.py
===================================================================
--- src/client/python/xplra.py	(revision 66)
+++ src/client/python/xplra.py	(revision 66)
@@ -0,0 +1,957 @@
+# X-Plane Remote Access client module
+#-------------------------------------------------------------------------------
+
+import os
+import struct
+import array
+
+#-------------------------------------------------------------------------------
+
+## @package xplra
+#
+# Python client module and C/C++ client library for the X-Plane Remote
+# Access plugin
+
+#-------------------------------------------------------------------------------
+
+## Protocol command: query the value of a single dataref
+COMMAND_GET_SINGLE = 0x01
+
+## Protocol command: set the value of a single dataref
+COMMAND_SET_SINGLE = 0x02
+
+## Protocol command: query the value of several datarefs
+COMMAND_GET_MULTI = 0x03
+
+## Protocol command: set the value of several datarefs
+COMMAND_SET_MULTI = 0x04
+
+## Protocol command: register a multi-dataref getter
+COMMAND_REGISTER_GET_MULTI = 0x11
+
+## Protocol command: unregister a multi-dataref getter
+COMMAND_UNREGISTER_GET_MULTI = 0x12
+
+## Protocol command: execute a registered multi-dataref getter
+COMMAND_EXECUTE_GET_MULTI = 0x13
+
+## Protocol command: register a multi-dataref setter
+COMMAND_REGISTER_SET_MULTI = 0x21
+
+## Protocol command: unregister a multi-dataref setter
+COMMAND_UNREGISTER_SET_MULTI = 0x22
+
+## Protocol command: execute a registered multi-dataref setter
+COMMAND_EXECUTE_SET_MULTI = 0x23
+
+## Protocol command: get the versions of X-Plane, XPLM and XPLRA
+COMMAND_GET_VERSIONS = 0x31
+
+## Protocol command: reload all plugins
+COMMAND_RELOAD_PLUGINS = 0x32
+
+## Protocol command: show a message to the pilot
+COMMAND_SHOW_MESSAGE = 0x41
+
+## Protocol command: register hotkeys
+COMMAND_REGISTER_HOTKEYS = 0x51
+
+## Protocol command: query the status of registered hotkeys
+COMMAND_QUERY_HOTKEYS = 0x52
+
+## Protocol command: unregister hotkeys
+COMMAND_UNREGISTER_HOTKEYS = 0x53
+
+## Protocol type constant: integer
+TYPE_INT = 0x01
+
+## Protocol type constant: single-precision floating point
+TYPE_FLOAT = 0x02
+
+## Protocol type constant: double-precision floating point
+TYPE_DOUBLE = 0x03
+
+## Protocol type constant: array of single-precision floating point values
+TYPE_FLOAT_ARRAY = 0x11
+
+## Protocol type constant: array of integers
+TYPE_INT_ARRAY = 0x12
+
+## Protocol type constant: array of bytes
+TYPE_BYTE_ARRAY = 0x13
+
+## Protocol result: OK
+RESULT_OK = 0x00
+
+## Protocol result: an invalid command was sent
+RESULT_INVALID_COMMAND = 0x01
+
+## Protocol result: an unknown dataref was attempted to query or set
+RESULT_UNKNOWN_DATAREF = 0x02
+
+## Protocol result: invalid type
+RESULT_INVALID_TYPE = 0x03
+
+## Protocol result: invalid length
+RESULT_INVALID_LENGTH = 0x04
+
+## Protocol result: invalid offset
+RESULT_INVALID_OFFSET = 0x05
+
+## Protocol result: invalid count
+RESULT_INVALID_COUNT = 0x06
+
+## Protocol result: invalid ID
+RESULT_INVALID_ID = 0x07
+
+## Protocol result: invalid duration
+RESULT_INVALID_DURATION = 0x08
+
+## Protocol result: other error
+RESULT_OTHER_ERROR = 0xff
+
+## Hotkey modifier: Shift
+HOTKEY_MODIFIER_SHIFT = 0x0100
+
+## Hotkey modifier: Control
+HOTKEY_MODIFIER_CONTROL = 0x0200
+
+#-------------------------------------------------------------------------------
+
+class ProtocolException(Exception):
+    """Exception to signify protocol errors."""
+
+    ## mapping from result codes to their string representation
+    _message = { RESULT_INVALID_COMMAND : "invalid command",
+                 RESULT_UNKNOWN_DATAREF : "unknown dataref",
+                 RESULT_INVALID_TYPE : "invalid type",
+                 RESULT_INVALID_LENGTH : "invalid length",
+                 RESULT_INVALID_OFFSET : "invalid offset",
+                 RESULT_INVALID_COUNT : "invalid count",
+                 RESULT_INVALID_ID : "invalid ID",
+                 RESULT_INVALID_DURATION : "invalid duration",
+                 RESULT_OTHER_ERROR : "other error" }
+
+    ## @var resultCode
+    # the result code, one of the RESULT_XXX constants
+    ## @var parameter
+    # an optional parameter for the result
+
+    @staticmethod
+    def getMessage(resultCode):
+        """Get the message for the given result code."""
+        if resultCode in ProtocolException._message:
+            return ProtocolException._message[resultCode]
+        else:
+            return "unknown error code " + `resultCode`
+
+    def __init__(self, resultCode, parameter = None):
+        """Construct the exception."""
+        message = "xplra.ProtocolException: " + self.getMessage(resultCode)
+        if parameter is not None:
+            if resultCode==RESULT_UNKNOWN_DATAREF:
+                message += " (# %d)" % (parameter,)
+
+        super(ProtocolException, self).__init__(message)
+        self.resultCode = resultCode
+        self.parameter = parameter
+
+#-------------------------------------------------------------------------------
+
+if os.name=="nt":
+    import win32file
+    import io
+
+    class Win32NamedPipe(io.RawIOBase):
+        """A stream object to represent a Win32 named pipe."""
+        ## @var _handle
+        # the Windows file handle for the pipe
+
+        def __init__(self, name):
+            """Construct the pipe with the given name."""
+            self._handle = win32file.CreateFile(name,
+                                                win32file.GENERIC_READ |
+                                                win32file.GENERIC_WRITE,
+                                                0, None,
+                                                win32file.OPEN_EXISTING, 0, None)
+
+        def close(self):
+            """Close the pipe, if not closed already."""
+            if self._handle is not None:
+                win32file.CloseHandle(self._handle)
+                self._handle = None
+
+        @property
+        def closed(self):
+            """Determine if the pipe is closed or not."""
+            return self._handle is None
+
+        def fileno(self):
+            """Get the file number, which is impossible."""
+            raise IOError("Win32NamedPipe.fileno: not supported")
+
+        def flush(self):
+            """Flush the stream."""
+            pass
+
+        def isatty(self):
+            """Determine if the stream is a terminal, which it is not."""
+            return False
+
+        def read(self, n = -1):
+            """Read at most the given number of bytes from the stream."""
+            if n==-1:
+                return self.readall()
+            else:
+                (error, data) = win32file.ReadFile(self._handle, n)
+                return data
+
+        def readable(self):
+            """Determine if the stream is readable, which it is."""
+            return self._handle is not None
+
+        def readall(self):
+            """Read all bytes from the stream, which is not supported."""
+            raise IOError("Win32NamedPipe.readall: not supported")
+
+        def readinto(self, buffer):
+            """Read into the given buffer."""
+            (error, data) = win32file.ReadFile(self._handle, len(buffer))
+            length = len(data)
+            buffer[:length] = data
+            return length
+
+        def readline(self, limit = -1):
+            """Read a line, which is currently not supported."""
+            raise IOError("Win32NamedPipe.readline: not supported")
+
+        def readlines(self, hint = -1):
+            """Read lines, which is currently not supported."""
+            raise IOError("Win32NamedPipe.readlines: not supported")
+
+        def seek(self, offset, whence = io.SEEK_SET):
+            """Seek in the stream, which is not supported."""
+            raise IOError("Win32NamedPipe.seek: not supported")
+
+        def seekable(self):
+            """Determine if the stream is seekable, which it is not."""
+            return False
+
+        def tell(self):
+            """Get the current position, which is not supported."""
+            raise IOError("Win32NamedPipe.tell: not supported")
+
+        def truncate(self, size = None):
+            """Truncate the stream, which is not supported."""
+            raise IOError("Win32NamedPipe.truncate: not supported")
+
+        def writable(self):
+            """Determine if the stream is writable, which it is."""
+            return self._handle is not None
+
+        def write(self, buffer):
+            """Write the given buffer into the stream."""
+            (error, written) = win32file.WriteFile(self._handle, buffer.tobytes())
+            return written
+
+        def writelines(self, lines):
+            """Write the given lines, which is not supported."""
+            raise IOError("Win32NamedPipe.writelines: not supported")
+
+#-------------------------------------------------------------------------------
+
+class XPlane(object):
+    """The main class representing the connection to X-Plane."""
+
+    ## @var _stream
+    # the data stream used to communicate with the plugin
+    ## @var _multiBuffers
+    # the list of multi-dataref buffers belonging to this object
+
+    @staticmethod
+    def _packLength(x):
+        """Pack the given integer as a variable-length value."""
+        s = ""
+        while True:
+            y = x&0x7f
+            x >>= 7
+            if x>0: y |= 0x80
+            s += struct.pack("B", y)
+            if x==0:
+                return s
+
+    @staticmethod
+    def _packString(s):
+        """Pack the given string."""
+        return XPlane._packLength(len(s)) + s
+
+    def __init__(self):
+        """Construct the object."""
+        self._stream = None
+        self._multiBuffers = []
+
+    def connect(self):
+        """Try to connect to X-Plane."""
+        if self._stream is not None:
+            return
+
+        if os.name=="nt":
+            pipe = Win32NamedPipe(r'\\.\pipe\\xplra')
+            self._stream = io.BufferedRWPair(pipe, pipe)
+        else:
+            import socket
+            s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            s.connect("/tmp/xplra-" + os.environ["LOGNAME"])
+            self._stream = s.makefile()
+
+        for multiBuffer in self._multiBuffers:
+            multiBuffer._reregister()
+
+    @property
+    def isConnected(self):
+        """Determine if we are connected to the simulator."""
+        return self._stream is not None
+
+    def createMultiGetter(self):
+        """Create a new multi-dataref getter for this X-Plane object."""
+        multiGetter = MultiGetter(self)
+        self._multiBuffers.append(multiGetter)
+        return multiGetter
+
+    def createMultiSetter(self):
+        """Create a new multi-dataref setter for this X-Plane object."""
+        multiSetter = MultiSetter(self)
+        self._multiBuffers.append(multiSetter)
+        return multiSetter
+
+    def destroyMultiBuffer(self, multiBuffer):
+        """Destroy the given multi-dataref buffer.
+
+        It actually removes it from the list of multiple buffers and
+        unregisters it safely.
+
+        Returns the result of the safe unregistration if the buffer was found,
+        None otherwise.
+        """
+        if multiBuffer in self._multiBuffers:
+            self._multiBuffers.remove(multiBuffer)
+            return multiBuffer.unregisterSafely()
+        else:
+            return None
+
+    def getVersions(self):
+        """Get the versions of X-Plane, XPLM and XPLRA as a tuple."""
+        self._writeU8(COMMAND_GET_VERSIONS)
+        self._flush()
+        self._checkResult()
+        return (self._readS32(), self._readS32(), self._readS32())
+
+    def reloadPlugins(self):
+        """Reload the plugins in X-Plane.
+
+        After this, this connection becomes invalid."""
+        self._writeU8(COMMAND_RELOAD_PLUGINS)
+        self._flush()
+        self._checkResult();
+
+    def getInt(self, name):
+        """Get the value of the integer dataref with the given name."""
+        return self._getSingle(name, TYPE_INT)
+
+    def getFloat(self, name):
+        """Get the value of the float dataref with the given name."""
+        return self._getSingle(name, TYPE_FLOAT)
+
+    def getDouble(self, name):
+        """Get the value of the double dataref with the given name."""
+        return self._getSingle(name, TYPE_DOUBLE)
+
+    def getFloatArray(self, name, length = -1, offset = 0):
+        """Get the value of the float array dataref with the given name."""
+        return self._getSingle(name, TYPE_FLOAT_ARRAY, length, offset)
+
+    def getIntArray(self, name, length = -1, offset = 0):
+        """Get the value of the integer array dataref with the given name."""
+        return self._getSingle(name, TYPE_INT_ARRAY, length, offset)
+
+    def getByteArray(self, name, length = -1, offset = 0):
+        """Get the value of the byte array dataref with the given name."""
+        return self._getSingle(name, TYPE_BYTE_ARRAY, length, offset)
+
+    def getString(self, name, offset = 0):
+        """Get the value of the byte array dataref with the given name as a
+        string."""
+        s = ""
+        for b in self.getByteArray(name, offset = offset):
+            if b==0: break
+            s += chr(b)
+        return s
+
+    def setInt(self, name, value):
+        """Set the value of the integer dataref with the given name."""
+        self._setSingle(name, TYPE_INT, value)
+
+    def setFloat(self, name, value):
+        """Set the value of the float dataref with the given name."""
+        self._setSingle(name, TYPE_FLOAT, value)
+
+    def setDouble(self, name, value):
+        """Set the value of the double dataref with the given name."""
+        self._setSingle(name, TYPE_DOUBLE, value)
+
+    def setFloatArray(self, name, value, offset = 0):
+        """Set the value of the float array dataref with the given name."""
+        self._setSingle(name, TYPE_FLOAT_ARRAY, value, offset = offset)
+
+    def setIntArray(self, name, value, offset = 0):
+        """Set the value of the integer array dataref with the given name."""
+        self._setSingle(name, TYPE_INT_ARRAY, value, offset = offset)
+
+    def setByteArray(self, name, value, offset = 0):
+        """Set the value of the byte array dataref with the given name."""
+        self._setSingle(name, TYPE_BYTE_ARRAY, value, offset = offset)
+
+    def setString(self, name, value, length, offset = 0):
+        """Set the value of the byte array dataref with the given name from a
+        string.
+
+        The string will be padded with 0's so that its length is the given
+        one."""
+        value = [ord(c) for c in value[:length]]
+        value += [0] * (length - len(value))
+        self.setByteArray(name, value, offset)
+
+    def showMessage(self, message, duration):
+        """Show a message in the simulator window for the given duration.
+
+        The duration is a floating-point number denoting seconds."""
+        self._writeU8(COMMAND_SHOW_MESSAGE)
+        self._writeString(message)
+        self._writeFloat(duration)
+        self._flush()
+        self._checkResult()
+
+    def registerHotkeys(self, hotkeyCodes):
+        """Register the given hotkey codes for watching."""
+        self._writeU8(COMMAND_REGISTER_HOTKEYS)
+        self._writeU32(len(hotkeyCodes))
+        for hotkeyCode in hotkeyCodes:
+            self._writeU16(hotkeyCode)
+        self._flush()
+        self._checkResult()
+
+    def queryHotkeys(self):
+        """Query the state of the hotkeys registered previously"""
+        self._writeU8(COMMAND_QUERY_HOTKEYS)
+        self._flush()
+        self._checkResult()
+
+        length = self._readU32()
+        states = []
+        for i in range(0, length):
+            states.append(self._readU8()!=0)
+
+        return states
+
+    def unregisterHotkeys(self):
+        """Unregister the previously registered hotkeys."""
+        self._writeU8(COMMAND_UNREGISTER_HOTKEYS)
+        self._flush()
+        self._checkResult()
+
+    def disconnect(self):
+        """Disconnect from X-Plane."""
+        if self._stream is not None:
+            try:
+                self._stream.close()
+            finally:
+                self._stream = None
+
+    def _checkResult(self, resultCode = None, parameter = None, multi = False):
+        """Check the given result code.
+
+        If it is None, it will be read first.
+
+        If it is not RESULT_OK, a ProtocolException is thrown."""
+
+        if resultCode is None:
+            resultCode = self._readU8()
+            if multi and resultCode==RESULT_UNKNOWN_DATAREF:
+                parameter = self._readU32()
+
+        if resultCode!=RESULT_OK:
+            raise ProtocolException(resultCode, parameter)
+
+    def _getSingle(self, name, type, length = None, offset = None):
+        """Get the single value of the given name and type."""
+        self._writeU8(COMMAND_GET_SINGLE)
+        self._writeString(name)
+        self._writeU8(type)
+        if length is not None and offset is not None:
+            self._writeS32(length)
+            self._writeS32(offset)
+
+        self._flush()
+        self._checkResult()
+        return self._readValue(type)
+
+    def _readValue(self, type):
+        """Read the value of the given type from the stream."""
+        if type==TYPE_INT:
+            return self._readS32()
+        elif type==TYPE_FLOAT:
+            return self._readFloat()
+        elif type==TYPE_DOUBLE:
+            return self._readDouble()
+        else:
+            length = self._readS32()
+            arr = None
+            elementSize = 4
+            if type==TYPE_FLOAT_ARRAY:
+                arr = array.array("f")
+            elif type==TYPE_INT_ARRAY:
+                arr = array.array("i")
+            elif type==TYPE_BYTE_ARRAY:
+                arr = array.array("B")
+                elementSize = 1
+            if arr is not None and length>0:
+                arr.fromstring(self._stream.read(length*elementSize))
+            return None if arr is None else arr.tolist()
+
+    def _setSingle(self, name, type, value, offset = None):
+        """Set the single value of the given name and type."""
+        self._writeU8(COMMAND_SET_SINGLE)
+        self._writeString(name)
+        self._writeU8(type)
+        if offset is not None:
+            self._writeS32(len(value))
+            self._writeS32(offset)
+
+        self._writeValue(type, value)
+        self._flush()
+        self._checkResult()
+
+    def _writeValue(self, type, value):
+        """Write a value of the given type."""
+        if type==TYPE_INT:
+            self._writeS32(int(value))
+        elif type==TYPE_FLOAT:
+            self._writeFloat(float(value))
+        elif type==TYPE_DOUBLE:
+            self._writeDouble(float(value))
+        else:
+            arr = None
+            if type==TYPE_FLOAT_ARRAY:
+                arr = array.array("f")
+            elif type==TYPE_INT_ARRAY:
+                arr = array.array("i")
+            elif type==TYPE_BYTE_ARRAY:
+                arr = array.array("B")
+            arr.fromlist(value)
+            self._stream.write(arr.tostring())
+
+    def _writeU8(self, x):
+        """Write the given value as an unsigned, 8-bit value."""
+        self._stream.write(struct.pack("B", x))
+
+    def _writeU16(self, x):
+        """Write the given value as an unsigned, 16-bit value."""
+        self._stream.write(struct.pack("H", x))
+
+    def _writeS32(self, x):
+        """Write the given value as a signed, 32-bit value."""
+        self._stream.write(struct.pack("i", x))
+
+    def _writeU32(self, x):
+        """Write the given value as an unsigned, 32-bit value."""
+        self._stream.write(struct.pack("I", x))
+
+    def _writeFloat(self, x):
+        """Write the given value as a single-precision floating point."""
+        self._stream.write(struct.pack("f", x))
+
+    def _writeDouble(self, x):
+        """Write the given value as a double-precision floating point."""
+        self._stream.write(struct.pack("d", x))
+
+    def _writeLength(self, length):
+        """Write the given value is a variable-length value into our stream."""
+        self._stream.write(self._packLength(length))
+
+    def _writeString(self, str):
+        """Write the given string into the stream."""
+        self._stream.write(self._packString(str))
+
+    def _flush(self):
+        """Flush our stream."""
+        self._stream.flush()
+
+    def _readU8(self):
+        """Read an unsigned, 8-bit value from the stream."""
+        (value,) = struct.unpack("B", self._stream.read(1))
+        return value
+
+    def _readS32(self):
+        """Read a signed, 32-bit value from the stream."""
+        (value,) = struct.unpack("i", self._stream.read(4))
+        return value
+
+    def _readU32(self):
+        """Read an unsigned, 32-bit value from the stream."""
+        (value,) = struct.unpack("I", self._stream.read(4))
+        return value
+
+    def _readFloat(self):
+        """Read a single-precision floating point value from the stream."""
+        (value,) = struct.unpack("f", self._stream.read(4))
+        return value
+
+    def _readDouble(self):
+        """Read a double-precision floating point value from the stream."""
+        (value,) = struct.unpack("d", self._stream.read(8))
+        return value
+
+    def _readLength(self):
+        """Read a variable-length value from our stream."""
+        length = 0
+        while True:
+            (x,) = struct.unpack("B", self._stream.read(1))
+            length <<= 7
+            length |= x&0x7f
+            if x&0x80==0:
+                return length
+
+    def _readString(self):
+        """Read a string from our stream."""
+        length = self._readLength()
+        return self._stream.read(length)
+
+#-------------------------------------------------------------------------------
+
+class MultiBuffer(object):
+    """Buffer for querying or setting multi-dataref values."""
+
+    ## @var _xplane
+    # the \ref XPlane object this buffer belongs to
+
+    ## @var _registerCommand
+    # the command used to perform the registration of this buffer
+    # (\ref COMMAND_REGISTER_GET_MULTI or \ref COMMAND_REGISTER_SET_MULTI)
+
+    ## @var _unregisterCommand
+    # the command used to perform the registration of this buffer
+    # (\ref COMMAND_UNREGISTER_GET_MULTI or \ref COMMAND_UNREGISTER_SET_MULTI)
+
+    ## @var _dataRefs
+    # the datarefs belonging to the buffer
+
+    ## @var _values
+    # the value of the datarefs before setting or after querying
+
+    ## @var _registeredID
+    # the ID with which the buffer is registered in X-Plane
+
+    @staticmethod
+    def _getDefault(type, length):
+        """Get the default value for the given type."""
+        if type==TYPE_INT:
+            return 0
+        elif type==TYPE_FLOAT:
+            return float(0.0)
+        elif type==TYPE_DOUBLE:
+            return 0.0
+        elif length<=0:
+            return []
+        elif type==TYPE_FLOAT_ARRAY:
+            return [float(0.0)] * length
+        elif type==TYPE_INT_ARRAY or type==TYPE_BYTE_ARRAY:
+            return [0] * length
+
+    def __init__(self, xplane, registerCommand, unregisterCommand):
+        """Construct the buffer for the given XPlane instance and with the
+        given register/unregister command values."""
+        self._xplane = xplane
+        self._registerCommand = registerCommand
+        self._unregisterCommand = unregisterCommand
+
+        self._dataRefs = []
+        self._values = None
+
+        self._registeredID = None
+
+    @property
+    def values(self):
+        """Query the values as a list."""
+        if self._values is None:
+            self.finalize()
+        return self._values
+
+    def addInt(self, name):
+        """Add an integer to the buffer with the given name
+
+        Returns an ID (or index) of the dataref."""
+        return self._add(name, TYPE_INT)
+
+    def addFloat(self, name):
+        """Add a float to the buffer with the given name
+
+        Returns an ID (or index) of the dataref."""
+        return self._add(name, TYPE_FLOAT)
+
+    def addDouble(self, name):
+        """Add a double to the buffer with the given name
+
+        Returns an ID (or index) of the dataref."""
+        return self._add(name, TYPE_DOUBLE)
+
+    def addFloatArray(self, name, length = -1, offset = 0):
+        """Add a floating point array to the buffer with the given name.
+
+        Returns an ID (or index) of the dataref."""
+        return self._add(name, TYPE_FLOAT_ARRAY, length, offset)
+
+    def addIntArray(self, name, length = -1, offset = 0):
+        """Add an integer array to the buffer with the given name.
+
+        Returns an ID (or index) of the dataref."""
+        return self._add(name, TYPE_INT_ARRAY, length, offset)
+
+    def addByteArray(self, name, length = -1, offset = 0):
+        """Add a byte array to the buffer with the given name.
+
+        Returns an ID (or index) of the dataref."""
+        return self._add(name, TYPE_BYTE_ARRAY, length, offset)
+
+    def finalize(self):
+        """Finalize the buffer, if not finalized yet.
+
+        It initializes the array of values with some defaults.
+
+        Returns whether there is any data in the buffer."""
+        if self._values is None:
+            self._values = [self._getDefault(type, length)
+                            for (_, type, length, _) in self._dataRefs]
+        return self._values!=[]
+
+    def register(self):
+        """Register the buffer in X-Plane."""
+        if self.finalize() and self._registeredID is None:
+            self._writeSpec(self._registerCommand)
+            self._registeredID = self._xplane._readU32()
+
+    def unregister(self):
+        """Unregister the buffer from X-Plane."""
+        if self._registeredID is not None:
+            self._xplane._writeU8(self._unregisterCommand)
+            self._xplane._writeU32(self._registeredID)
+            self._xplane._flush()
+            self._xplane._checkResult()
+            self._registeredID = None
+
+    def unregisterSafely(self):
+        """Unregister the buffer from X-Plane, ignoring exceptions.
+
+        Returns True if the unregistration succeeded, False otherwise.
+        """
+        try:
+            self.unregister()
+            return True
+        except:
+            return False
+        finally:
+            self._registeredID = None
+
+    def execute(self):
+        """Perform the querying or the setting of the values.
+
+        It first checks if the buffer is finalized. If not, it will be
+        finalized. However, if it is not finalized but also registered, it will
+        first be unregistered and the re-registered after finalizing."""
+        if self._values is None and self._registeredID is not None:
+            self.unregister()
+            self.register()
+        else:
+            self.finalize()
+
+        if self._registeredID is None:
+            self._executeUnregistered()
+        else:
+            self._executeRegistered()
+
+    def getString(self, id):
+        """Get the value of the dataref with the given ID as a string.
+
+        The dataref should be of type byte array."""
+        if self._dataRefs[id][1]!=TYPE_BYTE_ARRAY:
+            raise TypeError("xplra.MultiBuffer.getString: only byte arrays can be converted to strings")
+        if self._values is None:
+            self.finalize()
+        s = ""
+        for c in self._values[id]:
+            if c==0: break
+            s += chr(c)
+        return s
+
+    def _reregister(self):
+        """Re-register the buffer in X-Plane, if it has been registered earlier
+
+        If it has not been registered, nothing is done. Otherwise the buffer
+        gets registered, and the old ID is forgotten. This function is meant to
+        be used by the XPlane object when it creates a new connection. If the
+        registration fails, the original ID is restored, so the _reregister()
+        could be called again
+        """
+        if self._registeredID is not None:
+            origRegisteredID = self._registeredID
+            try:
+                self._registeredID = None
+                self.register()
+            except:
+                self._registeredID = origRegisteredID
+                raise
+
+    def _add(self, name, type, length = None, offset = None):
+        """Add a scalar to the buffer with the given name and type"""
+        index = len(self._dataRefs)
+        self._values = None
+        self._dataRefs.append( (name, type, length, offset) )
+        return index
+
+    def _writeSpec(self, command):
+        """Write the specification preceded by the given command and check for
+        the result.
+
+        The specification is basically the list of the datarefs."""
+        self._xplane._writeU8(command)
+        self._xplane._writeU32(len(self._dataRefs))
+
+        for (name, type, length, offset) in self._dataRefs:
+            self._xplane._writeString(name)
+            self._xplane._writeU8(type)
+            if length is not None and offset is not None:
+                self._xplane._writeS32(length)
+                self._xplane._writeS32(offset)
+
+        self._xplane._flush()
+        self._xplane._checkResult(multi = True)
+
+    def __len__(self):
+        """Get the number of value items in the buffer."""
+        if self._values is None:
+            self.finalize()
+        return len(self._values)
+
+    def __getitem__(self, id):
+        """Get the item with the given ID."""
+        if self._values is None:
+            self.finalize()
+        return self._values[id]
+
+    def __setitem__(self, id, value):
+        """Set the item with the given ID."""
+        if self._values is None:
+            self.finalize()
+        type = self._dataRefs[id][1]
+        length = self._dataRefs[id][2]
+        if type==TYPE_INT:
+            self._values[id] = int(value)
+        elif type==TYPE_FLOAT or type==TYPE_DOUBLE:
+            self._values[id] = float(value)
+        elif type==TYPE_FLOAT_ARRAY:
+            if len(value)!=length:
+                raise ValueError("xplra.MultiBuffer: expected a list of length %d" % (length,))
+            self._values[id] = [float(x) for x in value]
+        elif type==TYPE_INT_ARRAY:
+            if len(value)!=length:
+                raise ValueError("xplra.MultiBuffer: expected a list of length %d" % (length,))
+            self._values[id] = [int(x) for x in value]
+        elif type==TYPE_BYTE_ARRAY:
+            if isinstance(value, str):
+                lst = [ord(x) for x in value[:length]]
+                if len(lst)<length:
+                    lst += [0] * (length-len(lst))
+                self._values[id] = lst
+            else:
+                if len(value)!=length:
+                    raise ValueError("xplra.MultiBuffer: expected a list of length %d" % (length,))
+                self._values[id] = [int(x) for x in value]
+
+    def __iter__(self):
+        """Get an iterator over the values of this buffer."""
+        if self._values is None:
+            self.finalize()
+        return iter(self._values)
+
+
+#-------------------------------------------------------------------------------
+
+class MultiGetter(MultiBuffer):
+    """Multi-dataref buffer for querying."""
+    def __init__(self, xplane):
+        """Construct the getter."""
+        super(MultiGetter, self).__init__(xplane,
+                                          COMMAND_REGISTER_GET_MULTI,
+                                          COMMAND_UNREGISTER_GET_MULTI)
+
+    def _executeRegistered(self):
+        """Execute the query if the buffer is registered."""
+        self._xplane._writeU8(COMMAND_EXECUTE_GET_MULTI)
+        self._xplane._writeU32(self._registeredID)
+        self._xplane._flush()
+
+        self._xplane._checkResult(multi = True)
+
+        self._readValues()
+
+    def _executeUnregistered(self):
+        """Execute the query if the buffer is not registered."""
+        self._writeSpec(COMMAND_GET_MULTI)
+        self._readValues()
+
+    def _readValues(self):
+        """Read the values into the values array."""
+        for i in range(0, len(self._dataRefs)):
+            self._values[i] = self._xplane._readValue(self._dataRefs[i][1])
+
+#-------------------------------------------------------------------------------
+
+class MultiSetter(MultiBuffer):
+    """Multi-dataref buffer for setting."""
+    def __init__(self, xplane):
+        """Construct the getter."""
+        super(MultiSetter, self).__init__(xplane,
+                                          COMMAND_REGISTER_SET_MULTI,
+                                          COMMAND_UNREGISTER_SET_MULTI)
+
+    def _executeRegistered(self):
+        """Execute the query if the buffer is registered."""
+        self._xplane._writeU8(COMMAND_EXECUTE_SET_MULTI)
+        self._xplane._writeU32(self._registeredID)
+        for i in range(0, len(self._dataRefs)):
+            self._xplane._writeValue(self._dataRefs[i][1], self._values[i])
+        self._xplane._flush()
+
+        self._xplane._checkResult(multi = True)
+
+    def _executeUnregistered(self):
+        """Execute the query if the buffer is not registered."""
+        self._xplane._writeU8(COMMAND_SET_MULTI)
+
+        numDataRefs = len(self._dataRefs)
+        self._xplane._writeU32(numDataRefs)
+
+        for i in range(0, numDataRefs):
+            (name, type, length, offset) = self._dataRefs[i]
+            value = self._values[i]
+
+            self._xplane._writeString(name)
+            self._xplane._writeU8(type)
+            if length is not None and offset is not None:
+                self._xplane._writeS32(len(value))
+                self._xplane._writeS32(offset)
+            self._xplane._writeValue(type, value)
+
+        self._xplane._flush()
+        self._xplane._checkResult(multi = True)
+
+#-------------------------------------------------------------------------------
Index: src/client/python/xplra.py
===================================================================
--- src/client/python/xplra.py	(revision 64)
+++ 	(revision )
@@ -1,879 +1,0 @@
-# X-Plane Remote Access client module
-#-------------------------------------------------------------------------------
-
-import os
-import struct
-import array
-
-#-------------------------------------------------------------------------------
-
-COMMAND_GET_SINGLE = 0x01
-
-COMMAND_SET_SINGLE = 0x02
-
-COMMAND_GET_MULTI = 0x03
-
-COMMAND_SET_MULTI = 0x04
-
-COMMAND_REGISTER_GET_MULTI = 0x11
-
-COMMAND_UNREGISTER_GET_MULTI = 0x12
-
-COMMAND_EXECUTE_GET_MULTI = 0x13
-
-COMMAND_REGISTER_SET_MULTI = 0x21
-
-COMMAND_UNREGISTER_SET_MULTI = 0x22
-
-COMMAND_EXECUTE_SET_MULTI = 0x23
-
-COMMAND_GET_VERSIONS = 0x31
-
-COMMAND_RELOAD_PLUGINS = 0x32
-
-COMMAND_SHOW_MESSAGE = 0x41
-
-COMMAND_REGISTER_HOTKEYS = 0x51
-
-COMMAND_QUERY_HOTKEYS = 0x52
-
-COMMAND_UNREGISTER_HOTKEYS = 0x53
-
-TYPE_INT = 0x01
-
-TYPE_FLOAT = 0x02
-
-TYPE_DOUBLE = 0x03
-
-TYPE_FLOAT_ARRAY = 0x11
-
-TYPE_INT_ARRAY = 0x12
-
-TYPE_BYTE_ARRAY = 0x13
-
-RESULT_OK = 0x00
-
-RESULT_INVALID_COMMAND = 0x01
-
-RESULT_UNKNOWN_DATAREF = 0x02
-
-RESULT_INVALID_TYPE = 0x03
-
-RESULT_INVALID_LENGTH = 0x04
-
-RESULT_INVALID_OFFSET = 0x05
-
-RESULT_INVALID_COUNT = 0x06
-
-RESULT_INVALID_ID = 0x07
-
-RESULT_INVALID_DURATION = 0x08
-
-RESULT_OTHER_ERROR = 0xff
-
-HOTKEY_MODIFIER_SHIFT = 0x0100
-
-HOTKEY_MODIFIER_CONTROL = 0x0200
-
-#-------------------------------------------------------------------------------
-
-class ProtocolException(Exception):
-    """Exception to signify protocol errors."""
-    _message = { RESULT_INVALID_COMMAND : "invalid command",
-                 RESULT_UNKNOWN_DATAREF : "unknown dataref",
-                 RESULT_INVALID_TYPE : "invalid type",
-                 RESULT_INVALID_LENGTH : "invalid length",
-                 RESULT_INVALID_OFFSET : "invalid offset",
-                 RESULT_INVALID_COUNT : "invalid count",
-                 RESULT_INVALID_ID : "invalid ID",
-                 RESULT_INVALID_DURATION : "invalid duration",
-                 RESULT_OTHER_ERROR : "other error" }
-
-    @staticmethod
-    def getMessage(resultCode):
-        """Get the message for the given result code."""
-        if resultCode in ProtocolException._message:
-            return ProtocolException._message[resultCode]
-        else:
-            return "unknown error code " + `resultCode`
-
-    def __init__(self, resultCode, parameter = None):
-        message = "xplra.ProtocolException: " + self.getMessage(resultCode)
-        if parameter is not None:
-            if resultCode==RESULT_UNKNOWN_DATAREF:
-                message += " (# %d)" % (parameter,)
-
-        super(ProtocolException, self).__init__(message)
-        self.resultCode = resultCode
-        self.parameter = parameter
-
-#-------------------------------------------------------------------------------
-
-if os.name=="nt":
-    import win32file
-    import io
-
-    class Win32NamedPipe(io.RawIOBase):
-        """A stream object to represent a Win32 named pipe."""
-        def __init__(self, name):
-            """Construct the pipe with the given name."""
-            self._handle = win32file.CreateFile(name,
-                                                win32file.GENERIC_READ |
-                                                win32file.GENERIC_WRITE,
-                                                0, None,
-                                                win32file.OPEN_EXISTING, 0, None)
-
-        def close(self):
-            """Close the pipe, if not closed already."""
-            if self._handle is not None:
-                win32file.CloseHandle(self._handle)
-                self._handle = None
-
-        @property
-        def closed(self):
-            """Determine if the pipe is closed or not."""
-            return self._handle is None
-
-        def fileno(self):
-            """Get the file number, which is impossible."""
-            raise IOError("Win32NamedPipe.fileno: not supported")
-
-        def flush(self):
-            """Flush the stream."""
-            pass
-
-        def isatty(self):
-            """Determine if the stream is a terminal, which it is not."""
-            return False
-
-        def read(self, n = -1):
-            """Read at most the given number of bytes from the stream."""
-            if n==-1:
-                return self.readall()
-            else:
-                (error, data) = win32file.ReadFile(self._handle, n)
-                return data
-
-        def readable(self):
-            """Determine if the stream is readable, which it is."""
-            return self._handle is not None
-
-        def readall(self):
-            """Read all bytes from the stream, which is not supported."""
-            raise IOError("Win32NamedPipe.readall: not supported")
-
-        def readinto(self, buffer):
-            """Read into the given buffer."""
-            (error, data) = win32file.ReadFile(self._handle, len(buffer))
-            length = len(data)
-            buffer[:length] = data
-            return length
-
-        def readline(self, limit = -1):
-            """Read a line, which is currently not supported."""
-            raise IOError("Win32NamedPipe.readline: not supported")
-
-        def readlines(self, hint = -1):
-            """Read lines, which is currently not supported."""
-            raise IOError("Win32NamedPipe.readlines: not supported")
-
-        def seek(self, offset, whence = io.SEEK_SET):
-            """Seek in the stream, which is not supported."""
-            raise IOError("Win32NamedPipe.seek: not supported")
-
-        def seekable(self):
-            """Determine if the stream is seekable, which it is not."""
-            return False
-
-        def tell(self):
-            """Get the current position, which is not supported."""
-            raise IOError("Win32NamedPipe.tell: not supported")
-
-        def truncate(self, size = None):
-            """Truncate the stream, which is not supported."""
-            raise IOError("Win32NamedPipe.truncate: not supported")
-
-        def writable(self):
-            """Determine if the stream is writable, which it is."""
-            return self._handle is not None
-
-        def write(self, buffer):
-            """Write the given buffer into the stream."""
-            (error, written) = win32file.WriteFile(self._handle, buffer.tobytes())
-            return written
-
-        def writelines(self, lines):
-            """Write the given lines, which is not supported."""
-            raise IOError("Win32NamedPipe.writelines: not supported")
-
-#-------------------------------------------------------------------------------
-
-class XPlane(object):
-    """The main class representing the connection to X-Plane."""
-
-    @staticmethod
-    def _packLength(x):
-        """Pack the given integer as a variable-length value."""
-        s = ""
-        while True:
-            y = x&0x7f
-            x >>= 7
-            if x>0: y |= 0x80
-            s += struct.pack("B", y)
-            if x==0:
-                return s
-
-    @staticmethod
-    def _packString(s):
-        """Pack the given string."""
-        return XPlane._packLength(len(s)) + s
-
-    def __init__(self):
-        """Construct the object."""
-        self._stream = None
-        self._multiBuffers = []
-
-    def connect(self):
-        """Try to connect to X-Plane."""
-        if self._stream is not None:
-            return
-
-        if os.name=="nt":
-            pipe = Win32NamedPipe(r'\\.\pipe\\xplra')
-            self._stream = io.BufferedRWPair(pipe, pipe)
-        else:
-            import socket
-            s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-            s.connect("/tmp/xplra-" + os.environ["LOGNAME"])
-            self._stream = s.makefile()
-
-        for multiBuffer in self._multiBuffers:
-            multiBuffer._reregister()
-
-    @property
-    def isConnected(self):
-        """Determine if we are connected to the simulator."""
-        return self._stream is not None
-
-    def createMultiGetter(self):
-        """Create a new multi-dataref getter for this X-Plane object."""
-        multiGetter = MultiGetter(self)
-        self._multiBuffers.append(multiGetter)
-        return multiGetter
-
-    def createMultiSetter(self):
-        """Create a new multi-dataref setter for this X-Plane object."""
-        multiSetter = MultiSetter(self)
-        self._multiBuffers.append(multiSetter)
-        return multiSetter
-
-    def destroyMultiBuffer(self, multiBuffer):
-        """Destroy the given multi-dataref buffer.
-
-        It actually removes it from the list of multiple buffers and
-        unregisters it safely.
-
-        Returns the result of the safe unregistration if the buffer was found,
-        None otherwise.
-        """
-        if multiBuffer in self._multiBuffers:
-            self._multiBuffers.remove(multiBuffer)
-            return multiBuffer.unregisterSafely()
-        else:
-            return None
-
-    def getVersions(self):
-        """Get the versions of X-Plane, XPLM and XPLRA as a tuple."""
-        self._writeU8(COMMAND_GET_VERSIONS)
-        self._flush()
-        self._checkResult()
-        return (self._readS32(), self._readS32(), self._readS32())
-
-    def reloadPlugins(self):
-        """Reload the plugins in X-Plane.
-
-        After this, this connection becomes invalid."""
-        self._writeU8(COMMAND_RELOAD_PLUGINS)
-        self._flush()
-        self._checkResult();
-
-    def getInt(self, name):
-        """Get the value of the integer dataref with the given name."""
-        return self._getSingle(name, TYPE_INT)
-
-    def getFloat(self, name):
-        """Get the value of the float dataref with the given name."""
-        return self._getSingle(name, TYPE_FLOAT)
-
-    def getDouble(self, name):
-        """Get the value of the double dataref with the given name."""
-        return self._getSingle(name, TYPE_DOUBLE)
-
-    def getFloatArray(self, name, length = -1, offset = 0):
-        """Get the value of the float array dataref with the given name."""
-        return self._getSingle(name, TYPE_FLOAT_ARRAY, length, offset)
-
-    def getIntArray(self, name, length = -1, offset = 0):
-        """Get the value of the integer array dataref with the given name."""
-        return self._getSingle(name, TYPE_INT_ARRAY, length, offset)
-
-    def getByteArray(self, name, length = -1, offset = 0):
-        """Get the value of the byte array dataref with the given name."""
-        return self._getSingle(name, TYPE_BYTE_ARRAY, length, offset)
-
-    def getString(self, name, offset = 0):
-        """Get the value of the byte array dataref with the given name as a
-        string."""
-        s = ""
-        for b in self.getByteArray(name, offset = offset):
-            if b==0: break
-            s += chr(b)
-        return s
-
-    def setInt(self, name, value):
-        """Set the value of the integer dataref with the given name."""
-        self._setSingle(name, TYPE_INT, value)
-
-    def setFloat(self, name, value):
-        """Set the value of the float dataref with the given name."""
-        self._setSingle(name, TYPE_FLOAT, value)
-
-    def setDouble(self, name, value):
-        """Set the value of the double dataref with the given name."""
-        self._setSingle(name, TYPE_DOUBLE, value)
-
-    def setFloatArray(self, name, value, offset = 0):
-        """Set the value of the float array dataref with the given name."""
-        self._setSingle(name, TYPE_FLOAT_ARRAY, value, offset = offset)
-
-    def setIntArray(self, name, value, offset = 0):
-        """Set the value of the integer array dataref with the given name."""
-        self._setSingle(name, TYPE_INT_ARRAY, value, offset = offset)
-
-    def setByteArray(self, name, value, offset = 0):
-        """Set the value of the byte array dataref with the given name."""
-        self._setSingle(name, TYPE_BYTE_ARRAY, value, offset = offset)
-
-    def setString(self, name, value, length, offset = 0):
-        """Set the value of the byte array dataref with the given name from a
-        string.
-
-        The string will be padded with 0's so that its length is the given
-        one."""
-        value = [ord(c) for c in value[:length]]
-        value += [0] * (length - len(value))
-        self.setByteArray(name, value, offset)
-
-    def showMessage(self, message, duration):
-        """Show a message in the simulator window for the given duration.
-
-        The duration is a floating-point number denoting seconds."""
-        self._writeU8(COMMAND_SHOW_MESSAGE)
-        self._writeString(message)
-        self._writeFloat(duration)
-        self._flush()
-        self._checkResult()
-
-    def registerHotkeys(self, hotkeyCodes):
-        """Register the given hotkey codes for watching."""
-        self._writeU8(COMMAND_REGISTER_HOTKEYS)
-        self._writeU32(len(hotkeyCodes))
-        for hotkeyCode in hotkeyCodes:
-            self._writeU16(hotkeyCode)
-        self._flush()
-        self._checkResult()
-
-    def queryHotkeys(self):
-        """Query the state of the hotkeys registered previously"""
-        self._writeU8(COMMAND_QUERY_HOTKEYS)
-        self._flush()
-        self._checkResult()
-
-        length = self._readU32()
-        states = []
-        for i in range(0, length):
-            states.append(self._readU8()!=0)
-
-        return states
-
-    def unregisterHotkeys(self):
-        """Unregister the previously registered hotkeys."""
-        self._writeU8(COMMAND_UNREGISTER_HOTKEYS)
-        self._flush()
-        self._checkResult()
-
-    def disconnect(self):
-        """Disconnect from X-Plane."""
-        if self._stream is not None:
-            try:
-                self._stream.close()
-            finally:
-                self._stream = None
-
-    def _checkResult(self, resultCode = None, parameter = None, multi = False):
-        """Check the given result code.
-
-        If it is None, it will be read first.
-
-        If it is not RESULT_OK, a ProtocolException is thrown."""
-
-        if resultCode is None:
-            resultCode = self._readU8()
-            if multi and resultCode==RESULT_UNKNOWN_DATAREF:
-                parameter = self._readU32()
-
-        if resultCode!=RESULT_OK:
-            raise ProtocolException(resultCode, parameter)
-
-    def _getSingle(self, name, type, length = None, offset = None):
-        """Get the single value of the given name and type."""
-        self._writeU8(COMMAND_GET_SINGLE)
-        self._writeString(name)
-        self._writeU8(type)
-        if length is not None and offset is not None:
-            self._writeS32(length)
-            self._writeS32(offset)
-
-        self._flush()
-        self._checkResult()
-        return self._readValue(type)
-
-    def _readValue(self, type):
-        """Read the value of the given type from the stream."""
-        if type==TYPE_INT:
-            return self._readS32()
-        elif type==TYPE_FLOAT:
-            return self._readFloat()
-        elif type==TYPE_DOUBLE:
-            return self._readDouble()
-        else:
-            length = self._readS32()
-            arr = None
-            elementSize = 4
-            if type==TYPE_FLOAT_ARRAY:
-                arr = array.array("f")
-            elif type==TYPE_INT_ARRAY:
-                arr = array.array("i")
-            elif type==TYPE_BYTE_ARRAY:
-                arr = array.array("B")
-                elementSize = 1
-            if arr is not None and length>0:
-                arr.fromstring(self._stream.read(length*elementSize))
-            return None if arr is None else arr.tolist()
-
-    def _setSingle(self, name, type, value, offset = None):
-        """Set the single value of the given name and type."""
-        self._writeU8(COMMAND_SET_SINGLE)
-        self._writeString(name)
-        self._writeU8(type)
-        if offset is not None:
-            self._writeS32(len(value))
-            self._writeS32(offset)
-
-        self._writeValue(type, value)
-        self._flush()
-        self._checkResult()
-
-    def _writeValue(self, type, value):
-        """Write a value of the given type."""
-        if type==TYPE_INT:
-            self._writeS32(int(value))
-        elif type==TYPE_FLOAT:
-            self._writeFloat(float(value))
-        elif type==TYPE_DOUBLE:
-            self._writeDouble(float(value))
-        else:
-            arr = None
-            if type==TYPE_FLOAT_ARRAY:
-                arr = array.array("f")
-            elif type==TYPE_INT_ARRAY:
-                arr = array.array("i")
-            elif type==TYPE_BYTE_ARRAY:
-                arr = array.array("B")
-            arr.fromlist(value)
-            self._stream.write(arr.tostring())
-
-    def _writeU8(self, x):
-        """Write the given value as an unsigned, 8-bit value."""
-        self._stream.write(struct.pack("B", x))
-
-    def _writeU16(self, x):
-        """Write the given value as an unsigned, 16-bit value."""
-        self._stream.write(struct.pack("H", x))
-
-    def _writeS32(self, x):
-        """Write the given value as a signed, 32-bit value."""
-        self._stream.write(struct.pack("i", x))
-
-    def _writeU32(self, x):
-        """Write the given value as an unsigned, 32-bit value."""
-        self._stream.write(struct.pack("I", x))
-
-    def _writeFloat(self, x):
-        """Write the given value as a single-precision floating point."""
-        self._stream.write(struct.pack("f", x))
-
-    def _writeDouble(self, x):
-        """Write the given value as a double-precision floating point."""
-        self._stream.write(struct.pack("d", x))
-
-    def _writeLength(self, length):
-        """Write the given value is a variable-length value into our stream."""
-        self._stream.write(self._packLength(length))
-
-    def _writeString(self, str):
-        """Write the given string into the stream."""
-        self._stream.write(self._packString(str))
-
-    def _flush(self):
-        """Flush our stream."""
-        self._stream.flush()
-
-    def _readU8(self):
-        """Read an unsigned, 8-bit value from the stream."""
-        (value,) = struct.unpack("B", self._stream.read(1))
-        return value
-
-    def _readS32(self):
-        """Read a signed, 32-bit value from the stream."""
-        (value,) = struct.unpack("i", self._stream.read(4))
-        return value
-
-    def _readU32(self):
-        """Read an unsigned, 32-bit value from the stream."""
-        (value,) = struct.unpack("I", self._stream.read(4))
-        return value
-
-    def _readFloat(self):
-        """Read a single-precision floating point value from the stream."""
-        (value,) = struct.unpack("f", self._stream.read(4))
-        return value
-
-    def _readDouble(self):
-        """Read a double-precision floating point value from the stream."""
-        (value,) = struct.unpack("d", self._stream.read(8))
-        return value
-
-    def _readLength(self):
-        """Read a variable-length value from our stream."""
-        length = 0
-        while True:
-            (x,) = struct.unpack("B", self._stream.read(1))
-            length <<= 7
-            length |= x&0x7f
-            if x&0x80==0:
-                return length
-
-    def _readString(self):
-        """Read a string from our stream."""
-        length = self._readLength()
-        return self._stream.read(length)
-
-#-------------------------------------------------------------------------------
-
-class MultiBuffer(object):
-    """Buffer for querying or setting multi-dataref values."""
-    @staticmethod
-    def _getDefault(type, length):
-        """Get the default value for the given type."""
-        if type==TYPE_INT:
-            return 0
-        elif type==TYPE_FLOAT:
-            return float(0.0)
-        elif type==TYPE_DOUBLE:
-            return 0.0
-        elif length<=0:
-            return []
-        elif type==TYPE_FLOAT_ARRAY:
-            return [float(0.0)] * length
-        elif type==TYPE_INT_ARRAY or type==TYPE_BYTE_ARRAY:
-            return [0] * length
-
-    def __init__(self, xplane, registerCommand, unregisterCommand):
-        """Construct the buffer for the given XPlane instance and with the
-        given register/unregister command values."""
-        self._xplane = xplane
-        self._registerCommand = registerCommand
-        self._unregisterCommand = unregisterCommand
-
-        self._dataRefs = []
-        self._values = None
-
-        self._registeredID = None
-
-    @property
-    def values(self):
-        """Query the values as a list."""
-        if self._values is None:
-            self.finalize()
-        return self._values
-
-    def addInt(self, name):
-        """Add an integer to the buffer with the given name
-
-        Returns an ID (or index) of the dataref."""
-        return self._add(name, TYPE_INT)
-
-    def addFloat(self, name):
-        """Add a float to the buffer with the given name
-
-        Returns an ID (or index) of the dataref."""
-        return self._add(name, TYPE_FLOAT)
-
-    def addDouble(self, name):
-        """Add a double to the buffer with the given name
-
-        Returns an ID (or index) of the dataref."""
-        return self._add(name, TYPE_DOUBLE)
-
-    def addFloatArray(self, name, length = -1, offset = 0):
-        """Add a floating point array to the buffer with the given name.
-
-        Returns an ID (or index) of the dataref."""
-        return self._add(name, TYPE_FLOAT_ARRAY, length, offset)
-
-    def addIntArray(self, name, length = -1, offset = 0):
-        """Add an integer array to the buffer with the given name.
-
-        Returns an ID (or index) of the dataref."""
-        return self._add(name, TYPE_INT_ARRAY, length, offset)
-
-    def addByteArray(self, name, length = -1, offset = 0):
-        """Add a byte array to the buffer with the given name.
-
-        Returns an ID (or index) of the dataref."""
-        return self._add(name, TYPE_BYTE_ARRAY, length, offset)
-
-    def finalize(self):
-        """Finalize the buffer, if not finalized yet.
-
-        It initializes the array of values with some defaults.
-
-        Returns whether there is any data in the buffer."""
-        if self._values is None:
-            self._values = [self._getDefault(type, length)
-                            for (_, type, length, _) in self._dataRefs]
-        return self._values!=[]
-
-    def register(self):
-        """Register the buffer in X-Plane."""
-        if self.finalize() and self._registeredID is None:
-            self._writeSpec(self._registerCommand)
-            self._registeredID = self._xplane._readU32()
-
-    def unregister(self):
-        """Unregister the buffer from X-Plane."""
-        if self._registeredID is not None:
-            self._xplane._writeU8(self._unregisterCommand)
-            self._xplane._writeU32(self._registeredID)
-            self._xplane._flush()
-            self._xplane._checkResult()
-            self._registeredID = None
-
-    def unregisterSafely(self):
-        """Unregister the buffer from X-Plane, ignoring exceptions.
-
-        Returns True if the unregistration succeeded, False otherwise.
-        """
-        try:
-            self.unregister()
-            return True
-        except:
-            return False
-        finally:
-            self._registeredID = None
-
-    def execute(self):
-        """Perform the querying or the setting of the values.
-
-        It first checks if the buffer is finalized. If not, it will be
-        finalized. However, if it is not finalized but also registered, it will
-        first be unregistered and the re-registered after finalizing."""
-        if self._values is None and self._registeredID is not None:
-            self.unregister()
-            self.register()
-        else:
-            self.finalize()
-
-        if self._registeredID is None:
-            self._executeUnregistered()
-        else:
-            self._executeRegistered()
-
-    def getString(self, id):
-        """Get the value of the dataref with the given ID as a string.
-
-        The dataref should be of type byte array."""
-        if self._dataRefs[id][1]!=TYPE_BYTE_ARRAY:
-            raise TypeError("xplra.MultiBuffer.getString: only byte arrays can be converted to strings")
-        if self._values is None:
-            self.finalize()
-        s = ""
-        for c in self._values[id]:
-            if c==0: break
-            s += chr(c)
-        return s
-
-    def _reregister(self):
-        """Re-register the buffer in X-Plane, if it has been registered earlier
-
-        If it has not been registered, nothing is done. Otherwise the buffer
-        gets registered, and the old ID is forgotten. This function is meant to
-        be used by the XPlane object when it creates a new connection. If the
-        registration fails, the original ID is restored, so the _reregister()
-        could be called again
-        """
-        if self._registeredID is not None:
-            origRegisteredID = self._registeredID
-            try:
-                self._registeredID = None
-                self.register()
-            except:
-                self._registeredID = origRegisteredID
-                raise
-
-    def _add(self, name, type, length = None, offset = None):
-        """Add a scalar to the buffer with the given name and type"""
-        index = len(self._dataRefs)
-        self._values = None
-        self._dataRefs.append( (name, type, length, offset) )
-        return index
-
-    def _writeSpec(self, command):
-        """Write the specification preceded by the given command and check for
-        the result.
-
-        The specification is basically the list of the datarefs."""
-        self._xplane._writeU8(command)
-        self._xplane._writeU32(len(self._dataRefs))
-
-        for (name, type, length, offset) in self._dataRefs:
-            self._xplane._writeString(name)
-            self._xplane._writeU8(type)
-            if length is not None and offset is not None:
-                self._xplane._writeS32(length)
-                self._xplane._writeS32(offset)
-
-        self._xplane._flush()
-        self._xplane._checkResult(multi = True)
-
-    def __len__(self):
-        """Get the number of value items in the buffer."""
-        if self._values is None:
-            self.finalize()
-        return len(self._values)
-
-    def __getitem__(self, id):
-        """Get the item with the given ID."""
-        if self._values is None:
-            self.finalize()
-        return self._values[id]
-
-    def __setitem__(self, id, value):
-        """Set the item with the given ID."""
-        if self._values is None:
-            self.finalize()
-        type = self._dataRefs[id][1]
-        length = self._dataRefs[id][2]
-        if type==TYPE_INT:
-            self._values[id] = int(value)
-        elif type==TYPE_FLOAT or type==TYPE_DOUBLE:
-            self._values[id] = float(value)
-        elif type==TYPE_FLOAT_ARRAY:
-            if len(value)!=length:
-                raise ValueError("xplra.MultiBuffer: expected a list of length %d" % (length,))
-            self._values[id] = [float(x) for x in value]
-        elif type==TYPE_INT_ARRAY:
-            if len(value)!=length:
-                raise ValueError("xplra.MultiBuffer: expected a list of length %d" % (length,))
-            self._values[id] = [int(x) for x in value]
-        elif type==TYPE_BYTE_ARRAY:
-            if isinstance(value, str):
-                lst = [ord(x) for x in value[:length]]
-                if len(lst)<length:
-                    lst += [0] * (length-len(lst))
-                self._values[id] = lst
-            else:
-                if len(value)!=length:
-                    raise ValueError("xplra.MultiBuffer: expected a list of length %d" % (length,))
-                self._values[id] = [int(x) for x in value]
-
-    def __iter__(self):
-        """Get an iterator over the values of this buffer."""
-        if self._values is None:
-            self.finalize()
-        return iter(self._values)
-
-
-#-------------------------------------------------------------------------------
-
-class MultiGetter(MultiBuffer):
-    """Multi-dataref buffer for querying."""
-    def __init__(self, xplane):
-        """Construct the getter."""
-        super(MultiGetter, self).__init__(xplane,
-                                          COMMAND_REGISTER_GET_MULTI,
-                                          COMMAND_UNREGISTER_GET_MULTI)
-
-    def _executeRegistered(self):
-        """Execute the query if the buffer is registered."""
-        self._xplane._writeU8(COMMAND_EXECUTE_GET_MULTI)
-        self._xplane._writeU32(self._registeredID)
-        self._xplane._flush()
-
-        self._xplane._checkResult(multi = True)
-
-        self._readValues()
-
-    def _executeUnregistered(self):
-        """Execute the query if the buffer is not registered."""
-        self._writeSpec(COMMAND_GET_MULTI)
-        self._readValues()
-
-    def _readValues(self):
-        """Read the values into the values array."""
-        for i in range(0, len(self._dataRefs)):
-            self._values[i] = self._xplane._readValue(self._dataRefs[i][1])
-
-#-------------------------------------------------------------------------------
-
-class MultiSetter(MultiBuffer):
-    """Multi-dataref buffer for setting."""
-    def __init__(self, xplane):
-        """Construct the getter."""
-        super(MultiSetter, self).__init__(xplane,
-                                          COMMAND_REGISTER_SET_MULTI,
-                                          COMMAND_UNREGISTER_SET_MULTI)
-
-    def _executeRegistered(self):
-        """Execute the query if the buffer is registered."""
-        self._xplane._writeU8(COMMAND_EXECUTE_SET_MULTI)
-        self._xplane._writeU32(self._registeredID)
-        for i in range(0, len(self._dataRefs)):
-            self._xplane._writeValue(self._dataRefs[i][1], self._values[i])
-        self._xplane._flush()
-
-        self._xplane._checkResult(multi = True)
-
-    def _executeUnregistered(self):
-        """Execute the query if the buffer is not registered."""
-        self._xplane._writeU8(COMMAND_SET_MULTI)
-
-        numDataRefs = len(self._dataRefs)
-        self._xplane._writeU32(numDataRefs)
-
-        for i in range(0, numDataRefs):
-            (name, type, length, offset) = self._dataRefs[i]
-            value = self._values[i]
-
-            self._xplane._writeString(name)
-            self._xplane._writeU8(type)
-            if length is not None and offset is not None:
-                self._xplane._writeS32(len(value))
-                self._xplane._writeS32(offset)
-            self._xplane._writeValue(type, value)
-
-        self._xplane._flush()
-        self._xplane._checkResult(multi = True)
-
-#-------------------------------------------------------------------------------
Index: src/plugin/Makefile.am
===================================================================
--- src/plugin/Makefile.am	(revision 13)
+++ src/plugin/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=src
Index: src/plugin/Makefile.am
===================================================================
--- src/plugin/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=src
Index: src/plugin/bootstrap.sh
===================================================================
--- src/plugin/bootstrap.sh	(revision 13)
+++ src/plugin/bootstrap.sh	(revision 13)
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e -u
+
+scriptdir=`dirname $0`
+
+cd "${scriptdir}"
+
+#libtoolize
+aclocal -I $1
+automake -a
+autoconf
Index: src/plugin/bootstrap.sh
===================================================================
--- src/plugin/bootstrap.sh	(revision 13)
+++ 	(revision )
@@ -1,12 +1,0 @@
-#!/bin/sh
-
-set -e -u
-
-scriptdir=`dirname $0`
-
-cd "${scriptdir}"
-
-#libtoolize
-aclocal -I $1
-automake -a
-autoconf
Index: src/plugin/src/Makefile.am
===================================================================
--- src/plugin/src/Makefile.am	(revision 13)
+++ src/plugin/src/Makefile.am	(revision 13)
@@ -0,0 +1,1 @@
+SUBDIRS=xplra
Index: src/plugin/src/Makefile.am
===================================================================
--- src/plugin/src/Makefile.am	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-SUBDIRS=xplra
Index: src/plugin/src/xplra/.copyright
===================================================================
--- src/plugin/src/xplra/.copyright	(revision 13)
+++ src/plugin/src/xplra/.copyright	(revision 13)
@@ -0,0 +1,23 @@
+// 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.
Index: src/plugin/src/xplra/.copyright
===================================================================
--- src/plugin/src/xplra/.copyright	(revision 13)
+++ 	(revision )
@@ -1,23 +1,0 @@
-// 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.
Index: src/plugin/src/xplra/.namespace
===================================================================
--- src/plugin/src/xplra/.namespace	(revision 13)
+++ src/plugin/src/xplra/.namespace	(revision 13)
@@ -0,0 +1,1 @@
+xplra
Index: src/plugin/src/xplra/.namespace
===================================================================
--- src/plugin/src/xplra/.namespace	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-xplra
Index: src/plugin/src/xplra/.srcmessage
===================================================================
--- src/plugin/src/xplra/.srcmessage	(revision 13)
+++ src/plugin/src/xplra/.srcmessage	(revision 13)
@@ -0,0 +1,1 @@
+// This file is part of XPLRA, a remote-access plugin for X-Plane
Index: src/plugin/src/xplra/.srcmessage
===================================================================
--- src/plugin/src/xplra/.srcmessage	(revision 13)
+++ 	(revision )
@@ -1,1 +1,0 @@
-// This file is part of XPLRA, a remote-access plugin for X-Plane
Index: src/plugin/src/xplra/DataRefTask.cc
===================================================================
--- src/plugin/src/xplra/DataRefTask.cc	(revision 13)
+++ src/plugin/src/xplra/DataRefTask.cc	(revision 13)
@@ -0,0 +1,61 @@
+// 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 "DataRefTask.h"
+
+#include "hu/varadiistvan/xplcommon/Util.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::DataRefTask;
+
+using hu::varadiistvan::xplcommon::Util;
+
+//------------------------------------------------------------------------------
+
+void DataRefTask::perform()
+{
+    if (dataRef==0) {
+        // Util::debug("DataRefTask::perform: name='%s'\n", name.c_str());
+        dataRef = XPLMFindDataRef(name.c_str());
+        // Util::debug("DataRefTask::perform: dataRef=%p\n", dataRef);
+    }
+    if (dataRef!=0) {
+        process();
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/DataRefTask.cc
===================================================================
--- src/plugin/src/xplra/DataRefTask.cc	(revision 13)
+++ 	(revision )
@@ -1,61 +1,0 @@
-// 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 "DataRefTask.h"
-
-#include "hu/varadiistvan/xplcommon/Util.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::DataRefTask;
-
-using hu::varadiistvan::xplcommon::Util;
-
-//------------------------------------------------------------------------------
-
-void DataRefTask::perform()
-{
-    if (dataRef==0) {
-        // Util::debug("DataRefTask::perform: name='%s'\n", name.c_str());
-        dataRef = XPLMFindDataRef(name.c_str());
-        // Util::debug("DataRefTask::perform: dataRef=%p\n", dataRef);
-    }
-    if (dataRef!=0) {
-        process();
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/DataRefTask.h
===================================================================
--- src/plugin/src/xplra/DataRefTask.h	(revision 13)
+++ src/plugin/src/xplra/DataRefTask.h	(revision 13)
@@ -0,0 +1,155 @@
+// 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.
+
+#ifndef XPLRA_DATAREFTASK_H
+#define XPLRA_DATAREFTASK_H
+//------------------------------------------------------------------------------
+
+#include "Task.h"
+
+#include <XPLMDataAccess.h>
+
+#include <string>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A task that works with some dataref. This base class
+ * performs the mapping from dataref name to dataref value. The actual
+ * operation is performed by the subclasses.
+ */
+class DataRefTask : public Task
+{
+private:
+    /**
+     * The name of the dataref.
+     */
+    std::string name;
+
+    /**
+     * The dataref.
+     */
+    XPLMDataRef dataRef;
+
+protected:
+    /**
+     * Construct the dataref task for the dataref with the given name.
+     */
+    DataRefTask(const std::string& name);
+
+    /**
+     * Construct the dataref task for the given dataref.
+     */
+    DataRefTask(XPLMDataRef dataRef);
+
+public:
+    /**
+     * Determine if the task is valid, which is so, if the dataref is
+     * not 0.
+     */
+    bool isValid() const;
+
+    /**
+     * Get the name of the dataref.
+     */
+    const std::string& getName() const;
+
+    /**
+     * Get the dataref.
+     */
+    XPLMDataRef getDataRef() const;
+
+protected:
+    /**
+     * Perform the task. If the dataref is not valid yet, it will be
+     * queried. If the query is successful, the process() function is
+     * called.
+     */
+    virtual void perform();
+
+    /**
+     * Process the dataref. When this function is called, the dataref
+     * is valid.
+     */
+    virtual void process() = 0;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline DataRefTask::DataRefTask(const std::string& name) :
+    name(name),
+    dataRef(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline DataRefTask::DataRefTask(XPLMDataRef dataRef) :
+    dataRef(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline bool DataRefTask::isValid() const
+{
+    return dataRef!=0;
+}
+
+//------------------------------------------------------------------------------
+
+inline const std::string& DataRefTask::getName() const
+{
+    return name;
+}
+
+//------------------------------------------------------------------------------
+
+inline XPLMDataRef DataRefTask::getDataRef() const
+{
+    return dataRef;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_DATAREFTASK_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/DataRefTask.h
===================================================================
--- src/plugin/src/xplra/DataRefTask.h	(revision 13)
+++ 	(revision )
@@ -1,155 +1,0 @@
-// 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.
-
-#ifndef XPLRA_DATAREFTASK_H
-#define XPLRA_DATAREFTASK_H
-//------------------------------------------------------------------------------
-
-#include "Task.h"
-
-#include <XPLMDataAccess.h>
-
-#include <string>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A task that works with some dataref. This base class
- * performs the mapping from dataref name to dataref value. The actual
- * operation is performed by the subclasses.
- */
-class DataRefTask : public Task
-{
-private:
-    /**
-     * The name of the dataref.
-     */
-    std::string name;
-
-    /**
-     * The dataref.
-     */
-    XPLMDataRef dataRef;
-
-protected:
-    /**
-     * Construct the dataref task for the dataref with the given name.
-     */
-    DataRefTask(const std::string& name);
-
-    /**
-     * Construct the dataref task for the given dataref.
-     */
-    DataRefTask(XPLMDataRef dataRef);
-
-public:
-    /**
-     * Determine if the task is valid, which is so, if the dataref is
-     * not 0.
-     */
-    bool isValid() const;
-
-    /**
-     * Get the name of the dataref.
-     */
-    const std::string& getName() const;
-
-    /**
-     * Get the dataref.
-     */
-    XPLMDataRef getDataRef() const;
-
-protected:
-    /**
-     * Perform the task. If the dataref is not valid yet, it will be
-     * queried. If the query is successful, the process() function is
-     * called.
-     */
-    virtual void perform();
-
-    /**
-     * Process the dataref. When this function is called, the dataref
-     * is valid.
-     */
-    virtual void process() = 0;
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline DataRefTask::DataRefTask(const std::string& name) :
-    name(name),
-    dataRef(0)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline DataRefTask::DataRefTask(XPLMDataRef dataRef) :
-    dataRef(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline bool DataRefTask::isValid() const
-{
-    return dataRef!=0;
-}
-
-//------------------------------------------------------------------------------
-
-inline const std::string& DataRefTask::getName() const
-{
-    return name;
-}
-
-//------------------------------------------------------------------------------
-
-inline XPLMDataRef DataRefTask::getDataRef() const
-{
-    return dataRef;
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_DATAREFTASK_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/GetDataRefTask.cc
===================================================================
--- src/plugin/src/xplra/GetDataRefTask.cc	(revision 13)
+++ src/plugin/src/xplra/GetDataRefTask.cc	(revision 13)
@@ -0,0 +1,125 @@
+// 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 "GetDataRefTask.h"
+#include "Protocol.h"
+
+#include "hu/varadiistvan/xplcommon/Util.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::GetDataRefTask;
+using xplra::GetIntDataRefTask;
+using xplra::GetFloatDataRefTask;
+using xplra::GetDoubleDataRefTask;
+
+using hu::varadiistvan::scpl::io::DataStream;
+using hu::varadiistvan::xplcommon::Util;
+
+using std::string;
+
+//------------------------------------------------------------------------------
+
+GetDataRefTask* GetDataRefTask::create(uint8_t& result, DataStream& stream)
+{
+    result = Protocol::RESULT_OK;
+
+    string name = stream.readString();
+    uint8_t type = stream.readU8();
+    if (!stream) return 0;
+
+    // Util::debug("hu.varadiistvan.xplra.GetDataRefTask::execute: name='%s', type=0x%02x\n",
+    //             name.c_str(), type);
+
+    if (type==Protocol::TYPE_INT) {
+        return new GetIntDataRefTask(name);
+    } else if (type==Protocol::TYPE_FLOAT) {
+        return new GetFloatDataRefTask(name);
+    } else if (type==Protocol::TYPE_DOUBLE) {
+        return new GetDoubleDataRefTask(name);
+    } else if (type==Protocol::TYPE_FLOAT_ARRAY ||
+               type==Protocol::TYPE_INT_ARRAY ||
+               type==Protocol::TYPE_BYTE_ARRAY)
+    {
+        int length = stream.readS32();
+        int offset = stream.readS32();
+        if (!stream) return 0;
+
+        if (length>Protocol::MAX_LENGTH) {
+            result = Protocol::RESULT_INVALID_LENGTH;
+            return 0;
+        }
+        if (offset<0) {
+            result = Protocol::RESULT_INVALID_OFFSET;
+            return 0;
+        }
+
+        if (type==Protocol::TYPE_FLOAT_ARRAY) {
+            return new GetFloatArrayDataRefTask(name, length, offset);
+        } else if (type==Protocol::TYPE_INT_ARRAY) {
+            return new GetIntArrayDataRefTask(name, length, offset);
+        } else {
+            return new GetByteArrayDataRefTask(name, length, offset);
+        }
+    } else {
+        result = Protocol::RESULT_INVALID_TYPE;
+        return 0;
+    }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+void GetIntDataRefTask::writeValue(DataStream& stream)
+{
+    stream.writeS32(getValue());
+}
+
+//------------------------------------------------------------------------------
+
+void GetFloatDataRefTask::writeValue(DataStream& stream)
+{
+    stream.writeFloat(getValue());
+}
+
+//------------------------------------------------------------------------------
+
+void GetDoubleDataRefTask::writeValue(DataStream& stream)
+{
+    stream.writeDouble(getValue());
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/GetDataRefTask.cc
===================================================================
--- src/plugin/src/xplra/GetDataRefTask.cc	(revision 13)
+++ 	(revision )
@@ -1,125 +1,0 @@
-// 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 "GetDataRefTask.h"
-#include "Protocol.h"
-
-#include "hu/varadiistvan/xplcommon/Util.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::GetDataRefTask;
-using xplra::GetIntDataRefTask;
-using xplra::GetFloatDataRefTask;
-using xplra::GetDoubleDataRefTask;
-
-using hu::varadiistvan::scpl::io::DataStream;
-using hu::varadiistvan::xplcommon::Util;
-
-using std::string;
-
-//------------------------------------------------------------------------------
-
-GetDataRefTask* GetDataRefTask::create(uint8_t& result, DataStream& stream)
-{
-    result = Protocol::RESULT_OK;
-
-    string name = stream.readString();
-    uint8_t type = stream.readU8();
-    if (!stream) return 0;
-
-    // Util::debug("hu.varadiistvan.xplra.GetDataRefTask::execute: name='%s', type=0x%02x\n",
-    //             name.c_str(), type);
-
-    if (type==Protocol::TYPE_INT) {
-        return new GetIntDataRefTask(name);
-    } else if (type==Protocol::TYPE_FLOAT) {
-        return new GetFloatDataRefTask(name);
-    } else if (type==Protocol::TYPE_DOUBLE) {
-        return new GetDoubleDataRefTask(name);
-    } else if (type==Protocol::TYPE_FLOAT_ARRAY ||
-               type==Protocol::TYPE_INT_ARRAY ||
-               type==Protocol::TYPE_BYTE_ARRAY)
-    {
-        int length = stream.readS32();
-        int offset = stream.readS32();
-        if (!stream) return 0;
-
-        if (length>Protocol::MAX_LENGTH) {
-            result = Protocol::RESULT_INVALID_LENGTH;
-            return 0;
-        }
-        if (offset<0) {
-            result = Protocol::RESULT_INVALID_OFFSET;
-            return 0;
-        }
-
-        if (type==Protocol::TYPE_FLOAT_ARRAY) {
-            return new GetFloatArrayDataRefTask(name, length, offset);
-        } else if (type==Protocol::TYPE_INT_ARRAY) {
-            return new GetIntArrayDataRefTask(name, length, offset);
-        } else {
-            return new GetByteArrayDataRefTask(name, length, offset);
-        }
-    } else {
-        result = Protocol::RESULT_INVALID_TYPE;
-        return 0;
-    }
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-void GetIntDataRefTask::writeValue(DataStream& stream)
-{
-    stream.writeS32(getValue());
-}
-
-//------------------------------------------------------------------------------
-
-void GetFloatDataRefTask::writeValue(DataStream& stream)
-{
-    stream.writeFloat(getValue());
-}
-
-//------------------------------------------------------------------------------
-
-void GetDoubleDataRefTask::writeValue(DataStream& stream)
-{
-    stream.writeDouble(getValue());
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/GetDataRefTask.h
===================================================================
--- src/plugin/src/xplra/GetDataRefTask.h	(revision 66)
+++ src/plugin/src/xplra/GetDataRefTask.h	(revision 66)
@@ -0,0 +1,739 @@
+// 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.
+
+#ifndef XPLRA_GETDATAREFTASK_H
+#define XPLRA_GETDATAREFTASK_H
+//------------------------------------------------------------------------------
+
+#include "DataRefTask.h"
+
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for tasks that query the value of some dataref.
+ */
+class GetDataRefTask : public DataRefTask
+{
+public:
+    /**
+     * Read a dataref query specification and create the appropriate
+     * GetDataRefTask instance.
+     *
+     * @return the new instance, or 0 on error. In that case the given
+     * result reference variable will be filled with the error code,
+     * unless the stream failed, in which case it remains RESULT_OK.
+     */
+    static GetDataRefTask* create(uint8_t& result,
+                                  hu::varadiistvan::scpl::io::DataStream& stream);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    GetDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    GetDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Write the value into the given stream.
+     */
+    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream) = 0;
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for dataref querying tasks that query some scalar value.
+ *
+ * ConcreteClass is the actual child class. It should have a function
+ * called queryData, which wraps the corresponding function in XPLM.
+ */
+template <typename T, class ConcreteClass>
+class GetScalarDataRefTask : public GetDataRefTask
+{
+private:
+    /**
+     * The value retrieved.
+     */
+    T value;
+
+public:
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    GetScalarDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    GetScalarDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Get the value
+     */
+    T getValue() const;
+
+protected:
+    /**
+     * Perform the actual operation.
+     */
+    virtual void process();
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref task which retrieves the value of an integer.
+ */
+class GetIntDataRefTask :
+        public GetScalarDataRefTask<int, GetIntDataRefTask>
+{
+public:
+    /**
+     * Query the value from XPLM
+     */
+    static int queryData(XPLMDataRef dataRef);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    GetIntDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    GetIntDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Write the value into the given stream.
+     */
+    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref task which retrieves the value of a single-precision
+ * floating point data.
+ */
+class GetFloatDataRefTask :
+        public GetScalarDataRefTask<float, GetFloatDataRefTask>
+{
+public:
+    /**
+     * Query the value from XPLM
+     */
+    static float queryData(XPLMDataRef dataRef);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    GetFloatDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    GetFloatDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Write the value into the given stream.
+     */
+    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref task which retrieves the value of a double-precision
+ * floating point data.
+ */
+class GetDoubleDataRefTask :
+        public GetScalarDataRefTask<double, GetDoubleDataRefTask>
+{
+public:
+    /**
+     * Query the value from XPLM
+     */
+    static double queryData(XPLMDataRef dataRef);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    GetDoubleDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    GetDoubleDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Write the value into the given stream.
+     */
+    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for dataref querying tasks that query some array.
+ *
+ * ConcreteClass is the actual child class. It should have a function
+ * called queryData, which wraps the corresponding function in XPLM.
+ */
+template <typename T, class ConcreteClass>
+class GetArrayDataRefTask : public GetDataRefTask
+{
+private:
+    /**
+     * The maximal number of data items returned.
+     */
+    int maxCount;
+
+    /**
+     * The offset within the dataref's value to start the query from.
+     */
+    int offset;
+
+    /**
+     * The data.
+     */
+    T* data;
+
+    /**
+     * The actual length of the data retrieved.
+     */
+    int length;
+
+protected:
+    /**
+     * Construct the task for the dataref with the given name.
+     *
+     * @param name the name of the dataref
+     * @param maxCount the maximal number of items to retrieve. If <0,
+     * the function will perform an extra query to retrieve the size of
+     * of the dataref's data, which it will store in the task, so
+     * later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetArrayDataRefTask(const std::string& name,
+                        int maxCount = -1, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref
+     *
+     * @param dataRef the dataref
+     * @param maxCount the maximal number of items to retrieve. If <0,
+     * the function will perform an extra query to retrieve the size
+     * of the dataref's data, which it will store in the task, so
+     * later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetArrayDataRefTask(XPLMDataRef dataRef,
+                        int maxCount = -1, int offset = 0);
+
+public:
+    /**
+     * Destroy the object.
+     */
+    virtual ~GetArrayDataRefTask();
+
+    /**
+     * Get the data.
+     */
+    const T* getData() const;
+
+    /**
+     * Get the length of the data.
+     */
+    int getLength() const;
+
+protected:
+    /**
+     * Process the dataref by querying its value.
+     */
+    virtual void process();
+
+    /**
+     * Write the value into the given stream.
+     */
+    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref task which retrieves the value of a float array.
+ */
+class GetFloatArrayDataRefTask :
+        public GetArrayDataRefTask<float, GetFloatArrayDataRefTask>
+{
+public:
+    /**
+     * Get the data via XPLM
+     */
+    static int queryData(XPLMDataRef dataRef, float* dest,
+                         int offset, int count);
+
+public:
+    /**
+     * Construct the task for the dataref with the given name.
+     *
+     * @param name the name of the dataref
+     * @param maxCount the maximal number of data items to
+     * retrieve. If <0, the function will perform an extra query to
+     * retrieve the size of the dataref's data, which it will store in
+     * the task, so later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetFloatArrayDataRefTask(const std::string& name,
+                            int maxCount = -1, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref
+     *
+     * @param dataRef the dataref
+     * @param maxCount the maximal number of data items to
+     * retrieve. If <0, the function will perform an extra query to
+     * retrieve the size of the dataref's data, which it will store in
+     * the task, so later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetFloatArrayDataRefTask(XPLMDataRef dataRef,
+                             int maxCount = -1, int offset = 0);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref task which retrieves the value of an integer array.
+ */
+class GetIntArrayDataRefTask :
+        public GetArrayDataRefTask<int, GetIntArrayDataRefTask>
+{
+public:
+    /**
+     * Get the data via XPLM
+     */
+    static int queryData(XPLMDataRef dataRef, int* dest,
+                         int offset, int count);
+
+public:
+    /**
+     * Construct the task for the dataref with the given name.
+     *
+     * @param name the name of the dataref
+     * @param maxCount the maximal number of data items to
+     * retrieve. If <0, the function will perform an extra query to
+     * retrieve the size of the dataref's data, which it will store in
+     * the task, so later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetIntArrayDataRefTask(const std::string& name,
+                           int maxCount = -1, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref
+     *
+     * @param dataRef the dataref
+     * @param maxCount the maximal number of data items to
+     * retrieve. If <0, the function will perform an extra query to
+     * retrieve the size of the dataref's data, which it will store in
+     * the task, so later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetIntArrayDataRefTask(XPLMDataRef dataRef,
+                           int maxCount = -1, int offset = 0);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref task which retrieves the value of a byte array.
+ */
+class GetByteArrayDataRefTask :
+        public GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>
+{
+public:
+    /**
+     * Get the data via XPLM
+     */
+    static int queryData(XPLMDataRef dataRef, void* dest,
+                         int offset, int count);
+
+public:
+    /**
+     * Construct the task for the dataref with the given name.
+     *
+     * @param name the name of the dataref
+     * @param maxBytes the maximal number of bytes to retrieve. If <0,
+     * the function will perform an extra query to retrieve the size
+     * of the dataref's data, which it will store in the task, so
+     * later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetByteArrayDataRefTask(const std::string& name,
+                            int maxBytes = -1, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref
+     *
+     * @param dataRef the dataref
+     * @param maxBytes the maximal number of bytes to retrieve. If <0,
+     * the function will perform an extra query to retrieve the size
+     * of the dataref's data, which it will store in the task, so
+     * later on it can be reused.
+     * @param offset the offset from which to query the array
+     */
+    GetByteArrayDataRefTask(XPLMDataRef dataRef,
+                            int maxBytes = -1, int offset = 0);
+};
+
+//------------------------------------------------------------------------------
+// Template definitions
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline GetScalarDataRefTask<T, ConcreteClass>::
+GetScalarDataRefTask(const std::string& name) :
+    GetDataRefTask(name),
+    value(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline GetScalarDataRefTask<T, ConcreteClass>::
+GetScalarDataRefTask(XPLMDataRef dataRef) :
+    GetDataRefTask(dataRef),
+    value(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline T GetScalarDataRefTask<T, ConcreteClass>::getValue() const
+{
+    return value;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+void GetScalarDataRefTask<T, ConcreteClass>::process()
+{
+    value = ConcreteClass::queryData(getDataRef());
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline GetArrayDataRefTask<T, ConcreteClass>::
+GetArrayDataRefTask(const std::string& name, int maxCount, int offset) :
+    GetDataRefTask(name),
+    maxCount(maxCount),
+    offset(offset),
+    data( (maxCount>0) ? new T[maxCount] : 0 ),
+    length(-1)
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline GetArrayDataRefTask<T, ConcreteClass>::
+GetArrayDataRefTask(XPLMDataRef dataRef, int maxCount, int offset) :
+    GetDataRefTask(dataRef),
+    maxCount(maxCount),
+    offset(offset),
+    data( (maxCount>0) ? new T[maxCount] : 0),
+    length(-1)
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline GetArrayDataRefTask<T, ConcreteClass>::~GetArrayDataRefTask()
+{
+    delete [] data;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline const T* GetArrayDataRefTask<T, ConcreteClass>::getData() const
+{
+    return data;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline int GetArrayDataRefTask<T, ConcreteClass>::getLength() const
+{
+    return length;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+void GetArrayDataRefTask<T, ConcreteClass>::process()
+{
+    if (maxCount<0) {
+        maxCount = ConcreteClass::queryData(getDataRef(), 0, 0, 0);
+
+        if (maxCount>0) {
+            maxCount -= offset;
+        }
+
+        if (maxCount>0) {
+            data = new T[maxCount];
+        } else {
+            maxCount = 0;
+        }
+    }
+
+    // Util::debug("GetByteArrayDataRefTask::process: dataRef=%p, maxBytes=%d, data=%p, offset\n",
+    //             getDataRef(), maxBytes, data, offset);
+    if (maxCount>0) {
+        length = ConcreteClass::queryData(getDataRef(), data, offset, maxCount);
+    } else {
+        length = maxCount;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+void GetArrayDataRefTask<T, ConcreteClass>::
+writeValue(hu::varadiistvan::scpl::io::DataStream& stream)
+{
+    stream.writeS32(length);
+    if (length>0) {
+        stream.write(data, length * sizeof(T));
+    }
+}
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline GetDataRefTask::GetDataRefTask(const std::string& name) :
+    DataRefTask(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline GetDataRefTask::GetDataRefTask(XPLMDataRef dataRef) :
+    DataRefTask(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline int GetIntDataRefTask::queryData(XPLMDataRef dataRef)
+{
+    return XPLMGetDatai(dataRef);
+}
+
+//------------------------------------------------------------------------------
+
+inline GetIntDataRefTask::GetIntDataRefTask(const std::string& name) :
+    GetScalarDataRefTask<int, GetIntDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline GetIntDataRefTask::GetIntDataRefTask(XPLMDataRef dataRef) :
+    GetScalarDataRefTask<int, GetIntDataRefTask>(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline float GetFloatDataRefTask::queryData(XPLMDataRef dataRef)
+{
+    return XPLMGetDataf(dataRef);
+}
+
+//------------------------------------------------------------------------------
+
+inline GetFloatDataRefTask::GetFloatDataRefTask(const std::string& name) :
+    GetScalarDataRefTask<float, GetFloatDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline GetFloatDataRefTask::GetFloatDataRefTask(XPLMDataRef dataRef) :
+    GetScalarDataRefTask<float, GetFloatDataRefTask>(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline double GetDoubleDataRefTask::queryData(XPLMDataRef dataRef)
+{
+    return XPLMGetDatad(dataRef);
+}
+
+//------------------------------------------------------------------------------
+
+inline GetDoubleDataRefTask::GetDoubleDataRefTask(const std::string& name) :
+    GetScalarDataRefTask<double, GetDoubleDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline GetDoubleDataRefTask::GetDoubleDataRefTask(XPLMDataRef dataRef) :
+    GetScalarDataRefTask<double, GetDoubleDataRefTask>(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline int GetFloatArrayDataRefTask::queryData(XPLMDataRef dataRef, float* dest,
+                                               int offset, int count)
+{
+    return XPLMGetDatavf(dataRef, dest, offset, count);
+}
+
+//------------------------------------------------------------------------------
+
+inline
+GetFloatArrayDataRefTask::GetFloatArrayDataRefTask(const std::string& name,
+                                                   int maxCount, int offset) :
+    GetArrayDataRefTask<float, GetFloatArrayDataRefTask>(name, maxCount, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline
+GetFloatArrayDataRefTask::GetFloatArrayDataRefTask(XPLMDataRef dataRef,
+                                                 int maxCount, int offset) :
+    GetArrayDataRefTask<float, GetFloatArrayDataRefTask>(dataRef,
+                                                         maxCount, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline int GetIntArrayDataRefTask::queryData(XPLMDataRef dataRef, int* dest,
+                                             int offset, int count)
+{
+    return XPLMGetDatavi(dataRef, dest, offset, count);
+}
+
+//------------------------------------------------------------------------------
+
+inline
+GetIntArrayDataRefTask::GetIntArrayDataRefTask(const std::string& name,
+                                                   int maxCount, int offset) :
+    GetArrayDataRefTask<int, GetIntArrayDataRefTask>(name, maxCount, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline
+GetIntArrayDataRefTask::GetIntArrayDataRefTask(XPLMDataRef dataRef,
+                                               int maxCount, int offset) :
+    GetArrayDataRefTask<int, GetIntArrayDataRefTask>(dataRef,
+                                                     maxCount, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline int GetByteArrayDataRefTask::queryData(XPLMDataRef dataRef, void* dest,
+                                              int offset, int count)
+{
+    return XPLMGetDatab(dataRef, dest, offset, count);
+}
+
+//------------------------------------------------------------------------------
+
+inline
+GetByteArrayDataRefTask::GetByteArrayDataRefTask(const std::string& name,
+                                                 int maxBytes, int offset) :
+    GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>(name, maxBytes,
+                                                                offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline
+GetByteArrayDataRefTask::GetByteArrayDataRefTask(XPLMDataRef dataRef,
+                                                 int maxBytes, int offset) :
+    GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>(dataRef,
+                                                                maxBytes,
+                                                                offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_GETDATAREFTASK_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/GetDataRefTask.h
===================================================================
--- src/plugin/src/xplra/GetDataRefTask.h	(revision 13)
+++ 	(revision )
@@ -1,723 +1,0 @@
-// 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.
-
-#ifndef XPLRA_GETDATAREFTASK_H
-#define XPLRA_GETDATAREFTASK_H
-//------------------------------------------------------------------------------
-
-#include "DataRefTask.h"
-
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Base class for tasks that query the value of some dataref.
- */
-class GetDataRefTask : public DataRefTask
-{
-public:
-    /**
-     * Read a dataref query specification and create the appropriate
-     * GetDataRefTask instance.
-     *
-     * @return the new instance, or 0 on error. In that case the given
-     * result reference variable will be filled with the error code,
-     * unless the stream failed, in which case it remains RESULT_OK.
-     */
-    static GetDataRefTask* create(uint8_t& result,
-                                  hu::varadiistvan::scpl::io::DataStream& stream);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    GetDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    GetDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Write the value into the given stream.
-     */
-    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream) = 0;
-};
-
-//------------------------------------------------------------------------------
-
-/**
- * Base class for dataref querying tasks that query some scalar value.
- *
- * ConcreteClass is the actual child class. It should have a function
- * called queryData, which wraps the corresponding function in XPLM.
- */
-template <typename T, class ConcreteClass>
-class GetScalarDataRefTask : public GetDataRefTask
-{
-private:
-    /**
-     * The value retrieved.
-     */
-    T value;
-
-public:
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    GetScalarDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    GetScalarDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Get the value
-     */
-    T getValue() const;
-
-protected:
-    /**
-     * Perform the actual operation.
-     */
-    virtual void process();
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref task which retrieves the value of an integer.
- */
-class GetIntDataRefTask :
-        public GetScalarDataRefTask<int, GetIntDataRefTask>
-{
-public:
-    /**
-     * Query the value from XPLM
-     */
-    static int queryData(XPLMDataRef dataRef);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    GetIntDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    GetIntDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Write the value into the given stream.
-     */
-    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref task which retrieves the value of a single-precision
- * floating point data.
- */
-class GetFloatDataRefTask :
-        public GetScalarDataRefTask<float, GetFloatDataRefTask>
-{
-public:
-    /**
-     * Query the value from XPLM
-     */
-    static float queryData(XPLMDataRef dataRef);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    GetFloatDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    GetFloatDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Write the value into the given stream.
-     */
-    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref task which retrieves the value of a double-precision
- * floating point data.
- */
-class GetDoubleDataRefTask :
-        public GetScalarDataRefTask<double, GetDoubleDataRefTask>
-{
-public:
-    /**
-     * Query the value from XPLM
-     */
-    static double queryData(XPLMDataRef dataRef);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    GetDoubleDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    GetDoubleDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Write the value into the given stream.
-     */
-    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * Base class for dataref querying tasks that query some array.
- *
- * ConcreteClass is the actual child class. It should have a function
- * called queryData, which wraps the corresponding function in XPLM.
- */
-template <typename T, class ConcreteClass>
-class GetArrayDataRefTask : public GetDataRefTask
-{
-private:
-    /**
-     * The maximal number of data items returned.
-     */
-    int maxCount;
-
-    /**
-     * The offset within the dataref's value to start the query from.
-     */
-    int offset;
-
-    /**
-     * The data.
-     */
-    T* data;
-
-    /**
-     * The actual length of the data retrieved.
-     */
-    int length;
-
-protected:
-    /**
-     * Construct the task for the dataref with the given name.
-     *
-     * @param maxCount the maximal number of items to retrieve. If <0,
-     * the function will perform an extra query to retrieve the size of
-     * of the dataref's data, which it will store in the task, so
-     * later on it can be reused.
-     */
-    GetArrayDataRefTask(const std::string& name,
-                        int maxCount = -1, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref
-     *
-     * @param maxCount the maximal number of items to retrieve. If <0,
-     * the function will perform an extra query to retrieve the size
-     * of the dataref's data, which it will store in the task, so
-     * later on it can be reused.
-     */
-    GetArrayDataRefTask(XPLMDataRef dataRef,
-                        int maxCount = -1, int offset = 0);
-
-public:
-    /**
-     * Destroy the object.
-     */
-    virtual ~GetArrayDataRefTask();
-
-    /**
-     * Get the data.
-     */
-    const T* getData() const;
-
-    /**
-     * Get the length of the data.
-     */
-    int getLength() const;
-
-protected:
-    /**
-     * Process the dataref by querying its value.
-     */
-    virtual void process();
-
-    /**
-     * Write the value into the given stream.
-     */
-    virtual void writeValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref task which retrieves the value of a float array.
- */
-class GetFloatArrayDataRefTask :
-        public GetArrayDataRefTask<float, GetFloatArrayDataRefTask>
-{
-public:
-    /**
-     * Get the data via XPLM
-     */
-    static int queryData(XPLMDataRef dataRef, float* dest,
-                         int offset, int count);
-
-public:
-    /**
-     * Construct the task for the dataref with the given name.
-     *
-     * @param maxCount the maximal number of data items to
-     * retrieve. If <0, the function will perform an extra query to
-     * retrieve the size of the dataref's data, which it will store in
-     * the task, so later on it can be reused.
-     */
-    GetFloatArrayDataRefTask(const std::string& name,
-                            int maxCount = -1, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref
-     *
-     * @param maxBytes the maximal number of data items to
-     * retrieve. If <0, the function will perform an extra query to
-     * retrieve the size of the dataref's data, which it will store in
-     * the task, so later on it can be reused.
-     */
-    GetFloatArrayDataRefTask(XPLMDataRef dataRef,
-                             int maxCount = -1, int offset = 0);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref task which retrieves the value of an integer array.
- */
-class GetIntArrayDataRefTask :
-        public GetArrayDataRefTask<int, GetIntArrayDataRefTask>
-{
-public:
-    /**
-     * Get the data via XPLM
-     */
-    static int queryData(XPLMDataRef dataRef, int* dest,
-                         int offset, int count);
-
-public:
-    /**
-     * Construct the task for the dataref with the given name.
-     *
-     * @param maxCount the maximal number of data items to
-     * retrieve. If <0, the function will perform an extra query to
-     * retrieve the size of the dataref's data, which it will store in
-     * the task, so later on it can be reused.
-     */
-    GetIntArrayDataRefTask(const std::string& name,
-                           int maxCount = -1, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref
-     *
-     * @param maxBytes the maximal number of data items to
-     * retrieve. If <0, the function will perform an extra query to
-     * retrieve the size of the dataref's data, which it will store in
-     * the task, so later on it can be reused.
-     */
-    GetIntArrayDataRefTask(XPLMDataRef dataRef,
-                           int maxCount = -1, int offset = 0);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref task which retrieves the value of a byte array.
- */
-class GetByteArrayDataRefTask :
-        public GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>
-{
-public:
-    /**
-     * Get the data via XPLM
-     */
-    static int queryData(XPLMDataRef dataRef, void* dest,
-                         int offset, int count);
-
-public:
-    /**
-     * Construct the task for the dataref with the given name.
-     *
-     * @param maxBytes the maximal number of bytes to retrieve. If <0,
-     * the function will perform an extra query to retrieve the size
-     * of the dataref's data, which it will store in the task, so
-     * later on it can be reused.
-     */
-    GetByteArrayDataRefTask(const std::string& name,
-                            int maxBytes = -1, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref
-     *
-     * @param maxBytes the maximal number of bytes to retrieve. If <0,
-     * the function will perform an extra query to retrieve the size
-     * of the dataref's data, which it will store in the task, so
-     * later on it can be reused.
-     */
-    GetByteArrayDataRefTask(XPLMDataRef dataRef,
-                            int maxBytes = -1, int offset = 0);
-};
-
-//------------------------------------------------------------------------------
-// Template definitions
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline GetScalarDataRefTask<T, ConcreteClass>::
-GetScalarDataRefTask(const std::string& name) :
-    GetDataRefTask(name),
-    value(0)
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline GetScalarDataRefTask<T, ConcreteClass>::
-GetScalarDataRefTask(XPLMDataRef dataRef) :
-    GetDataRefTask(dataRef),
-    value(0)
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline T GetScalarDataRefTask<T, ConcreteClass>::getValue() const
-{
-    return value;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-void GetScalarDataRefTask<T, ConcreteClass>::process()
-{
-    value = ConcreteClass::queryData(getDataRef());
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline GetArrayDataRefTask<T, ConcreteClass>::
-GetArrayDataRefTask(const std::string& name, int maxCount, int offset) :
-    GetDataRefTask(name),
-    maxCount(maxCount),
-    offset(offset),
-    data( (maxCount>0) ? new T[maxCount] : 0 ),
-    length(-1)
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline GetArrayDataRefTask<T, ConcreteClass>::
-GetArrayDataRefTask(XPLMDataRef dataRef, int maxCount, int offset) :
-    GetDataRefTask(dataRef),
-    maxCount(maxCount),
-    offset(offset),
-    data( (maxCount>0) ? new T[maxCount] : 0),
-    length(-1)
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline GetArrayDataRefTask<T, ConcreteClass>::~GetArrayDataRefTask()
-{
-    delete [] data;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline const T* GetArrayDataRefTask<T, ConcreteClass>::getData() const
-{
-    return data;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline int GetArrayDataRefTask<T, ConcreteClass>::getLength() const
-{
-    return length;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-void GetArrayDataRefTask<T, ConcreteClass>::process()
-{
-    if (maxCount<0) {
-        maxCount = ConcreteClass::queryData(getDataRef(), 0, 0, 0);
-
-        if (maxCount>0) {
-            maxCount -= offset;
-        }
-
-        if (maxCount>0) {
-            data = new T[maxCount];
-        } else {
-            maxCount = 0;
-        }
-    }
-
-    // Util::debug("GetByteArrayDataRefTask::process: dataRef=%p, maxBytes=%d, data=%p, offset\n",
-    //             getDataRef(), maxBytes, data, offset);
-    if (maxCount>0) {
-        length = ConcreteClass::queryData(getDataRef(), data, offset, maxCount);
-    } else {
-        length = maxCount;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-void GetArrayDataRefTask<T, ConcreteClass>::
-writeValue(hu::varadiistvan::scpl::io::DataStream& stream)
-{
-    stream.writeS32(length);
-    if (length>0) {
-        stream.write(data, length * sizeof(T));
-    }
-}
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline GetDataRefTask::GetDataRefTask(const std::string& name) :
-    DataRefTask(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline GetDataRefTask::GetDataRefTask(XPLMDataRef dataRef) :
-    DataRefTask(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline int GetIntDataRefTask::queryData(XPLMDataRef dataRef)
-{
-    return XPLMGetDatai(dataRef);
-}
-
-//------------------------------------------------------------------------------
-
-inline GetIntDataRefTask::GetIntDataRefTask(const std::string& name) :
-    GetScalarDataRefTask<int, GetIntDataRefTask>(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline GetIntDataRefTask::GetIntDataRefTask(XPLMDataRef dataRef) :
-    GetScalarDataRefTask<int, GetIntDataRefTask>(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline float GetFloatDataRefTask::queryData(XPLMDataRef dataRef)
-{
-    return XPLMGetDataf(dataRef);
-}
-
-//------------------------------------------------------------------------------
-
-inline GetFloatDataRefTask::GetFloatDataRefTask(const std::string& name) :
-    GetScalarDataRefTask<float, GetFloatDataRefTask>(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline GetFloatDataRefTask::GetFloatDataRefTask(XPLMDataRef dataRef) :
-    GetScalarDataRefTask<float, GetFloatDataRefTask>(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline double GetDoubleDataRefTask::queryData(XPLMDataRef dataRef)
-{
-    return XPLMGetDatad(dataRef);
-}
-
-//------------------------------------------------------------------------------
-
-inline GetDoubleDataRefTask::GetDoubleDataRefTask(const std::string& name) :
-    GetScalarDataRefTask<double, GetDoubleDataRefTask>(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline GetDoubleDataRefTask::GetDoubleDataRefTask(XPLMDataRef dataRef) :
-    GetScalarDataRefTask<double, GetDoubleDataRefTask>(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline int GetFloatArrayDataRefTask::queryData(XPLMDataRef dataRef, float* dest,
-                                               int offset, int count)
-{
-    return XPLMGetDatavf(dataRef, dest, offset, count);
-}
-
-//------------------------------------------------------------------------------
-
-inline
-GetFloatArrayDataRefTask::GetFloatArrayDataRefTask(const std::string& name,
-                                                   int maxCount, int offset) :
-    GetArrayDataRefTask<float, GetFloatArrayDataRefTask>(name, maxCount, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline
-GetFloatArrayDataRefTask::GetFloatArrayDataRefTask(XPLMDataRef dataRef,
-                                                 int maxCount, int offset) :
-    GetArrayDataRefTask<float, GetFloatArrayDataRefTask>(dataRef,
-                                                         maxCount, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline int GetIntArrayDataRefTask::queryData(XPLMDataRef dataRef, int* dest,
-                                             int offset, int count)
-{
-    return XPLMGetDatavi(dataRef, dest, offset, count);
-}
-
-//------------------------------------------------------------------------------
-
-inline
-GetIntArrayDataRefTask::GetIntArrayDataRefTask(const std::string& name,
-                                                   int maxCount, int offset) :
-    GetArrayDataRefTask<int, GetIntArrayDataRefTask>(name, maxCount, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline
-GetIntArrayDataRefTask::GetIntArrayDataRefTask(XPLMDataRef dataRef,
-                                               int maxCount, int offset) :
-    GetArrayDataRefTask<int, GetIntArrayDataRefTask>(dataRef,
-                                                     maxCount, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline int GetByteArrayDataRefTask::queryData(XPLMDataRef dataRef, void* dest,
-                                              int offset, int count)
-{
-    return XPLMGetDatab(dataRef, dest, offset, count);
-}
-
-//------------------------------------------------------------------------------
-
-inline
-GetByteArrayDataRefTask::GetByteArrayDataRefTask(const std::string& name,
-                                                 int maxBytes, int offset) :
-    GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>(name, maxBytes,
-                                                                offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline
-GetByteArrayDataRefTask::GetByteArrayDataRefTask(XPLMDataRef dataRef,
-                                                 int maxBytes, int offset) :
-    GetArrayDataRefTask<unsigned char, GetByteArrayDataRefTask>(dataRef,
-                                                                maxBytes,
-                                                                offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_GETDATAREFTASK_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/GetMultiDataRefRequest.cc
===================================================================
--- src/plugin/src/xplra/GetMultiDataRefRequest.cc	(revision 13)
+++ src/plugin/src/xplra/GetMultiDataRefRequest.cc	(revision 13)
@@ -0,0 +1,96 @@
+// 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 "GetMultiDataRefRequest.h"
+
+#include "Protocol.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::GetMultiDataRefRequest;
+
+using hu::varadiistvan::scpl::io::DataStream;
+using hu::varadiistvan::xplcommon::Util;
+
+//------------------------------------------------------------------------------
+
+GetMultiDataRefRequest::GetMultiDataRefRequest(uint8_t& result,
+                                               DataStream& stream)
+{
+    result = Protocol::RESULT_OK;
+
+    uint32_t numTasks = stream.readU32();
+    if (!stream) return;
+    if (numTasks==0 || numTasks>Protocol::MAX_MULTI_COUNT) {
+        result = Protocol::RESULT_INVALID_COUNT;
+        return;
+    }
+
+    for(size_t i = 0;
+        i<numTasks && result==Protocol::RESULT_OK && stream; ++i)
+    {
+        GetDataRefTask* task = GetDataRefTask::create(result, stream);
+        if (task!=0) addTask(task);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void GetMultiDataRefRequest::writeResult(DataStream& stream) const
+{
+    // Util::debug("hu.varadiistvan.xplra.GetMultiDataRefRequest[%p]::writeResult\n", this);
+    size_t numTasks = getNumTasks();
+    for(size_t i = 0; i<numTasks; ++i) {
+        GetDataRefTask* task = getTask(i);
+        // Util::debug("hu.varadiistvan.xplra.GetMultiDataRefRequest[%p]::writeResult: task[%zu]: %d @ %p\n",
+        //             this, i, task->isValid(), task);
+        if (!task->isValid()) {
+            stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
+            stream.writeU32(i);
+            return;
+        }
+    }
+
+    stream.writeU8(Protocol::RESULT_OK);
+    for(size_t i = 0; i<numTasks; ++i) {
+        GetDataRefTask* task = getTask(i);
+        task->writeValue(stream);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/GetMultiDataRefRequest.cc
===================================================================
--- src/plugin/src/xplra/GetMultiDataRefRequest.cc	(revision 13)
+++ 	(revision )
@@ -1,96 +1,0 @@
-// 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 "GetMultiDataRefRequest.h"
-
-#include "Protocol.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::GetMultiDataRefRequest;
-
-using hu::varadiistvan::scpl::io::DataStream;
-using hu::varadiistvan::xplcommon::Util;
-
-//------------------------------------------------------------------------------
-
-GetMultiDataRefRequest::GetMultiDataRefRequest(uint8_t& result,
-                                               DataStream& stream)
-{
-    result = Protocol::RESULT_OK;
-
-    uint32_t numTasks = stream.readU32();
-    if (!stream) return;
-    if (numTasks==0 || numTasks>Protocol::MAX_MULTI_COUNT) {
-        result = Protocol::RESULT_INVALID_COUNT;
-        return;
-    }
-
-    for(size_t i = 0;
-        i<numTasks && result==Protocol::RESULT_OK && stream; ++i)
-    {
-        GetDataRefTask* task = GetDataRefTask::create(result, stream);
-        if (task!=0) addTask(task);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void GetMultiDataRefRequest::writeResult(DataStream& stream) const
-{
-    // Util::debug("hu.varadiistvan.xplra.GetMultiDataRefRequest[%p]::writeResult\n", this);
-    size_t numTasks = getNumTasks();
-    for(size_t i = 0; i<numTasks; ++i) {
-        GetDataRefTask* task = getTask(i);
-        // Util::debug("hu.varadiistvan.xplra.GetMultiDataRefRequest[%p]::writeResult: task[%zu]: %d @ %p\n",
-        //             this, i, task->isValid(), task);
-        if (!task->isValid()) {
-            stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
-            stream.writeU32(i);
-            return;
-        }
-    }
-
-    stream.writeU8(Protocol::RESULT_OK);
-    for(size_t i = 0; i<numTasks; ++i) {
-        GetDataRefTask* task = getTask(i);
-        task->writeValue(stream);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/GetMultiDataRefRequest.h
===================================================================
--- src/plugin/src/xplra/GetMultiDataRefRequest.h	(revision 13)
+++ src/plugin/src/xplra/GetMultiDataRefRequest.h	(revision 13)
@@ -0,0 +1,78 @@
+// 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.
+
+#ifndef XPLRA_GETMULTIDATAREFREQUEST_H
+#define XPLRA_GETMULTIDATAREFREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "MultiTaskRequest.h"
+#include "GetDataRefTask.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request containing several dataref query tasks.
+ */
+class GetMultiDataRefRequest : public MultiTaskRequestTemplate<GetDataRefTask>
+{
+public:
+    /**
+     * Construct the request by reading the given number of task
+     * specifications from the given stream.
+     */
+    GetMultiDataRefRequest(uint8_t& result, hu::varadiistvan::scpl::io::DataStream& stream);
+
+    /**
+     * Write the result of an execution.
+     *
+     * If there is at least one invalid dataref, the result will be
+     * RESULT_UNKNOWN_DATAREF followed by a 32-bit unsigned value with
+     * the index of the first unknown dataref.
+     *
+     * Otherwise the result is RESULT_OK, followed by the values of
+     * the datarefs queried.
+     */
+    void writeResult(hu::varadiistvan::scpl::io::DataStream& stream) const;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_GETMULTIDATAREFREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/GetMultiDataRefRequest.h
===================================================================
--- src/plugin/src/xplra/GetMultiDataRefRequest.h	(revision 13)
+++ 	(revision )
@@ -1,78 +1,0 @@
-// 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.
-
-#ifndef XPLRA_GETMULTIDATAREFREQUEST_H
-#define XPLRA_GETMULTIDATAREFREQUEST_H
-//------------------------------------------------------------------------------
-
-#include "MultiTaskRequest.h"
-#include "GetDataRefTask.h"
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A request containing several dataref query tasks.
- */
-class GetMultiDataRefRequest : public MultiTaskRequestTemplate<GetDataRefTask>
-{
-public:
-    /**
-     * Construct the request by reading the given number of task
-     * specifications from the given stream.
-     */
-    GetMultiDataRefRequest(uint8_t& result, hu::varadiistvan::scpl::io::DataStream& stream);
-
-    /**
-     * Write the result of an execution.
-     *
-     * If there is at least one invalid dataref, the result will be
-     * RESULT_UNKNOWN_DATAREF followed by a 32-bit unsigned value with
-     * the index of the first unknown dataref.
-     *
-     * Otherwise the result is RESULT_OK, followed by the values of
-     * the datarefs queried.
-     */
-    void writeResult(hu::varadiistvan::scpl::io::DataStream& stream) const;
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_GETMULTIDATAREFREQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Globals.cc
===================================================================
--- src/plugin/src/xplra/Globals.cc	(revision 44)
+++ src/plugin/src/xplra/Globals.cc	(revision 44)
@@ -0,0 +1,54 @@
+// 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 "Globals.h"
+
+#include <XPLMUtilities.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::Globals;
+
+//------------------------------------------------------------------------------
+
+Globals::Globals() :
+    menu(messageWindow)
+{
+    XPLMHostApplicationID hostID = 0;
+    XPLMGetVersions(&xplaneVersion, &xplmVersion, &hostID);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Globals.cc
===================================================================
--- src/plugin/src/xplra/Globals.cc	(revision 44)
+++ 	(revision )
@@ -1,54 +1,0 @@
-// 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 "Globals.h"
-
-#include <XPLMUtilities.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::Globals;
-
-//------------------------------------------------------------------------------
-
-Globals::Globals() :
-    menu(messageWindow)
-{
-    XPLMHostApplicationID hostID = 0;
-    XPLMGetVersions(&xplaneVersion, &xplmVersion, &hostID);
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Globals.h
===================================================================
--- src/plugin/src/xplra/Globals.h	(revision 45)
+++ src/plugin/src/xplra/Globals.h	(revision 45)
@@ -0,0 +1,132 @@
+// 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.
+
+#ifndef XPLRA_GLOBALS_H
+#define XPLRA_GLOBALS_H
+//------------------------------------------------------------------------------
+
+#include "MessageWindow.h"
+#include "Menu.h"
+#include "HotkeyHandler.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Class containing the globals for the enabled instance of the
+ * plugin.
+ */
+class Globals
+{
+private:
+    /**
+     * The version of X-Plane.
+     */
+    int xplaneVersion;
+
+    /**
+     * The version of the XPLM library.
+     */
+    int xplmVersion;
+
+    /**
+     * The message window.
+     */
+    MessageWindow messageWindow;
+
+    /**
+     * The menu.
+     */
+    Menu menu;
+
+    /**
+     * The hotkey handler.
+     */
+    HotkeyHandler hotkeyHandler;
+
+public:
+    /**
+     * Construct the globals.
+     */
+    Globals();
+
+    /**
+     * Get the versions.
+     */
+    void getVersions(int& xplaneV, int& xplmV) const;
+
+    /**
+     * Get the message window.
+     */
+    MessageWindow& getMessageWindow();
+
+    /**
+     * Get the hotkey handler.
+     */
+    HotkeyHandler& getHotkeyHandler();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline void Globals::getVersions(int& xplaneV, int& xplmV) const
+{
+    xplaneV = xplaneVersion;
+    xplmV = xplmVersion;
+}
+
+//------------------------------------------------------------------------------
+
+inline MessageWindow& Globals::getMessageWindow()
+{
+    return messageWindow;
+}
+
+//------------------------------------------------------------------------------
+
+inline HotkeyHandler& Globals::getHotkeyHandler()
+{
+    return hotkeyHandler;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_GLOBALS_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Globals.h
===================================================================
--- src/plugin/src/xplra/Globals.h	(revision 45)
+++ 	(revision )
@@ -1,132 +1,0 @@
-// 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.
-
-#ifndef XPLRA_GLOBALS_H
-#define XPLRA_GLOBALS_H
-//------------------------------------------------------------------------------
-
-#include "MessageWindow.h"
-#include "Menu.h"
-#include "HotkeyHandler.h"
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Class containing the globals for the enabled instance of the
- * plugin.
- */
-class Globals
-{
-private:
-    /**
-     * The version of X-Plane.
-     */
-    int xplaneVersion;
-
-    /**
-     * The version of the XPLM library.
-     */
-    int xplmVersion;
-
-    /**
-     * The message window.
-     */
-    MessageWindow messageWindow;
-
-    /**
-     * The menu.
-     */
-    Menu menu;
-
-    /**
-     * The hotkey handler.
-     */
-    HotkeyHandler hotkeyHandler;
-
-public:
-    /**
-     * Construct the globals.
-     */
-    Globals();
-
-    /**
-     * Get the versions.
-     */
-    void getVersions(int& xplaneV, int& xplmV) const;
-
-    /**
-     * Get the message window.
-     */
-    MessageWindow& getMessageWindow();
-
-    /**
-     * Get the hotkey handler.
-     */
-    HotkeyHandler& getHotkeyHandler();
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline void Globals::getVersions(int& xplaneV, int& xplmV) const
-{
-    xplaneV = xplaneVersion;
-    xplmV = xplmVersion;
-}
-
-//------------------------------------------------------------------------------
-
-inline MessageWindow& Globals::getMessageWindow()
-{
-    return messageWindow;
-}
-
-//------------------------------------------------------------------------------
-
-inline HotkeyHandler& Globals::getHotkeyHandler()
-{
-    return hotkeyHandler;
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_GLOBALS_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/HotkeyHandler.cc
===================================================================
--- src/plugin/src/xplra/HotkeyHandler.cc	(revision 46)
+++ src/plugin/src/xplra/HotkeyHandler.cc	(revision 46)
@@ -0,0 +1,166 @@
+// 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 "HotkeyHandler.h"
+
+#include "Protocol.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+#include <XPLMDisplay.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::HotkeyHandler;
+
+using hu::varadiistvan::xplcommon::Util;
+
+using hu::varadiistvan::scpl::io::DataStream;
+
+//------------------------------------------------------------------------------
+
+HotkeyHandler::Hotkeys::Hotkeys(size_t numHotkeys, DataStream& stream) :
+    numHotkeys(numHotkeys),
+    hotkeys(new uint16_t[numHotkeys]),
+    pressed(0)
+{
+    if (stream.read(hotkeys, sizeof(uint16_t)*numHotkeys)) {
+        pressed = new uint8_t[numHotkeys];
+        memset(pressed, 0, sizeof(uint8_t)*numHotkeys);
+    } else {
+        delete hotkeys; hotkeys = 0;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+HotkeyHandler::Hotkeys::~Hotkeys()
+{
+    delete [] pressed;
+    delete [] hotkeys;
+}
+
+//------------------------------------------------------------------------------
+
+bool HotkeyHandler::Hotkeys::handleKey(uint16_t code)
+{
+    for(size_t i = 0; i<numHotkeys; ++i) {
+        if (hotkeys[i]==code) {
+            pressed[i] = 1;
+            return true;
+        }
+    }
+    return false;
+}
+
+//------------------------------------------------------------------------------
+
+void HotkeyHandler::Hotkeys::writePressed(DataStream& stream)
+{
+    uint8_t pressed1[numHotkeys];
+
+    for(size_t i = 0; i<numHotkeys; ++i) {
+        pressed1[i] = __sync_val_compare_and_swap(pressed + i, 1, 0);
+    }
+
+    stream.writeU32(numHotkeys);
+    stream.write(pressed1, sizeof(pressed1));
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+int HotkeyHandler::keyCallback(char c, XPLMKeyFlags flags, char virtualKey,
+                               void* refCon)
+{
+    HotkeyHandler* hotkeyHandler = reinterpret_cast<HotkeyHandler*>(refCon);
+    return hotkeyHandler->handleKey(c, flags, virtualKey) ? 0 : 1;
+}
+
+//------------------------------------------------------------------------------
+
+HotkeyHandler::HotkeyHandler()
+{
+    XPLMRegisterKeySniffer(&keyCallback, 0, this);
+}
+
+//------------------------------------------------------------------------------
+
+void HotkeyHandler::registerHotkeys(Hotkeys* hotkeys)
+{
+    mutex.lock();
+    hotkeySets.push_back(hotkeys);
+    mutex.unlock();
+}
+
+//------------------------------------------------------------------------------
+
+void HotkeyHandler::unregisterHotkeys(Hotkeys* hotkeys)
+{
+    mutex.lock();
+    hotkeySets.remove(hotkeys);
+    mutex.unlock();
+}
+
+//------------------------------------------------------------------------------
+
+bool HotkeyHandler::handleKey(char /*c*/, XPLMKeyFlags flags, char virtualKey)
+{
+    if ( (flags&xplm_DownFlag)==0 ) return false;
+
+    uint16_t code = static_cast<uint16_t>(virtualKey);
+    if ( (flags&xplm_ShiftFlag)!=0 ) code |= Protocol::HOTKEY_MODIFIER_SHIFT;
+    if ( (flags&xplm_ControlFlag)!=0 ) code |= Protocol::HOTKEY_MODIFIER_CONTROL;
+
+    bool handled = false;
+
+    mutex.lock();
+    for(hotkeySets_t::iterator i = hotkeySets.begin(); i!=hotkeySets.end();
+        ++i)
+    {
+        Hotkeys* hotkeys = *i;
+        if (hotkeys->handleKey(code)) {
+            handled = true;
+        }
+    }
+    mutex.unlock();
+
+    return handled;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/HotkeyHandler.cc
===================================================================
--- src/plugin/src/xplra/HotkeyHandler.cc	(revision 46)
+++ 	(revision )
@@ -1,166 +1,0 @@
-// 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 "HotkeyHandler.h"
-
-#include "Protocol.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-#include <XPLMDisplay.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::HotkeyHandler;
-
-using hu::varadiistvan::xplcommon::Util;
-
-using hu::varadiistvan::scpl::io::DataStream;
-
-//------------------------------------------------------------------------------
-
-HotkeyHandler::Hotkeys::Hotkeys(size_t numHotkeys, DataStream& stream) :
-    numHotkeys(numHotkeys),
-    hotkeys(new uint16_t[numHotkeys]),
-    pressed(0)
-{
-    if (stream.read(hotkeys, sizeof(uint16_t)*numHotkeys)) {
-        pressed = new uint8_t[numHotkeys];
-        memset(pressed, 0, sizeof(uint8_t)*numHotkeys);
-    } else {
-        delete hotkeys; hotkeys = 0;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-HotkeyHandler::Hotkeys::~Hotkeys()
-{
-    delete [] pressed;
-    delete [] hotkeys;
-}
-
-//------------------------------------------------------------------------------
-
-bool HotkeyHandler::Hotkeys::handleKey(uint16_t code)
-{
-    for(size_t i = 0; i<numHotkeys; ++i) {
-        if (hotkeys[i]==code) {
-            pressed[i] = 1;
-            return true;
-        }
-    }
-    return false;
-}
-
-//------------------------------------------------------------------------------
-
-void HotkeyHandler::Hotkeys::writePressed(DataStream& stream)
-{
-    uint8_t pressed1[numHotkeys];
-
-    for(size_t i = 0; i<numHotkeys; ++i) {
-        pressed1[i] = __sync_val_compare_and_swap(pressed + i, 1, 0);
-    }
-
-    stream.writeU32(numHotkeys);
-    stream.write(pressed1, sizeof(pressed1));
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-int HotkeyHandler::keyCallback(char c, XPLMKeyFlags flags, char virtualKey,
-                               void* refCon)
-{
-    HotkeyHandler* hotkeyHandler = reinterpret_cast<HotkeyHandler*>(refCon);
-    return hotkeyHandler->handleKey(c, flags, virtualKey) ? 0 : 1;
-}
-
-//------------------------------------------------------------------------------
-
-HotkeyHandler::HotkeyHandler()
-{
-    XPLMRegisterKeySniffer(&keyCallback, 0, this);
-}
-
-//------------------------------------------------------------------------------
-
-void HotkeyHandler::registerHotkeys(Hotkeys* hotkeys)
-{
-    mutex.lock();
-    hotkeySets.push_back(hotkeys);
-    mutex.unlock();
-}
-
-//------------------------------------------------------------------------------
-
-void HotkeyHandler::unregisterHotkeys(Hotkeys* hotkeys)
-{
-    mutex.lock();
-    hotkeySets.remove(hotkeys);
-    mutex.unlock();
-}
-
-//------------------------------------------------------------------------------
-
-bool HotkeyHandler::handleKey(char /*c*/, XPLMKeyFlags flags, char virtualKey)
-{
-    if ( (flags&xplm_DownFlag)==0 ) return false;
-
-    uint16_t code = static_cast<uint16_t>(virtualKey);
-    if ( (flags&xplm_ShiftFlag)!=0 ) code |= Protocol::HOTKEY_MODIFIER_SHIFT;
-    if ( (flags&xplm_ControlFlag)!=0 ) code |= Protocol::HOTKEY_MODIFIER_CONTROL;
-
-    bool handled = false;
-
-    mutex.lock();
-    for(hotkeySets_t::iterator i = hotkeySets.begin(); i!=hotkeySets.end();
-        ++i)
-    {
-        Hotkeys* hotkeys = *i;
-        if (hotkeys->handleKey(code)) {
-            handled = true;
-        }
-    }
-    mutex.unlock();
-
-    return handled;
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/HotkeyHandler.h
===================================================================
--- src/plugin/src/xplra/HotkeyHandler.h	(revision 45)
+++ src/plugin/src/xplra/HotkeyHandler.h	(revision 45)
@@ -0,0 +1,185 @@
+// 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.
+
+#ifndef XPLRA_HOTKEYHANDLER_H
+#define XPLRA_HOTKEYHANDLER_H
+//------------------------------------------------------------------------------
+
+#include <hu/varadiistvan/scpl/Mutex.h>
+
+#include <XPLMDefs.h>
+
+#include <list>
+
+#include <inttypes.h>
+
+//------------------------------------------------------------------------------
+
+namespace hu { namespace varadiistvan { namespace scpl { namespace io {
+
+class DataStream;
+
+} } } }
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * The handler for hotkeys.
+ */
+class HotkeyHandler
+{
+public:
+    /**
+     * A set of hotkeys for a client.
+     */
+    class Hotkeys
+    {
+    private:
+        /**
+         * The number of hotkeys.
+         */
+        size_t numHotkeys;
+
+        /**
+         * The hotkey codes.
+         */
+        uint16_t* hotkeys;
+
+        /**
+         * The array of indicators whether the hotkey at the given
+         * index in the array of codes has been pressed.
+         */
+        uint8_t* pressed;
+
+    public:
+        /**
+         * Construct the set of hotkeys by reading the data from the
+         * given data stream.
+         */
+        Hotkeys(size_t numHotkeys, hu::varadiistvan::scpl::io::DataStream& stream);
+
+        /**
+         * Destroy the set of hotkeys.
+         */
+        ~Hotkeys();
+
+        /**
+         * Determine if this hotkey set is valid.
+         */
+        bool isValid() const;
+
+        /**
+         * Handle the hotkey with the given code. If it matches any of
+         * the codes registered, the corresponding value in the
+         * pressed array will be set atomically.
+         *
+         * @return whether the hotkey was handled or not.
+         */
+        bool handleKey(uint16_t code);
+
+        /**
+         * Write the pressed indicators into the given stream. It also
+         * clears the indicators.
+         */
+        void writePressed(hu::varadiistvan::scpl::io::DataStream& stream);
+    };
+
+    friend class Hotkeys;
+
+private:
+    /**
+     * Type for the the list of hotkey sets.
+     */
+    typedef std::list<Hotkeys*> hotkeySets_t;
+
+    /**
+     * The callback function receiving the keypresses.
+     */
+    static int keyCallback(char c, XPLMKeyFlags flags, char virtualKey,
+                           void* refCon);
+
+    /**
+     * Mutex to protect some common data structures.
+     */
+    hu::varadiistvan::scpl::Mutex mutex;
+
+    /**
+     * The list of hotkey sets.
+     */
+    hotkeySets_t hotkeySets;
+
+public:
+    /**
+     * Construct the hotkey handler.
+     */
+    HotkeyHandler();
+
+    /**
+     * Register the given set of hotkeys.
+     */
+    void registerHotkeys(Hotkeys* hotkeys);
+
+    /**
+     * Unregister the given set of hotkeys.
+     */
+    void unregisterHotkeys(Hotkeys* hotkeys);
+
+protected:
+    /**
+     * Handle the given hotkey code.
+     *
+     * @return true if the hotkey was handled, false otherwise.
+     */
+    bool handleKey(char c, XPLMKeyFlags flags, char virtualKey);
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline bool HotkeyHandler::Hotkeys::isValid() const
+{
+    return hotkeys!=0;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_HOTKEYHANDLER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/HotkeyHandler.h
===================================================================
--- src/plugin/src/xplra/HotkeyHandler.h	(revision 45)
+++ 	(revision )
@@ -1,185 +1,0 @@
-// 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.
-
-#ifndef XPLRA_HOTKEYHANDLER_H
-#define XPLRA_HOTKEYHANDLER_H
-//------------------------------------------------------------------------------
-
-#include <hu/varadiistvan/scpl/Mutex.h>
-
-#include <XPLMDefs.h>
-
-#include <list>
-
-#include <inttypes.h>
-
-//------------------------------------------------------------------------------
-
-namespace hu { namespace varadiistvan { namespace scpl { namespace io {
-
-class DataStream;
-
-} } } }
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * The handler for hotkeys.
- */
-class HotkeyHandler
-{
-public:
-    /**
-     * A set of hotkeys for a client.
-     */
-    class Hotkeys
-    {
-    private:
-        /**
-         * The number of hotkeys.
-         */
-        size_t numHotkeys;
-
-        /**
-         * The hotkey codes.
-         */
-        uint16_t* hotkeys;
-
-        /**
-         * The array of indicators whether the hotkey at the given
-         * index in the array of codes has been pressed.
-         */
-        uint8_t* pressed;
-
-    public:
-        /**
-         * Construct the set of hotkeys by reading the data from the
-         * given data stream.
-         */
-        Hotkeys(size_t numHotkeys, hu::varadiistvan::scpl::io::DataStream& stream);
-
-        /**
-         * Destroy the set of hotkeys.
-         */
-        ~Hotkeys();
-
-        /**
-         * Determine if this hotkey set is valid.
-         */
-        bool isValid() const;
-
-        /**
-         * Handle the hotkey with the given code. If it matches any of
-         * the codes registered, the corresponding value in the
-         * pressed array will be set atomically.
-         *
-         * @return whether the hotkey was handled or not.
-         */
-        bool handleKey(uint16_t code);
-
-        /**
-         * Write the pressed indicators into the given stream. It also
-         * clears the indicators.
-         */
-        void writePressed(hu::varadiistvan::scpl::io::DataStream& stream);
-    };
-
-    friend class Hotkeys;
-
-private:
-    /**
-     * Type for the the list of hotkey sets.
-     */
-    typedef std::list<Hotkeys*> hotkeySets_t;
-
-    /**
-     * The callback function receiving the keypresses.
-     */
-    static int keyCallback(char c, XPLMKeyFlags flags, char virtualKey,
-                           void* refCon);
-
-    /**
-     * Mutex to protect some common data structures.
-     */
-    hu::varadiistvan::scpl::Mutex mutex;
-
-    /**
-     * The list of hotkey sets.
-     */
-    hotkeySets_t hotkeySets;
-
-public:
-    /**
-     * Construct the hotkey handler.
-     */
-    HotkeyHandler();
-
-    /**
-     * Register the given set of hotkeys.
-     */
-    void registerHotkeys(Hotkeys* hotkeys);
-
-    /**
-     * Unregister the given set of hotkeys.
-     */
-    void unregisterHotkeys(Hotkeys* hotkeys);
-
-protected:
-    /**
-     * Handle the given hotkey code.
-     *
-     * @return true if the hotkey was handled, false otherwise.
-     */
-    bool handleKey(char c, XPLMKeyFlags flags, char virtualKey);
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline bool HotkeyHandler::Hotkeys::isValid() const
-{
-    return hotkeys!=0;
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_HOTKEYHANDLER_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/ListenThread.cc
===================================================================
--- src/plugin/src/xplra/ListenThread.cc	(revision 61)
+++ src/plugin/src/xplra/ListenThread.cc	(revision 61)
@@ -0,0 +1,76 @@
+// 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 "ListenThread.h"
+
+#include "ServerThread.h"
+
+#include <hu/varadiistvan/scpl/io/LocalServerSocket.h>
+#include <hu/varadiistvan/scpl/io/LocalAcceptor.h>
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::ListenThread;
+
+using hu::varadiistvan::scpl::io::LocalServerSocket;
+using hu::varadiistvan::scpl::io::LocalAcceptor;
+using hu::varadiistvan::xplcommon::Util;
+
+//------------------------------------------------------------------------------
+
+void ListenThread::run()
+{
+    Util::debug("xplra::ListenThread::run: started\n");
+
+    LocalServerSocket socket("xplra", &waiter);
+    LocalAcceptor& acceptor = socket.getAcceptor();
+    while(!quitEvent.check() && !quitEvent.failed() && !acceptor.failed()) {
+        while (acceptor.accept()) {
+            ServerThread* serverThread = new ServerThread(*this,
+                                                          requestQueue,
+                                                          acceptor);
+            serverThread->start();
+        }
+        waiter.wait();
+    }
+
+    ServerThread::quitAll();
+
+    Util::debug("xplra::ListenThread::run: quitting\n");
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/ListenThread.cc
===================================================================
--- src/plugin/src/xplra/ListenThread.cc	(revision 61)
+++ 	(revision )
@@ -1,76 +1,0 @@
-// 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 "ListenThread.h"
-
-#include "ServerThread.h"
-
-#include <hu/varadiistvan/scpl/io/LocalServerSocket.h>
-#include <hu/varadiistvan/scpl/io/LocalAcceptor.h>
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::ListenThread;
-
-using hu::varadiistvan::scpl::io::LocalServerSocket;
-using hu::varadiistvan::scpl::io::LocalAcceptor;
-using hu::varadiistvan::xplcommon::Util;
-
-//------------------------------------------------------------------------------
-
-void ListenThread::run()
-{
-    Util::debug("xplra::ListenThread::run: started\n");
-
-    LocalServerSocket socket("xplra", &waiter);
-    LocalAcceptor& acceptor = socket.getAcceptor();
-    while(!quitEvent.check() && !quitEvent.failed() && !acceptor.failed()) {
-        while (acceptor.accept()) {
-            ServerThread* serverThread = new ServerThread(*this,
-                                                          requestQueue,
-                                                          acceptor);
-            serverThread->start();
-        }
-        waiter.wait();
-    }
-
-    ServerThread::quitAll();
-
-    Util::debug("xplra::ListenThread::run: quitting\n");
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/ListenThread.h
===================================================================
--- src/plugin/src/xplra/ListenThread.h	(revision 46)
+++ src/plugin/src/xplra/ListenThread.h	(revision 46)
@@ -0,0 +1,138 @@
+// 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.
+
+#ifndef XPLRA_LISTENTHREAD_H
+#define XPLRA_LISTENTHREAD_H
+//------------------------------------------------------------------------------
+
+#include <hu/varadiistvan/scpl/Thread.h>
+
+#include "RequestQueue.h"
+
+#include <hu/varadiistvan/scpl/io/Waiter.h>
+#include <hu/varadiistvan/scpl/io/WaitableEvent.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class Globals;
+
+//------------------------------------------------------------------------------
+
+/**
+ * The thread that listens to incoming connections and starts the
+ * client serving threads.
+ *
+ * This is a detached thread, to allow it to quit automatically.
+ */
+class ListenThread : public hu::varadiistvan::scpl::Thread
+{
+private:
+    /**
+     * The global objects.
+     */
+    Globals& globals;
+
+    /**
+     * The waiter used in the thread.
+     */
+    hu::varadiistvan::scpl::io::Waiter waiter;
+
+    /**
+     * The event that can be fired to notify the thread that it should
+     * quit.
+     */
+    hu::varadiistvan::scpl::io::WaitableEvent quitEvent;
+
+    /**
+     * The queue for the requests.
+     */
+    RequestQueue requestQueue;
+
+public:
+    /**
+     * Construct the thread.
+     */
+    ListenThread(Globals& globals);
+
+    /**
+     * Get the globals
+     */
+    Globals& getGlobals();
+
+    /**
+     * Notify the thread to quit.
+     */
+    void quit();
+
+    /**
+     * Perform the thread's operation.
+     */
+    virtual void run();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline ListenThread::ListenThread(Globals& globals) :
+    globals(globals),
+    quitEvent(&waiter)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline Globals& ListenThread::getGlobals()
+{
+    return globals;
+}
+
+//------------------------------------------------------------------------------
+
+inline void ListenThread::quit()
+{
+    requestQueue.disable();
+    quitEvent.fire();
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_LISTENTHREAD_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/ListenThread.h
===================================================================
--- src/plugin/src/xplra/ListenThread.h	(revision 46)
+++ 	(revision )
@@ -1,138 +1,0 @@
-// 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.
-
-#ifndef XPLRA_LISTENTHREAD_H
-#define XPLRA_LISTENTHREAD_H
-//------------------------------------------------------------------------------
-
-#include <hu/varadiistvan/scpl/Thread.h>
-
-#include "RequestQueue.h"
-
-#include <hu/varadiistvan/scpl/io/Waiter.h>
-#include <hu/varadiistvan/scpl/io/WaitableEvent.h>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class Globals;
-
-//------------------------------------------------------------------------------
-
-/**
- * The thread that listens to incoming connections and starts the
- * client serving threads.
- *
- * This is a detached thread, to allow it to quit automatically.
- */
-class ListenThread : public hu::varadiistvan::scpl::Thread
-{
-private:
-    /**
-     * The global objects.
-     */
-    Globals& globals;
-
-    /**
-     * The waiter used in the thread.
-     */
-    hu::varadiistvan::scpl::io::Waiter waiter;
-
-    /**
-     * The event that can be fired to notify the thread that it should
-     * quit.
-     */
-    hu::varadiistvan::scpl::io::WaitableEvent quitEvent;
-
-    /**
-     * The queue for the requests.
-     */
-    RequestQueue requestQueue;
-
-public:
-    /**
-     * Construct the thread.
-     */
-    ListenThread(Globals& globals);
-
-    /**
-     * Get the globals
-     */
-    Globals& getGlobals();
-
-    /**
-     * Notify the thread to quit.
-     */
-    void quit();
-
-    /**
-     * Perform the thread's operation.
-     */
-    virtual void run();
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline ListenThread::ListenThread(Globals& globals) :
-    globals(globals),
-    quitEvent(&waiter)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline Globals& ListenThread::getGlobals()
-{
-    return globals;
-}
-
-//------------------------------------------------------------------------------
-
-inline void ListenThread::quit()
-{
-    requestQueue.disable();
-    quitEvent.fire();
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_LISTENTHREAD_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Makefile.am
===================================================================
--- src/plugin/src/xplra/Makefile.am	(revision 59)
+++ src/plugin/src/xplra/Makefile.am	(revision 59)
@@ -0,0 +1,72 @@
+INCLUDES=@XPSDK_INCLUDES@
+
+AM_CXXFLAGS=$(VSCPL_CFLAGS) $(LIBXPLCOMMON_CFLAGS)
+
+AM_CPPFLAGS=-DXPLM100
+
+SRCS= \
+	plugin.cc			\
+	ListenThread.cc			\
+	RequestQueue.cc			\
+	ServerThread.cc			\
+	TaskRequest.cc			\
+	DataRefTask.cc			\
+	GetDataRefTask.cc		\
+	SetDataRefTask.cc		\
+	MultiTaskRequest.cc		\
+	GetMultiDataRefRequest.cc	\
+	SetMultiDataRefRequest.cc	\
+	ReloadPluginsRequest.cc		\
+	Globals.cc			\
+	MessageWindow.cc		\
+	MessageRequest.cc		\
+	Menu.cc				\
+	HotkeyHandler.cc
+
+noinst_HEADERS= \
+	ListenThread.h			\
+	Request.h			\
+	RequestQueue.h			\
+	Protocol.h			\
+	ServerThread.h			\
+	Task.h				\
+	TaskRequest.h			\
+	DataRefTask.h			\
+	GetDataRefTask.h		\
+	SetDataRefTask.h		\
+	MultiTaskRequest.h		\
+	GetMultiDataRefRequest.h	\
+	SetMultiDataRefRequest.h	\
+	ReloadPluginsRequest.h		\
+	Globals.h			\
+	MessageWindow.h			\
+	MessageRequest.h		\
+	Menu.h				\
+	HotkeyHandler.h
+
+if TARGET_API_POSIX
+AM_CPPFLAGS+=-DLIN
+AM_CXXFLAGS+=-fPIC -fno-stack-protector
+AM_LDFLAGS=-shared -rdynamic -nodefaultlibs -undefined_warning -Wl,-version-script=$(srcdir)/version.ldscript
+noinst_PROGRAMS=lin.xpl
+lin_xpl_SOURCES=$(SRCS)
+lin_xpl_LDADD=$(VSCPL_LIBS) $(LIBXPLCOMMON_LIBS)
+endif
+
+if TARGET_API_WIN32
+AM_CPPFLAGS+=-DIBM
+AM_LDFLAGS=-shared -Wl,--enable-auto-image-base -static -static-libgcc -static-libstdc++
+
+noinst_PROGRAMS=win.xpl
+win_xpl_SOURCES=$(SRCS)
+
+win_xpl_LDADD=$(LIBXPLCOMMON_LIBS) $(VSCPL_LIBS)
+win_xpl_LDADD+=@XPSDK_LDFLAGS@
+if TARGET_API_WIN64
+win_xpl_LDADD+=-lXPLM_64
+else
+win_xpl_LDADD+=-lXPLM
+endif
+endif
+
+EXTRA_DIST=version.ldscript
Index: src/plugin/src/xplra/Makefile.am
===================================================================
--- src/plugin/src/xplra/Makefile.am	(revision 59)
+++ 	(revision )
@@ -1,72 +1,0 @@
-INCLUDES=@XPSDK_INCLUDES@
-
-AM_CXXFLAGS=$(VSCPL_CFLAGS) $(LIBXPLCOMMON_CFLAGS)
-
-AM_CPPFLAGS=-DXPLM100
-
-SRCS= \
-	plugin.cc			\
-	ListenThread.cc			\
-	RequestQueue.cc			\
-	ServerThread.cc			\
-	TaskRequest.cc			\
-	DataRefTask.cc			\
-	GetDataRefTask.cc		\
-	SetDataRefTask.cc		\
-	MultiTaskRequest.cc		\
-	GetMultiDataRefRequest.cc	\
-	SetMultiDataRefRequest.cc	\
-	ReloadPluginsRequest.cc		\
-	Globals.cc			\
-	MessageWindow.cc		\
-	MessageRequest.cc		\
-	Menu.cc				\
-	HotkeyHandler.cc
-
-noinst_HEADERS= \
-	ListenThread.h			\
-	Request.h			\
-	RequestQueue.h			\
-	Protocol.h			\
-	ServerThread.h			\
-	Task.h				\
-	TaskRequest.h			\
-	DataRefTask.h			\
-	GetDataRefTask.h		\
-	SetDataRefTask.h		\
-	MultiTaskRequest.h		\
-	GetMultiDataRefRequest.h	\
-	SetMultiDataRefRequest.h	\
-	ReloadPluginsRequest.h		\
-	Globals.h			\
-	MessageWindow.h			\
-	MessageRequest.h		\
-	Menu.h				\
-	HotkeyHandler.h
-
-if TARGET_API_POSIX
-AM_CPPFLAGS+=-DLIN
-AM_CXXFLAGS+=-fPIC -fno-stack-protector
-AM_LDFLAGS=-shared -rdynamic -nodefaultlibs -undefined_warning -Wl,-version-script=$(srcdir)/version.ldscript
-noinst_PROGRAMS=lin.xpl
-lin_xpl_SOURCES=$(SRCS)
-lin_xpl_LDADD=$(VSCPL_LIBS) $(LIBXPLCOMMON_LIBS)
-endif
-
-if TARGET_API_WIN32
-AM_CPPFLAGS+=-DIBM
-AM_LDFLAGS=-shared -Wl,--enable-auto-image-base -static -static-libgcc -static-libstdc++
-
-noinst_PROGRAMS=win.xpl
-win_xpl_SOURCES=$(SRCS)
-
-win_xpl_LDADD=$(LIBXPLCOMMON_LIBS) $(VSCPL_LIBS)
-win_xpl_LDADD+=@XPSDK_LDFLAGS@
-if TARGET_API_WIN64
-win_xpl_LDADD+=-lXPLM_64
-else
-win_xpl_LDADD+=-lXPLM
-endif
-endif
-
-EXTRA_DIST=version.ldscript
Index: src/plugin/src/xplra/Menu.cc
===================================================================
--- src/plugin/src/xplra/Menu.cc	(revision 47)
+++ src/plugin/src/xplra/Menu.cc	(revision 47)
@@ -0,0 +1,96 @@
+// 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 "Menu.h"
+
+#include "MessageWindow.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::Menu;
+
+//------------------------------------------------------------------------------
+
+void* const Menu::showMessageAreaRef = reinterpret_cast<void*>(1);
+
+void* const Menu::resetMessageAreaRef = reinterpret_cast<void*>(2);
+
+//------------------------------------------------------------------------------
+
+void Menu::menuHandlerCallback(void* menuRef, void* itemRef)
+{
+    Menu* menu = reinterpret_cast<Menu*>(menuRef);
+    menu->handleMenu(itemRef);
+}
+
+//------------------------------------------------------------------------------
+
+Menu::Menu(MessageWindow& messageWindow) :
+    messageWindow(messageWindow),
+    menuID(0),
+    showMessageAreaIndex(-1)
+{
+    XPLMMenuID pluginsMenuID = XPLMFindPluginsMenu();
+
+    int menuIndex = XPLMAppendMenuItem(pluginsMenuID, "Remote Access", 0, 1);
+    menuID = XPLMCreateMenu("Remote Access", pluginsMenuID, menuIndex,
+                            &menuHandlerCallback, this);
+    showMessageAreaIndex = XPLMAppendMenuItem(menuID, "Show message area",
+                                              showMessageAreaRef, 1);
+    XPLMCheckMenuItem(menuID, showMessageAreaIndex, xplm_Menu_Unchecked);
+    XPLMAppendMenuItem(menuID, "Reset message area", resetMessageAreaRef, 1);
+}
+
+//------------------------------------------------------------------------------
+
+void Menu::handleMenu(void* itemRef)
+{
+    if (itemRef==showMessageAreaRef) {
+        XPLMMenuCheck checked = xplm_Menu_NoCheck;
+        XPLMCheckMenuItemState(menuID, showMessageAreaIndex, &checked);
+        if (checked==xplm_Menu_Unchecked) {
+            XPLMCheckMenuItem(menuID, showMessageAreaIndex, xplm_Menu_Checked);
+            messageWindow.show();
+        } else if (checked==xplm_Menu_Checked) {
+            XPLMCheckMenuItem(menuID, showMessageAreaIndex, xplm_Menu_Unchecked);
+            messageWindow.hide();
+        }
+    } else if (itemRef==resetMessageAreaRef) {
+        messageWindow.reset();
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Menu.cc
===================================================================
--- src/plugin/src/xplra/Menu.cc	(revision 47)
+++ 	(revision )
@@ -1,96 +1,0 @@
-// 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 "Menu.h"
-
-#include "MessageWindow.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::Menu;
-
-//------------------------------------------------------------------------------
-
-void* const Menu::showMessageAreaRef = reinterpret_cast<void*>(1);
-
-void* const Menu::resetMessageAreaRef = reinterpret_cast<void*>(2);
-
-//------------------------------------------------------------------------------
-
-void Menu::menuHandlerCallback(void* menuRef, void* itemRef)
-{
-    Menu* menu = reinterpret_cast<Menu*>(menuRef);
-    menu->handleMenu(itemRef);
-}
-
-//------------------------------------------------------------------------------
-
-Menu::Menu(MessageWindow& messageWindow) :
-    messageWindow(messageWindow),
-    menuID(0),
-    showMessageAreaIndex(-1)
-{
-    XPLMMenuID pluginsMenuID = XPLMFindPluginsMenu();
-
-    int menuIndex = XPLMAppendMenuItem(pluginsMenuID, "Remote Access", 0, 1);
-    menuID = XPLMCreateMenu("Remote Access", pluginsMenuID, menuIndex,
-                            &menuHandlerCallback, this);
-    showMessageAreaIndex = XPLMAppendMenuItem(menuID, "Show message area",
-                                              showMessageAreaRef, 1);
-    XPLMCheckMenuItem(menuID, showMessageAreaIndex, xplm_Menu_Unchecked);
-    XPLMAppendMenuItem(menuID, "Reset message area", resetMessageAreaRef, 1);
-}
-
-//------------------------------------------------------------------------------
-
-void Menu::handleMenu(void* itemRef)
-{
-    if (itemRef==showMessageAreaRef) {
-        XPLMMenuCheck checked = xplm_Menu_NoCheck;
-        XPLMCheckMenuItemState(menuID, showMessageAreaIndex, &checked);
-        if (checked==xplm_Menu_Unchecked) {
-            XPLMCheckMenuItem(menuID, showMessageAreaIndex, xplm_Menu_Checked);
-            messageWindow.show();
-        } else if (checked==xplm_Menu_Checked) {
-            XPLMCheckMenuItem(menuID, showMessageAreaIndex, xplm_Menu_Unchecked);
-            messageWindow.hide();
-        }
-    } else if (itemRef==resetMessageAreaRef) {
-        messageWindow.reset();
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Menu.h
===================================================================
--- src/plugin/src/xplra/Menu.h	(revision 47)
+++ src/plugin/src/xplra/Menu.h	(revision 47)
@@ -0,0 +1,106 @@
+// 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.
+
+#ifndef XPLRA_MENU_H
+#define XPLRA_MENU_H
+//------------------------------------------------------------------------------
+
+#include <XPLMMenus.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class MessageWindow;
+
+//------------------------------------------------------------------------------
+
+/**
+ * The menu handler.
+ */
+class Menu
+{
+private:
+    /**
+     * The menu handler callback.
+     */
+    static void menuHandlerCallback(void* menuRef, void* itemRef);
+
+    /**
+     * Item reference for the show message area menu item.
+     */
+    static void* const showMessageAreaRef;
+
+    /**
+     * Item reference for the show message area menu item.
+     */
+    static void* const resetMessageAreaRef;
+
+    /**
+     * Reference to the message window.
+     */
+    MessageWindow& messageWindow;
+
+    /**
+     * The menu ID.
+     */
+    XPLMMenuID menuID;
+
+    /**
+     * The index of the "Show Message Area" menu item.
+     */
+    int showMessageAreaIndex;
+
+public:
+    /**
+     * Construct the menu. It creates the menu for the plugin under
+     * the Plugins menu
+     */
+    Menu(MessageWindow& messageWindow);
+
+protected:
+    /**
+     * Handle the menu clicks.
+     */
+    void handleMenu(void* itemRef);
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_MENU_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Menu.h
===================================================================
--- src/plugin/src/xplra/Menu.h	(revision 47)
+++ 	(revision )
@@ -1,106 +1,0 @@
-// 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.
-
-#ifndef XPLRA_MENU_H
-#define XPLRA_MENU_H
-//------------------------------------------------------------------------------
-
-#include <XPLMMenus.h>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class MessageWindow;
-
-//------------------------------------------------------------------------------
-
-/**
- * The menu handler.
- */
-class Menu
-{
-private:
-    /**
-     * The menu handler callback.
-     */
-    static void menuHandlerCallback(void* menuRef, void* itemRef);
-
-    /**
-     * Item reference for the show message area menu item.
-     */
-    static void* const showMessageAreaRef;
-
-    /**
-     * Item reference for the show message area menu item.
-     */
-    static void* const resetMessageAreaRef;
-
-    /**
-     * Reference to the message window.
-     */
-    MessageWindow& messageWindow;
-
-    /**
-     * The menu ID.
-     */
-    XPLMMenuID menuID;
-
-    /**
-     * The index of the "Show Message Area" menu item.
-     */
-    int showMessageAreaIndex;
-
-public:
-    /**
-     * Construct the menu. It creates the menu for the plugin under
-     * the Plugins menu
-     */
-    Menu(MessageWindow& messageWindow);
-
-protected:
-    /**
-     * Handle the menu clicks.
-     */
-    void handleMenu(void* itemRef);
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_MENU_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/MessageRequest.cc
===================================================================
--- src/plugin/src/xplra/MessageRequest.cc	(revision 38)
+++ src/plugin/src/xplra/MessageRequest.cc	(revision 38)
@@ -0,0 +1,52 @@
+// 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 "MessageRequest.h"
+
+#include "MessageWindow.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::MessageRequest;
+
+//------------------------------------------------------------------------------
+
+void MessageRequest::execute()
+{
+    messageWindow.setNewMessage(message, duration);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/MessageRequest.cc
===================================================================
--- src/plugin/src/xplra/MessageRequest.cc	(revision 38)
+++ 	(revision )
@@ -1,52 +1,0 @@
-// 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 "MessageRequest.h"
-
-#include "MessageWindow.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::MessageRequest;
-
-//------------------------------------------------------------------------------
-
-void MessageRequest::execute()
-{
-    messageWindow.setNewMessage(message, duration);
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/MessageRequest.h
===================================================================
--- src/plugin/src/xplra/MessageRequest.h	(revision 38)
+++ src/plugin/src/xplra/MessageRequest.h	(revision 38)
@@ -0,0 +1,106 @@
+// 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.
+
+#ifndef XPLRA_MESSAGEREQUEST_H
+#define XPLRA_MESSAGEREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "Request.h"
+
+#include <string>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class MessageWindow;
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request that sets up a new message to be displayed in the message window.
+ */
+class MessageRequest : public Request
+{
+private:
+    /**
+     * The message window to use.
+     */
+    MessageWindow& messageWindow;
+
+    /**
+     * The message.
+     */
+    std::string message;
+
+    /**
+     * The duration.
+     */
+    float duration;
+
+public:
+    /**
+     * Construct the request.
+     */
+    MessageRequest(MessageWindow& messageWindow,
+                   const std::string& message, float duration);
+
+protected:
+    /**
+     * Execute the request by
+     */
+    virtual void execute();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline MessageRequest::MessageRequest(MessageWindow& messageWindow,
+                                      const std::string& message,
+                                      float duration) :
+    messageWindow(messageWindow),
+    message(message),
+    duration(duration)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_MESSAGEREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/MessageRequest.h
===================================================================
--- src/plugin/src/xplra/MessageRequest.h	(revision 38)
+++ 	(revision )
@@ -1,106 +1,0 @@
-// 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.
-
-#ifndef XPLRA_MESSAGEREQUEST_H
-#define XPLRA_MESSAGEREQUEST_H
-//------------------------------------------------------------------------------
-
-#include "Request.h"
-
-#include <string>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class MessageWindow;
-
-//------------------------------------------------------------------------------
-
-/**
- * A request that sets up a new message to be displayed in the message window.
- */
-class MessageRequest : public Request
-{
-private:
-    /**
-     * The message window to use.
-     */
-    MessageWindow& messageWindow;
-
-    /**
-     * The message.
-     */
-    std::string message;
-
-    /**
-     * The duration.
-     */
-    float duration;
-
-public:
-    /**
-     * Construct the request.
-     */
-    MessageRequest(MessageWindow& messageWindow,
-                   const std::string& message, float duration);
-
-protected:
-    /**
-     * Execute the request by
-     */
-    virtual void execute();
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline MessageRequest::MessageRequest(MessageWindow& messageWindow,
-                                      const std::string& message,
-                                      float duration) :
-    messageWindow(messageWindow),
-    message(message),
-    duration(duration)
-{
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_MESSAGEREQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/MessageWindow.cc
===================================================================
--- src/plugin/src/xplra/MessageWindow.cc	(revision 51)
+++ src/plugin/src/xplra/MessageWindow.cc	(revision 51)
@@ -0,0 +1,315 @@
+// 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 "MessageWindow.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+#include <XPLMProcessing.h>
+#include <XPLMGraphics.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::MessageWindow;
+
+using hu::varadiistvan::xplcommon::Util;
+
+using std::string;
+using std::min;
+using std::max;
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::drawWindowCallback(XPLMWindowID /*windowID*/, void* refCon)
+{
+    MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
+    messageWindow->drawWindow();
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::handleKeyCallback(XPLMWindowID /*windowID*/, char key,
+                                      XPLMKeyFlags flags, char virtualKey,
+                                      void* refCon, int losingFocus)
+{
+    MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
+    messageWindow->handleKey(key, flags, virtualKey, losingFocus!=0);
+}
+
+//------------------------------------------------------------------------------
+
+int MessageWindow::handleMouseClickCallback(XPLMWindowID /*windowID*/,
+                                            int x, int y,
+                                            XPLMMouseStatus mouse, void* refCon)
+{
+    MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
+    return messageWindow->handleMouseClick(x, y, mouse) ? 1 : 0;
+}
+
+//------------------------------------------------------------------------------
+
+MessageWindow::MessageWindow() :
+    maxMessageLength(0),
+    showForced(false),
+    showTime(0.0),
+    hideTime(0.0),
+    clickedX(-1),
+    clickedY(-1),
+    clickedLeft(-1),
+    clickedTop(-1),
+    clickedRight(-1),
+    clickedBottom(-1),
+    duration(0.0)
+{
+    widthDataRef = XPLMFindDataRef("sim/graphics/view/window_width");
+    heightDataRef = XPLMFindDataRef("sim/graphics/view/window_height");
+
+    int digitsOnly = 0;
+    XPLMGetFontDimensions(xplmFont_Basic, &fontWidth, &fontHeight, &digitsOnly);
+
+    Util::debug("hu.varadiistvan.xplra.MessageWindow: fontWidth=%d, fontHeight=%d\n",
+                fontWidth, fontHeight);
+
+    resetLocation();
+
+    windowID = XPLMCreateWindow(left, top, right, bottom, 0,
+                                &drawWindowCallback,
+                                &handleKeyCallback,
+                                &handleMouseClickCallback, this);
+}
+
+//------------------------------------------------------------------------------
+
+MessageWindow::~MessageWindow()
+{
+    XPLMSetWindowIsVisible(windowID, 0);
+    XPLMDestroyWindow(windowID);
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::show()
+{
+    showForced = true;
+    XPLMSetWindowIsVisible(windowID, 1);
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::hide()
+{
+    showForced = false;
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::reset()
+{
+    resetLocation();
+    XPLMSetWindowGeometry(windowID, left, top, right, bottom);
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::drawWindow()
+{
+    static float colour[3] = { 0.2, 1.0, 0.65 };
+
+    float now = XPLMGetElapsedTime();
+
+    float d = getNewMessage(displayedMessage);
+    if (d>0.0) {
+        showTime = now;
+        hideTime = now + d;
+    }
+
+    if (now>=hideTime) hideTime = 0.0;
+
+    if (hideTime==0.0 && !showForced) {
+        XPLMSetWindowIsVisible(windowID, 0);
+    } else {
+        XPLMDrawTranslucentDarkBox(left, top, right, bottom);
+        if (hideTime!=0.0) {
+            size_t offset = 0;
+            if  (displayedMessage.size()>maxMessageLength &&
+                 now > (showTime + scrollTimeout) )
+            {
+                offset = (now - showTime - scrollTimeout) /
+                    scrollInterval;
+                offset = min(offset,
+                             displayedMessage.size() - maxMessageLength);
+            }
+
+            string dm(displayedMessage, offset, maxMessageLength);
+
+            XPLMDrawString(colour,
+                           left + horizontalMarginSize,
+                           bottom + verticalMarginSize + baseLineSize,
+                           const_cast<char*>(dm.c_str()), 0,
+                           xplmFont_Basic);
+        }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::handleKey(char key, XPLMKeyFlags flags, char virtualKey,
+                              bool losingFocus)
+{
+    Util::debug("hu.varadiistvan.xplra.MessageWindow.handleKey: key=0x%02d (%c), flags=0x%04x, virtualKey=0x%02d (%c), losingFocus=%d\n",
+                key, key, flags, virtualKey, virtualKey, losingFocus);
+}
+
+//------------------------------------------------------------------------------
+
+bool MessageWindow::handleMouseClick(int x, int y, XPLMMouseStatus mouse)
+{
+    if (mouse==xplm_MouseDown) {
+        if (x <= (left + resizeArea) ) {
+            mouseMode = MOUSE_RESIZE_LEFT;
+        } else if (x > (right-resizeArea) ) {
+            mouseMode = MOUSE_RESIZE_RIGHT;
+        } else {
+            mouseMode = MOUSE_MOVE;
+        }
+        clickedX = x;
+        clickedY = y;
+        clickedLeft = left;
+        clickedTop = top;
+        clickedRight = right;
+        clickedBottom = bottom;
+    } else if (mouse==xplm_MouseDrag) {
+        int xDiff = x - clickedX;
+
+        if (mouseMode==MOUSE_MOVE) {
+            int newLeft = clickedLeft + xDiff;
+            int newRight = clickedRight + xDiff;
+
+            int screenWidth = XPLMGetDatai(widthDataRef);
+            if (newLeft>=0 && newRight<screenWidth) {
+                left = newLeft;
+                right = newRight;
+            }
+
+            int yDiff = y - clickedY;
+            int newTop = clickedTop + yDiff;
+            int newBottom = clickedBottom + yDiff;
+
+            int screenHeight = XPLMGetDatai(heightDataRef);
+            if (newTop<screenHeight && newBottom>=0) {
+                top = newTop;
+                bottom = newBottom;
+            }
+        } else if (mouseMode==MOUSE_RESIZE_LEFT) {
+            int newLeft = clickedLeft + xDiff;
+            if (newLeft>=0 && (right-newLeft)>=minimalWidth) {
+                left = newLeft;
+                recalculateMaxMessageLength();
+            }
+        } else if (mouseMode==MOUSE_RESIZE_RIGHT) {
+            int newRight = clickedRight + xDiff;
+            int screenWidth = XPLMGetDatai(widthDataRef);
+            if (newRight<screenWidth && (newRight-left)>=minimalWidth) {
+                right = newRight;
+                recalculateMaxMessageLength();
+            }
+        }
+
+        XPLMSetWindowGeometry(windowID, left, top, right, bottom);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+float MessageWindow::getNewMessage(std::string& dest)
+{
+    mutex.lock();
+
+    float d = duration;
+    if (d>0.0) {
+        dest = message;
+
+        message.clear();
+        duration = 0.0;
+    }
+
+    mutex.unlock();
+
+    return d;
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::setNewMessage(const std::string& msg, float d)
+{
+    mutex.lock();
+    message = msg;
+    duration = d;
+    mutex.unlock();
+
+    XPLMSetWindowIsVisible(windowID, 1);
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::resetLocation()
+{
+    int screenWidth = XPLMGetDatai(widthDataRef);
+    int screenHeight = XPLMGetDatai(heightDataRef);
+
+    // Util::debug("hu.varadiistvan.xplra.MessageWindow: screenWidth=%d, screenHeight=%d\n",
+    //             screenWidth, screenHeight);
+
+    left = 50;
+    right = screenWidth - left;
+
+    top = screenHeight * 9 / 10;
+    bottom = top - fontHeight - 2*verticalMarginSize;
+
+    recalculateMaxMessageLength();
+}
+
+//------------------------------------------------------------------------------
+
+void MessageWindow::recalculateMaxMessageLength()
+{
+    maxMessageLength = (right + 1 - left) - 2 * horizontalMarginSize;
+    maxMessageLength /= fontWidth;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/MessageWindow.cc
===================================================================
--- src/plugin/src/xplra/MessageWindow.cc	(revision 51)
+++ 	(revision )
@@ -1,315 +1,0 @@
-// 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 "MessageWindow.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-#include <XPLMProcessing.h>
-#include <XPLMGraphics.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::MessageWindow;
-
-using hu::varadiistvan::xplcommon::Util;
-
-using std::string;
-using std::min;
-using std::max;
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::drawWindowCallback(XPLMWindowID /*windowID*/, void* refCon)
-{
-    MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
-    messageWindow->drawWindow();
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::handleKeyCallback(XPLMWindowID /*windowID*/, char key,
-                                      XPLMKeyFlags flags, char virtualKey,
-                                      void* refCon, int losingFocus)
-{
-    MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
-    messageWindow->handleKey(key, flags, virtualKey, losingFocus!=0);
-}
-
-//------------------------------------------------------------------------------
-
-int MessageWindow::handleMouseClickCallback(XPLMWindowID /*windowID*/,
-                                            int x, int y,
-                                            XPLMMouseStatus mouse, void* refCon)
-{
-    MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
-    return messageWindow->handleMouseClick(x, y, mouse) ? 1 : 0;
-}
-
-//------------------------------------------------------------------------------
-
-MessageWindow::MessageWindow() :
-    maxMessageLength(0),
-    showForced(false),
-    showTime(0.0),
-    hideTime(0.0),
-    clickedX(-1),
-    clickedY(-1),
-    clickedLeft(-1),
-    clickedTop(-1),
-    clickedRight(-1),
-    clickedBottom(-1),
-    duration(0.0)
-{
-    widthDataRef = XPLMFindDataRef("sim/graphics/view/window_width");
-    heightDataRef = XPLMFindDataRef("sim/graphics/view/window_height");
-
-    int digitsOnly = 0;
-    XPLMGetFontDimensions(xplmFont_Basic, &fontWidth, &fontHeight, &digitsOnly);
-
-    Util::debug("hu.varadiistvan.xplra.MessageWindow: fontWidth=%d, fontHeight=%d\n",
-                fontWidth, fontHeight);
-
-    resetLocation();
-
-    windowID = XPLMCreateWindow(left, top, right, bottom, 0,
-                                &drawWindowCallback,
-                                &handleKeyCallback,
-                                &handleMouseClickCallback, this);
-}
-
-//------------------------------------------------------------------------------
-
-MessageWindow::~MessageWindow()
-{
-    XPLMSetWindowIsVisible(windowID, 0);
-    XPLMDestroyWindow(windowID);
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::show()
-{
-    showForced = true;
-    XPLMSetWindowIsVisible(windowID, 1);
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::hide()
-{
-    showForced = false;
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::reset()
-{
-    resetLocation();
-    XPLMSetWindowGeometry(windowID, left, top, right, bottom);
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::drawWindow()
-{
-    static float colour[3] = { 0.2, 1.0, 0.65 };
-
-    float now = XPLMGetElapsedTime();
-
-    float d = getNewMessage(displayedMessage);
-    if (d>0.0) {
-        showTime = now;
-        hideTime = now + d;
-    }
-
-    if (now>=hideTime) hideTime = 0.0;
-
-    if (hideTime==0.0 && !showForced) {
-        XPLMSetWindowIsVisible(windowID, 0);
-    } else {
-        XPLMDrawTranslucentDarkBox(left, top, right, bottom);
-        if (hideTime!=0.0) {
-            size_t offset = 0;
-            if  (displayedMessage.size()>maxMessageLength &&
-                 now > (showTime + scrollTimeout) )
-            {
-                offset = (now - showTime - scrollTimeout) /
-                    scrollInterval;
-                offset = min(offset,
-                             displayedMessage.size() - maxMessageLength);
-            }
-
-            string dm(displayedMessage, offset, maxMessageLength);
-
-            XPLMDrawString(colour,
-                           left + horizontalMarginSize,
-                           bottom + verticalMarginSize + baseLineSize,
-                           const_cast<char*>(dm.c_str()), 0,
-                           xplmFont_Basic);
-        }
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::handleKey(char key, XPLMKeyFlags flags, char virtualKey,
-                              bool losingFocus)
-{
-    Util::debug("hu.varadiistvan.xplra.MessageWindow.handleKey: key=0x%02d (%c), flags=0x%04x, virtualKey=0x%02d (%c), losingFocus=%d\n",
-                key, key, flags, virtualKey, virtualKey, losingFocus);
-}
-
-//------------------------------------------------------------------------------
-
-bool MessageWindow::handleMouseClick(int x, int y, XPLMMouseStatus mouse)
-{
-    if (mouse==xplm_MouseDown) {
-        if (x <= (left + resizeArea) ) {
-            mouseMode = MOUSE_RESIZE_LEFT;
-        } else if (x > (right-resizeArea) ) {
-            mouseMode = MOUSE_RESIZE_RIGHT;
-        } else {
-            mouseMode = MOUSE_MOVE;
-        }
-        clickedX = x;
-        clickedY = y;
-        clickedLeft = left;
-        clickedTop = top;
-        clickedRight = right;
-        clickedBottom = bottom;
-    } else if (mouse==xplm_MouseDrag) {
-        int xDiff = x - clickedX;
-
-        if (mouseMode==MOUSE_MOVE) {
-            int newLeft = clickedLeft + xDiff;
-            int newRight = clickedRight + xDiff;
-
-            int screenWidth = XPLMGetDatai(widthDataRef);
-            if (newLeft>=0 && newRight<screenWidth) {
-                left = newLeft;
-                right = newRight;
-            }
-
-            int yDiff = y - clickedY;
-            int newTop = clickedTop + yDiff;
-            int newBottom = clickedBottom + yDiff;
-
-            int screenHeight = XPLMGetDatai(heightDataRef);
-            if (newTop<screenHeight && newBottom>=0) {
-                top = newTop;
-                bottom = newBottom;
-            }
-        } else if (mouseMode==MOUSE_RESIZE_LEFT) {
-            int newLeft = clickedLeft + xDiff;
-            if (newLeft>=0 && (right-newLeft)>=minimalWidth) {
-                left = newLeft;
-                recalculateMaxMessageLength();
-            }
-        } else if (mouseMode==MOUSE_RESIZE_RIGHT) {
-            int newRight = clickedRight + xDiff;
-            int screenWidth = XPLMGetDatai(widthDataRef);
-            if (newRight<screenWidth && (newRight-left)>=minimalWidth) {
-                right = newRight;
-                recalculateMaxMessageLength();
-            }
-        }
-
-        XPLMSetWindowGeometry(windowID, left, top, right, bottom);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-float MessageWindow::getNewMessage(std::string& dest)
-{
-    mutex.lock();
-
-    float d = duration;
-    if (d>0.0) {
-        dest = message;
-
-        message.clear();
-        duration = 0.0;
-    }
-
-    mutex.unlock();
-
-    return d;
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::setNewMessage(const std::string& msg, float d)
-{
-    mutex.lock();
-    message = msg;
-    duration = d;
-    mutex.unlock();
-
-    XPLMSetWindowIsVisible(windowID, 1);
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::resetLocation()
-{
-    int screenWidth = XPLMGetDatai(widthDataRef);
-    int screenHeight = XPLMGetDatai(heightDataRef);
-
-    // Util::debug("hu.varadiistvan.xplra.MessageWindow: screenWidth=%d, screenHeight=%d\n",
-    //             screenWidth, screenHeight);
-
-    left = 50;
-    right = screenWidth - left;
-
-    top = screenHeight * 9 / 10;
-    bottom = top - fontHeight - 2*verticalMarginSize;
-
-    recalculateMaxMessageLength();
-}
-
-//------------------------------------------------------------------------------
-
-void MessageWindow::recalculateMaxMessageLength()
-{
-    maxMessageLength = (right + 1 - left) - 2 * horizontalMarginSize;
-    maxMessageLength /= fontWidth;
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/MessageWindow.h
===================================================================
--- src/plugin/src/xplra/MessageWindow.h	(revision 51)
+++ src/plugin/src/xplra/MessageWindow.h	(revision 51)
@@ -0,0 +1,325 @@
+// 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.
+
+#ifndef XPLRA_MESSAGEWINDOW_H
+#define XPLRA_MESSAGEWINDOW_H
+//------------------------------------------------------------------------------
+
+#include <hu/varadiistvan/scpl/Mutex.h>
+
+#include <string>
+
+#include <XPLMDataAccess.h>
+#include <XPLMDisplay.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Class to handle the activities related to the message window.
+ */
+class MessageWindow
+{
+private:
+    /**
+     * Window drawing callback.
+     */
+    static void drawWindowCallback(XPLMWindowID windowID, void* refCon);
+
+    /**
+     * Handle the keypresses.
+     */
+    static void handleKeyCallback(XPLMWindowID windowID, char key,
+                                  XPLMKeyFlags flags, char virtualKey,
+                                  void* refCon, int losingFocus);
+
+    /**
+     * Handle the mouse clicks.
+     */
+    static int handleMouseClickCallback(XPLMWindowID windowID, int x, int y,
+                                        XPLMMouseStatus mouse, void* refCon);
+
+
+    /**
+     * The minimal width of the message area.
+     */
+    static const int minimalWidth = 150;
+
+    /**
+     * The size of the resize sensitivity area.
+     */
+    static const int resizeArea = 50;
+
+    /**
+     * The size of the margins at each side of the window.
+     */
+    static const int horizontalMarginSize = 25;
+
+    /**
+     * The size of the margins at the top and the bottom of the window.
+     */
+    static const int verticalMarginSize = 5;
+
+    /**
+     * The size for the baseline above the bottom of the letters.
+     */
+    static const int baseLineSize = 2;
+
+    /**
+     * The amount of time in seconds after which the message is
+     * started to be scrolled, if it should be scrolled.
+     */
+    static const float scrollTimeout = 1.0;
+
+    /**
+     * The amount of time in seconds between each character step.
+     */
+    static const float scrollInterval = 0.1;
+
+private:
+    /**
+     * The dataref containing the width of the program's window.
+     */
+    XPLMDataRef widthDataRef;
+
+    /**
+     * The dataref containing the height of the program's window.
+     */
+    XPLMDataRef heightDataRef;
+
+    /**
+     * The width of one character of the font.
+     */
+    int fontWidth;
+
+    /**
+     * The height of one character of the font.
+     */
+    int fontHeight;
+
+    /**
+     * The window ID.
+     */
+    XPLMWindowID windowID;
+
+    /**
+     * The X-coordinate of the left side of the window.
+     */
+    int left;
+
+    /**
+     * The Y-coordinate of the top of the window.
+     */
+    int top;
+
+    /**
+     * The X-coordinate of the right side of the window.
+     */
+    int right;
+
+    /**
+     * The Y-coordinate of the bottom of the window.
+     */
+    int bottom;
+
+    /**
+     * The maximal message length.
+     */
+    size_t maxMessageLength;
+
+    /**
+     * Indicate if the message window should be shown
+     */
+    bool showForced;
+
+    /**
+     * The currently displayed message.
+     */
+    std::string displayedMessage;
+
+    /**
+     * The time the current message was shown.
+     */
+    float showTime;
+
+    /**
+     * The time to hide the current message. If not positive, no
+     * message is currently shown.
+     */
+    float hideTime;
+
+    /**
+     * The mouse mode
+     */
+    enum {
+        // Move the message area
+        MOUSE_MOVE,
+
+        // Resize the message area from the left
+        MOUSE_RESIZE_LEFT,
+
+        // Resize the message area from the right.
+        MOUSE_RESIZE_RIGHT
+    } mouseMode;
+
+    /**
+     * The X-coordinate where the window was clicked.
+     */
+    int clickedX;
+
+    /**
+     * The Y-coordinate where the window was clicked.
+     */
+    int clickedY;
+
+    /**
+     * The left coordinate of the window when it was clicked.
+     */
+    int clickedLeft;
+
+    /**
+     * The top coordinate of the window when it was clicked.
+     */
+    int clickedTop;
+
+    /**
+     * The right coordinate of the window when it was clicked.
+     */
+    int clickedRight;
+
+    /**
+     * The bottom coordinate of the window when it was clicked.
+     */
+    int clickedBottom;
+
+    /**
+     * The mutex protecting some of the data structures that are used
+     * from both the simulator loop and the server thread.
+     */
+    hu::varadiistvan::scpl::Mutex mutex;
+
+    /**
+     * The message to show.
+     */
+    std::string message;
+
+    /**
+     * The number of seconds for which the message should be shown. If
+     * positive, there is a new message.
+     */
+    float duration;
+
+public:
+    /**
+     * Construct the message window. It creates the X-Plane window and
+     * registers the callback functions. The window is hidden
+     * initially.
+     */
+    MessageWindow();
+
+    /**
+     * Destroy the message window. It destroys the X-Plane window.
+     */
+    ~MessageWindow();
+
+    /**
+     * Force showing the message window.
+     */
+    void show();
+
+    /**
+     * Hide the message window if it does not have to display an
+     * actual message.
+     */
+    void hide();
+
+    /**
+     * Reset the location of the message window.
+     */
+    void reset();
+
+private:
+    /**
+     * Called from the window drawing callback.
+     */
+    void drawWindow();
+
+    /**
+     * Called from the key handling callback.
+     */
+    void handleKey(char key, XPLMKeyFlags flags, char virtualKey,
+                   bool losingFocus);
+
+    /**
+     * Called from the mouse click handling callback.
+     *
+     * @return true if the click is consumed, false otherwise.
+     */
+    bool handleMouseClick(int x, int y, XPLMMouseStatus mouse);
+
+    /**
+     * Get the new message, if any.
+     *
+     * @return the duration of the message, or 0.0 if there is no new
+     * message. The message will be cleared.
+     */
+    float getNewMessage(std::string& dest);
+
+    /**
+     * Set the new message, if any.
+     */
+    void setNewMessage(const std::string& msg, float d);
+
+    /**
+     * Reset the location of the message window.
+     */
+    void resetLocation();
+
+    /**
+     * Recalculate the maximal message length.
+     */
+    void recalculateMaxMessageLength();
+
+    friend class MessageRequest;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_MESSAGEWINDOW_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/MessageWindow.h
===================================================================
--- src/plugin/src/xplra/MessageWindow.h	(revision 51)
+++ 	(revision )
@@ -1,325 +1,0 @@
-// 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.
-
-#ifndef XPLRA_MESSAGEWINDOW_H
-#define XPLRA_MESSAGEWINDOW_H
-//------------------------------------------------------------------------------
-
-#include <hu/varadiistvan/scpl/Mutex.h>
-
-#include <string>
-
-#include <XPLMDataAccess.h>
-#include <XPLMDisplay.h>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Class to handle the activities related to the message window.
- */
-class MessageWindow
-{
-private:
-    /**
-     * Window drawing callback.
-     */
-    static void drawWindowCallback(XPLMWindowID windowID, void* refCon);
-
-    /**
-     * Handle the keypresses.
-     */
-    static void handleKeyCallback(XPLMWindowID windowID, char key,
-                                  XPLMKeyFlags flags, char virtualKey,
-                                  void* refCon, int losingFocus);
-
-    /**
-     * Handle the mouse clicks.
-     */
-    static int handleMouseClickCallback(XPLMWindowID windowID, int x, int y,
-                                        XPLMMouseStatus mouse, void* refCon);
-
-
-    /**
-     * The minimal width of the message area.
-     */
-    static const int minimalWidth = 150;
-
-    /**
-     * The size of the resize sensitivity area.
-     */
-    static const int resizeArea = 50;
-
-    /**
-     * The size of the margins at each side of the window.
-     */
-    static const int horizontalMarginSize = 25;
-
-    /**
-     * The size of the margins at the top and the bottom of the window.
-     */
-    static const int verticalMarginSize = 5;
-
-    /**
-     * The size for the baseline above the bottom of the letters.
-     */
-    static const int baseLineSize = 2;
-
-    /**
-     * The amount of time in seconds after which the message is
-     * started to be scrolled, if it should be scrolled.
-     */
-    static const float scrollTimeout = 1.0;
-
-    /**
-     * The amount of time in seconds between each character step.
-     */
-    static const float scrollInterval = 0.1;
-
-private:
-    /**
-     * The dataref containing the width of the program's window.
-     */
-    XPLMDataRef widthDataRef;
-
-    /**
-     * The dataref containing the height of the program's window.
-     */
-    XPLMDataRef heightDataRef;
-
-    /**
-     * The width of one character of the font.
-     */
-    int fontWidth;
-
-    /**
-     * The height of one character of the font.
-     */
-    int fontHeight;
-
-    /**
-     * The window ID.
-     */
-    XPLMWindowID windowID;
-
-    /**
-     * The X-coordinate of the left side of the window.
-     */
-    int left;
-
-    /**
-     * The Y-coordinate of the top of the window.
-     */
-    int top;
-
-    /**
-     * The X-coordinate of the right side of the window.
-     */
-    int right;
-
-    /**
-     * The Y-coordinate of the bottom of the window.
-     */
-    int bottom;
-
-    /**
-     * The maximal message length.
-     */
-    size_t maxMessageLength;
-
-    /**
-     * Indicate if the message window should be shown
-     */
-    bool showForced;
-
-    /**
-     * The currently displayed message.
-     */
-    std::string displayedMessage;
-
-    /**
-     * The time the current message was shown.
-     */
-    float showTime;
-
-    /**
-     * The time to hide the current message. If not positive, no
-     * message is currently shown.
-     */
-    float hideTime;
-
-    /**
-     * The mouse mode
-     */
-    enum {
-        // Move the message area
-        MOUSE_MOVE,
-
-        // Resize the message area from the left
-        MOUSE_RESIZE_LEFT,
-
-        // Resize the message area from the right.
-        MOUSE_RESIZE_RIGHT
-    } mouseMode;
-
-    /**
-     * The X-coordinate where the window was clicked.
-     */
-    int clickedX;
-
-    /**
-     * The Y-coordinate where the window was clicked.
-     */
-    int clickedY;
-
-    /**
-     * The left coordinate of the window when it was clicked.
-     */
-    int clickedLeft;
-
-    /**
-     * The top coordinate of the window when it was clicked.
-     */
-    int clickedTop;
-
-    /**
-     * The right coordinate of the window when it was clicked.
-     */
-    int clickedRight;
-
-    /**
-     * The bottom coordinate of the window when it was clicked.
-     */
-    int clickedBottom;
-
-    /**
-     * The mutex protecting some of the data structures that are used
-     * from both the simulator loop and the server thread.
-     */
-    hu::varadiistvan::scpl::Mutex mutex;
-
-    /**
-     * The message to show.
-     */
-    std::string message;
-
-    /**
-     * The number of seconds for which the message should be shown. If
-     * positive, there is a new message.
-     */
-    float duration;
-
-public:
-    /**
-     * Construct the message window. It creates the X-Plane window and
-     * registers the callback functions. The window is hidden
-     * initially.
-     */
-    MessageWindow();
-
-    /**
-     * Destroy the message window. It destroys the X-Plane window.
-     */
-    ~MessageWindow();
-
-    /**
-     * Force showing the message window.
-     */
-    void show();
-
-    /**
-     * Hide the message window if it does not have to display an
-     * actual message.
-     */
-    void hide();
-
-    /**
-     * Reset the location of the message window.
-     */
-    void reset();
-
-private:
-    /**
-     * Called from the window drawing callback.
-     */
-    void drawWindow();
-
-    /**
-     * Called from the key handling callback.
-     */
-    void handleKey(char key, XPLMKeyFlags flags, char virtualKey,
-                   bool losingFocus);
-
-    /**
-     * Called from the mouse click handling callback.
-     *
-     * @return true if the click is consumed, false otherwise.
-     */
-    bool handleMouseClick(int x, int y, XPLMMouseStatus mouse);
-
-    /**
-     * Get the new message, if any.
-     *
-     * @return the duration of the message, or 0.0 if there is no new
-     * message. The message will be cleared.
-     */
-    float getNewMessage(std::string& dest);
-
-    /**
-     * Set the new message, if any.
-     */
-    void setNewMessage(const std::string& msg, float d);
-
-    /**
-     * Reset the location of the message window.
-     */
-    void resetLocation();
-
-    /**
-     * Recalculate the maximal message length.
-     */
-    void recalculateMaxMessageLength();
-
-    friend class MessageRequest;
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_MESSAGEWINDOW_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/MultiTaskRequest.cc
===================================================================
--- src/plugin/src/xplra/MultiTaskRequest.cc	(revision 13)
+++ src/plugin/src/xplra/MultiTaskRequest.cc	(revision 13)
@@ -0,0 +1,70 @@
+// 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 "MultiTaskRequest.h"
+
+#include "Task.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::MultiTaskRequest;
+
+using hu::varadiistvan::xplcommon::Util;
+
+//------------------------------------------------------------------------------
+
+MultiTaskRequest::~MultiTaskRequest()
+{
+    for(tasks_t::iterator i = tasks.begin(); i!=tasks.end(); ++i) {
+        delete *i;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void MultiTaskRequest::execute()
+{
+    // Util::debug("hu.varadiistvan.xplra.MultiTaskRequest[%p]::execute\n", this);
+    for(tasks_t::iterator i = tasks.begin(); i!=tasks.end(); ++i) {
+        // Util::debug("hu.varadiistvan.xplra.MultiTaskRequest[%p]::execute: task=%p\n",
+        //             this, *i);
+        (*i)->perform();
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/MultiTaskRequest.cc
===================================================================
--- src/plugin/src/xplra/MultiTaskRequest.cc	(revision 13)
+++ 	(revision )
@@ -1,70 +1,0 @@
-// 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 "MultiTaskRequest.h"
-
-#include "Task.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::MultiTaskRequest;
-
-using hu::varadiistvan::xplcommon::Util;
-
-//------------------------------------------------------------------------------
-
-MultiTaskRequest::~MultiTaskRequest()
-{
-    for(tasks_t::iterator i = tasks.begin(); i!=tasks.end(); ++i) {
-        delete *i;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void MultiTaskRequest::execute()
-{
-    // Util::debug("hu.varadiistvan.xplra.MultiTaskRequest[%p]::execute\n", this);
-    for(tasks_t::iterator i = tasks.begin(); i!=tasks.end(); ++i) {
-        // Util::debug("hu.varadiistvan.xplra.MultiTaskRequest[%p]::execute: task=%p\n",
-        //             this, *i);
-        (*i)->perform();
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/MultiTaskRequest.h
===================================================================
--- src/plugin/src/xplra/MultiTaskRequest.h	(revision 13)
+++ src/plugin/src/xplra/MultiTaskRequest.h	(revision 13)
@@ -0,0 +1,170 @@
+// 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.
+
+#ifndef XPLRA_MULTITASKREQUEST_H
+#define XPLRA_MULTITASKREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "Request.h"
+
+#include <vector>
+
+#include <cstdlib>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class Task;
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request containing several tasks which it performs one-by-one
+ * when executing the request. It owns the tasks, which get deleted
+ * when the request object is deleted.
+ */
+class MultiTaskRequest : public Request
+{
+private:
+    /**
+     * Type for the vector of the tasks.
+     */
+    typedef std::vector<Task*> tasks_t;
+
+    /**
+     * The tasks.
+     */
+    tasks_t tasks;
+
+public:
+    /**
+     * Destroy the request by deleting the tasks.
+     */
+    virtual ~MultiTaskRequest();
+
+    /**
+     * Add a task to the request.
+     */
+    void addTask(Task* task);
+
+    /**
+     * Get the number of tasks.
+     */
+    size_t getNumTasks() const;
+
+    /**
+     * Get the task at the given index.
+     */
+    Task* getTask(size_t index) const;
+
+protected:
+    /**
+     * Perform the tasks one-by-one.
+     */
+    virtual void execute();
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A templated version of MultiTaskRequest, which accepts and returns
+ * tasks of a given type only.
+ */
+template <class TaskClass>
+class MultiTaskRequestTemplate : public MultiTaskRequest
+{
+public:
+    /**
+     * Add the given task.
+     */
+    void addTask(TaskClass* task);
+
+    /**
+     * Get the task at the given index.
+     */
+    TaskClass* getTask(size_t index) const;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline void MultiTaskRequest::addTask(Task* task)
+{
+    tasks.push_back(task);
+}
+
+//------------------------------------------------------------------------------
+
+inline size_t MultiTaskRequest::getNumTasks() const
+{
+    return tasks.size();
+}
+
+//------------------------------------------------------------------------------
+
+inline Task* MultiTaskRequest::getTask(size_t index) const
+{
+    return tasks[index];
+}
+
+//------------------------------------------------------------------------------
+// Template definitions
+//------------------------------------------------------------------------------
+
+template <class TaskClass>
+inline void MultiTaskRequestTemplate<TaskClass>::addTask(TaskClass* task)
+{
+    MultiTaskRequest::addTask(task);
+}
+
+//------------------------------------------------------------------------------
+
+template <class TaskClass>
+inline TaskClass*
+MultiTaskRequestTemplate<TaskClass>::getTask(size_t index) const
+{
+    return static_cast<TaskClass*>(MultiTaskRequest::getTask(index));
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_MULTITASKREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/MultiTaskRequest.h
===================================================================
--- src/plugin/src/xplra/MultiTaskRequest.h	(revision 13)
+++ 	(revision )
@@ -1,170 +1,0 @@
-// 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.
-
-#ifndef XPLRA_MULTITASKREQUEST_H
-#define XPLRA_MULTITASKREQUEST_H
-//------------------------------------------------------------------------------
-
-#include "Request.h"
-
-#include <vector>
-
-#include <cstdlib>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class Task;
-
-//------------------------------------------------------------------------------
-
-/**
- * A request containing several tasks which it performs one-by-one
- * when executing the request. It owns the tasks, which get deleted
- * when the request object is deleted.
- */
-class MultiTaskRequest : public Request
-{
-private:
-    /**
-     * Type for the vector of the tasks.
-     */
-    typedef std::vector<Task*> tasks_t;
-
-    /**
-     * The tasks.
-     */
-    tasks_t tasks;
-
-public:
-    /**
-     * Destroy the request by deleting the tasks.
-     */
-    virtual ~MultiTaskRequest();
-
-    /**
-     * Add a task to the request.
-     */
-    void addTask(Task* task);
-
-    /**
-     * Get the number of tasks.
-     */
-    size_t getNumTasks() const;
-
-    /**
-     * Get the task at the given index.
-     */
-    Task* getTask(size_t index) const;
-
-protected:
-    /**
-     * Perform the tasks one-by-one.
-     */
-    virtual void execute();
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A templated version of MultiTaskRequest, which accepts and returns
- * tasks of a given type only.
- */
-template <class TaskClass>
-class MultiTaskRequestTemplate : public MultiTaskRequest
-{
-public:
-    /**
-     * Add the given task.
-     */
-    void addTask(TaskClass* task);
-
-    /**
-     * Get the task at the given index.
-     */
-    TaskClass* getTask(size_t index) const;
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline void MultiTaskRequest::addTask(Task* task)
-{
-    tasks.push_back(task);
-}
-
-//------------------------------------------------------------------------------
-
-inline size_t MultiTaskRequest::getNumTasks() const
-{
-    return tasks.size();
-}
-
-//------------------------------------------------------------------------------
-
-inline Task* MultiTaskRequest::getTask(size_t index) const
-{
-    return tasks[index];
-}
-
-//------------------------------------------------------------------------------
-// Template definitions
-//------------------------------------------------------------------------------
-
-template <class TaskClass>
-inline void MultiTaskRequestTemplate<TaskClass>::addTask(TaskClass* task)
-{
-    MultiTaskRequest::addTask(task);
-}
-
-//------------------------------------------------------------------------------
-
-template <class TaskClass>
-inline TaskClass*
-MultiTaskRequestTemplate<TaskClass>::getTask(size_t index) const
-{
-    return static_cast<TaskClass*>(MultiTaskRequest::getTask(index));
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_MULTITASKREQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Protocol.h
===================================================================
--- src/plugin/src/xplra/Protocol.h	(revision 45)
+++ src/plugin/src/xplra/Protocol.h	(revision 45)
@@ -0,0 +1,278 @@
+// 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.
+
+#ifndef XPLRA_PROTOCOL_H
+#define XPLRA_PROTOCOL_H
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Constants and helpers for the protocol.
+ */
+class Protocol
+{
+public:
+    /**
+     * Command: get the value of a single dataref.
+     */
+    static const uint8_t COMMAND_GET_SINGLE = 0x01;
+
+    /**
+     * Command: set the value of a single dataref.
+     */
+    static const uint8_t COMMAND_SET_SINGLE = 0x02;
+
+    /**
+     * Command: get the value of a multiple datarefs.
+     */
+    static const uint8_t COMMAND_GET_MULTI = 0x03;
+
+    /**
+     * Command: set the value of a multiple datarefs.
+     */
+    static const uint8_t COMMAND_SET_MULTI = 0x04;
+
+    /**
+     * Command: register a multiple-data query request
+     */
+    static const uint8_t COMMAND_REGISTER_GET_MULTI = 0x11;
+
+    /**
+     * Command: unregister a multiple-data query request
+     */
+    static const uint8_t COMMAND_UNREGISTER_GET_MULTI = 0x12;
+
+    /**
+     * Command: execute a registered multiple-data query request
+     */
+    static const uint8_t COMMAND_EXECUTE_GET_MULTI = 0x13;
+
+    /**
+     * Command: register a multiple-data update request
+     */
+    static const uint8_t COMMAND_REGISTER_SET_MULTI = 0x21;
+
+    /**
+     * Command: unregister a multiple-data update request
+     */
+    static const uint8_t COMMAND_UNREGISTER_SET_MULTI = 0x22;
+
+    /**
+     * Command: execute a registered multiple-data update request
+     */
+    static const uint8_t COMMAND_EXECUTE_SET_MULTI = 0x23;
+
+    /**
+     * Command: get the versions of the simulator
+     */
+    static const uint8_t COMMAND_GET_VERSIONS = 0x31;
+
+    /**
+     * Command: reload the plugins
+     */
+    static const uint8_t COMMAND_RELOAD_PLUGINS = 0x32;
+
+    /**
+     * Command: show a message in the message window.
+     */
+    static const uint8_t COMMAND_SHOW_MESSAGE = 0x41;
+
+    /**
+     * Command: register a set of hotkeys for the client. Old hotkeys,
+     * if any, are forgotten.
+     *
+     * The command is followed by the following data:
+     * - The number of the hotkeys defined (U32).
+     * - The code of the hotkeys (U16*number of the hotkeys).
+     *   The lower byte is the same as the X-Plane virtual key code
+     *   (the same as the ASCII code for numbers and upper-case letters),
+     *   the upper one is a logical OR of the HOTKEY_MODIFIER_XXX
+     *   codes.
+     *
+     * The reply consists of a result code only. It may fail with an
+     * invalid length code if the number of hotkeys is too large.
+     */
+    static const uint8_t COMMAND_REGISTER_HOTKEYS = 0x51;
+
+    /**
+     * Command: query the hotkeys.
+     *
+     * The reply consists of a result code, followed by the following
+     * data, if the result code is RESULT_OK:
+     * - The number of hotkeys defined (U32).
+     * - An array of U8 values each being 0 or 1 depending on whether
+     *   the corresponding hotkey has been pressed since the last
+     *   query (or the registration, whichever is later). The value at
+     *   index i corresponds to the hotkey code at index i in the
+     *   array passed with COMMAND_REGISTER_HOTKEYS.
+     *
+     * If not hotkey has been registered, the number of hotkeys is
+     * returned as 0.
+     */
+    static const uint8_t COMMAND_QUERY_HOTKEYS = 0x52;
+
+    /**
+     * Command: unregister the previously registered hotkeys.
+     *
+     * The reply is a result code.
+     */
+    static const uint8_t COMMAND_UNREGISTER_HOTKEYS = 0x53;
+
+    /**
+     * Data type: int
+     */
+    static const uint8_t TYPE_INT = 0x01;
+
+    /**
+     * Data type: float
+     */
+    static const uint8_t TYPE_FLOAT = 0x02;
+
+    /**
+     * Data type: double
+     */
+    static const uint8_t TYPE_DOUBLE = 0x03;
+
+    /**
+     * Data type: float array
+     */
+    static const uint8_t TYPE_FLOAT_ARRAY = 0x11;
+
+    /**
+     * Data type: int array
+     */
+    static const uint8_t TYPE_INT_ARRAY = 0x12;
+
+    /**
+     * Data type: byte array
+     */
+    static const uint8_t TYPE_BYTE_ARRAY = 0x13;
+
+    /**
+     * Result code: no error, everything is OK.
+     */
+    static const uint8_t RESULT_OK = 0x00;
+
+    /**
+     * Result code: invalid command
+     */
+    static const uint8_t RESULT_INVALID_COMMAND = 0x01;
+
+    /**
+     * Result code: unknown dataref
+     */
+    static const uint8_t RESULT_UNKNOWN_DATAREF = 0x02;
+
+    /**
+     * Result code: invalid type
+     */
+    static const uint8_t RESULT_INVALID_TYPE = 0x03;
+
+    /**
+     * Result code: invalid length
+     */
+    static const uint8_t RESULT_INVALID_LENGTH = 0x04;
+
+    /**
+     * Result code: invalid offset
+     */
+    static const uint8_t RESULT_INVALID_OFFSET = 0x05;
+
+    /**
+     * Result code: invalid count
+     */
+    static const uint8_t RESULT_INVALID_COUNT = 0x06;
+
+    /**
+     * Result code: invalid ID
+     */
+    static const uint8_t RESULT_INVALID_ID = 0x07;
+
+    /**
+     * Result code: invalid duration
+     */
+    static const uint8_t RESULT_INVALID_DURATION = 0x08;
+
+    /**
+     * Result code: other error
+     */
+    static const uint8_t RESULT_OTHER_ERROR = 0xff;
+
+    /**
+     * Hotkey modifier: shift
+     */
+    static const uint16_t HOTKEY_MODIFIER_SHIFT = 0x0100;
+
+    /**
+     * Hotkey modifier: control
+     */
+    static const uint16_t HOTKEY_MODIFIER_CONTROL = 0x0200;
+
+    /**
+     * The maximal length we accept (in order to protect ourselves).
+     */
+    static const int MAX_LENGTH = 2048;
+
+    /**
+     * The maximal count of requests in a multiple-data query or
+     * update.
+     */
+    static const size_t MAX_MULTI_COUNT = 1024;
+
+    /**
+     * The maximal message duration
+     */
+    static const float MAX_MESSAGE_DURATION = 5*60;
+
+    /**
+     * The maximal number of hotkeys that can be registered for a
+     * client.
+     */
+    static const size_t MAX_HOTKEY_COUNT = 128;
+
+    /**
+     * The version of the plugin.
+     */
+    static const int version = 10;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_PROTOCOL_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Protocol.h
===================================================================
--- src/plugin/src/xplra/Protocol.h	(revision 45)
+++ 	(revision )
@@ -1,278 +1,0 @@
-// 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.
-
-#ifndef XPLRA_PROTOCOL_H
-#define XPLRA_PROTOCOL_H
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Constants and helpers for the protocol.
- */
-class Protocol
-{
-public:
-    /**
-     * Command: get the value of a single dataref.
-     */
-    static const uint8_t COMMAND_GET_SINGLE = 0x01;
-
-    /**
-     * Command: set the value of a single dataref.
-     */
-    static const uint8_t COMMAND_SET_SINGLE = 0x02;
-
-    /**
-     * Command: get the value of a multiple datarefs.
-     */
-    static const uint8_t COMMAND_GET_MULTI = 0x03;
-
-    /**
-     * Command: set the value of a multiple datarefs.
-     */
-    static const uint8_t COMMAND_SET_MULTI = 0x04;
-
-    /**
-     * Command: register a multiple-data query request
-     */
-    static const uint8_t COMMAND_REGISTER_GET_MULTI = 0x11;
-
-    /**
-     * Command: unregister a multiple-data query request
-     */
-    static const uint8_t COMMAND_UNREGISTER_GET_MULTI = 0x12;
-
-    /**
-     * Command: execute a registered multiple-data query request
-     */
-    static const uint8_t COMMAND_EXECUTE_GET_MULTI = 0x13;
-
-    /**
-     * Command: register a multiple-data update request
-     */
-    static const uint8_t COMMAND_REGISTER_SET_MULTI = 0x21;
-
-    /**
-     * Command: unregister a multiple-data update request
-     */
-    static const uint8_t COMMAND_UNREGISTER_SET_MULTI = 0x22;
-
-    /**
-     * Command: execute a registered multiple-data update request
-     */
-    static const uint8_t COMMAND_EXECUTE_SET_MULTI = 0x23;
-
-    /**
-     * Command: get the versions of the simulator
-     */
-    static const uint8_t COMMAND_GET_VERSIONS = 0x31;
-
-    /**
-     * Command: reload the plugins
-     */
-    static const uint8_t COMMAND_RELOAD_PLUGINS = 0x32;
-
-    /**
-     * Command: show a message in the message window.
-     */
-    static const uint8_t COMMAND_SHOW_MESSAGE = 0x41;
-
-    /**
-     * Command: register a set of hotkeys for the client. Old hotkeys,
-     * if any, are forgotten.
-     *
-     * The command is followed by the following data:
-     * - The number of the hotkeys defined (U32).
-     * - The code of the hotkeys (U16*number of the hotkeys).
-     *   The lower byte is the same as the X-Plane virtual key code
-     *   (the same as the ASCII code for numbers and upper-case letters),
-     *   the upper one is a logical OR of the HOTKEY_MODIFIER_XXX
-     *   codes.
-     *
-     * The reply consists of a result code only. It may fail with an
-     * invalid length code if the number of hotkeys is too large.
-     */
-    static const uint8_t COMMAND_REGISTER_HOTKEYS = 0x51;
-
-    /**
-     * Command: query the hotkeys.
-     *
-     * The reply consists of a result code, followed by the following
-     * data, if the result code is RESULT_OK:
-     * - The number of hotkeys defined (U32).
-     * - An array of U8 values each being 0 or 1 depending on whether
-     *   the corresponding hotkey has been pressed since the last
-     *   query (or the registration, whichever is later). The value at
-     *   index i corresponds to the hotkey code at index i in the
-     *   array passed with COMMAND_REGISTER_HOTKEYS.
-     *
-     * If not hotkey has been registered, the number of hotkeys is
-     * returned as 0.
-     */
-    static const uint8_t COMMAND_QUERY_HOTKEYS = 0x52;
-
-    /**
-     * Command: unregister the previously registered hotkeys.
-     *
-     * The reply is a result code.
-     */
-    static const uint8_t COMMAND_UNREGISTER_HOTKEYS = 0x53;
-
-    /**
-     * Data type: int
-     */
-    static const uint8_t TYPE_INT = 0x01;
-
-    /**
-     * Data type: float
-     */
-    static const uint8_t TYPE_FLOAT = 0x02;
-
-    /**
-     * Data type: double
-     */
-    static const uint8_t TYPE_DOUBLE = 0x03;
-
-    /**
-     * Data type: float array
-     */
-    static const uint8_t TYPE_FLOAT_ARRAY = 0x11;
-
-    /**
-     * Data type: int array
-     */
-    static const uint8_t TYPE_INT_ARRAY = 0x12;
-
-    /**
-     * Data type: byte array
-     */
-    static const uint8_t TYPE_BYTE_ARRAY = 0x13;
-
-    /**
-     * Result code: no error, everything is OK.
-     */
-    static const uint8_t RESULT_OK = 0x00;
-
-    /**
-     * Result code: invalid command
-     */
-    static const uint8_t RESULT_INVALID_COMMAND = 0x01;
-
-    /**
-     * Result code: unknown dataref
-     */
-    static const uint8_t RESULT_UNKNOWN_DATAREF = 0x02;
-
-    /**
-     * Result code: invalid type
-     */
-    static const uint8_t RESULT_INVALID_TYPE = 0x03;
-
-    /**
-     * Result code: invalid length
-     */
-    static const uint8_t RESULT_INVALID_LENGTH = 0x04;
-
-    /**
-     * Result code: invalid offset
-     */
-    static const uint8_t RESULT_INVALID_OFFSET = 0x05;
-
-    /**
-     * Result code: invalid count
-     */
-    static const uint8_t RESULT_INVALID_COUNT = 0x06;
-
-    /**
-     * Result code: invalid ID
-     */
-    static const uint8_t RESULT_INVALID_ID = 0x07;
-
-    /**
-     * Result code: invalid duration
-     */
-    static const uint8_t RESULT_INVALID_DURATION = 0x08;
-
-    /**
-     * Result code: other error
-     */
-    static const uint8_t RESULT_OTHER_ERROR = 0xff;
-
-    /**
-     * Hotkey modifier: shift
-     */
-    static const uint16_t HOTKEY_MODIFIER_SHIFT = 0x0100;
-
-    /**
-     * Hotkey modifier: control
-     */
-    static const uint16_t HOTKEY_MODIFIER_CONTROL = 0x0200;
-
-    /**
-     * The maximal length we accept (in order to protect ourselves).
-     */
-    static const int MAX_LENGTH = 2048;
-
-    /**
-     * The maximal count of requests in a multiple-data query or
-     * update.
-     */
-    static const size_t MAX_MULTI_COUNT = 1024;
-
-    /**
-     * The maximal message duration
-     */
-    static const float MAX_MESSAGE_DURATION = 5*60;
-
-    /**
-     * The maximal number of hotkeys that can be registered for a
-     * client.
-     */
-    static const size_t MAX_HOTKEY_COUNT = 128;
-
-    /**
-     * The version of the plugin.
-     */
-    static const int version = 10;
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_PROTOCOL_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/ReloadPluginsRequest.cc
===================================================================
--- src/plugin/src/xplra/ReloadPluginsRequest.cc	(revision 39)
+++ src/plugin/src/xplra/ReloadPluginsRequest.cc	(revision 39)
@@ -0,0 +1,52 @@
+// 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 "ReloadPluginsRequest.h"
+
+#include <XPLMPlugin.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::ReloadPluginsRequest;
+
+//------------------------------------------------------------------------------
+
+void ReloadPluginsRequest::execute()
+{
+    XPLMReloadPlugins();
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/ReloadPluginsRequest.cc
===================================================================
--- src/plugin/src/xplra/ReloadPluginsRequest.cc	(revision 39)
+++ 	(revision )
@@ -1,52 +1,0 @@
-// 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 "ReloadPluginsRequest.h"
-
-#include <XPLMPlugin.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::ReloadPluginsRequest;
-
-//------------------------------------------------------------------------------
-
-void ReloadPluginsRequest::execute()
-{
-    XPLMReloadPlugins();
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/ReloadPluginsRequest.h
===================================================================
--- src/plugin/src/xplra/ReloadPluginsRequest.h	(revision 39)
+++ src/plugin/src/xplra/ReloadPluginsRequest.h	(revision 39)
@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef XPLRA_RELOADPLUGINSREQUEST_H
+#define XPLRA_RELOADPLUGINSREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "Request.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request that simply reloads all plugins.
+ */
+class ReloadPluginsRequest : public Request
+{
+protected:
+    /**
+     * Execute the request.
+     */
+    virtual void execute();
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_RELOADPLUGINSREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/ReloadPluginsRequest.h
===================================================================
--- src/plugin/src/xplra/ReloadPluginsRequest.h	(revision 39)
+++ 	(revision )
@@ -1,64 +1,0 @@
-// 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.
-
-#ifndef XPLRA_RELOADPLUGINSREQUEST_H
-#define XPLRA_RELOADPLUGINSREQUEST_H
-//------------------------------------------------------------------------------
-
-#include "Request.h"
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A request that simply reloads all plugins.
- */
-class ReloadPluginsRequest : public Request
-{
-protected:
-    /**
-     * Execute the request.
-     */
-    virtual void execute();
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_RELOADPLUGINSREQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Request.h
===================================================================
--- src/plugin/src/xplra/Request.h	(revision 13)
+++ src/plugin/src/xplra/Request.h	(revision 13)
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef XPLRA_REQUEST_H
+#define XPLRA_REQUEST_H
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for requests. A request is something that is executed in
+ * the flight loop.
+ */
+class Request
+{
+private:
+    /**
+     * Indicate that the request is completed.
+     */
+    volatile bool completed;
+
+public:
+    /**
+     * Construct the request.
+     */
+    Request();
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~Request();
+
+protected:
+    /**
+     * Execute the request. Make this very fast!
+     */
+    virtual void execute() = 0;
+
+    friend class RequestQueue;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline Request::Request() :
+    completed(false)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline Request::~Request()
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_REQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Request.h
===================================================================
--- src/plugin/src/xplra/Request.h	(revision 13)
+++ 	(revision )
@@ -1,95 +1,0 @@
-// 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.
-
-#ifndef XPLRA_REQUEST_H
-#define XPLRA_REQUEST_H
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Base class for requests. A request is something that is executed in
- * the flight loop.
- */
-class Request
-{
-private:
-    /**
-     * Indicate that the request is completed.
-     */
-    volatile bool completed;
-
-public:
-    /**
-     * Construct the request.
-     */
-    Request();
-
-    /**
-     * Virtual destructor.
-     */
-    virtual ~Request();
-
-protected:
-    /**
-     * Execute the request. Make this very fast!
-     */
-    virtual void execute() = 0;
-
-    friend class RequestQueue;
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline Request::Request() :
-    completed(false)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline Request::~Request()
-{
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_REQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/RequestQueue.cc
===================================================================
--- src/plugin/src/xplra/RequestQueue.cc	(revision 13)
+++ src/plugin/src/xplra/RequestQueue.cc	(revision 13)
@@ -0,0 +1,156 @@
+// 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 "RequestQueue.h"
+
+#include "Request.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+//------------------------------------------------------------------------------
+
+using xplra::RequestQueue;
+
+using hu::varadiistvan::xplcommon::Util;
+
+//------------------------------------------------------------------------------
+
+float RequestQueue::flightLoop(float /*inElapsedSinceLastCall*/,
+                               float /*inElapsedTimeSinceLastFlightLoop*/,
+                               int /*inCounter*/, void* inRefCon)
+{
+    RequestQueue* requestQueue = reinterpret_cast<RequestQueue*>(inRefCon);
+    requestQueue->run();
+#if USE_SCHEDULE_FLIGHTLOOP
+    return 0.0;
+#else
+    return flightLoopInterval;
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+RequestQueue::RequestQueue() :
+    enabled(true)
+{
+#if USE_SCHEDULE_FLIGHTLOOP
+    XPLMCreateFlightLoop_t createFL;
+
+    createFL.structSize = sizeof(createFL);
+    createFL.phase = xplm_FlightLoop_Phase_AfterFlightModel;
+    createFL.callbackFunc = &flightLoop;
+    createFL.refcon = this;
+
+    flightLoopID = XPLMCreateFlightLoop(&createFL);
+#else
+    XPLMRegisterFlightLoopCallback(&flightLoop, flightLoopInterval, this);
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+bool RequestQueue::execute(Request* request)
+{
+    mutex.lock();
+    if (!enabled) {
+        mutex.unlock();
+        return false;
+    }
+
+    request->completed = false;
+    requests.push_back(request);
+
+#if USE_SCHEDULE_FLIGHTLOOP
+    if (requests.size()==1) {
+        XPLMScheduleFlightLoop(flightLoopID, -2.0, true);
+    }
+#endif
+
+    while(enabled && !request->completed) {
+        requestsDone.wait(mutex);
+    }
+
+    bool result = request->completed;
+
+    mutex.unlock();
+
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
+void RequestQueue::disable()
+{
+    mutex.lock();
+    enabled = false;
+    mutex.unlock();
+    requestsDone.broadcast();
+#if USE_SCHEDULE_FLIGHTLOOP
+    XPLMDestroyFlightLoop(flightLoopID);
+#else
+    XPLMUnregisterFlightLoopCallback(&flightLoop, this);
+#endif
+}
+
+//------------------------------------------------------------------------------
+
+void RequestQueue::run()
+{
+    requests_t queuedRequests;
+
+    mutex.lock();
+    requests.swap(queuedRequests);
+    mutex.unlock();
+
+    if (queuedRequests.empty()) return;
+
+    for(requests_t::const_iterator i = queuedRequests.begin();
+        i!=queuedRequests.end(); ++i)
+    {
+        (*i)->execute();
+    }
+
+    mutex.lock();
+    for(requests_t::const_iterator i = queuedRequests.begin();
+        i!=queuedRequests.end(); ++i)
+    {
+        (*i)->completed = true;
+    }
+    mutex.unlock();
+    requestsDone.broadcast();
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/RequestQueue.cc
===================================================================
--- src/plugin/src/xplra/RequestQueue.cc	(revision 13)
+++ 	(revision )
@@ -1,156 +1,0 @@
-// 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 "RequestQueue.h"
-
-#include "Request.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-//------------------------------------------------------------------------------
-
-using xplra::RequestQueue;
-
-using hu::varadiistvan::xplcommon::Util;
-
-//------------------------------------------------------------------------------
-
-float RequestQueue::flightLoop(float /*inElapsedSinceLastCall*/,
-                               float /*inElapsedTimeSinceLastFlightLoop*/,
-                               int /*inCounter*/, void* inRefCon)
-{
-    RequestQueue* requestQueue = reinterpret_cast<RequestQueue*>(inRefCon);
-    requestQueue->run();
-#if USE_SCHEDULE_FLIGHTLOOP
-    return 0.0;
-#else
-    return flightLoopInterval;
-#endif
-}
-
-//------------------------------------------------------------------------------
-
-RequestQueue::RequestQueue() :
-    enabled(true)
-{
-#if USE_SCHEDULE_FLIGHTLOOP
-    XPLMCreateFlightLoop_t createFL;
-
-    createFL.structSize = sizeof(createFL);
-    createFL.phase = xplm_FlightLoop_Phase_AfterFlightModel;
-    createFL.callbackFunc = &flightLoop;
-    createFL.refcon = this;
-
-    flightLoopID = XPLMCreateFlightLoop(&createFL);
-#else
-    XPLMRegisterFlightLoopCallback(&flightLoop, flightLoopInterval, this);
-#endif
-}
-
-//------------------------------------------------------------------------------
-
-bool RequestQueue::execute(Request* request)
-{
-    mutex.lock();
-    if (!enabled) {
-        mutex.unlock();
-        return false;
-    }
-
-    request->completed = false;
-    requests.push_back(request);
-
-#if USE_SCHEDULE_FLIGHTLOOP
-    if (requests.size()==1) {
-        XPLMScheduleFlightLoop(flightLoopID, -2.0, true);
-    }
-#endif
-
-    while(enabled && !request->completed) {
-        requestsDone.wait(mutex);
-    }
-
-    bool result = request->completed;
-
-    mutex.unlock();
-
-    return result;
-}
-
-//------------------------------------------------------------------------------
-
-void RequestQueue::disable()
-{
-    mutex.lock();
-    enabled = false;
-    mutex.unlock();
-    requestsDone.broadcast();
-#if USE_SCHEDULE_FLIGHTLOOP
-    XPLMDestroyFlightLoop(flightLoopID);
-#else
-    XPLMUnregisterFlightLoopCallback(&flightLoop, this);
-#endif
-}
-
-//------------------------------------------------------------------------------
-
-void RequestQueue::run()
-{
-    requests_t queuedRequests;
-
-    mutex.lock();
-    requests.swap(queuedRequests);
-    mutex.unlock();
-
-    if (queuedRequests.empty()) return;
-
-    for(requests_t::const_iterator i = queuedRequests.begin();
-        i!=queuedRequests.end(); ++i)
-    {
-        (*i)->execute();
-    }
-
-    mutex.lock();
-    for(requests_t::const_iterator i = queuedRequests.begin();
-        i!=queuedRequests.end(); ++i)
-    {
-        (*i)->completed = true;
-    }
-    mutex.unlock();
-    requestsDone.broadcast();
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/RequestQueue.h
===================================================================
--- src/plugin/src/xplra/RequestQueue.h	(revision 13)
+++ src/plugin/src/xplra/RequestQueue.h	(revision 13)
@@ -0,0 +1,168 @@
+// 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.
+
+#ifndef XPLRA_REQUESTQUEUE_H
+#define XPLRA_REQUESTQUEUE_H
+//------------------------------------------------------------------------------
+
+#include <hu/varadiistvan/scpl/Mutex.h>
+#include <hu/varadiistvan/scpl/CondVar.h>
+
+#include <XPLMProcessing.h>
+
+#include <vector>
+
+//------------------------------------------------------------------------------
+
+// Define to 1, if the new XPLMScheduleFlightLoop function should be
+// used to schedule the flight loop only on-demand
+#define USE_SCHEDULE_FLIGHTLOOP 0
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class Request;
+
+//------------------------------------------------------------------------------
+
+/**
+ * The queue of the requests. Client serving threads can add requests
+ * to the queue. The queue provides a flight loop callback, which it
+ * automatically schedules if a request is added to it, unless we are
+ * already disabled.
+ *
+ * An instance of the queue should be created in the plugin enable
+ * callback. The disable callback should disable the queue, so that it
+ * will not accept any further requests.
+ */
+class RequestQueue
+{
+private:
+    /**
+     * Type for the collection of the queued requests.
+     */
+    typedef std::vector<Request*> requests_t;
+
+#if !USE_SCHEDULE_FLIGHTLOOP
+    /**
+     * The interval of the flight loop.
+     */
+    static const float flightLoopInterval = 0.1;
+#endif
+
+    /**
+     * The flight loop function.
+     */
+    static float flightLoop(float inElapsedSinceLastCall,
+                            float inElapsedTimeSinceLastFlightLoop,
+                            int inCounter, void* inRefCon);
+
+#if USE_SCHEDULE_FLIGHTLOOP
+    /**
+     * The ID of the flight loop running the queue.
+     */
+    XPLMFlightLoopID flightLoopID;
+#endif
+
+    /**
+     * The mutex protecting the queue.
+     */
+    hu::varadiistvan::scpl::Mutex mutex;
+
+    /**
+     * A conditional variable to notify the threads waiting for their
+     * request to be executed.
+     */
+    hu::varadiistvan::scpl::CondVar requestsDone;
+
+    /**
+     * Indicate if the queue is enabled or not.
+     */
+    volatile bool enabled;
+
+    /**
+     * The vector of the queued requests.
+     */
+    requests_t requests;
+
+public:
+    /**
+     * Construct the queue. It creates the flight loop, so it should
+     * be called from a plugin callback.
+     */
+    RequestQueue();
+
+    /**
+     * Execute the given request. It will be enqueued, and then this
+     * function will wait until the request is executed or the request
+     * queue is disabled.
+     *
+     * If the queue is already disabled when calling this function, it
+     * returns immediately with false.
+     *
+     * @return if the request was executed
+     */
+    bool execute(Request* request);
+
+    /**
+     * Disable the queue. It sets the flag indicating that the queue
+     * is disabled, and wakes up all waiters waiting on the
+     * conditional variable. It should be called from a plugin
+     * callback, as it also destroys the flight loop.
+     */
+    void disable();
+
+private:
+    /**
+     * Run the queue.
+     *
+     * It locks the mutex, swaps the vector of requests with an empty
+     * one, unlocks the mutex and runs the requests one by one. When
+     * all requests are executed, it wakes up all waiters waiting on
+     * the conditional variable.
+     *
+     * It is called from the flight loop function.
+     */
+    void run();
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_REQUESTQUEUE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/RequestQueue.h
===================================================================
--- src/plugin/src/xplra/RequestQueue.h	(revision 13)
+++ 	(revision )
@@ -1,168 +1,0 @@
-// 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.
-
-#ifndef XPLRA_REQUESTQUEUE_H
-#define XPLRA_REQUESTQUEUE_H
-//------------------------------------------------------------------------------
-
-#include <hu/varadiistvan/scpl/Mutex.h>
-#include <hu/varadiistvan/scpl/CondVar.h>
-
-#include <XPLMProcessing.h>
-
-#include <vector>
-
-//------------------------------------------------------------------------------
-
-// Define to 1, if the new XPLMScheduleFlightLoop function should be
-// used to schedule the flight loop only on-demand
-#define USE_SCHEDULE_FLIGHTLOOP 0
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class Request;
-
-//------------------------------------------------------------------------------
-
-/**
- * The queue of the requests. Client serving threads can add requests
- * to the queue. The queue provides a flight loop callback, which it
- * automatically schedules if a request is added to it, unless we are
- * already disabled.
- *
- * An instance of the queue should be created in the plugin enable
- * callback. The disable callback should disable the queue, so that it
- * will not accept any further requests.
- */
-class RequestQueue
-{
-private:
-    /**
-     * Type for the collection of the queued requests.
-     */
-    typedef std::vector<Request*> requests_t;
-
-#if !USE_SCHEDULE_FLIGHTLOOP
-    /**
-     * The interval of the flight loop.
-     */
-    static const float flightLoopInterval = 0.1;
-#endif
-
-    /**
-     * The flight loop function.
-     */
-    static float flightLoop(float inElapsedSinceLastCall,
-                            float inElapsedTimeSinceLastFlightLoop,
-                            int inCounter, void* inRefCon);
-
-#if USE_SCHEDULE_FLIGHTLOOP
-    /**
-     * The ID of the flight loop running the queue.
-     */
-    XPLMFlightLoopID flightLoopID;
-#endif
-
-    /**
-     * The mutex protecting the queue.
-     */
-    hu::varadiistvan::scpl::Mutex mutex;
-
-    /**
-     * A conditional variable to notify the threads waiting for their
-     * request to be executed.
-     */
-    hu::varadiistvan::scpl::CondVar requestsDone;
-
-    /**
-     * Indicate if the queue is enabled or not.
-     */
-    volatile bool enabled;
-
-    /**
-     * The vector of the queued requests.
-     */
-    requests_t requests;
-
-public:
-    /**
-     * Construct the queue. It creates the flight loop, so it should
-     * be called from a plugin callback.
-     */
-    RequestQueue();
-
-    /**
-     * Execute the given request. It will be enqueued, and then this
-     * function will wait until the request is executed or the request
-     * queue is disabled.
-     *
-     * If the queue is already disabled when calling this function, it
-     * returns immediately with false.
-     *
-     * @return if the request was executed
-     */
-    bool execute(Request* request);
-
-    /**
-     * Disable the queue. It sets the flag indicating that the queue
-     * is disabled, and wakes up all waiters waiting on the
-     * conditional variable. It should be called from a plugin
-     * callback, as it also destroys the flight loop.
-     */
-    void disable();
-
-private:
-    /**
-     * Run the queue.
-     *
-     * It locks the mutex, swaps the vector of requests with an empty
-     * one, unlocks the mutex and runs the requests one by one. When
-     * all requests are executed, it wakes up all waiters waiting on
-     * the conditional variable.
-     *
-     * It is called from the flight loop function.
-     */
-    void run();
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_REQUESTQUEUE_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/ServerThread.cc
===================================================================
--- src/plugin/src/xplra/ServerThread.cc	(revision 46)
+++ src/plugin/src/xplra/ServerThread.cc	(revision 46)
@@ -0,0 +1,521 @@
+// 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 "ServerThread.h"
+
+#include "ListenThread.h"
+#include "RequestQueue.h"
+#include "Protocol.h"
+#include "GetDataRefTask.h"
+#include "SetDataRefTask.h"
+#include "TaskRequest.h"
+#include "GetMultiDataRefRequest.h"
+#include "SetMultiDataRefRequest.h"
+#include "ReloadPluginsRequest.h"
+#include "MessageRequest.h"
+#include "Globals.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using xplra::ServerThread;
+
+using hu::varadiistvan::scpl::io::LocalAcceptor;
+using hu::varadiistvan::scpl::Mutex;
+using hu::varadiistvan::xplcommon::Util;
+
+using std::string;
+
+//------------------------------------------------------------------------------
+
+Mutex ServerThread::instancesMutex;
+
+ServerThread::instances_t ServerThread::instances;
+
+//------------------------------------------------------------------------------
+
+void ServerThread::quitAll()
+{
+    instancesMutex.lock();
+    for(instances_t::iterator i = instances.begin(); i!=instances.end(); ++i) {
+        ServerThread* thread = *i;
+        thread->quit();
+        thread->join();
+        delete thread;
+    }
+    instances.clear();
+    instancesMutex.unlock();
+}
+
+//------------------------------------------------------------------------------
+
+inline bool ServerThread::destroyHotkeys()
+{
+    if (hotkeys!=0) {
+        listenThread.getGlobals().getHotkeyHandler().unregisterHotkeys(hotkeys);
+        delete hotkeys; hotkeys = 0;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+ServerThread::ServerThread(ListenThread& listenThread,
+                           RequestQueue& requestQueue, LocalAcceptor& acceptor) :
+    listenThread(listenThread),
+    requestQueue(requestQueue),
+    bufferedStream(acceptor.getSocket(&waiter)),
+    stream(*bufferedStream),
+    nextGetMultiRequestID(1),
+    nextSetMultiRequestID(1),
+    hotkeys(0)
+{
+    instancesMutex.lock();
+    instances.insert(this);
+    instancesMutex.unlock();
+}
+
+//------------------------------------------------------------------------------
+
+ServerThread::~ServerThread()
+{
+    delete bufferedStream;
+
+    for(getMultiRequests_t::iterator i = getMultiRequests.begin();
+        i!=getMultiRequests.end(); ++i)
+    {
+        delete i->second;
+    }
+
+    for(setMultiRequests_t::iterator i = setMultiRequests.begin();
+        i!=setMultiRequests.end(); ++i)
+    {
+        delete i->second;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void ServerThread::quit()
+{
+    stream.interrupt();
+}
+
+//------------------------------------------------------------------------------
+
+void ServerThread::run()
+{
+    Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run\n", this);
+    while(stream) {
+        uint8_t command = stream.readU8();
+        if (!stream) continue;
+
+        // Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run: command=0x%02x\n",
+        //             this, command);
+
+        if (command==Protocol::COMMAND_GET_SINGLE) {
+            if (!handleGetSingle()) break;
+        } else if (command==Protocol::COMMAND_SET_SINGLE) {
+            if (!handleSetSingle()) break;
+        } else if (command==Protocol::COMMAND_GET_MULTI) {
+            if (!handleGetMulti()) break;
+        } else if (command==Protocol::COMMAND_SET_MULTI) {
+            if (!handleSetMulti()) break;
+        } else if (command==Protocol::COMMAND_REGISTER_GET_MULTI) {
+            if (!handleRegisterGetMulti()) break;
+        } else if (command==Protocol::COMMAND_UNREGISTER_GET_MULTI) {
+            if (!handleUnregisterGetMulti()) break;
+        } else if (command==Protocol::COMMAND_EXECUTE_GET_MULTI) {
+            if (!handleExecuteGetMulti()) break;
+        } else if (command==Protocol::COMMAND_REGISTER_SET_MULTI) {
+            if (!handleRegisterSetMulti()) break;
+        } else if (command==Protocol::COMMAND_UNREGISTER_SET_MULTI) {
+            if (!handleUnregisterSetMulti()) break;
+        } else if (command==Protocol::COMMAND_EXECUTE_SET_MULTI) {
+            if (!handleExecuteSetMulti()) break;
+        } else if (command==Protocol::COMMAND_GET_VERSIONS) {
+            if (!handleGetVersions()) break;
+        } else if (command==Protocol::COMMAND_RELOAD_PLUGINS) {
+            if (!handleReloadPlugins()) break;
+        } else if (command==Protocol::COMMAND_SHOW_MESSAGE) {
+            if (!handleShowMessage()) break;
+        } else if (command==Protocol::COMMAND_REGISTER_HOTKEYS) {
+            if (!handleRegisterHotkeys()) break;
+        } else if (command==Protocol::COMMAND_QUERY_HOTKEYS) {
+            if (!handleQueryHotkeys()) break;
+        } else if (command==Protocol::COMMAND_UNREGISTER_HOTKEYS) {
+            if (!handleUnregisterHotkeys()) break;
+        } else {
+            stream.writeU8(Protocol::RESULT_INVALID_COMMAND);
+        }
+        stream.flush();
+    }
+
+    destroyHotkeys();
+
+    Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run: quitting\n", this);
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleGetSingle()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    GetDataRefTask* task = GetDataRefTask::create(result, stream);
+
+    if (!stream) {
+        return false;
+    } else if (task==0) {
+        stream.writeU8(result);
+        return true;
+    }
+
+    TaskRequest request(task);
+    if (!requestQueue.execute(&request)) return false;
+
+    if (task->isValid()) {
+        stream.writeU8(Protocol::RESULT_OK);
+        task->writeValue(stream);
+    } else {
+        stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleSetSingle()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    SetDataRefTask* task = SetDataRefTask::create(result, stream);
+
+    if (!stream) {
+        return false;
+    } else if (task==0) {
+        stream.writeU8(result);
+        return true;
+    }
+
+    task->readValue(stream);
+    if (!stream) {
+        delete task;
+        return false;
+    }
+
+    TaskRequest request(task);
+    if (!requestQueue.execute(&request)) return false;
+
+    stream.writeU8(task->isValid() ? Protocol::RESULT_OK :
+                   Protocol::RESULT_UNKNOWN_DATAREF);
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleGetMulti()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    GetMultiDataRefRequest* request =
+        new GetMultiDataRefRequest(result, stream);
+    if (result!=Protocol::RESULT_OK || !stream) {
+        delete request;
+        stream.writeU8(result);
+        return stream;
+    }
+
+    bool isOK = requestQueue.execute(request);
+
+    if (isOK) {
+        request->writeResult(stream);
+    }
+
+    delete request;
+
+    return isOK;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleSetMulti()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    SetMultiDataRefRequest* request =
+        new SetMultiDataRefRequest(result, stream, true);
+    if (result!=Protocol::RESULT_OK || !stream) {
+        delete request;
+        stream.writeU8(result);
+        return stream;
+    }
+
+    bool isOK = requestQueue.execute(request);
+
+    if (isOK) {
+        request->writeResult(stream);
+    }
+
+    delete request;
+
+    return isOK;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleRegisterGetMulti()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    GetMultiDataRefRequest* request =
+        new GetMultiDataRefRequest(result, stream);
+    if (result!=Protocol::RESULT_OK || !stream) {
+        delete request;
+        stream.writeU8(result);
+        return stream;
+    }
+
+    size_t id = nextGetMultiRequestID++;
+    getMultiRequests[id] = request;
+
+    stream.writeU8(Protocol::RESULT_OK);
+    stream.writeU32(id);
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleUnregisterGetMulti()
+{
+    uint32_t id = stream.readU32();
+    if (!stream) return false;
+
+    getMultiRequests_t::iterator i = getMultiRequests.find(id);
+    if (i==getMultiRequests.end()) {
+        stream.writeU8(Protocol::RESULT_INVALID_ID);
+    } else {
+        GetMultiDataRefRequest* request = i->second;
+        getMultiRequests.erase(i);
+        delete request;
+        stream.writeU8(Protocol::RESULT_OK);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleExecuteGetMulti()
+{
+    uint32_t id = stream.readU32();
+    if (!stream) return false;
+
+    getMultiRequests_t::iterator i = getMultiRequests.find(id);
+    if (i==getMultiRequests.end()) {
+        stream.writeU8(Protocol::RESULT_INVALID_ID);
+    } else {
+        GetMultiDataRefRequest* request = i->second;
+        if (!requestQueue.execute(request)) return false;
+        request->writeResult(stream);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleRegisterSetMulti()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    SetMultiDataRefRequest* request =
+        new SetMultiDataRefRequest(result, stream, false);
+    if (result!=Protocol::RESULT_OK || !stream) {
+        delete request;
+        stream.writeU8(result);
+        return stream;
+    }
+
+    size_t id = nextSetMultiRequestID++;
+    setMultiRequests[id] = request;
+
+    stream.writeU8(Protocol::RESULT_OK);
+    stream.writeU32(id);
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleUnregisterSetMulti()
+{
+    uint32_t id = stream.readU32();
+    if (!stream) return false;
+
+    setMultiRequests_t::iterator i = setMultiRequests.find(id);
+    if (i==setMultiRequests.end()) {
+        stream.writeU8(Protocol::RESULT_INVALID_ID);
+    } else {
+        SetMultiDataRefRequest* request = i->second;
+        setMultiRequests.erase(i);
+        delete request;
+        stream.writeU8(Protocol::RESULT_OK);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleExecuteSetMulti()
+{
+    uint32_t id = stream.readU32();
+    if (!stream) return false;
+
+    setMultiRequests_t::iterator i = setMultiRequests.find(id);
+    if (i==setMultiRequests.end()) {
+        stream.writeU8(Protocol::RESULT_INVALID_ID);
+    } else {
+        SetMultiDataRefRequest* request = i->second;
+        request->readValues(stream);
+        if (!stream || !requestQueue.execute(request)) return false;
+        request->writeResult(stream);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleGetVersions()
+{
+    int xplaneVersion = 0;
+    int xplmVersion = 0;
+
+    listenThread.getGlobals().getVersions(xplaneVersion, xplmVersion);
+
+    stream.writeU8(Protocol::RESULT_OK);
+    stream.writeS32(xplaneVersion);
+    stream.writeS32(xplmVersion);
+    stream.writeS32(Protocol::version);
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleReloadPlugins()
+{
+    ReloadPluginsRequest request;
+    if (!requestQueue.execute(&request)) return false;
+
+    stream.writeU8(Protocol::RESULT_OK);
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleShowMessage()
+{
+    string message = stream.readString();
+    float duration = stream.readFloat();
+    if (!stream) return false;
+
+    if (duration>Protocol::MAX_MESSAGE_DURATION) {
+        stream.writeU8(Protocol::RESULT_INVALID_DURATION);
+    } else {
+        MessageRequest request(listenThread.getGlobals().getMessageWindow(),
+                               message, duration);
+        if (!requestQueue.execute(&request)) return false;
+
+        stream.writeU8(Protocol::RESULT_OK);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleRegisterHotkeys()
+{
+    size_t numHotkeys = stream.readU32();
+    if (!stream) return false;
+
+    if (numHotkeys>Protocol::MAX_HOTKEY_COUNT) {
+        stream.writeU8(Protocol::RESULT_INVALID_LENGTH);
+    } else {
+        HotkeyHandler::Hotkeys* newHotkeys =
+            new HotkeyHandler::Hotkeys(numHotkeys, stream);
+        if (newHotkeys->isValid()) {
+            destroyHotkeys();
+            hotkeys = newHotkeys;
+            listenThread.getGlobals().getHotkeyHandler().registerHotkeys(hotkeys);
+            stream.writeU8(Protocol::RESULT_OK);
+        } else {
+            delete newHotkeys;
+            return false;
+        }
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleQueryHotkeys()
+{
+    stream.writeU8(Protocol::RESULT_OK);
+    if (hotkeys==0) {
+        stream.writeU32(0);
+    } else {
+        hotkeys->writePressed(stream);
+    }
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleUnregisterHotkeys()
+{
+    destroyHotkeys();
+    stream.writeU8(Protocol::RESULT_OK);
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/ServerThread.cc
===================================================================
--- src/plugin/src/xplra/ServerThread.cc	(revision 46)
+++ 	(revision )
@@ -1,521 +1,0 @@
-// 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 "ServerThread.h"
-
-#include "ListenThread.h"
-#include "RequestQueue.h"
-#include "Protocol.h"
-#include "GetDataRefTask.h"
-#include "SetDataRefTask.h"
-#include "TaskRequest.h"
-#include "GetMultiDataRefRequest.h"
-#include "SetMultiDataRefRequest.h"
-#include "ReloadPluginsRequest.h"
-#include "MessageRequest.h"
-#include "Globals.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-
-#include <cstdio>
-
-//------------------------------------------------------------------------------
-
-using xplra::ServerThread;
-
-using hu::varadiistvan::scpl::io::LocalAcceptor;
-using hu::varadiistvan::scpl::Mutex;
-using hu::varadiistvan::xplcommon::Util;
-
-using std::string;
-
-//------------------------------------------------------------------------------
-
-Mutex ServerThread::instancesMutex;
-
-ServerThread::instances_t ServerThread::instances;
-
-//------------------------------------------------------------------------------
-
-void ServerThread::quitAll()
-{
-    instancesMutex.lock();
-    for(instances_t::iterator i = instances.begin(); i!=instances.end(); ++i) {
-        ServerThread* thread = *i;
-        thread->quit();
-        thread->join();
-        delete thread;
-    }
-    instances.clear();
-    instancesMutex.unlock();
-}
-
-//------------------------------------------------------------------------------
-
-inline bool ServerThread::destroyHotkeys()
-{
-    if (hotkeys!=0) {
-        listenThread.getGlobals().getHotkeyHandler().unregisterHotkeys(hotkeys);
-        delete hotkeys; hotkeys = 0;
-        return true;
-    } else {
-        return false;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-ServerThread::ServerThread(ListenThread& listenThread,
-                           RequestQueue& requestQueue, LocalAcceptor& acceptor) :
-    listenThread(listenThread),
-    requestQueue(requestQueue),
-    bufferedStream(acceptor.getSocket(&waiter)),
-    stream(*bufferedStream),
-    nextGetMultiRequestID(1),
-    nextSetMultiRequestID(1),
-    hotkeys(0)
-{
-    instancesMutex.lock();
-    instances.insert(this);
-    instancesMutex.unlock();
-}
-
-//------------------------------------------------------------------------------
-
-ServerThread::~ServerThread()
-{
-    delete bufferedStream;
-
-    for(getMultiRequests_t::iterator i = getMultiRequests.begin();
-        i!=getMultiRequests.end(); ++i)
-    {
-        delete i->second;
-    }
-
-    for(setMultiRequests_t::iterator i = setMultiRequests.begin();
-        i!=setMultiRequests.end(); ++i)
-    {
-        delete i->second;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void ServerThread::quit()
-{
-    stream.interrupt();
-}
-
-//------------------------------------------------------------------------------
-
-void ServerThread::run()
-{
-    Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run\n", this);
-    while(stream) {
-        uint8_t command = stream.readU8();
-        if (!stream) continue;
-
-        // Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run: command=0x%02x\n",
-        //             this, command);
-
-        if (command==Protocol::COMMAND_GET_SINGLE) {
-            if (!handleGetSingle()) break;
-        } else if (command==Protocol::COMMAND_SET_SINGLE) {
-            if (!handleSetSingle()) break;
-        } else if (command==Protocol::COMMAND_GET_MULTI) {
-            if (!handleGetMulti()) break;
-        } else if (command==Protocol::COMMAND_SET_MULTI) {
-            if (!handleSetMulti()) break;
-        } else if (command==Protocol::COMMAND_REGISTER_GET_MULTI) {
-            if (!handleRegisterGetMulti()) break;
-        } else if (command==Protocol::COMMAND_UNREGISTER_GET_MULTI) {
-            if (!handleUnregisterGetMulti()) break;
-        } else if (command==Protocol::COMMAND_EXECUTE_GET_MULTI) {
-            if (!handleExecuteGetMulti()) break;
-        } else if (command==Protocol::COMMAND_REGISTER_SET_MULTI) {
-            if (!handleRegisterSetMulti()) break;
-        } else if (command==Protocol::COMMAND_UNREGISTER_SET_MULTI) {
-            if (!handleUnregisterSetMulti()) break;
-        } else if (command==Protocol::COMMAND_EXECUTE_SET_MULTI) {
-            if (!handleExecuteSetMulti()) break;
-        } else if (command==Protocol::COMMAND_GET_VERSIONS) {
-            if (!handleGetVersions()) break;
-        } else if (command==Protocol::COMMAND_RELOAD_PLUGINS) {
-            if (!handleReloadPlugins()) break;
-        } else if (command==Protocol::COMMAND_SHOW_MESSAGE) {
-            if (!handleShowMessage()) break;
-        } else if (command==Protocol::COMMAND_REGISTER_HOTKEYS) {
-            if (!handleRegisterHotkeys()) break;
-        } else if (command==Protocol::COMMAND_QUERY_HOTKEYS) {
-            if (!handleQueryHotkeys()) break;
-        } else if (command==Protocol::COMMAND_UNREGISTER_HOTKEYS) {
-            if (!handleUnregisterHotkeys()) break;
-        } else {
-            stream.writeU8(Protocol::RESULT_INVALID_COMMAND);
-        }
-        stream.flush();
-    }
-
-    destroyHotkeys();
-
-    Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run: quitting\n", this);
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleGetSingle()
-{
-    uint8_t result = Protocol::RESULT_OK;
-    GetDataRefTask* task = GetDataRefTask::create(result, stream);
-
-    if (!stream) {
-        return false;
-    } else if (task==0) {
-        stream.writeU8(result);
-        return true;
-    }
-
-    TaskRequest request(task);
-    if (!requestQueue.execute(&request)) return false;
-
-    if (task->isValid()) {
-        stream.writeU8(Protocol::RESULT_OK);
-        task->writeValue(stream);
-    } else {
-        stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleSetSingle()
-{
-    uint8_t result = Protocol::RESULT_OK;
-    SetDataRefTask* task = SetDataRefTask::create(result, stream);
-
-    if (!stream) {
-        return false;
-    } else if (task==0) {
-        stream.writeU8(result);
-        return true;
-    }
-
-    task->readValue(stream);
-    if (!stream) {
-        delete task;
-        return false;
-    }
-
-    TaskRequest request(task);
-    if (!requestQueue.execute(&request)) return false;
-
-    stream.writeU8(task->isValid() ? Protocol::RESULT_OK :
-                   Protocol::RESULT_UNKNOWN_DATAREF);
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleGetMulti()
-{
-    uint8_t result = Protocol::RESULT_OK;
-    GetMultiDataRefRequest* request =
-        new GetMultiDataRefRequest(result, stream);
-    if (result!=Protocol::RESULT_OK || !stream) {
-        delete request;
-        stream.writeU8(result);
-        return stream;
-    }
-
-    bool isOK = requestQueue.execute(request);
-
-    if (isOK) {
-        request->writeResult(stream);
-    }
-
-    delete request;
-
-    return isOK;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleSetMulti()
-{
-    uint8_t result = Protocol::RESULT_OK;
-    SetMultiDataRefRequest* request =
-        new SetMultiDataRefRequest(result, stream, true);
-    if (result!=Protocol::RESULT_OK || !stream) {
-        delete request;
-        stream.writeU8(result);
-        return stream;
-    }
-
-    bool isOK = requestQueue.execute(request);
-
-    if (isOK) {
-        request->writeResult(stream);
-    }
-
-    delete request;
-
-    return isOK;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleRegisterGetMulti()
-{
-    uint8_t result = Protocol::RESULT_OK;
-    GetMultiDataRefRequest* request =
-        new GetMultiDataRefRequest(result, stream);
-    if (result!=Protocol::RESULT_OK || !stream) {
-        delete request;
-        stream.writeU8(result);
-        return stream;
-    }
-
-    size_t id = nextGetMultiRequestID++;
-    getMultiRequests[id] = request;
-
-    stream.writeU8(Protocol::RESULT_OK);
-    stream.writeU32(id);
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleUnregisterGetMulti()
-{
-    uint32_t id = stream.readU32();
-    if (!stream) return false;
-
-    getMultiRequests_t::iterator i = getMultiRequests.find(id);
-    if (i==getMultiRequests.end()) {
-        stream.writeU8(Protocol::RESULT_INVALID_ID);
-    } else {
-        GetMultiDataRefRequest* request = i->second;
-        getMultiRequests.erase(i);
-        delete request;
-        stream.writeU8(Protocol::RESULT_OK);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleExecuteGetMulti()
-{
-    uint32_t id = stream.readU32();
-    if (!stream) return false;
-
-    getMultiRequests_t::iterator i = getMultiRequests.find(id);
-    if (i==getMultiRequests.end()) {
-        stream.writeU8(Protocol::RESULT_INVALID_ID);
-    } else {
-        GetMultiDataRefRequest* request = i->second;
-        if (!requestQueue.execute(request)) return false;
-        request->writeResult(stream);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleRegisterSetMulti()
-{
-    uint8_t result = Protocol::RESULT_OK;
-    SetMultiDataRefRequest* request =
-        new SetMultiDataRefRequest(result, stream, false);
-    if (result!=Protocol::RESULT_OK || !stream) {
-        delete request;
-        stream.writeU8(result);
-        return stream;
-    }
-
-    size_t id = nextSetMultiRequestID++;
-    setMultiRequests[id] = request;
-
-    stream.writeU8(Protocol::RESULT_OK);
-    stream.writeU32(id);
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleUnregisterSetMulti()
-{
-    uint32_t id = stream.readU32();
-    if (!stream) return false;
-
-    setMultiRequests_t::iterator i = setMultiRequests.find(id);
-    if (i==setMultiRequests.end()) {
-        stream.writeU8(Protocol::RESULT_INVALID_ID);
-    } else {
-        SetMultiDataRefRequest* request = i->second;
-        setMultiRequests.erase(i);
-        delete request;
-        stream.writeU8(Protocol::RESULT_OK);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleExecuteSetMulti()
-{
-    uint32_t id = stream.readU32();
-    if (!stream) return false;
-
-    setMultiRequests_t::iterator i = setMultiRequests.find(id);
-    if (i==setMultiRequests.end()) {
-        stream.writeU8(Protocol::RESULT_INVALID_ID);
-    } else {
-        SetMultiDataRefRequest* request = i->second;
-        request->readValues(stream);
-        if (!stream || !requestQueue.execute(request)) return false;
-        request->writeResult(stream);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleGetVersions()
-{
-    int xplaneVersion = 0;
-    int xplmVersion = 0;
-
-    listenThread.getGlobals().getVersions(xplaneVersion, xplmVersion);
-
-    stream.writeU8(Protocol::RESULT_OK);
-    stream.writeS32(xplaneVersion);
-    stream.writeS32(xplmVersion);
-    stream.writeS32(Protocol::version);
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleReloadPlugins()
-{
-    ReloadPluginsRequest request;
-    if (!requestQueue.execute(&request)) return false;
-
-    stream.writeU8(Protocol::RESULT_OK);
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleShowMessage()
-{
-    string message = stream.readString();
-    float duration = stream.readFloat();
-    if (!stream) return false;
-
-    if (duration>Protocol::MAX_MESSAGE_DURATION) {
-        stream.writeU8(Protocol::RESULT_INVALID_DURATION);
-    } else {
-        MessageRequest request(listenThread.getGlobals().getMessageWindow(),
-                               message, duration);
-        if (!requestQueue.execute(&request)) return false;
-
-        stream.writeU8(Protocol::RESULT_OK);
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleRegisterHotkeys()
-{
-    size_t numHotkeys = stream.readU32();
-    if (!stream) return false;
-
-    if (numHotkeys>Protocol::MAX_HOTKEY_COUNT) {
-        stream.writeU8(Protocol::RESULT_INVALID_LENGTH);
-    } else {
-        HotkeyHandler::Hotkeys* newHotkeys =
-            new HotkeyHandler::Hotkeys(numHotkeys, stream);
-        if (newHotkeys->isValid()) {
-            destroyHotkeys();
-            hotkeys = newHotkeys;
-            listenThread.getGlobals().getHotkeyHandler().registerHotkeys(hotkeys);
-            stream.writeU8(Protocol::RESULT_OK);
-        } else {
-            delete newHotkeys;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleQueryHotkeys()
-{
-    stream.writeU8(Protocol::RESULT_OK);
-    if (hotkeys==0) {
-        stream.writeU32(0);
-    } else {
-        hotkeys->writePressed(stream);
-    }
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ServerThread::handleUnregisterHotkeys()
-{
-    destroyHotkeys();
-    stream.writeU8(Protocol::RESULT_OK);
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/ServerThread.h
===================================================================
--- src/plugin/src/xplra/ServerThread.h	(revision 45)
+++ src/plugin/src/xplra/ServerThread.h	(revision 45)
@@ -0,0 +1,309 @@
+// 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.
+
+#ifndef XPLRA_SERVERTHREAD_H
+#define XPLRA_SERVERTHREAD_H
+//------------------------------------------------------------------------------
+
+#include "HotkeyHandler.h"
+
+#include <hu/varadiistvan/scpl/Thread.h>
+
+#include <hu/varadiistvan/scpl/io/Waiter.h>
+#include <hu/varadiistvan/scpl/io/BufferedStream.h>
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+#include <hu/varadiistvan/scpl/io/LocalAcceptor.h>
+
+#include <hu/varadiistvan/scpl/Mutex.h>
+
+#include <set>
+#include <map>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+class ListenThread;
+
+class RequestQueue;
+
+class GetMultiDataRefRequest;
+class SetMultiDataRefRequest;
+
+//------------------------------------------------------------------------------
+
+/**
+ * A thread serving a client.
+ */
+class ServerThread : public hu::varadiistvan::scpl::Thread
+{
+private:
+    /**
+     * Type for the set of server thread instances.
+     */
+    typedef std::set<ServerThread*> instances_t;
+
+    /**
+     * Type for the registered multiple-data query requests.
+     */
+    typedef std::map<size_t, GetMultiDataRefRequest*> getMultiRequests_t;
+
+    /**
+     * Type for the registered multiple-data update requests.
+     */
+    typedef std::map<size_t, SetMultiDataRefRequest*> setMultiRequests_t;
+
+    /**
+     * A mutex to protect the collection of server threads.
+     */
+    static hu::varadiistvan::scpl::Mutex instancesMutex;
+
+    /**
+     * The instances of this class.
+     */
+    static instances_t instances;
+
+public:
+    /**
+     * Call quit() an all threads.
+     */
+    static void quitAll();
+
+private:
+    /**
+     * The listen thread this server was started by.
+     */
+    ListenThread& listenThread;
+
+    /**
+     * The request queue to use.
+     */
+    RequestQueue& requestQueue;
+
+    /**
+     * Our waiter.
+     */
+    hu::varadiistvan::scpl::io::Waiter waiter;
+
+    /**
+     * The buffered stream to use for communication at the low-level.
+     */
+    hu::varadiistvan::scpl::io::BufferedStream* bufferedStream;
+
+    /**
+     * The data stream being used for communication.
+     */
+    hu::varadiistvan::scpl::io::DataStream stream;
+
+    /**
+     * The ID of the next multiple-data query request.
+     */
+    size_t nextGetMultiRequestID;
+
+    /**
+     * The registered multiple-data query requests.
+     */
+    getMultiRequests_t getMultiRequests;
+
+    /**
+     * The ID of the next multiple-data update request.
+     */
+    size_t nextSetMultiRequestID;
+
+    /**
+     * The registered multiple-data query requests.
+     */
+    setMultiRequests_t setMultiRequests;
+
+    /**
+     * The set of hotkeys currently being handled.
+     */
+    HotkeyHandler::Hotkeys* hotkeys;
+
+public:
+    /**
+     * Construct the thread by using a LocalSocket returned by the
+     * given acceptor.
+     */
+    ServerThread(ListenThread& listenThread, RequestQueue& requestQueue,
+                 hu::varadiistvan::scpl::io::LocalAcceptor& acceptor);
+
+    /**
+     * Destroy the thread.
+     */
+    virtual ~ServerThread();
+
+    /**
+     * Quit the thread. It interrupts the blocking stream.
+     */
+    void quit();
+
+    /**
+     * Perform the thread's operation.
+     */
+    virtual void run();
+
+private:
+    /**
+     * Handle the COMMAND_GET_SINGLE command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleGetSingle();
+
+    /**
+     * Handle the COMMAND_SET_SINGLE command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleSetSingle();
+
+    /**
+     * Handle the COMMAND_GET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleGetMulti();
+
+    /**
+     * Handle the COMMAND_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleSetMulti();
+
+    /**
+     * Handle the COMMAND_REGISTER_GET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleRegisterGetMulti();
+
+    /**
+     * Handle the COMMAND_UNREGISTER_GET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleUnregisterGetMulti();
+
+    /**
+     * Handle the COMMAND_EXECUTE_GET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleExecuteGetMulti();
+
+    /**
+     * Handle the COMMAND_REGISTER_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleRegisterSetMulti();
+
+    /**
+     * Handle the COMMAND_UNREGISTER_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleUnregisterSetMulti();
+
+    /**
+     * Handle the COMMAND_EXECUTE_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleExecuteSetMulti();
+
+    /**
+     * Handle the COMMAND_GET_VERSIONS command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleGetVersions();
+
+    /**
+     * Handle the COMMAND_RELOAD_PLUGINS command.
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleReloadPlugins();
+
+    /**
+     * Handle the COMMAND_SHOW_MESSAGE command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleShowMessage();
+
+    /**
+     * Handle the COMMAND_REGISTER_HOTKEYS command.
+     *
+     * @return true if we can continue, false if the thread should
+     * quit.
+     */
+    bool handleRegisterHotkeys();
+
+    /**
+     * Handle the COMMAND_QUERY_HOTKEYS command.
+     *
+     * @return true if we can continue, false if the thread should
+     * quit.
+     */
+    bool handleQueryHotkeys();
+
+    /**
+     * Handle the COMMAND_UNREGISTER_HOTKEYS command.
+     *
+     * @return true if we can continue, false if the thread should
+     * quit.
+     */
+    bool handleUnregisterHotkeys();
+
+private:
+    /**
+     * Destroy the current set of hotkeys, if any.
+     *
+     * @return whether there were any hotkeys or not.
+     */
+    bool destroyHotkeys();
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_SERVERTHREAD_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/ServerThread.h
===================================================================
--- src/plugin/src/xplra/ServerThread.h	(revision 45)
+++ 	(revision )
@@ -1,309 +1,0 @@
-// 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.
-
-#ifndef XPLRA_SERVERTHREAD_H
-#define XPLRA_SERVERTHREAD_H
-//------------------------------------------------------------------------------
-
-#include "HotkeyHandler.h"
-
-#include <hu/varadiistvan/scpl/Thread.h>
-
-#include <hu/varadiistvan/scpl/io/Waiter.h>
-#include <hu/varadiistvan/scpl/io/BufferedStream.h>
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-#include <hu/varadiistvan/scpl/io/LocalAcceptor.h>
-
-#include <hu/varadiistvan/scpl/Mutex.h>
-
-#include <set>
-#include <map>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-class ListenThread;
-
-class RequestQueue;
-
-class GetMultiDataRefRequest;
-class SetMultiDataRefRequest;
-
-//------------------------------------------------------------------------------
-
-/**
- * A thread serving a client.
- */
-class ServerThread : public hu::varadiistvan::scpl::Thread
-{
-private:
-    /**
-     * Type for the set of server thread instances.
-     */
-    typedef std::set<ServerThread*> instances_t;
-
-    /**
-     * Type for the registered multiple-data query requests.
-     */
-    typedef std::map<size_t, GetMultiDataRefRequest*> getMultiRequests_t;
-
-    /**
-     * Type for the registered multiple-data update requests.
-     */
-    typedef std::map<size_t, SetMultiDataRefRequest*> setMultiRequests_t;
-
-    /**
-     * A mutex to protect the collection of server threads.
-     */
-    static hu::varadiistvan::scpl::Mutex instancesMutex;
-
-    /**
-     * The instances of this class.
-     */
-    static instances_t instances;
-
-public:
-    /**
-     * Call quit() an all threads.
-     */
-    static void quitAll();
-
-private:
-    /**
-     * The listen thread this server was started by.
-     */
-    ListenThread& listenThread;
-
-    /**
-     * The request queue to use.
-     */
-    RequestQueue& requestQueue;
-
-    /**
-     * Our waiter.
-     */
-    hu::varadiistvan::scpl::io::Waiter waiter;
-
-    /**
-     * The buffered stream to use for communication at the low-level.
-     */
-    hu::varadiistvan::scpl::io::BufferedStream* bufferedStream;
-
-    /**
-     * The data stream being used for communication.
-     */
-    hu::varadiistvan::scpl::io::DataStream stream;
-
-    /**
-     * The ID of the next multiple-data query request.
-     */
-    size_t nextGetMultiRequestID;
-
-    /**
-     * The registered multiple-data query requests.
-     */
-    getMultiRequests_t getMultiRequests;
-
-    /**
-     * The ID of the next multiple-data update request.
-     */
-    size_t nextSetMultiRequestID;
-
-    /**
-     * The registered multiple-data query requests.
-     */
-    setMultiRequests_t setMultiRequests;
-
-    /**
-     * The set of hotkeys currently being handled.
-     */
-    HotkeyHandler::Hotkeys* hotkeys;
-
-public:
-    /**
-     * Construct the thread by using a LocalSocket returned by the
-     * given acceptor.
-     */
-    ServerThread(ListenThread& listenThread, RequestQueue& requestQueue,
-                 hu::varadiistvan::scpl::io::LocalAcceptor& acceptor);
-
-    /**
-     * Destroy the thread.
-     */
-    virtual ~ServerThread();
-
-    /**
-     * Quit the thread. It interrupts the blocking stream.
-     */
-    void quit();
-
-    /**
-     * Perform the thread's operation.
-     */
-    virtual void run();
-
-private:
-    /**
-     * Handle the COMMAND_GET_SINGLE command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleGetSingle();
-
-    /**
-     * Handle the COMMAND_SET_SINGLE command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleSetSingle();
-
-    /**
-     * Handle the COMMAND_GET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleGetMulti();
-
-    /**
-     * Handle the COMMAND_SET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleSetMulti();
-
-    /**
-     * Handle the COMMAND_REGISTER_GET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleRegisterGetMulti();
-
-    /**
-     * Handle the COMMAND_UNREGISTER_GET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleUnregisterGetMulti();
-
-    /**
-     * Handle the COMMAND_EXECUTE_GET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleExecuteGetMulti();
-
-    /**
-     * Handle the COMMAND_REGISTER_SET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleRegisterSetMulti();
-
-    /**
-     * Handle the COMMAND_UNREGISTER_SET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleUnregisterSetMulti();
-
-    /**
-     * Handle the COMMAND_EXECUTE_SET_MULTI command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleExecuteSetMulti();
-
-    /**
-     * Handle the COMMAND_GET_VERSIONS command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleGetVersions();
-
-    /**
-     * Handle the COMMAND_RELOAD_PLUGINS command.
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleReloadPlugins();
-
-    /**
-     * Handle the COMMAND_SHOW_MESSAGE command
-     *
-     * @return true, if we can continue, false if the thread should quit
-     */
-    bool handleShowMessage();
-
-    /**
-     * Handle the COMMAND_REGISTER_HOTKEYS command.
-     *
-     * @return true if we can continue, false if the thread should
-     * quit.
-     */
-    bool handleRegisterHotkeys();
-
-    /**
-     * Handle the COMMAND_QUERY_HOTKEYS command.
-     *
-     * @return true if we can continue, false if the thread should
-     * quit.
-     */
-    bool handleQueryHotkeys();
-
-    /**
-     * Handle the COMMAND_UNREGISTER_HOTKEYS command.
-     *
-     * @return true if we can continue, false if the thread should
-     * quit.
-     */
-    bool handleUnregisterHotkeys();
-
-private:
-    /**
-     * Destroy the current set of hotkeys, if any.
-     *
-     * @return whether there were any hotkeys or not.
-     */
-    bool destroyHotkeys();
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_SERVERTHREAD_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/SetDataRefTask.cc
===================================================================
--- src/plugin/src/xplra/SetDataRefTask.cc	(revision 13)
+++ src/plugin/src/xplra/SetDataRefTask.cc	(revision 13)
@@ -0,0 +1,122 @@
+// 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 "SetDataRefTask.h"
+
+#include "Protocol.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::SetDataRefTask;
+using xplra::SetIntDataRefTask;
+using xplra::SetFloatDataRefTask;
+using xplra::SetDoubleDataRefTask;
+
+using hu::varadiistvan::scpl::io::DataStream;
+
+using std::string;
+
+//------------------------------------------------------------------------------
+
+SetDataRefTask* SetDataRefTask::create(uint8_t& result, DataStream& stream)
+{
+    result = Protocol::RESULT_OK;
+
+    string name = stream.readString();
+    uint8_t type = stream.readU8();
+    if (!stream) return 0;
+
+    if (type==Protocol::TYPE_INT) {
+        return new SetIntDataRefTask(name);
+    } else if (type==Protocol::TYPE_FLOAT) {
+        return new SetFloatDataRefTask(name);
+    } else if (type==Protocol::TYPE_DOUBLE) {
+        return new SetDoubleDataRefTask(name);
+    } else if (type==Protocol::TYPE_FLOAT_ARRAY ||
+               type==Protocol::TYPE_INT_ARRAY ||
+               type==Protocol::TYPE_BYTE_ARRAY)
+    {
+        int length = stream.readS32();
+        int offset = stream.readS32();
+        if (!stream) return 0;
+        if (length<=0 || length>Protocol::MAX_LENGTH) {
+            result = Protocol::RESULT_INVALID_LENGTH;
+            return 0;
+        }
+        if (offset<0) {
+            result = Protocol::RESULT_INVALID_OFFSET;
+            return 0;
+        }
+
+        if (type==Protocol::TYPE_INT_ARRAY) {
+            return new SetIntArrayDataRefTask(name, length, offset);
+        } else if (type==Protocol::TYPE_FLOAT_ARRAY) {
+            return new SetFloatArrayDataRefTask(name, length, offset);
+        } else {
+            return new SetByteArrayDataRefTask(name, length, offset);
+        }
+    } else {
+        result = Protocol::RESULT_INVALID_TYPE;
+    }
+
+    return 0;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+void SetIntDataRefTask::readValue(DataStream& stream)
+{
+    value = stream.readS32();
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+void SetFloatDataRefTask::readValue(DataStream& stream)
+{
+    value = stream.readFloat();
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+void SetDoubleDataRefTask::readValue(DataStream& stream)
+{
+    value = stream.readDouble();
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/SetDataRefTask.cc
===================================================================
--- src/plugin/src/xplra/SetDataRefTask.cc	(revision 13)
+++ 	(revision )
@@ -1,122 +1,0 @@
-// 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 "SetDataRefTask.h"
-
-#include "Protocol.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::SetDataRefTask;
-using xplra::SetIntDataRefTask;
-using xplra::SetFloatDataRefTask;
-using xplra::SetDoubleDataRefTask;
-
-using hu::varadiistvan::scpl::io::DataStream;
-
-using std::string;
-
-//------------------------------------------------------------------------------
-
-SetDataRefTask* SetDataRefTask::create(uint8_t& result, DataStream& stream)
-{
-    result = Protocol::RESULT_OK;
-
-    string name = stream.readString();
-    uint8_t type = stream.readU8();
-    if (!stream) return 0;
-
-    if (type==Protocol::TYPE_INT) {
-        return new SetIntDataRefTask(name);
-    } else if (type==Protocol::TYPE_FLOAT) {
-        return new SetFloatDataRefTask(name);
-    } else if (type==Protocol::TYPE_DOUBLE) {
-        return new SetDoubleDataRefTask(name);
-    } else if (type==Protocol::TYPE_FLOAT_ARRAY ||
-               type==Protocol::TYPE_INT_ARRAY ||
-               type==Protocol::TYPE_BYTE_ARRAY)
-    {
-        int length = stream.readS32();
-        int offset = stream.readS32();
-        if (!stream) return 0;
-        if (length<=0 || length>Protocol::MAX_LENGTH) {
-            result = Protocol::RESULT_INVALID_LENGTH;
-            return 0;
-        }
-        if (offset<0) {
-            result = Protocol::RESULT_INVALID_OFFSET;
-            return 0;
-        }
-
-        if (type==Protocol::TYPE_INT_ARRAY) {
-            return new SetIntArrayDataRefTask(name, length, offset);
-        } else if (type==Protocol::TYPE_FLOAT_ARRAY) {
-            return new SetFloatArrayDataRefTask(name, length, offset);
-        } else {
-            return new SetByteArrayDataRefTask(name, length, offset);
-        }
-    } else {
-        result = Protocol::RESULT_INVALID_TYPE;
-    }
-
-    return 0;
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-void SetIntDataRefTask::readValue(DataStream& stream)
-{
-    value = stream.readS32();
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-void SetFloatDataRefTask::readValue(DataStream& stream)
-{
-    value = stream.readFloat();
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-void SetDoubleDataRefTask::readValue(DataStream& stream)
-{
-    value = stream.readDouble();
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/SetDataRefTask.h
===================================================================
--- src/plugin/src/xplra/SetDataRefTask.h	(revision 66)
+++ src/plugin/src/xplra/SetDataRefTask.h	(revision 66)
@@ -0,0 +1,616 @@
+// 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.
+
+#ifndef XPLRA_SETDATAREFTASK_H
+#define XPLRA_SETDATAREFTASK_H
+//------------------------------------------------------------------------------
+
+#include "DataRefTask.h"
+
+#include <hu/varadiistvan/scpl/io/DataStream.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for dataref tasks that set the value of some data
+ * referenced by a dataref.
+ *
+ * Since XPLM provides no feedback on whether the setting is
+ * successful, we detect only if the dataref is valid or not. So the
+ * isValid() function provides the only feedback if the task executed
+ * successfully or not. (We could use XPLMCanWriteDataRef, but for
+ * efficiency reasons we refrain from it. A separate task may be
+ * created for this purpose.)
+ */
+class SetDataRefTask : public DataRefTask
+{
+public:
+    /**
+     * Read a dataref setting specification and create the appropriate
+     * SetDataRefTask instance.
+     *
+     * @param result will contain the result of the operation. It
+     * signifies an error only, if some wrong data is read. If the
+     * stream fails, it will indicate RESULT_OK.
+     * @param stream the stream to read from
+     *
+     * @return the new instance or 0 on error.
+     */
+    static SetDataRefTask* create(uint8_t& result, hu::varadiistvan::scpl::io::DataStream& stream);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Read and set the value to update from the given stream
+     */
+    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream) = 0;
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for dataref setting tasks that set a single scalar
+ * value.
+ *
+ * ConcreteClass is the actual child class. It should have a function
+ * name setData() which performs the actual setting.
+ */
+template <typename T, class ConcreteClass>
+class SetScalarDataRefTask : public SetDataRefTask
+{
+protected:
+    /**
+     * The value to set.
+     */
+    T value;
+
+public:
+    /**
+     * Construct the task for setting the data referenced by the
+     * dataref with the given name.
+     */
+    SetScalarDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for setting the data referenced by the given
+     * dataref.
+     */
+    SetScalarDataRefTask(XPLMDataRef dataRef);
+
+protected:
+    /**
+     * Perform the actual operation.
+     */
+    virtual void process();
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * Task to set the value of an integer data.
+ */
+class SetIntDataRefTask :
+        public SetScalarDataRefTask<int, SetIntDataRefTask>
+{
+public:
+    /**
+     * Set the given dataref's value to the given value.
+     */
+    static void setData(XPLMDataRef dataRef, int value);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetIntDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetIntDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Read and set the value to update from the given stream
+     */
+    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * Task to set the value of a single-precision floating point data.
+ */
+class SetFloatDataRefTask :
+        public SetScalarDataRefTask<float, SetFloatDataRefTask>
+{
+public:
+    /**
+     * Set the given dataref's value to the given value.
+     */
+    static void setData(XPLMDataRef dataRef, float value);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetFloatDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetFloatDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Read and set the value to update from the given stream
+     */
+    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * Task to set the value of a double-precision floating point data.
+ */
+class SetDoubleDataRefTask :
+        public SetScalarDataRefTask<double, SetDoubleDataRefTask>
+{
+public:
+    /**
+     * Set the given dataref's value to the given value.
+     */
+    static void setData(XPLMDataRef dataRef, double value);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetDoubleDataRefTask(const std::string& name);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetDoubleDataRefTask(XPLMDataRef dataRef);
+
+    /**
+     * Read and set the value to update from the given stream
+     */
+    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for dataref setting tasks that set the values of an
+ * array.
+ *
+ * ConcreteClass is the actual child class. It should have a function
+ * name setData() which performs the actual setting.
+ */
+template <typename T, class ConcreteClass>
+class SetArrayDataRefTask : public SetDataRefTask
+{
+private:
+    /**
+     * The number of data items in the value.
+     */
+    int count;
+
+    /**
+     * The offset starting with which the data should be set.
+     */
+    int offset;
+
+    /**
+     * The value to set.
+     */
+    T* value;
+
+public:
+    /**
+     * Construct the data setting task for the dataref with the given
+     * name.
+     *
+     * The value array will be allocated, but not filled with
+     * data. Thus count should be positive!
+     */
+    SetArrayDataRefTask(const std::string& name, int count, int offset = 0);
+
+    /**
+     * Construct the data setting task for the given dataref.
+     *
+     * The value array will be allocated, but not filled with
+     * data. Thus count should be positive!
+     */
+    SetArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
+
+    /**
+     * Destroy the task.
+     */
+    virtual ~SetArrayDataRefTask();
+
+    /**
+     * Read and set the value to update from the given stream
+     */
+    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
+
+protected:
+    /**
+     * Perform the actual operation.
+     */
+    virtual void process();
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref setting task which sets an array of integers.
+ */
+class SetIntArrayDataRefTask :
+    public SetArrayDataRefTask<int, SetIntArrayDataRefTask>
+{
+public:
+    /**
+     * Perform the actual setting.
+     */
+    static void setData(XPLMDataRef dataRef, int* value, int count, int offset);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetIntArrayDataRefTask(const std::string& name, int count, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetIntArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref setting task which sets an array of single-precision
+ * floating-point values.
+ */
+class SetFloatArrayDataRefTask :
+    public SetArrayDataRefTask<float, SetFloatArrayDataRefTask>
+{
+public:
+    /**
+     * Perform the actual setting.
+     */
+    static void setData(XPLMDataRef dataRef, float* value, int count, int offset);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetFloatArrayDataRefTask(const std::string& name, int count, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetFloatArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * A dataref setting task which sets an array of bytes.
+ */
+class SetByteArrayDataRefTask :
+    public SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>
+{
+public:
+    /**
+     * Perform the actual setting.
+     */
+    static void setData(XPLMDataRef dataRef, unsigned char* value,
+                        int count, int offset);
+
+    /**
+     * Construct the task for the dataref with the given name.
+     */
+    SetByteArrayDataRefTask(const std::string& name, int count, int offset = 0);
+
+    /**
+     * Construct the task for the given dataref.
+     */
+    SetByteArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
+};
+
+//------------------------------------------------------------------------------
+// Template definitions
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline SetScalarDataRefTask<T, ConcreteClass>::
+SetScalarDataRefTask(const std::string& name) :
+    SetDataRefTask(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline SetScalarDataRefTask<T, ConcreteClass>::
+SetScalarDataRefTask(XPLMDataRef dataRef) :
+    SetDataRefTask(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+void SetScalarDataRefTask<T, ConcreteClass>::process()
+{
+    ConcreteClass::setData(getDataRef(), value);
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline SetArrayDataRefTask<T, ConcreteClass>::
+SetArrayDataRefTask(const std::string& name, int count, int offset) :
+    SetDataRefTask(name),
+    count(count),
+    offset(offset),
+    value(new T[count])
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline SetArrayDataRefTask<T, ConcreteClass>::
+SetArrayDataRefTask(XPLMDataRef dataRef, int count, int offset) :
+    SetDataRefTask(dataRef),
+    count(count),
+    offset(offset),
+    value(new T[count])
+{
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+inline SetArrayDataRefTask<T, ConcreteClass>::~SetArrayDataRefTask()
+{
+    delete [] value;
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+void SetArrayDataRefTask<T, ConcreteClass>::
+readValue(hu::varadiistvan::scpl::io::DataStream& stream)
+{
+    stream.read(value, count * sizeof(T));
+}
+
+//------------------------------------------------------------------------------
+
+template <typename T, class ConcreteClass>
+void SetArrayDataRefTask<T, ConcreteClass>::process()
+{
+    ConcreteClass::setData(getDataRef(), value, count, offset);
+}
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline SetDataRefTask::SetDataRefTask(const std::string& name) :
+    DataRefTask(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetDataRefTask::SetDataRefTask(XPLMDataRef dataRef) :
+    DataRefTask(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void SetIntDataRefTask::setData(XPLMDataRef dataRef, int value)
+{
+    XPLMSetDatai(dataRef, value);
+}
+
+//------------------------------------------------------------------------------
+
+inline SetIntDataRefTask::SetIntDataRefTask(const std::string& name) :
+    SetScalarDataRefTask<int, SetIntDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetIntDataRefTask::SetIntDataRefTask(XPLMDataRef dataRef) :
+    SetScalarDataRefTask<int, SetIntDataRefTask>(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void SetFloatDataRefTask::setData(XPLMDataRef dataRef, float value)
+{
+    XPLMSetDatai(dataRef, value);
+}
+
+//------------------------------------------------------------------------------
+
+inline SetFloatDataRefTask::SetFloatDataRefTask(const std::string& name) :
+    SetScalarDataRefTask<float, SetFloatDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetFloatDataRefTask::SetFloatDataRefTask(XPLMDataRef dataRef) :
+    SetScalarDataRefTask<float, SetFloatDataRefTask>(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void SetDoubleDataRefTask::setData(XPLMDataRef dataRef, double value)
+{
+    XPLMSetDatai(dataRef, value);
+}
+
+//------------------------------------------------------------------------------
+
+inline SetDoubleDataRefTask::SetDoubleDataRefTask(const std::string& name) :
+    SetScalarDataRefTask<double, SetDoubleDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetDoubleDataRefTask::SetDoubleDataRefTask(XPLMDataRef dataRef) :
+    SetScalarDataRefTask<double, SetDoubleDataRefTask>(dataRef)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void SetIntArrayDataRefTask::setData(XPLMDataRef dataRef, int* value,
+                                            int count, int offset)
+{
+    XPLMSetDatavi(dataRef, value, offset, count);
+}
+
+//------------------------------------------------------------------------------
+
+inline SetIntArrayDataRefTask::SetIntArrayDataRefTask(const std::string& name,
+                                                      int count, int offset) :
+    SetArrayDataRefTask<int, SetIntArrayDataRefTask>(name, count, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetIntArrayDataRefTask::SetIntArrayDataRefTask(XPLMDataRef dataRef,
+                                                      int count, int offset) :
+    SetArrayDataRefTask<int, SetIntArrayDataRefTask>(dataRef, count, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void SetFloatArrayDataRefTask::setData(XPLMDataRef dataRef,
+                                              float* value,
+                                              int count, int offset)
+{
+    XPLMSetDatavf(dataRef, value, offset, count);
+}
+
+//------------------------------------------------------------------------------
+
+inline
+SetFloatArrayDataRefTask::SetFloatArrayDataRefTask(const std::string& name,
+                                                   int count, int offset) :
+    SetArrayDataRefTask<float, SetFloatArrayDataRefTask>(name, count, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline
+SetFloatArrayDataRefTask::SetFloatArrayDataRefTask(XPLMDataRef dataRef,
+                                                   int count, int offset) :
+    SetArrayDataRefTask<float, SetFloatArrayDataRefTask>(dataRef, count, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+inline void SetByteArrayDataRefTask::setData(XPLMDataRef dataRef,
+                                             unsigned char* value,
+                                             int count, int offset)
+{
+    XPLMSetDatab(dataRef, value, offset, count);
+}
+
+//------------------------------------------------------------------------------
+
+inline
+SetByteArrayDataRefTask::SetByteArrayDataRefTask(const std::string& name,
+                                                 int count, int offset) :
+    SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>(name,
+                                                                count, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline
+SetByteArrayDataRefTask::SetByteArrayDataRefTask(XPLMDataRef dataRef,
+                                                 int count, int offset) :
+    SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>(dataRef,
+                                                                count, offset)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_SETDATAREFTASK_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/SetDataRefTask.h
===================================================================
--- src/plugin/src/xplra/SetDataRefTask.h	(revision 13)
+++ 	(revision )
@@ -1,615 +1,0 @@
-// 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.
-
-#ifndef XPLRA_SETDATAREFTASK_H
-#define XPLRA_SETDATAREFTASK_H
-//------------------------------------------------------------------------------
-
-#include "DataRefTask.h"
-
-#include <hu/varadiistvan/scpl/io/DataStream.h>
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * Base class for dataref tasks that set the value of some data
- * referenced by a dataref.
- *
- * Since XPLM provides no feedback on whether the setting is
- * successful, we detect only if the dataref is valid or not. So the
- * isValid() function provides the only feedback if the task executed
- * successfully or not. (We could use XPLMCanWriteDataRef, but for
- * efficiency reasons we refrain from it. A separate task may be
- * created for this purpose.)
- */
-class SetDataRefTask : public DataRefTask
-{
-public:
-    /**
-     * Read a dataref setting specification and create the appropriate
-     * SetDataRefTask instance.
-     *
-     * @param result will contain the result of the operation. It
-     * signifies an error only, if some wrong data is read. If the
-     * stream fails, it will indicate RESULT_OK.
-     *
-     * @return the new instance or 0 on error.
-     */
-    static SetDataRefTask* create(uint8_t& result, hu::varadiistvan::scpl::io::DataStream& stream);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Read and set the value to update from the given stream
-     */
-    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream) = 0;
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * Base class for dataref setting tasks that set a single scalar
- * value.
- *
- * ConcreteClass is the actual child class. It should have a function
- * name setData() which performs the actual setting.
- */
-template <typename T, class ConcreteClass>
-class SetScalarDataRefTask : public SetDataRefTask
-{
-protected:
-    /**
-     * The value to set.
-     */
-    T value;
-
-public:
-    /**
-     * Construct the task for setting the data referenced by the
-     * dataref with the given name.
-     */
-    SetScalarDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for setting the data referenced by the given
-     * dataref.
-     */
-    SetScalarDataRefTask(XPLMDataRef dataRef);
-
-protected:
-    /**
-     * Perform the actual operation.
-     */
-    virtual void process();
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * Task to set the value of an integer data.
- */
-class SetIntDataRefTask :
-        public SetScalarDataRefTask<int, SetIntDataRefTask>
-{
-public:
-    /**
-     * Set the given dataref's value to the given value.
-     */
-    static void setData(XPLMDataRef dataRef, int value);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetIntDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetIntDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Read and set the value to update from the given stream
-     */
-    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * Task to set the value of a single-precision floating point data.
- */
-class SetFloatDataRefTask :
-        public SetScalarDataRefTask<float, SetFloatDataRefTask>
-{
-public:
-    /**
-     * Set the given dataref's value to the given value.
-     */
-    static void setData(XPLMDataRef dataRef, float value);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetFloatDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetFloatDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Read and set the value to update from the given stream
-     */
-    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * Task to set the value of a double-precision floating point data.
- */
-class SetDoubleDataRefTask :
-        public SetScalarDataRefTask<double, SetDoubleDataRefTask>
-{
-public:
-    /**
-     * Set the given dataref's value to the given value.
-     */
-    static void setData(XPLMDataRef dataRef, double value);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetDoubleDataRefTask(const std::string& name);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetDoubleDataRefTask(XPLMDataRef dataRef);
-
-    /**
-     * Read and set the value to update from the given stream
-     */
-    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * Base class for dataref setting tasks that set the values of an
- * array.
- *
- * ConcreteClass is the actual child class. It should have a function
- * name setData() which performs the actual setting.
- */
-template <typename T, class ConcreteClass>
-class SetArrayDataRefTask : public SetDataRefTask
-{
-private:
-    /**
-     * The number of data items in the value.
-     */
-    int count;
-
-    /**
-     * The offset starting with which the data should be set.
-     */
-    int offset;
-
-    /**
-     * The value to set.
-     */
-    T* value;
-
-public:
-    /**
-     * Construct the data setting task for the dataref with the given
-     * name.
-     *
-     * The value array will be allocated, but not filled with
-     * data. Thus count should be positive!
-     */
-    SetArrayDataRefTask(const std::string& name, int count, int offset = 0);
-
-    /**
-     * Construct the data setting task for the given dataref.
-     *
-     * The value array will be allocated, but not filled with
-     * data. Thus count should be positive!
-     */
-    SetArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
-
-    /**
-     * Destroy the task.
-     */
-    virtual ~SetArrayDataRefTask();
-
-    /**
-     * Read and set the value to update from the given stream
-     */
-    virtual void readValue(hu::varadiistvan::scpl::io::DataStream& stream);
-
-protected:
-    /**
-     * Perform the actual operation.
-     */
-    virtual void process();
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref setting task which sets an array of integers.
- */
-class SetIntArrayDataRefTask :
-    public SetArrayDataRefTask<int, SetIntArrayDataRefTask>
-{
-public:
-    /**
-     * Perform the actual setting.
-     */
-    static void setData(XPLMDataRef dataRef, int* value, int count, int offset);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetIntArrayDataRefTask(const std::string& name, int count, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetIntArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref setting task which sets an array of single-precision
- * floating-point values.
- */
-class SetFloatArrayDataRefTask :
-    public SetArrayDataRefTask<float, SetFloatArrayDataRefTask>
-{
-public:
-    /**
-     * Perform the actual setting.
-     */
-    static void setData(XPLMDataRef dataRef, float* value, int count, int offset);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetFloatArrayDataRefTask(const std::string& name, int count, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetFloatArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-/**
- * A dataref setting task which sets an array of bytes.
- */
-class SetByteArrayDataRefTask :
-    public SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>
-{
-public:
-    /**
-     * Perform the actual setting.
-     */
-    static void setData(XPLMDataRef dataRef, unsigned char* value,
-                        int count, int offset);
-
-    /**
-     * Construct the task for the dataref with the given name.
-     */
-    SetByteArrayDataRefTask(const std::string& name, int count, int offset = 0);
-
-    /**
-     * Construct the task for the given dataref.
-     */
-    SetByteArrayDataRefTask(XPLMDataRef dataRef, int count, int offset = 0);
-};
-
-//------------------------------------------------------------------------------
-// Template definitions
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline SetScalarDataRefTask<T, ConcreteClass>::
-SetScalarDataRefTask(const std::string& name) :
-    SetDataRefTask(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline SetScalarDataRefTask<T, ConcreteClass>::
-SetScalarDataRefTask(XPLMDataRef dataRef) :
-    SetDataRefTask(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-void SetScalarDataRefTask<T, ConcreteClass>::process()
-{
-    ConcreteClass::setData(getDataRef(), value);
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline SetArrayDataRefTask<T, ConcreteClass>::
-SetArrayDataRefTask(const std::string& name, int count, int offset) :
-    SetDataRefTask(name),
-    count(count),
-    offset(offset),
-    value(new T[count])
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline SetArrayDataRefTask<T, ConcreteClass>::
-SetArrayDataRefTask(XPLMDataRef dataRef, int count, int offset) :
-    SetDataRefTask(dataRef),
-    count(count),
-    offset(offset),
-    value(new T[count])
-{
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-inline SetArrayDataRefTask<T, ConcreteClass>::~SetArrayDataRefTask()
-{
-    delete [] value;
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-void SetArrayDataRefTask<T, ConcreteClass>::
-readValue(hu::varadiistvan::scpl::io::DataStream& stream)
-{
-    stream.read(value, count * sizeof(T));
-}
-
-//------------------------------------------------------------------------------
-
-template <typename T, class ConcreteClass>
-void SetArrayDataRefTask<T, ConcreteClass>::process()
-{
-    ConcreteClass::setData(getDataRef(), value, count, offset);
-}
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline SetDataRefTask::SetDataRefTask(const std::string& name) :
-    DataRefTask(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetDataRefTask::SetDataRefTask(XPLMDataRef dataRef) :
-    DataRefTask(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void SetIntDataRefTask::setData(XPLMDataRef dataRef, int value)
-{
-    XPLMSetDatai(dataRef, value);
-}
-
-//------------------------------------------------------------------------------
-
-inline SetIntDataRefTask::SetIntDataRefTask(const std::string& name) :
-    SetScalarDataRefTask<int, SetIntDataRefTask>(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetIntDataRefTask::SetIntDataRefTask(XPLMDataRef dataRef) :
-    SetScalarDataRefTask<int, SetIntDataRefTask>(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void SetFloatDataRefTask::setData(XPLMDataRef dataRef, float value)
-{
-    XPLMSetDatai(dataRef, value);
-}
-
-//------------------------------------------------------------------------------
-
-inline SetFloatDataRefTask::SetFloatDataRefTask(const std::string& name) :
-    SetScalarDataRefTask<float, SetFloatDataRefTask>(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetFloatDataRefTask::SetFloatDataRefTask(XPLMDataRef dataRef) :
-    SetScalarDataRefTask<float, SetFloatDataRefTask>(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void SetDoubleDataRefTask::setData(XPLMDataRef dataRef, double value)
-{
-    XPLMSetDatai(dataRef, value);
-}
-
-//------------------------------------------------------------------------------
-
-inline SetDoubleDataRefTask::SetDoubleDataRefTask(const std::string& name) :
-    SetScalarDataRefTask<double, SetDoubleDataRefTask>(name)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetDoubleDataRefTask::SetDoubleDataRefTask(XPLMDataRef dataRef) :
-    SetScalarDataRefTask<double, SetDoubleDataRefTask>(dataRef)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void SetIntArrayDataRefTask::setData(XPLMDataRef dataRef, int* value,
-                                            int count, int offset)
-{
-    XPLMSetDatavi(dataRef, value, offset, count);
-}
-
-//------------------------------------------------------------------------------
-
-inline SetIntArrayDataRefTask::SetIntArrayDataRefTask(const std::string& name,
-                                                      int count, int offset) :
-    SetArrayDataRefTask<int, SetIntArrayDataRefTask>(name, count, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetIntArrayDataRefTask::SetIntArrayDataRefTask(XPLMDataRef dataRef,
-                                                      int count, int offset) :
-    SetArrayDataRefTask<int, SetIntArrayDataRefTask>(dataRef, count, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void SetFloatArrayDataRefTask::setData(XPLMDataRef dataRef,
-                                              float* value,
-                                              int count, int offset)
-{
-    XPLMSetDatavf(dataRef, value, offset, count);
-}
-
-//------------------------------------------------------------------------------
-
-inline
-SetFloatArrayDataRefTask::SetFloatArrayDataRefTask(const std::string& name,
-                                                   int count, int offset) :
-    SetArrayDataRefTask<float, SetFloatArrayDataRefTask>(name, count, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline
-SetFloatArrayDataRefTask::SetFloatArrayDataRefTask(XPLMDataRef dataRef,
-                                                   int count, int offset) :
-    SetArrayDataRefTask<float, SetFloatArrayDataRefTask>(dataRef, count, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-inline void SetByteArrayDataRefTask::setData(XPLMDataRef dataRef,
-                                             unsigned char* value,
-                                             int count, int offset)
-{
-    XPLMSetDatab(dataRef, value, offset, count);
-}
-
-//------------------------------------------------------------------------------
-
-inline
-SetByteArrayDataRefTask::SetByteArrayDataRefTask(const std::string& name,
-                                                 int count, int offset) :
-    SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>(name,
-                                                                count, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline
-SetByteArrayDataRefTask::SetByteArrayDataRefTask(XPLMDataRef dataRef,
-                                                 int count, int offset) :
-    SetArrayDataRefTask<unsigned char, SetByteArrayDataRefTask>(dataRef,
-                                                                count, offset)
-{
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_SETDATAREFTASK_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/SetMultiDataRefRequest.cc
===================================================================
--- src/plugin/src/xplra/SetMultiDataRefRequest.cc	(revision 13)
+++ src/plugin/src/xplra/SetMultiDataRefRequest.cc	(revision 13)
@@ -0,0 +1,102 @@
+// 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 "SetMultiDataRefRequest.h"
+
+#include "Protocol.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::SetMultiDataRefRequest;
+
+using hu::varadiistvan::scpl::io::DataStream;
+
+//------------------------------------------------------------------------------
+
+SetMultiDataRefRequest::SetMultiDataRefRequest(uint8_t& result,
+                                               DataStream& stream,
+                                               bool readValues)
+{
+    result = Protocol::RESULT_OK;
+
+    uint32_t numTasks = stream.readU32();
+    if (!stream) return;
+    if (numTasks==0 || numTasks>Protocol::MAX_MULTI_COUNT) {
+        result = Protocol::RESULT_INVALID_COUNT;
+        return;
+    }
+
+    for(size_t i = 0;
+        i<numTasks && result==Protocol::RESULT_OK && stream; ++i) {
+        SetDataRefTask* task = SetDataRefTask::create(result, stream);
+        if (task!=0) {
+            if (readValues) {
+                task->readValue(stream);
+            }
+            addTask(task);
+        }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void SetMultiDataRefRequest::readValues(DataStream& stream)
+{
+    size_t numTasks = getNumTasks();
+    for(size_t i = 0; i<numTasks && stream; ++i) {
+        SetDataRefTask* task = getTask(i);
+        task->readValue(stream);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void SetMultiDataRefRequest::writeResult(DataStream& stream) const
+{
+    size_t numTasks = getNumTasks();
+    for(size_t i = 0; i<numTasks; ++i) {
+        SetDataRefTask* task = getTask(i);
+        if (!task->isValid()) {
+            stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
+            stream.writeU32(i);
+            return;
+        }
+    }
+
+    stream.writeU8(Protocol::RESULT_OK);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/SetMultiDataRefRequest.cc
===================================================================
--- src/plugin/src/xplra/SetMultiDataRefRequest.cc	(revision 13)
+++ 	(revision )
@@ -1,102 +1,0 @@
-// 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 "SetMultiDataRefRequest.h"
-
-#include "Protocol.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::SetMultiDataRefRequest;
-
-using hu::varadiistvan::scpl::io::DataStream;
-
-//------------------------------------------------------------------------------
-
-SetMultiDataRefRequest::SetMultiDataRefRequest(uint8_t& result,
-                                               DataStream& stream,
-                                               bool readValues)
-{
-    result = Protocol::RESULT_OK;
-
-    uint32_t numTasks = stream.readU32();
-    if (!stream) return;
-    if (numTasks==0 || numTasks>Protocol::MAX_MULTI_COUNT) {
-        result = Protocol::RESULT_INVALID_COUNT;
-        return;
-    }
-
-    for(size_t i = 0;
-        i<numTasks && result==Protocol::RESULT_OK && stream; ++i) {
-        SetDataRefTask* task = SetDataRefTask::create(result, stream);
-        if (task!=0) {
-            if (readValues) {
-                task->readValue(stream);
-            }
-            addTask(task);
-        }
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void SetMultiDataRefRequest::readValues(DataStream& stream)
-{
-    size_t numTasks = getNumTasks();
-    for(size_t i = 0; i<numTasks && stream; ++i) {
-        SetDataRefTask* task = getTask(i);
-        task->readValue(stream);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void SetMultiDataRefRequest::writeResult(DataStream& stream) const
-{
-    size_t numTasks = getNumTasks();
-    for(size_t i = 0; i<numTasks; ++i) {
-        SetDataRefTask* task = getTask(i);
-        if (!task->isValid()) {
-            stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
-            stream.writeU32(i);
-            return;
-        }
-    }
-
-    stream.writeU8(Protocol::RESULT_OK);
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/SetMultiDataRefRequest.h
===================================================================
--- src/plugin/src/xplra/SetMultiDataRefRequest.h	(revision 13)
+++ src/plugin/src/xplra/SetMultiDataRefRequest.h	(revision 13)
@@ -0,0 +1,84 @@
+// 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.
+
+#ifndef XPLRA_SETMULTIDATAREFREQUEST_H
+#define XPLRA_SETMULTIDATAREFREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "MultiTaskRequest.h"
+#include "SetDataRefTask.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request containing several dataref update tasks.
+ */
+class SetMultiDataRefRequest : public MultiTaskRequestTemplate<SetDataRefTask>
+{
+public:
+    /**
+     * Construct the request by reading the task specifications from
+     * the given stream.
+     */
+    SetMultiDataRefRequest(uint8_t& result,
+                           hu::varadiistvan::scpl::io::DataStream& stream,
+                           bool readValues);
+
+    /**
+     * Read the values of all tasks.
+     */
+    void readValues(hu::varadiistvan::scpl::io::DataStream& stream);
+
+    /**
+     * Write the result of an execution.
+     *
+     * If there is at least one invalid dataref, the result will be
+     * RESULT_UNKNOWN_DATAREF followed by a 32-bit unsigned value with
+     * the index of the first unknown dataref.
+     *
+     * Otherwise the result is RESULT_OK.
+     */
+    void writeResult(hu::varadiistvan::scpl::io::DataStream& stream) const;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_SETMULTIDATAREFREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/SetMultiDataRefRequest.h
===================================================================
--- src/plugin/src/xplra/SetMultiDataRefRequest.h	(revision 13)
+++ 	(revision )
@@ -1,84 +1,0 @@
-// 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.
-
-#ifndef XPLRA_SETMULTIDATAREFREQUEST_H
-#define XPLRA_SETMULTIDATAREFREQUEST_H
-//------------------------------------------------------------------------------
-
-#include "MultiTaskRequest.h"
-#include "SetDataRefTask.h"
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A request containing several dataref update tasks.
- */
-class SetMultiDataRefRequest : public MultiTaskRequestTemplate<SetDataRefTask>
-{
-public:
-    /**
-     * Construct the request by reading the task specifications from
-     * the given stream.
-     */
-    SetMultiDataRefRequest(uint8_t& result,
-                           hu::varadiistvan::scpl::io::DataStream& stream,
-                           bool readValues);
-
-    /**
-     * Read the values of all tasks.
-     */
-    void readValues(hu::varadiistvan::scpl::io::DataStream& stream);
-
-    /**
-     * Write the result of an execution.
-     *
-     * If there is at least one invalid dataref, the result will be
-     * RESULT_UNKNOWN_DATAREF followed by a 32-bit unsigned value with
-     * the index of the first unknown dataref.
-     *
-     * Otherwise the result is RESULT_OK.
-     */
-    void writeResult(hu::varadiistvan::scpl::io::DataStream& stream) const;
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_SETMULTIDATAREFREQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/Task.h
===================================================================
--- src/plugin/src/xplra/Task.h	(revision 13)
+++ src/plugin/src/xplra/Task.h	(revision 13)
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef XPLRA_TASK_H
+#define XPLRA_TASK_H
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A task is like a request, but it cannot be executed directly by the
+ * flight loop callback. Instead, it defines some simple task, of
+ * which potentially many can be added to a single request.
+ */
+class Task
+{
+public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~Task();
+
+    /**
+     * Perform the task
+     */
+    virtual void perform() = 0;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline Task::~Task()
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_TASK_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/Task.h
===================================================================
--- src/plugin/src/xplra/Task.h	(revision 13)
+++ 	(revision )
@@ -1,75 +1,0 @@
-// 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.
-
-#ifndef XPLRA_TASK_H
-#define XPLRA_TASK_H
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A task is like a request, but it cannot be executed directly by the
- * flight loop callback. Instead, it defines some simple task, of
- * which potentially many can be added to a single request.
- */
-class Task
-{
-public:
-    /**
-     * Virtual destructor.
-     */
-    virtual ~Task();
-
-    /**
-     * Perform the task
-     */
-    virtual void perform() = 0;
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline Task::~Task()
-{
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_TASK_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/TaskRequest.cc
===================================================================
--- src/plugin/src/xplra/TaskRequest.cc	(revision 13)
+++ src/plugin/src/xplra/TaskRequest.cc	(revision 13)
@@ -0,0 +1,50 @@
+// 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 "TaskRequest.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::TaskRequest;
+
+//------------------------------------------------------------------------------
+
+void TaskRequest::execute()
+{
+    task->perform();
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/TaskRequest.cc
===================================================================
--- src/plugin/src/xplra/TaskRequest.cc	(revision 13)
+++ 	(revision )
@@ -1,50 +1,0 @@
-// 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 "TaskRequest.h"
-
-//------------------------------------------------------------------------------
-
-using xplra::TaskRequest;
-
-//------------------------------------------------------------------------------
-
-void TaskRequest::execute()
-{
-    task->perform();
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/TaskRequest.h
===================================================================
--- src/plugin/src/xplra/TaskRequest.h	(revision 13)
+++ src/plugin/src/xplra/TaskRequest.h	(revision 13)
@@ -0,0 +1,101 @@
+// 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.
+
+#ifndef XPLRA_TASKREQUEST_H
+#define XPLRA_TASKREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "Request.h"
+
+#include "Task.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request the performs a task.
+ */
+class TaskRequest : public Request
+{
+private:
+    /**
+     * The task belonging to the request. It is owned by the request,
+     * i.e. deleted when the request is deleted.
+     */
+    Task* task;
+
+public:
+    /**
+     * Construct the request for the given task. The task will become
+     * owned by the request, so it will be deleted when the task is
+     * deleted.
+     */
+    TaskRequest(Task* task);
+
+    /**
+     * Destroy the task request.
+     */
+    virtual ~TaskRequest();
+
+    /**
+     * Execute the request by performing the task.
+     */
+    virtual void execute();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline TaskRequest::TaskRequest(Task* task) :
+    task(task)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline TaskRequest::~TaskRequest()
+{
+    delete task;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_TASKREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/TaskRequest.h
===================================================================
--- src/plugin/src/xplra/TaskRequest.h	(revision 13)
+++ 	(revision )
@@ -1,101 +1,0 @@
-// 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.
-
-#ifndef XPLRA_TASKREQUEST_H
-#define XPLRA_TASKREQUEST_H
-//------------------------------------------------------------------------------
-
-#include "Request.h"
-
-#include "Task.h"
-
-//------------------------------------------------------------------------------
-
-namespace xplra {
-
-//------------------------------------------------------------------------------
-
-/**
- * A request the performs a task.
- */
-class TaskRequest : public Request
-{
-private:
-    /**
-     * The task belonging to the request. It is owned by the request,
-     * i.e. deleted when the request is deleted.
-     */
-    Task* task;
-
-public:
-    /**
-     * Construct the request for the given task. The task will become
-     * owned by the request, so it will be deleted when the task is
-     * deleted.
-     */
-    TaskRequest(Task* task);
-
-    /**
-     * Destroy the task request.
-     */
-    virtual ~TaskRequest();
-
-    /**
-     * Execute the request by performing the task.
-     */
-    virtual void execute();
-};
-
-//------------------------------------------------------------------------------
-// Inline definitions
-//------------------------------------------------------------------------------
-
-inline TaskRequest::TaskRequest(Task* task) :
-    task(task)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline TaskRequest::~TaskRequest()
-{
-    delete task;
-}
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplra */
-
-//------------------------------------------------------------------------------
-#endif // XPLRA_TASKREQUEST_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/plugin.cc
===================================================================
--- src/plugin/src/xplra/plugin.cc	(revision 46)
+++ src/plugin/src/xplra/plugin.cc	(revision 46)
@@ -0,0 +1,139 @@
+// 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 "ListenThread.h"
+
+#include "Globals.h"
+
+#include <hu/varadiistvan/xplcommon/Util.h>
+#include <hu/varadiistvan/scpl/config.h>
+
+#include <XPLMDefs.h>
+#include <XPLMProcessing.h>
+#include <XPLMMenus.h>
+
+#include <cstdio>
+#include <cstring>
+#include <cstdarg>
+
+#if TARGET_API_POSIX
+#include <signal.h>
+#endif
+
+//------------------------------------------------------------------------------
+
+using xplra::ListenThread;
+using xplra::Globals;
+
+using hu::varadiistvan::xplcommon::Util;
+
+//------------------------------------------------------------------------------
+
+/**
+ * The global objects.
+ */
+static Globals* globals = 0;
+
+/**
+ * The thread to use to listen for incoming connections.
+ */
+static ListenThread* listenThread = 0;
+
+//------------------------------------------------------------------------------
+
+PLUGIN_API int XPluginStart(char* outName, char* outSignature,
+                            char* outDescription)
+{
+    Util::debug("hu.varadiistvan.xplra called\n");
+
+    strcpy(outName, "X-Plane Remote Access");
+    strcpy(outSignature, "hu.varadiistvan.xplra");
+    strcpy(outDescription, "Provides remote access to datarefs");
+
+#if TARGET_API_POSIX
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
+    return 1;
+}
+
+//------------------------------------------------------------------------------
+
+PLUGIN_API void XPluginEnable(void)
+{
+    Util::debug("hu.varadiistvan.xplra.XPluginEnable called\n");
+    // XPLMRegisterFlightLoopCallback(&callback, 5.0, 0);
+
+    globals = new Globals();
+
+    listenThread = new ListenThread(*globals);
+    listenThread->start();
+}
+
+//------------------------------------------------------------------------------
+
+PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, long inMessage,
+                                      void* inParam)
+{
+    Util::debug("hu.varadiistvan.xplra.XPluginReceiveMessage called, inFrom=%d, inMessage=%ld, inParam=%p\n",
+          inFrom, inMessage, inParam);
+}
+
+//------------------------------------------------------------------------------
+
+PLUGIN_API void XPluginDisable(void)
+{
+    Util::debug("hu.varadiistvan.xplra.XPluginDisable called\n");
+    // XPLMUnregisterFlightLoopCallback(&callback, 0);
+
+    if (listenThread!=0) {
+        listenThread->quit();
+        listenThread->join();
+        delete listenThread;
+        listenThread = 0;
+    }
+
+    delete globals; globals = 0;
+}
+
+//------------------------------------------------------------------------------
+
+PLUGIN_API void XPluginStop(void)
+{
+    Util::debug("hu.varadiistvan.xplra.XPluginStop called\n");
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/plugin/src/xplra/plugin.cc
===================================================================
--- src/plugin/src/xplra/plugin.cc	(revision 46)
+++ 	(revision )
@@ -1,139 +1,0 @@
-// 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 "ListenThread.h"
-
-#include "Globals.h"
-
-#include <hu/varadiistvan/xplcommon/Util.h>
-#include <hu/varadiistvan/scpl/config.h>
-
-#include <XPLMDefs.h>
-#include <XPLMProcessing.h>
-#include <XPLMMenus.h>
-
-#include <cstdio>
-#include <cstring>
-#include <cstdarg>
-
-#if TARGET_API_POSIX
-#include <signal.h>
-#endif
-
-//------------------------------------------------------------------------------
-
-using xplra::ListenThread;
-using xplra::Globals;
-
-using hu::varadiistvan::xplcommon::Util;
-
-//------------------------------------------------------------------------------
-
-/**
- * The global objects.
- */
-static Globals* globals = 0;
-
-/**
- * The thread to use to listen for incoming connections.
- */
-static ListenThread* listenThread = 0;
-
-//------------------------------------------------------------------------------
-
-PLUGIN_API int XPluginStart(char* outName, char* outSignature,
-                            char* outDescription)
-{
-    Util::debug("hu.varadiistvan.xplra called\n");
-
-    strcpy(outName, "X-Plane Remote Access");
-    strcpy(outSignature, "hu.varadiistvan.xplra");
-    strcpy(outDescription, "Provides remote access to datarefs");
-
-#if TARGET_API_POSIX
-    signal(SIGPIPE, SIG_IGN);
-#endif
-
-    return 1;
-}
-
-//------------------------------------------------------------------------------
-
-PLUGIN_API void XPluginEnable(void)
-{
-    Util::debug("hu.varadiistvan.xplra.XPluginEnable called\n");
-    // XPLMRegisterFlightLoopCallback(&callback, 5.0, 0);
-
-    globals = new Globals();
-
-    listenThread = new ListenThread(*globals);
-    listenThread->start();
-}
-
-//------------------------------------------------------------------------------
-
-PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, long inMessage,
-                                      void* inParam)
-{
-    Util::debug("hu.varadiistvan.xplra.XPluginReceiveMessage called, inFrom=%d, inMessage=%ld, inParam=%p\n",
-          inFrom, inMessage, inParam);
-}
-
-//------------------------------------------------------------------------------
-
-PLUGIN_API void XPluginDisable(void)
-{
-    Util::debug("hu.varadiistvan.xplra.XPluginDisable called\n");
-    // XPLMUnregisterFlightLoopCallback(&callback, 0);
-
-    if (listenThread!=0) {
-        listenThread->quit();
-        listenThread->join();
-        delete listenThread;
-        listenThread = 0;
-    }
-
-    delete globals; globals = 0;
-}
-
-//------------------------------------------------------------------------------
-
-PLUGIN_API void XPluginStop(void)
-{
-    Util::debug("hu.varadiistvan.xplra.XPluginStop called\n");
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/plugin/src/xplra/version.ldscript
===================================================================
--- src/plugin/src/xplra/version.ldscript	(revision 13)
+++ src/plugin/src/xplra/version.ldscript	(revision 13)
@@ -0,0 +1,10 @@
+{
+ global:
+  XPluginStart;
+  XPluginStop;
+  XPluginEnable;
+  XPluginDisable;
+  XPluginReceiveMessage;
+ local:
+   *;
+};
Index: src/plugin/src/xplra/version.ldscript
===================================================================
--- src/plugin/src/xplra/version.ldscript	(revision 13)
+++ 	(revision )
@@ -1,10 +1,0 @@
-{
- global:
-  XPluginStart;
-  XPluginStop;
-  XPluginEnable;
-  XPluginDisable;
-  XPluginReceiveMessage;
- local:
-   *;
-};
