source: xplra/src/client/c/hu/varadiistvan/xplra/MultiBuffer.h@ 66:f7c8521991df

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

Added the Doxygen configuration file and updated the documentation to eliminate the warnings

File size: 18.8 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 use for registering the buffer.
136 */
137 uint8_t registerCommand;
138
139 /**
140 * The command to unregister the buffer.
141 */
142 uint8_t unregisterCommand;
143
144 /**
145 * The ID with which this buffer is registered in the plugin. If
146 * negative, the buffer is not registerd yet.
147 */
148 int registeredID;
149
150protected:
151 /**
152 * Construct an empty buffer for the given XPlane instance.
153 */
154 MultiBuffer(XPlane& xplane, uint8_t registerCommand,
155 uint8_t unregisterCommand) throw();
156
157 /**
158 * Destroy the buffer. If it is registered, an attempt will be
159 * made to unregister it.
160 */
161 virtual ~MultiBuffer() throw();
162
163public:
164 /**
165 * Get the X-Plane object this buffer belongs to.
166 */
167 XPlane& getXPlane() const throw();
168
169 /**
170 * Add an integer dataref.
171 *
172 * @return the ID of the dataref, that can be used later to set or
173 * get the value.
174 */
175 size_t addInt(const std::string& name) throw();
176
177 /**
178 * Add a float dataref.
179 *
180 * @return the ID of the dataref, that can be used later to set or
181 * get the value.
182 */
183 size_t addFloat(const std::string& name) throw();
184
185 /**
186 * Add a double dataref.
187 *
188 * @return the ID of the dataref, that can be used later to set or
189 * get the value.
190 */
191 size_t addDouble(const std::string& name) throw();
192
193 /**
194 * Add a float array dataref.
195 *
196 * @return the ID of the dataref, that can be used later to set or
197 * get the value.
198 */
199 size_t addFloatArray(const std::string& name, size_t length,
200 size_t offset = 0) throw();
201
202 /**
203 * Add an integer array dataref.
204 *
205 * @return the ID of the dataref, that can be used later to set or
206 * get the value.
207 */
208 size_t addIntArray(const std::string& name, size_t length,
209 size_t offset = 0) throw();
210
211 /**
212 * Add a byte array dataref.
213 *
214 * @return the ID of the dataref, that can be used later to set or
215 * get the value.
216 */
217 size_t addByteArray(const std::string& name, size_t length,
218 size_t offset = 0) throw();
219
220 /**
221 * Finalize the buffer, if not finalized yet.
222 *
223 * @return if there is any data in it
224 */
225 bool finalize() const;
226
227 /**
228 * Register this buffer in X-Plane the for either getting or
229 * setting, depending on the actual subclass. It will be finalized
230 * too.
231 */
232 void registerInXPlane() throw(Exception);
233
234 /**
235 * Unregister this buffer from X-Plane.
236 */
237 void unregisterFromXPlane() throw(Exception);
238
239 /**
240 * Unregister this buffer from X-Plane safely, i.e. without
241 * throwing any exceptions. If unregistration fails, the
242 * registered ID will be cleared anyway.
243 *
244 * @return whether unregistration succeeded.
245 */
246 bool unregisterSafelyFromXPlane() throw();
247
248 /**
249 * Execute the buffer by either reading or writing it. If the
250 * buffer is not finalized, it will be finalized. If it is not
251 * finalized, but registered, the registration will be cleared,
252 * and it will be re-registered after finalizing.
253 */
254 void execute() throw(Exception);
255
256 /**
257 * Set the value of an integer dataref with the given ID.
258 */
259 void setInt(size_t id, int value)
260 throw(InvalidIDException, TypeMismatchException);
261
262 /**
263 * Get the value of an integer dataref with the given ID.
264 */
265 int getInt(size_t id) const
266 throw(InvalidIDException, TypeMismatchException);
267
268 /**
269 * Get a reference to the integer dataref with the given ID
270 */
271 const int32_t& getIntRef(size_t id) const
272 throw(InvalidIDException, TypeMismatchException);
273
274 /**
275 * Get a reference to the integer dataref with the given ID
276 */
277 int32_t& getIntRef(size_t id)
278 throw(InvalidIDException, TypeMismatchException);
279
280 /**
281 * Set the value of a float dataref with the given ID.
282 */
283 void setFloat(size_t id, float value)
284 throw(InvalidIDException, TypeMismatchException);
285
286 /**
287 * Get the value of a float dataref with the given ID.
288 */
289 float getFloat(size_t id) const
290 throw(InvalidIDException, TypeMismatchException);
291
292 /**
293 * Get a reference to the float dataref with the given ID
294 */
295 const float& getFloatRef(size_t id) const
296 throw(InvalidIDException, TypeMismatchException);
297
298 /**
299 * Get a reference to the integer dataref with the given ID
300 */
301 float& getFloatRef(size_t id)
302 throw(InvalidIDException, TypeMismatchException);
303
304 /**
305 * Set the value of a double dataref with the given ID.
306 */
307 void setDouble(size_t id, double value)
308 throw(InvalidIDException, TypeMismatchException);
309
310 /**
311 * Get the value of a double dataref with the given ID.
312 */
313 double getDouble(size_t id) const
314 throw(InvalidIDException, TypeMismatchException);
315
316 /**
317 * Get a reference to the double dataref with the given ID
318 */
319 const double& getDoubleRef(size_t id) const
320 throw(InvalidIDException, TypeMismatchException);
321
322 /**
323 * Get a reference to the double dataref with the given ID
324 */
325 double& getDoubleRef(size_t id)
326 throw(InvalidIDException, TypeMismatchException);
327
328 /**
329 * Set the value of the float array dataref with the given ID.
330 *
331 * @param id the ID of the float array dataref
332 * @param value the source buffer
333 * @param length the amount of data, i.e. you can set only a part
334 * of the data in the buffer. If 0, it is assumed to be the length
335 * of the data in the buffer minus the offset (see below).
336 *
337 * @param offset the offset within the buffer to set the data from
338 *
339 * @return the number of data items set
340 */
341 size_t setFloatArray(size_t id, const float* value,
342 size_t length = 0, size_t offset = 0)
343 throw(InvalidIDException, TypeMismatchException);
344
345 /**
346 * Get the value of the float array dataref with the given ID
347 *
348 * @param id the ID of the float array dataref
349 * @param value the destination buffer
350 * @param length the size of the buffer. If 0, it is assumed to be
351 * the length of the data in the buffer minus the offset (see
352 * below).
353 *
354 * @param offset the offset within the buffer to get the data from
355 *
356 * @return the number of data items retrieved.
357 */
358 size_t getFloatArray(size_t id, float* value,
359 size_t length = 0, size_t offset = 0) const
360 throw(InvalidIDException, TypeMismatchException);
361
362 /**
363 * Get the array of floating point values as a directly readable
364 * buffer.
365 *
366 * @param id the ID of the float array dataref
367 * @param offset the offset within the buffer. If it is not less
368 * than the length of the buffer, 0 is returned.
369 */
370 const float* getFloatArray(size_t id, size_t offset = 0) const
371 throw(InvalidIDException, TypeMismatchException);
372
373 /**
374 * Set the value of the integer array dataref with the given ID.
375 *
376 * @param id the ID of the integer array dataref
377 * @param value the source buffer
378 * @param length the amount of data, i.e. you can set only a part
379 * of the data in the buffer. If 0, it is assumed to be the length
380 * of the data in the buffer minus the offset (see below).
381 *
382 * @param offset the offset within the buffer to set the data from
383 *
384 * @return the number of data items set
385 */
386 size_t setIntArray(size_t id, const int32_t* value,
387 size_t length = 0, size_t offset = 0)
388 throw(InvalidIDException, TypeMismatchException);
389
390 /**
391 * Get the value of the integer array dataref with the given ID
392 *
393 * @param id the ID of the integer array dataref
394 * @param value the destination buffer
395 * @param length the size of the buffer. If 0, it is assumed to be
396 * the length of the data in the buffer minus the offset (see
397 * below).
398 *
399 * @param offset the offset within the buffer to get the data from
400 *
401 * @return the number of data items retrieved.
402 */
403 size_t getIntArray(size_t id, int32_t* value,
404 size_t length = 0, size_t offset = 0) const
405 throw(InvalidIDException, TypeMismatchException);
406
407 /**
408 * Get the array of integer values as a directly readable buffer.
409 *
410 * @param id the ID of the float array dataref
411 * @param offset the offset within the buffer. If it is not less
412 * than the length of the buffer, 0 is returned.
413 */
414 const int32_t* getIntArray(size_t id, size_t offset = 0) const
415 throw(InvalidIDException, TypeMismatchException);
416
417
418 /**
419 * Set the value of the byte array dataref with the given ID.
420 *
421 * @param id the ID of the byte array dataref
422 * @param value the source buffer
423 * @param length the amount of data, i.e. you can set only a part
424 * of the data in the buffer. If 0, it is assumed to be the length
425 * of the data in the buffer minus the offset (see below).
426 *
427 * @param offset the offset within the buffer to set the data from
428 *
429 * @return the number of data items set
430 */
431 size_t setByteArray(size_t id, const uint8_t* value,
432 size_t length = 0, size_t offset = 0)
433 throw(InvalidIDException, TypeMismatchException);
434
435 /**
436 * Get the value of the byte array dataref with the given ID
437 *
438 * @param id the ID of the byte array dataref
439 * @param value the destination buffer
440 * @param length the size of the buffer. If 0, it is assumed to be
441 * the length of the data in the buffer minus the offset (see
442 * below).
443 *
444 * @param offset the offset within the buffer to get the data from
445 *
446 * @return the number of data items retrieved.
447 */
448 size_t getByteArray(size_t id, uint8_t* value,
449 size_t length = 0, size_t offset = 0) const
450 throw(InvalidIDException, TypeMismatchException);
451
452 /**
453 * Get the array of byte values as a directly readable buffer.
454 *
455 * @param id the ID of the byte array dataref
456 * @param offset the offset within the buffer. If it is not less
457 * than the length of the buffer, 0 is returned.
458 */
459 const uint8_t* getByteArray(size_t id, size_t offset = 0) const
460 throw(InvalidIDException, TypeMismatchException);
461
462
463 /**
464 * Set the value of the byte array dataref with the given ID
465 * from the given string. If the string contains less characters
466 * than the array's length, the rest will be filled with 0s.
467 *
468 * @return the number of bytes set
469 */
470 size_t setString(size_t id, const std::string& value,
471 size_t offset = 0)
472 throw(InvalidIDException, TypeMismatchException);
473
474 /**
475 * Get the value of the byte array dataref with the given ID as
476 * a string.
477 */
478 std::string getString(size_t id, size_t offset = 0) const
479 throw(InvalidIDException, TypeMismatchException);
480
481 /**
482 * Get a string pointer to the value of the byte array dataref
483 * with the given ID.
484 */
485 const char* getStringPtr(size_t id, size_t offset = 0) const
486 throw(InvalidIDException, TypeMismatchException);
487
488protected:
489 /**
490 * Perform the main part of the execution if the buffer is
491 * registered.
492 */
493 virtual void doExecute() throw(Exception) = 0;
494
495 /**
496 * Perform the main part of the execution if the buffer is
497 * not registered.
498 */
499 virtual void doExecuteUnregistered() throw(Exception) = 0;
500
501 /**
502 * Write the data specification with the given command. It also
503 * checks the result
504 */
505 void writeSpec(uint8_t command) const throw(Exception);
506
507 /**
508 * Re-register the buffer in X-Plane, if it has been registered
509 * earlier.
510 *
511 * it has not been registered, nothing is done. Otherwise the
512 * buffer gets registered, and the old ID is forgotten. This
513 * function is meant to be used by the XPlane object when it
514 * creates a new connection. If the registration fails, the
515 * original ID is restored, so that this function could be called
516 * again
517 */
518 void reregisterInXPlane() throw(Exception);
519
520private:
521 /**
522 * Unfinalize the buffer, if it is finalized.
523 */
524 void unfinalize() throw();
525
526 /**
527 * Forget the registration of this buffer. This is called from the
528 * destructor of the XPlane object, since that closes the
529 * connection anyway, so there is no need to unregister the
530 * multi-buffers.
531 */
532 void forgetRegistration() throw();
533
534 /**
535 * Get the last dataref, or 0 if there are not datarefs yet.
536 */
537 const DataRef* getLastDataRef() const throw();
538
539 /**
540 * Get the dataref with the given ID if it is of the given
541 * type. Otherwise throw an exception.
542 */
543 const DataRef& getDataRef(size_t id, uint8_t type) const
544 throw(InvalidIDException, TypeMismatchException);
545
546 /**
547 * Get the data area belonging to the given dataref it is of the
548 * given type. If the buffer is not finalized yet, it will be.
549 */
550 void* getData(size_t id, uint8_t type)
551 throw(InvalidIDException, TypeMismatchException);
552
553 /**
554 * Get the data area belonging to the given dataref it is of the
555 * given type. If the buffer is not finalized yet, it will be.
556 */
557 const void* getData(size_t id, uint8_t type) const
558 throw(InvalidIDException, TypeMismatchException);
559
560 /**
561 * Template function for setting an array of a certain type.
562 */
563 template <typename T, uint8_t type> size_t
564 setArray(size_t id, const T* value, size_t length, size_t offset)
565 throw(InvalidIDException, TypeMismatchException);
566
567 /**
568 * Template function for getting the elements of an array of a
569 * certain type.
570 */
571 template <typename T, uint8_t type> size_t
572 getArray(size_t id, T* value, size_t length, size_t offset) const
573 throw(InvalidIDException, TypeMismatchException);
574
575 /**
576 * Template function for getting the elements of an array of a
577 * certain type.
578 */
579 template <typename T, uint8_t type> const T*
580 getArray(size_t id, size_t offset) const
581 throw(InvalidIDException, TypeMismatchException);
582
583 friend class XPlane;
584};
585
586//------------------------------------------------------------------------------
587// Inline definitions
588//------------------------------------------------------------------------------
589
590inline XPlane& MultiBuffer::getXPlane() const throw()
591{
592 return xplane;
593}
594
595//------------------------------------------------------------------------------
596
597} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
598
599//------------------------------------------------------------------------------
600#endif // HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
601
602// Local Variables:
603// mode: C++
604// c-basic-offset: 4
605// indent-tabs-mode: nil
606// End:
Note: See TracBrowser for help on using the repository browser.