source: xplra/src/client/c/hu/varadiistvan/xplra/XPlane.cc@ 18:c957b01ca44c

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

Added the setting of array values

File size: 12.7 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//------------------------------------------------------------------------------
30
31#include "XPlane.h"
32
33#include <hu/varadiistvan/scpl/io/LocalClientSocket.h>
34#include <hu/varadiistvan/scpl/io/DataStream.h>
35
36#include <xplra/Protocol.h>
37
38#include <memory>
39
40//------------------------------------------------------------------------------
41
42using hu::varadiistvan::xplra::XPlane;
43
44using hu::varadiistvan::scpl::io::LocalClientSocket;
45using hu::varadiistvan::scpl::io::LocalConnector;
46using hu::varadiistvan::scpl::io::DataStream;
47
48using xplra::Protocol;
49
50using std::auto_ptr;
51using std::string;
52
53//------------------------------------------------------------------------------
54
55inline void XPlane::checkStream() throw(NotConnectedException, IOException)
56{
57 if (stream==0) {
58 throw NotConnectedException();
59 } else if (stream->failed()) {
60 throw IOException(stream->getErrorCode());
61 }
62}
63
64//------------------------------------------------------------------------------
65
66void XPlane::checkResult(uint8_t result) throw(ProtocolException)
67{
68 switch(result) {
69 case Protocol::RESULT_OK:
70 return;
71 case Protocol::RESULT_INVALID_COMMAND:
72 throw ProtocolException(ProtocolException::INVALID_COMMAND);
73 case Protocol::RESULT_UNKNOWN_DATAREF:
74 throw ProtocolException(ProtocolException::UNKNOWN_DATAREF);
75 case Protocol::RESULT_INVALID_TYPE:
76 throw ProtocolException(ProtocolException::INVALID_TYPE);
77 case Protocol::RESULT_INVALID_LENGTH:
78 throw ProtocolException(ProtocolException::INVALID_LENGTH);
79 case Protocol::RESULT_INVALID_OFFSET:
80 throw ProtocolException(ProtocolException::INVALID_OFFSET);
81 case Protocol::RESULT_INVALID_COUNT:
82 throw ProtocolException(ProtocolException::INVALID_COUNT);
83 case Protocol::RESULT_INVALID_ID:
84 throw ProtocolException(ProtocolException::INVALID_ID);
85 case Protocol::RESULT_OTHER_ERROR:
86 default:
87 throw ProtocolException(ProtocolException::OTHER);
88 }
89}
90
91//------------------------------------------------------------------------------
92
93inline void XPlane::checkResult() throw(ProtocolException)
94{
95 uint8_t result = stream->readU8();
96 checkStream();
97 checkResult(result);
98}
99
100//------------------------------------------------------------------------------
101//------------------------------------------------------------------------------
102
103XPlane::~XPlane() throw()
104{
105 disconnect();
106}
107
108//------------------------------------------------------------------------------
109
110void XPlane::connect() throw(IOException)
111{
112 if (socket!=0) return;
113
114 auto_ptr<LocalClientSocket> clientSocket(new LocalClientSocket("xplra",
115 &waiter));
116 LocalConnector& connector = clientSocket->getConnector();
117
118 while (!connector.connect()) {
119 if (connector.failed()) {
120 throw IOException(connector.getErrorCode());
121 }
122 waiter.wait();
123 if (waiter.failed()) {
124 throw IOException(waiter.getErrorCode());
125 }
126 }
127
128 socket = clientSocket.release();
129 stream = new DataStream(*socket);
130}
131
132//------------------------------------------------------------------------------
133
134void XPlane::disconnect() throw()
135{
136 if (socket==0) return;
137
138 delete stream; stream = 0;
139 delete socket; socket = 0;
140}
141
142//------------------------------------------------------------------------------
143
144void XPlane::getScalar(const char* name, uint8_t type) throw(Exception)
145{
146 checkStream();
147
148 stream->writeU8(Protocol::COMMAND_GET_SINGLE);
149 stream->writeString(name, strlen(name));
150 stream->writeU8(type);
151 if (!stream->flush()) checkStream();
152
153 checkResult();
154}
155
156//------------------------------------------------------------------------------
157
158int XPlane::getInt(const char* name) throw(Exception)
159{
160 getScalar(name, Protocol::TYPE_INT);
161
162 int value = stream->readS32();
163 checkStream();
164 return value;
165}
166
167//------------------------------------------------------------------------------
168
169float XPlane::getFloat(const char* name) throw(Exception)
170{
171 getScalar(name, Protocol::TYPE_FLOAT);
172
173 float value = stream->readFloat();
174 checkStream();
175 return value;
176}
177
178//------------------------------------------------------------------------------
179
180double XPlane::getDouble(const char* name) throw(Exception)
181{
182 getScalar(name, Protocol::TYPE_DOUBLE);
183
184 double value = stream->readDouble();
185 checkStream();
186 return value;
187}
188
189//------------------------------------------------------------------------------
190
191size_t XPlane::getArray(const char* name, uint8_t type,
192 ssize_t length, size_t offset) throw(Exception)
193{
194 checkStream();
195
196 stream->writeU8(Protocol::COMMAND_GET_SINGLE);
197 stream->writeString(name, strlen(name));
198 stream->writeU8(type);
199 stream->writeS32(static_cast<int32_t>(length));
200 stream->writeS32(static_cast<int32_t>(offset));
201 if (!stream->flush()) checkStream();
202
203 uint8_t result = stream->readU8();
204 length = stream->readS32();
205 checkStream();
206 checkResult(result);
207
208 return length;
209}
210
211//------------------------------------------------------------------------------
212
213size_t XPlane::getFloatArray(const char* name, float* dest,
214 size_t length, size_t offset) throw(Exception)
215{
216 length = getArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
217
218 if (!stream->read(dest, length*sizeof(float))) checkStream();
219
220 return length;
221}
222
223//------------------------------------------------------------------------------
224
225float* XPlane::getFloatArray(const char* name, size_t& length,
226 size_t offset) throw(Exception)
227{
228 length = getArray(name, Protocol::TYPE_FLOAT_ARRAY, -1, offset);
229
230 auto_ptr<float> data(new float[length]);
231 if (!stream->read(data.get(), length*sizeof(float))) checkStream();
232 return data.release();
233}
234
235//------------------------------------------------------------------------------
236
237size_t XPlane::getIntArray(const char* name, int32_t* dest,
238 size_t length, size_t offset) throw(Exception)
239{
240 length = getArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
241
242 if (!stream->read(dest, length*sizeof(int32_t))) checkStream();
243
244 return length;
245}
246
247//------------------------------------------------------------------------------
248
249int32_t* XPlane::getIntArray(const char* name, size_t& length,
250 size_t offset) throw(Exception)
251{
252 length = getArray(name, Protocol::TYPE_INT_ARRAY, -1, offset);
253
254 auto_ptr<int32_t> data(new int32_t[length]);
255 if (!stream->read(data.get(), length*sizeof(int32_t))) checkStream();
256 return data.release();
257}
258
259//------------------------------------------------------------------------------
260
261size_t XPlane::getByteArray(const char* name, uint8_t* dest,
262 size_t length, size_t offset) throw(Exception)
263{
264 length = getArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
265
266 if (!stream->read(dest, length*sizeof(uint8_t))) checkStream();
267
268 return length;
269}
270
271//------------------------------------------------------------------------------
272
273uint8_t* XPlane::getByteArray(const char* name, size_t& length,
274 size_t offset) throw(Exception)
275{
276 length = getArray(name, Protocol::TYPE_BYTE_ARRAY, -1, offset);
277
278 auto_ptr<uint8_t> data(new uint8_t[length]);
279 if (!stream->read(data.get(), length*sizeof(uint8_t))) checkStream();
280 return data.release();
281}
282
283//------------------------------------------------------------------------------
284
285string XPlane::getString(const char* name, size_t offset) throw(Exception)
286{
287 size_t length = 0;
288 auto_ptr<uint8_t> data(getByteArray(name, length, offset));
289 return string(reinterpret_cast<char*>(data.get()));
290}
291
292//------------------------------------------------------------------------------
293
294void XPlane::setScalar(const char* name, uint8_t type) throw(Exception)
295{
296 stream->writeU8(Protocol::COMMAND_SET_SINGLE);
297 stream->writeString(name, strlen(name));
298 stream->writeU8(type);
299}
300
301//------------------------------------------------------------------------------
302
303void XPlane::setInt(const char* name, int value) throw(Exception)
304{
305 setScalar(name, Protocol::TYPE_INT);
306 stream->writeS32(value);
307 stream->flush();
308 checkResult();
309}
310
311//------------------------------------------------------------------------------
312
313void XPlane::setFloat(const char* name, float value) throw(Exception)
314{
315 setScalar(name, Protocol::TYPE_FLOAT);
316 stream->writeFloat(value);
317 stream->flush();
318 checkResult();
319}
320
321//------------------------------------------------------------------------------
322
323void XPlane::setDouble(const char* name, double value) throw(Exception)
324{
325 setScalar(name, Protocol::TYPE_DOUBLE);
326 stream->writeDouble(value);
327 stream->flush();
328 checkResult();
329}
330
331//------------------------------------------------------------------------------
332
333void XPlane::setArray(const char* name, uint8_t type, size_t length,
334 size_t offset) throw(Exception)
335{
336 stream->writeU8(Protocol::COMMAND_SET_SINGLE);
337 stream->writeString(name, strlen(name));
338 stream->writeU8(type);
339 stream->writeS32(static_cast<int32_t>(length));
340 stream->writeS32(static_cast<int32_t>(offset));
341}
342
343//------------------------------------------------------------------------------
344
345void XPlane::setFloatArray(const char* name, const float* values, size_t length,
346 size_t offset) throw(Exception)
347{
348 setArray(name, Protocol::TYPE_FLOAT_ARRAY, length, offset);
349 stream->write(values, length*sizeof(*values));
350 stream->flush();
351 checkResult();
352}
353
354//------------------------------------------------------------------------------
355
356void XPlane::setIntArray(const char* name, const int32_t* values, size_t length,
357 size_t offset) throw(Exception)
358{
359 setArray(name, Protocol::TYPE_INT_ARRAY, length, offset);
360 stream->write(values, length*sizeof(*values));
361 stream->flush();
362 checkResult();
363}
364
365//------------------------------------------------------------------------------
366
367void XPlane::setByteArray(const char* name, const uint8_t* values, size_t length,
368 size_t offset) throw(Exception)
369{
370 setArray(name, Protocol::TYPE_BYTE_ARRAY, length, offset);
371 stream->write(values, length*sizeof(*values));
372 stream->flush();
373 checkResult();
374}
375
376//------------------------------------------------------------------------------
377
378void XPlane::setString(const char* name, const char* value, size_t length,
379 size_t offset) throw(Exception)
380{
381 size_t valueLength = strlen(value);
382 if ((valueLength+1)>=length) {
383 setByteArray(name, reinterpret_cast<const uint8_t*>(value),
384 length, offset);
385 } else {
386 auto_ptr<uint8_t> buffer(new uint8_t[length]);
387 memcpy(buffer.get(), value, valueLength);
388 memset(buffer.get() + valueLength, 0, length - valueLength);
389 setByteArray(name, buffer.get(), length, offset);
390 }
391}
392//------------------------------------------------------------------------------
393
394// Local Variables:
395// mode: C++
396// c-basic-offset: 4
397// indent-tabs-mode: nil
398// End:
Note: See TracBrowser for help on using the repository browser.