source: xplra/src/client/c/hu/varadiistvan/xplra/MultiBuffer.h@ 19:280541440d22

Last change on this file since 19:280541440d22 was 19:280541440d22, checked in by István Váradi <ivaradi@…>, 11 years ago

Getting multiple values works

File size: 16.5 KB
Line 
1// Copyright (c) 2013 by István Váradi
2
3// This file is part of XPLRA, a remote-access plugin for X-Plane
4
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7
8// 1. Redistributions of source code must retain the above copyright notice, this
9// list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25// The views and conclusions contained in the software and documentation are those
26// of the authors and should not be interpreted as representing official policies,
27// either expressed or implied, of the FreeBSD Project.
28
29#ifndef HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
30#define HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
31//------------------------------------------------------------------------------
32
33#include "Exception.h"
34
35#include <string>
36#include <vector>
37
38#include <inttypes.h>
39
40//------------------------------------------------------------------------------
41
42namespace hu { namespace varadiistvan { namespace xplra {
43
44//------------------------------------------------------------------------------
45
46class XPlane;
47
48//------------------------------------------------------------------------------
49
50/**
51 * Base class for the multi-get and multi-set handlers. It contains
52 * the meta-data of the datarefs as well as a buffer for storing the
53 * data.
54 */
55class MultiBuffer
56{
57protected:
58 /**
59 * Information about a dataref.
60 */
61 class DataRef
62 {
63 public:
64 /**
65 * The name.
66 */
67 std::string name;
68
69 /**
70 * The type (the protocol constant).
71 */
72 uint8_t type;
73
74 /**
75 * The length in case of array types.
76 */
77 size_t length;
78
79 /**
80 * The offset in case of array types.
81 */
82 size_t offset;
83
84 /**
85 * The offset within the data buffer.
86 */
87 size_t dataOffset;
88
89 /**
90 * Construct the dataref with the given data.
91 */
92 DataRef(const std::string& name, uint8_t type,
93 const DataRef* previous = 0,
94 size_t length = 0, size_t offset = 0) throw();
95
96 /**
97 * Get the size of the data represented by this object.
98 */
99 size_t getSize() const throw();
100
101 /**
102 * Get the alignment requirement of the data represented by
103 * this dataref.
104 */
105 size_t getAlignment() const throw();
106
107 /**
108 * Determine if the dataref is an array.
109 */
110 bool isArray() const throw();
111
112 /**
113 * Get the length of the data the can be copied for the given
114 * user parameters.
115 */
116 size_t getCopyLength(size_t userLength, size_t userOffset) const throw();
117 };
118
119 /**
120 * The datarefs.
121 */
122 std::vector<DataRef> dataRefs;
123
124 /**
125 * The data buffer.
126 */
127 mutable unsigned char* data;
128
129 /**
130 * The XPlane object this buffer belongs to.
131 */
132 XPlane& xplane;
133
134 /**
135 * The command to unregister the buffer.
136 */
137 uint8_t unregisterCommand;
138
139 /**
140 * The ID with which this buffer is registered in the plugin. If
141 * negative, the buffer is not registerd yet.
142 */
143 int registeredID;
144
145protected:
146 /**
147 * Construct an empty buffer for the given XPlane instance.
148 */
149 MultiBuffer(XPlane& xplane) throw();
150
151public:
152 /**
153 * Destroy the buffer. If it is registered, an attempt will be
154 * made to unregister it.
155 */
156 virtual ~MultiBuffer() throw(Exception);
157
158 /**
159 * Add an integer dataref.
160 *
161 * @return the ID if the dataref, that can be used later to set or
162 * get the value.
163 */
164 size_t addInt(const std::string& name) throw();
165
166 /**
167 * Add a float dataref.
168 *
169 * @return the ID if the dataref, that can be used later to set or
170 * get the value.
171 */
172 size_t addFloat(const std::string& name) throw();
173
174 /**
175 * Add a double dataref.
176 *
177 * @return the ID if the dataref, that can be used later to set or
178 * get the value.
179 */
180 size_t addDouble(const std::string& name) throw();
181
182 /**
183 * Add a float array dataref.
184 *
185 * @return the ID if the dataref, that can be used later to set or
186 * get the value.
187 */
188 size_t addFloatArray(const std::string& name, size_t length,
189 size_t offset = 0) throw();
190
191 /**
192 * Add an integer array dataref.
193 *
194 * @return the ID if the dataref, that can be used later to set or
195 * get the value.
196 */
197 size_t addIntArray(const std::string& name, size_t length,
198 size_t offset = 0) throw();
199
200 /**
201 * Add a byte array dataref.
202 *
203 * @return the ID if the dataref, that can be used later to set or
204 * get the value.
205 */
206 size_t addByteArray(const std::string& name, size_t length,
207 size_t offset = 0) throw();
208
209 /**
210 * Finalize the buffer, if not finalized yet.
211 *
212 * @return if there is any data in it
213 */
214 bool finalize() const;
215
216 /**
217 * Register this buffer in X-Plane the for either getting or
218 * setting, depending on the actual subclass. It will be finalized
219 * too.
220 */
221 void registerInXPlane() throw(Exception);
222
223 /**
224 * Unregister this buffer from X-Plane.
225 */
226 void unregisterFromXPlane() throw(Exception);
227
228 /**
229 * Execute the buffer by either reading or writing it. If the
230 * buffer is not finalized, it will be finalized. If it is not
231 * finalized, but registered, the registration will be cleared,
232 * and it will be re-registered after finalizing.
233 */
234 void execute() throw(Exception);
235
236 /**
237 * Set the value of an integer dataref with the given ID.
238 */
239 void setInt(size_t id, int value)
240 throw(InvalidIDException, TypeMismatchException);
241
242 /**
243 * Get the value of an integer dataref with the given ID.
244 */
245 int getInt(size_t id) const
246 throw(InvalidIDException, TypeMismatchException);
247
248 /**
249 * Get a reference to the integer dataref with the given ID
250 */
251 const int32_t& getIntRef(size_t id) const
252 throw(InvalidIDException, TypeMismatchException);
253
254 /**
255 * Get a reference to the integer dataref with the given ID
256 */
257 int32_t& getIntRef(size_t id)
258 throw(InvalidIDException, TypeMismatchException);
259
260 /**
261 * Set the value of a float dataref with the given ID.
262 */
263 void setFloat(size_t id, float value)
264 throw(InvalidIDException, TypeMismatchException);
265
266 /**
267 * Get the value of a float dataref with the given ID.
268 */
269 float getFloat(size_t id) const
270 throw(InvalidIDException, TypeMismatchException);
271
272 /**
273 * Get a reference to the float dataref with the given ID
274 */
275 const float& getFloatRef(size_t id) const
276 throw(InvalidIDException, TypeMismatchException);
277
278 /**
279 * Get a reference to the integer dataref with the given ID
280 */
281 float& getFloatRef(size_t id)
282 throw(InvalidIDException, TypeMismatchException);
283
284 /**
285 * Set the value of a double dataref with the given ID.
286 */
287 void setDouble(size_t id, double value)
288 throw(InvalidIDException, TypeMismatchException);
289
290 /**
291 * Get the value of a double dataref with the given ID.
292 */
293 double getDouble(size_t id) const
294 throw(InvalidIDException, TypeMismatchException);
295
296 /**
297 * Get a reference to the double dataref with the given ID
298 */
299 const double& getDoubleRef(size_t id) const
300 throw(InvalidIDException, TypeMismatchException);
301
302 /**
303 * Get a reference to the double dataref with the given ID
304 */
305 double& getDoubleRef(size_t id)
306 throw(InvalidIDException, TypeMismatchException);
307
308 /**
309 * Set the value of the float array dataref with the given ID.
310 *
311 * @param length the amount of data, i.e. you can set only a part
312 * of the data in the buffer. If 0, it is assumed to be the length
313 * of the data in the buffer minus the offset (see below).
314 *
315 * @param offset the offset within the buffer to set the data from
316 *
317 * @return the number of data items set
318 */
319 size_t setFloatArray(size_t id, const float* value,
320 size_t length = 0, size_t offset = 0)
321 throw(InvalidIDException, TypeMismatchException);
322
323 /**
324 * Get the value of the float array dataref with the given ID
325 *
326 * @param length the size of the buffer. If 0, it is assumed to be
327 * the length of the data in the buffer minus the offset (see
328 * below).
329 *
330 * @param offset the offset within the buffer to get the data from
331 *
332 * @return the number of data items retrieved.
333 */
334 size_t getFloatArray(size_t id, float* value,
335 size_t length = 0, size_t offset = 0) const
336 throw(InvalidIDException, TypeMismatchException);
337
338 /**
339 * Get the array of floating point values as a directly readable
340 * buffer.
341 *
342 * @param offset the offset within the buffer. If it is not less
343 * than the length of the buffer, 0 is returned.
344 */
345 const float* getFloatArray(size_t id, size_t offset = 0) const
346 throw(InvalidIDException, TypeMismatchException);
347
348 /**
349 * Set the value of the integer array dataref with the given ID.
350 *
351 * @param length the amount of data, i.e. you can set only a part
352 * of the data in the buffer. If 0, it is assumed to be the length
353 * of the data in the buffer minus the offset (see below).
354 *
355 * @param offset the offset within the buffer to set the data from
356 *
357 * @return the number of data items set
358 */
359 size_t setIntArray(size_t id, const int32_t* value,
360 size_t length = 0, size_t offset = 0)
361 throw(InvalidIDException, TypeMismatchException);
362
363 /**
364 * Get the value of the integer array dataref with the given ID
365 *
366 * @param length the size of the buffer. If 0, it is assumed to be
367 * the length of the data in the buffer minus the offset (see
368 * below).
369 *
370 * @param offset the offset within the buffer to get the data from
371 *
372 * @return the number of data items retrieved.
373 */
374 size_t getIntArray(size_t id, int32_t* value,
375 size_t length = 0, size_t offset = 0) const
376 throw(InvalidIDException, TypeMismatchException);
377
378 /**
379 * Get the array of integer values as a directly readable buffer.
380 *
381 * @param offset the offset within the buffer. If it is not less
382 * than the length of the buffer, 0 is returned.
383 */
384 const int32_t* getIntArray(size_t id, size_t offset = 0) const
385 throw(InvalidIDException, TypeMismatchException);
386
387
388 /**
389 * Set the value of the byte array dataref with the given ID.
390 *
391 * @param length the amount of data, i.e. you can set only a part
392 * of the data in the buffer. If 0, it is assumed to be the length
393 * of the data in the buffer minus the offset (see below).
394 *
395 * @param offset the offset within the buffer to set the data from
396 *
397 * @return the number of data items set
398 */
399 size_t setByteArray(size_t id, const uint8_t* value,
400 size_t length = 0, size_t offset = 0)
401 throw(InvalidIDException, TypeMismatchException);
402
403 /**
404 * Get the value of the byte array dataref with the given ID
405 *
406 * @param length the size of the buffer. If 0, it is assumed to be
407 * the length of the data in the buffer minus the offset (see
408 * below).
409 *
410 * @param offset the offset within the buffer to get the data from
411 *
412 * @return the number of data items retrieved.
413 */
414 size_t getByteArray(size_t id, uint8_t* value,
415 size_t length = 0, size_t offset = 0) const
416 throw(InvalidIDException, TypeMismatchException);
417
418 /**
419 * Get the array of byte values as a directly readable buffer.
420 *
421 * @param offset the offset within the buffer. If it is not less
422 * than the length of the buffer, 0 is returned.
423 */
424 const uint8_t* getByteArray(size_t id, size_t offset = 0) const
425 throw(InvalidIDException, TypeMismatchException);
426
427
428 /**
429 * Set the value of the byte array dataref with the given ID
430 * from the given string. If the string contains less characters
431 * than the array's length, the rest will be filled with 0s.
432 *
433 * @return the number of bytes set
434 */
435 size_t setString(size_t id, const std::string& value,
436 size_t offset = 0)
437 throw(InvalidIDException, TypeMismatchException);
438
439 /**
440 * Get the value of the byte array dataref with the given ID as
441 * a string.
442 */
443 std::string getString(size_t id, size_t offset = 0) const
444 throw(InvalidIDException, TypeMismatchException);
445
446 /**
447 * Get a string pointer to the value of the byte array dataref
448 * with the given ID.
449 */
450 const char* getStringPtr(size_t id, size_t offset = 0) const
451 throw(InvalidIDException, TypeMismatchException);
452
453protected:
454 /**
455 * Perform the first part of the registration depending on the
456 * actual type.
457 */
458 virtual uint8_t doRegister() throw(Exception) = 0;
459
460 /**
461 * Perform the main part of the execution if the buffer is
462 * registered.
463 */
464 virtual void doExecute() throw(Exception) = 0;
465
466 /**
467 * Perform the main part of the execution if the buffer is
468 * not registered.
469 */
470 virtual void doExecuteUnregistered() throw(Exception) = 0;
471
472private:
473 /**
474 * Unfinalize the buffer, if it is finalized.
475 */
476 void unfinalize() throw();
477
478 /**
479 * Get the last dataref, or 0 if there are not datarefs yet.
480 */
481 const DataRef* getLastDataRef() const throw();
482
483 /**
484 * Get the dataref with the given ID if it is of the given
485 * type. Otherwise throw an exception.
486 */
487 const DataRef& getDataRef(size_t id, uint8_t type) const
488 throw(InvalidIDException, TypeMismatchException);
489
490 /**
491 * Get the data area belonging to the given dataref it is of the
492 * given type. If the buffer is not finalized yet, it will be.
493 */
494 void* getData(size_t id, uint8_t type)
495 throw(InvalidIDException, TypeMismatchException);
496
497 /**
498 * Get the data area belonging to the given dataref it is of the
499 * given type. If the buffer is not finalized yet, it will be.
500 */
501 const void* getData(size_t id, uint8_t type) const
502 throw(InvalidIDException, TypeMismatchException);
503
504 /**
505 * Template function for setting an array of a certain type.
506 */
507 template <typename T, uint8_t type> size_t
508 setArray(size_t id, const T* value, size_t length, size_t offset)
509 throw(InvalidIDException, TypeMismatchException);
510
511 /**
512 * Template function for getting the elements of an array of a
513 * certain type.
514 */
515 template <typename T, uint8_t type> size_t
516 getArray(size_t id, T* value, size_t length, size_t offset) const
517 throw(InvalidIDException, TypeMismatchException);
518
519 /**
520 * Template function for getting the elements of an array of a
521 * certain type.
522 */
523 template <typename T, uint8_t type> const T*
524 getArray(size_t id, size_t offset) const
525 throw(InvalidIDException, TypeMismatchException);
526};
527
528//------------------------------------------------------------------------------
529
530} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
531
532//------------------------------------------------------------------------------
533#endif // HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
534
535// Local Variables:
536// mode: C++
537// c-basic-offset: 4
538// indent-tabs-mode: nil
539// End:
Note: See TracBrowser for help on using the repository browser.