source: xplra/src/client/c/hu/varadiistvan/xplra/MultiBuffer.h@ 33:080fa73274f8

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

Using the multi-get and multi-set commands in unregistered multi-dataref getters and setters, respectively

File size: 17.4 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(Exception);
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 * Execute the buffer by either reading or writing it. If the
241 * buffer is not finalized, it will be finalized. If it is not
242 * finalized, but registered, the registration will be cleared,
243 * and it will be re-registered after finalizing.
244 */
245 void execute() throw(Exception);
246
247 /**
248 * Set the value of an integer dataref with the given ID.
249 */
250 void setInt(size_t id, int value)
251 throw(InvalidIDException, TypeMismatchException);
252
253 /**
254 * Get the value of an integer dataref with the given ID.
255 */
256 int getInt(size_t id) const
257 throw(InvalidIDException, TypeMismatchException);
258
259 /**
260 * Get a reference to the integer dataref with the given ID
261 */
262 const int32_t& getIntRef(size_t id) const
263 throw(InvalidIDException, TypeMismatchException);
264
265 /**
266 * Get a reference to the integer dataref with the given ID
267 */
268 int32_t& getIntRef(size_t id)
269 throw(InvalidIDException, TypeMismatchException);
270
271 /**
272 * Set the value of a float dataref with the given ID.
273 */
274 void setFloat(size_t id, float value)
275 throw(InvalidIDException, TypeMismatchException);
276
277 /**
278 * Get the value of a float dataref with the given ID.
279 */
280 float getFloat(size_t id) const
281 throw(InvalidIDException, TypeMismatchException);
282
283 /**
284 * Get a reference to the float dataref with the given ID
285 */
286 const float& getFloatRef(size_t id) const
287 throw(InvalidIDException, TypeMismatchException);
288
289 /**
290 * Get a reference to the integer dataref with the given ID
291 */
292 float& getFloatRef(size_t id)
293 throw(InvalidIDException, TypeMismatchException);
294
295 /**
296 * Set the value of a double dataref with the given ID.
297 */
298 void setDouble(size_t id, double value)
299 throw(InvalidIDException, TypeMismatchException);
300
301 /**
302 * Get the value of a double dataref with the given ID.
303 */
304 double getDouble(size_t id) const
305 throw(InvalidIDException, TypeMismatchException);
306
307 /**
308 * Get a reference to the double dataref with the given ID
309 */
310 const double& getDoubleRef(size_t id) const
311 throw(InvalidIDException, TypeMismatchException);
312
313 /**
314 * Get a reference to the double dataref with the given ID
315 */
316 double& getDoubleRef(size_t id)
317 throw(InvalidIDException, TypeMismatchException);
318
319 /**
320 * Set the value of the float array dataref with the given ID.
321 *
322 * @param length the amount of data, i.e. you can set only a part
323 * of the data in the buffer. If 0, it is assumed to be the length
324 * of the data in the buffer minus the offset (see below).
325 *
326 * @param offset the offset within the buffer to set the data from
327 *
328 * @return the number of data items set
329 */
330 size_t setFloatArray(size_t id, const float* value,
331 size_t length = 0, size_t offset = 0)
332 throw(InvalidIDException, TypeMismatchException);
333
334 /**
335 * Get the value of the float array dataref with the given ID
336 *
337 * @param length the size of the buffer. If 0, it is assumed to be
338 * the length of the data in the buffer minus the offset (see
339 * below).
340 *
341 * @param offset the offset within the buffer to get the data from
342 *
343 * @return the number of data items retrieved.
344 */
345 size_t getFloatArray(size_t id, float* value,
346 size_t length = 0, size_t offset = 0) const
347 throw(InvalidIDException, TypeMismatchException);
348
349 /**
350 * Get the array of floating point values as a directly readable
351 * buffer.
352 *
353 * @param offset the offset within the buffer. If it is not less
354 * than the length of the buffer, 0 is returned.
355 */
356 const float* getFloatArray(size_t id, size_t offset = 0) const
357 throw(InvalidIDException, TypeMismatchException);
358
359 /**
360 * Set the value of the integer array dataref with the given ID.
361 *
362 * @param length the amount of data, i.e. you can set only a part
363 * of the data in the buffer. If 0, it is assumed to be the length
364 * of the data in the buffer minus the offset (see below).
365 *
366 * @param offset the offset within the buffer to set the data from
367 *
368 * @return the number of data items set
369 */
370 size_t setIntArray(size_t id, const int32_t* value,
371 size_t length = 0, size_t offset = 0)
372 throw(InvalidIDException, TypeMismatchException);
373
374 /**
375 * Get the value of the integer array dataref with the given ID
376 *
377 * @param length the size of the buffer. If 0, it is assumed to be
378 * the length of the data in the buffer minus the offset (see
379 * below).
380 *
381 * @param offset the offset within the buffer to get the data from
382 *
383 * @return the number of data items retrieved.
384 */
385 size_t getIntArray(size_t id, int32_t* value,
386 size_t length = 0, size_t offset = 0) const
387 throw(InvalidIDException, TypeMismatchException);
388
389 /**
390 * Get the array of integer values as a directly readable buffer.
391 *
392 * @param offset the offset within the buffer. If it is not less
393 * than the length of the buffer, 0 is returned.
394 */
395 const int32_t* getIntArray(size_t id, size_t offset = 0) const
396 throw(InvalidIDException, TypeMismatchException);
397
398
399 /**
400 * Set the value of the byte array dataref with the given ID.
401 *
402 * @param length the amount of data, i.e. you can set only a part
403 * of the data in the buffer. If 0, it is assumed to be the length
404 * of the data in the buffer minus the offset (see below).
405 *
406 * @param offset the offset within the buffer to set the data from
407 *
408 * @return the number of data items set
409 */
410 size_t setByteArray(size_t id, const uint8_t* value,
411 size_t length = 0, size_t offset = 0)
412 throw(InvalidIDException, TypeMismatchException);
413
414 /**
415 * Get the value of the byte array dataref with the given ID
416 *
417 * @param length the size of the buffer. If 0, it is assumed to be
418 * the length of the data in the buffer minus the offset (see
419 * below).
420 *
421 * @param offset the offset within the buffer to get the data from
422 *
423 * @return the number of data items retrieved.
424 */
425 size_t getByteArray(size_t id, uint8_t* value,
426 size_t length = 0, size_t offset = 0) const
427 throw(InvalidIDException, TypeMismatchException);
428
429 /**
430 * Get the array of byte values as a directly readable buffer.
431 *
432 * @param offset the offset within the buffer. If it is not less
433 * than the length of the buffer, 0 is returned.
434 */
435 const uint8_t* getByteArray(size_t id, size_t offset = 0) const
436 throw(InvalidIDException, TypeMismatchException);
437
438
439 /**
440 * Set the value of the byte array dataref with the given ID
441 * from the given string. If the string contains less characters
442 * than the array's length, the rest will be filled with 0s.
443 *
444 * @return the number of bytes set
445 */
446 size_t setString(size_t id, const std::string& value,
447 size_t offset = 0)
448 throw(InvalidIDException, TypeMismatchException);
449
450 /**
451 * Get the value of the byte array dataref with the given ID as
452 * a string.
453 */
454 std::string getString(size_t id, size_t offset = 0) const
455 throw(InvalidIDException, TypeMismatchException);
456
457 /**
458 * Get a string pointer to the value of the byte array dataref
459 * with the given ID.
460 */
461 const char* getStringPtr(size_t id, size_t offset = 0) const
462 throw(InvalidIDException, TypeMismatchException);
463
464protected:
465 /**
466 * Perform the main part of the execution if the buffer is
467 * registered.
468 */
469 virtual void doExecute() throw(Exception) = 0;
470
471 /**
472 * Perform the main part of the execution if the buffer is
473 * not registered.
474 */
475 virtual void doExecuteUnregistered() throw(Exception) = 0;
476
477 /**
478 * Write the data specification with the given command. It also
479 * checks the result
480 */
481 void writeSpec(uint8_t command) const throw(Exception);
482
483private:
484 /**
485 * Unfinalize the buffer, if it is finalized.
486 */
487 void unfinalize() throw();
488
489 /**
490 * Forget the registration of this buffer. This is called from the
491 * destructor of the XPlane object, since that closes the
492 * connection anyway, so there is no need to unregister the
493 * multi-buffers.
494 */
495 void forgetRegistration() throw();
496
497 /**
498 * Get the last dataref, or 0 if there are not datarefs yet.
499 */
500 const DataRef* getLastDataRef() const throw();
501
502 /**
503 * Get the dataref with the given ID if it is of the given
504 * type. Otherwise throw an exception.
505 */
506 const DataRef& getDataRef(size_t id, uint8_t type) const
507 throw(InvalidIDException, TypeMismatchException);
508
509 /**
510 * Get the data area belonging to the given dataref it is of the
511 * given type. If the buffer is not finalized yet, it will be.
512 */
513 void* getData(size_t id, uint8_t type)
514 throw(InvalidIDException, TypeMismatchException);
515
516 /**
517 * Get the data area belonging to the given dataref it is of the
518 * given type. If the buffer is not finalized yet, it will be.
519 */
520 const void* getData(size_t id, uint8_t type) const
521 throw(InvalidIDException, TypeMismatchException);
522
523 /**
524 * Template function for setting an array of a certain type.
525 */
526 template <typename T, uint8_t type> size_t
527 setArray(size_t id, const T* value, size_t length, size_t offset)
528 throw(InvalidIDException, TypeMismatchException);
529
530 /**
531 * Template function for getting the elements of an array of a
532 * certain type.
533 */
534 template <typename T, uint8_t type> size_t
535 getArray(size_t id, T* value, size_t length, size_t offset) const
536 throw(InvalidIDException, TypeMismatchException);
537
538 /**
539 * Template function for getting the elements of an array of a
540 * certain type.
541 */
542 template <typename T, uint8_t type> const T*
543 getArray(size_t id, size_t offset) const
544 throw(InvalidIDException, TypeMismatchException);
545
546 friend class XPlane;
547};
548
549//------------------------------------------------------------------------------
550// Inline definitions
551//------------------------------------------------------------------------------
552
553inline XPlane& MultiBuffer::getXPlane() const throw()
554{
555 return xplane;
556}
557
558//------------------------------------------------------------------------------
559
560} /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */
561
562//------------------------------------------------------------------------------
563#endif // HU_VARADIISTVAN_XPLRA_MULTIBUFFER_H
564
565// Local Variables:
566// mode: C++
567// c-basic-offset: 4
568// indent-tabs-mode: nil
569// End:
Note: See TracBrowser for help on using the repository browser.