Index: src/xplra/GetDataRefTask.cc
===================================================================
--- src/xplra/GetDataRefTask.cc	(revision 3)
+++ src/xplra/GetDataRefTask.cc	(revision 4)
@@ -35,67 +35,4 @@
 //------------------------------------------------------------------------------
 
-using xplra::GetByteArrayDataRefTask;
-
-using xplcommon::Util;
-
-using std::string;
-
-//------------------------------------------------------------------------------
-
-GetByteArrayDataRefTask::GetByteArrayDataRefTask(const std::string& name,
-                                                 int maxBytes, int offset) :
-    DataRefTask(name),
-    maxBytes(maxBytes),
-    offset(offset),
-    data((maxBytes>0) ? new unsigned char[maxBytes] : 0),
-    length(-1)
-{
-}
-
-//------------------------------------------------------------------------------
-
-GetByteArrayDataRefTask::GetByteArrayDataRefTask(XPLMDataRef dataRef,
-                                                 int maxBytes, int offset) :
-    DataRefTask(dataRef),
-    maxBytes(maxBytes),
-    offset(offset),
-    data((maxBytes>0) ? new unsigned char[maxBytes] : 0),
-    length(-1)
-{
-}
-
-//------------------------------------------------------------------------------
-
-GetByteArrayDataRefTask::~GetByteArrayDataRefTask()
-{
-    delete [] data;
-}
-
-//------------------------------------------------------------------------------
-
-void GetByteArrayDataRefTask::process()
-{
-    if (maxBytes<0) {
-        maxBytes = XPLMGetDatab(getDataRef(), 0, 0, 0);
-
-        if (maxBytes>0) {
-            maxBytes -= offset;
-        }
-
-        if (maxBytes>0) {
-            data = new unsigned char[maxBytes];
-        } else {
-            maxBytes = 0;
-        }
-    }
-
-    Util::debug("GetByteArrayDataRefTask::process: dataRef=%p, maxBytes=%d, data=%p, offset\n",
-                getDataRef(), maxBytes, data, offset);
-    if (maxBytes>0) {
-        length = XPLMGetDatab(getDataRef(), data, offset, maxBytes);
-    } else {
-        length = -1;
-    }
-}
 
 //------------------------------------------------------------------------------
Index: src/xplra/GetDataRefTask.h
===================================================================
--- src/xplra/GetDataRefTask.h	(revision 3)
+++ src/xplra/GetDataRefTask.h	(revision 4)
@@ -40,28 +40,314 @@
 
 /**
+ * Base class for tasks that query the value of some dataref.
+ */
+class GetDataRefTask : public DataRefTask
+{
+public:
+    /**
+     * 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);
+};
+
+//------------------------------------------------------------------------------
+
+/**
+ * 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);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * 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);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * 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);
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * 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();
+};
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+/**
+ * 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 DataRefTask
-{
-private:
-    /**
-     * The maximal number of bytes accepted.
-     */
-    int maxBytes;
-
-    /**
-     * The offset within the dataref's value to start querying from.
-     */
-    int offset;
-
-    /**
-     * The array to store the data in.
-     */
-    unsigned char* data;
-
-    /**
-     * The actual length of the data retrieved.
-     */
-    int length;
+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:
@@ -87,27 +373,122 @@
     GetByteArrayDataRefTask(XPLMDataRef dataRef,
                             int maxBytes = -1, int offset = 0);
-
-
-    /**
-     * Destroy the task object.
-     */
-    virtual ~GetByteArrayDataRefTask();
-
-    /**
-     * Get the data.
-     */
-    const unsigned char* getData() const;
-
-    /**
-     * Get the length of the data.
-     */
-    int getLength() const;
-
-protected:
-    /**
-     * Process the dataref by querying its value.
-     */
-    virtual void process();
-};
+};
+
+//------------------------------------------------------------------------------
+// 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;
+    }
+}
 
 //------------------------------------------------------------------------------
@@ -115,14 +496,166 @@
 //------------------------------------------------------------------------------
 
-inline const unsigned char* GetByteArrayDataRefTask::getData() const
-{
-    return data;
-}
-
-//------------------------------------------------------------------------------
-
-inline int GetByteArrayDataRefTask::getLength() const
-{
-    return length;
+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)
+{
 }
 
Index: src/xplra/Makefile.am
===================================================================
--- src/xplra/Makefile.am	(revision 3)
+++ src/xplra/Makefile.am	(revision 4)
@@ -29,6 +29,5 @@
 	ServerThread.cc		\
 	TaskRequest.cc		\
-	DataRefTask.cc		\
-	GetDataRefTask.cc
+	DataRefTask.cc
 
 libxplra_la_LIBADD=$(LIBXPLCOMMON_LIBS)
