source: pacpusframework/branches/2.0-beta1/include/Pacpus/PacpusTools/BinaryDecoder.h@ 89

Last change on this file since 89 was 89, checked in by morasjul, 11 years ago

PACPUS 2.0 Beta deployed in new branch

Major changes:
-Add communication interface between components
-Add examples for communications interface (TestComponents)
-Move to Qt5 support

  • Property svn:executable set to *
File size: 49.1 KB
Line 
1// %pacpus:license{
2// This file is part of the PACPUS framework distributed under the
3// CECILL-C License, Version 1.0.
4// %pacpus:license}
5/// @file
6/// @author Gerald Dherbomez <firstname.surname@utc.fr>
7/// @date July, 2008
8/// @version $Id: BinaryDecoder.h 76 2013-01-10 17:05:10Z kurdejma $
9/// @copyright Copyright (c) UTC/CNRS Heudiasyc 2006 - 2013. All rights reserved.
10/// @brief Extracts data of specified type in a string.
11///
12/// Purpose: Extract data of specified type in a string (char *)
13/// Usage:
14/// bool xDecodeToXXX(T* result, const char * data, const unsigned int startBit, const unsigned int length)
15/// => x = format (i:Intel, Little Endian)
16/// (m:Motorola, Big Endian)
17/// => XXX = type of return value
18/// (Bool = bool)
19/// (I8 = char - 8 bits)
20/// (UI8 = unsigned char - 8 bits)
21/// (I16 = short - 16 bits)
22/// (UI16 = unsigned short - 16 bits)
23/// (I32 = long - 32 bits)
24/// (UI32 = unsigned long - 32 bits)
25/// (I64 = long long - 64 bits)
26/// (UI16 = unisgned long long - 64 bits)
27///
28/// ex: inline bool mDecodeToUI16(r, str, 8, 12);
29
30#ifndef BINARYDECODER_H
31#define BINARYDECODER_H
32
33#ifdef __cplusplus
34extern "C"
35{
36#endif // __cplusplus
37
38#include <stdio.h>
39
40//////////////////////////////////////////////////////////////////////////
41// print the data in the hexadecimal format in the console
42inline void displayData(const unsigned char * data, const unsigned long length, const int id)
43{
44 printf("\ndata = ");
45 for (unsigned int i = 0;i< length;++i )
46 printf("%02x ",data[i]);
47 printf(" dlc = %ld ID = 0x%x\n", length, id);
48}
49
50//////////////////////////////////////////////////////////////////////////
51// for Big Endian - Motorola coding
52//------------------------------------------------------------------------
53// return true if the signal is spread on more than 1 byte
54// ie if length is greater than ((startBit%8) + 1)
55// example:
56// 7654 3210
57// 0 .... ..||
58// 1 |||| ....
59// startBit is 1 and the length is 8: result gives (1%8)+1 = 2 < length(=6)
60inline bool mSpreadOnMoreThan1Byte(const unsigned int startBit, const unsigned int length)
61{
62 if ( (length > (startBit & 0x07) + 1) ) {
63 return true;
64 } else {
65 return false;
66 }
67}
68
69//////////////////////////////////////////////////////////////////////////
70// for Little Endian - Intel coding
71//------------------------------------------------------------------------
72// return true if the signal is spread on more than 1 byte
73// ie if length is greater than 8-(startBit%8)
74// example:
75// 7654 3210
76// 0 ||.. ....
77// 1 .... ||||
78// startBit is 6 and the length is 6: result gives 8-((6%8)) = 2 < length(=6)
79inline bool iSpreadOnMoreThan1Byte(const unsigned int startBit, const unsigned int length)
80{
81 if ( length > 8 - (startBit & 0x07) ) {
82 return true;
83 } else {
84 return false;
85 }
86}
87
88//////////////////////////////////////////////////////////////////////////
89// for Big Endian - Motorola coding
90//------------------------------------------------------------------------
91// return true if the signal is spread on more than 2 bytes
92// ie if (length - ((startBit%8) + 1) is greater than 8
93// example:
94// 7654 3210
95// 0 .... ...|
96// 1 |||| ||||
97// 2 ||.. ....
98// the start bit is 0 and the length is 11: result gives 11 - (0%8+1) = 10 (>8)
99//////////////////////////////////////////////////////////////////////////
100inline bool mSpreadOnMoreThan2Bytes(const unsigned int startBit, const unsigned int length)
101{
102 if ( length - ((startBit & 0x07) + 1) > 8 )
103 return true;
104 else
105 return false;
106}
107
108//////////////////////////////////////////////////////////////////////////
109// for Little Endian - Intel coding
110//------------------------------------------------------------------------
111// return true if the signal is spread on more than 2 bytes
112// ie if (length - (8 - startBit)) is greater than 8
113// example:
114// 7654 3210
115// 0 |... ....
116// 1 |||| ||||
117// 2 .... ..||
118// the start bit is 7 and the length is 11: result gives 11 - (8 - 7) = 10 (>8)
119//////////////////////////////////////////////////////////////////////////
120inline bool iSpreadOnMoreThan2Bytes(const unsigned int startBit, const unsigned int length)
121{
122 if ( length - (8 - (startBit & 0x07)) > 8 )
123 return true;
124 else
125 return false;
126}
127
128//////////////////////////////////////////////////////////////////////////
129// for Big Endian - Motorola coding
130//------------------------------------------------------------------------
131// return true if the signal is spread on more than 4 bytes
132// ie if length is greater than ((startBit%8) + 1)
133// example:
134// 7654 3210
135// 0 .... ..||
136// 1 |||| ||||
137// 2 |||| ||||
138// 3 |||| ||||
139// 4 |||. ....
140// startBit is 1 and the length is 29: result gives 29 - ((1%8)+1) = 27 (> 24)
141inline bool mSpreadOnMoreThan4Bytes(const unsigned int startBit, const unsigned int length)
142{
143 return (3*8) < (length - ((startBit & 0x07) + 1));
144}
145
146//////////////////////////////////////////////////////////////////////////
147// for Little Endian - Intel coding
148//------------------------------------------------------------------------
149// return true if the signal is spread on more than 4 bytes
150// ie if length is greater than 8-(startBit%8)
151// example:
152// 7654 3210
153// 0 ||.. ....
154// 1 |||| ||||
155// 2 |||| ||||
156// 3 |||| ||||
157// 4 .... ..||
158// startBit is 6 and the length is 28: result gives 28 - (8-((6%8))) = 26 (>24)
159inline bool iSpreadOnMoreThan4Bytes(const unsigned int startBit, const unsigned int length)
160{
161 return (3*8) < (length - (8 - (startBit & 0x07)));
162}
163
164//////////////////////////////////////////////////////////////////////////
165// return a 8-bits shifted-left mask corresponding to the length parameter
166// ex: shift = 2 and length = 3
167// mask will be 0b00011100
168inline unsigned char getShiftMask8(const unsigned int shift, const unsigned int length)
169{
170 unsigned char mask;
171 switch (length)
172 {
173 case 1: mask = 0x01; break;
174 case 2: mask = 0x03; break;
175 case 3: mask = 0x07; break;
176 case 4: mask = 0x0F; break;
177 case 5: mask = 0x1F; break;
178 case 6: mask = 0x3F; break;
179 case 7: mask = 0x7F; break;
180 case 8: mask = 0xFF; break;
181 default: mask = 0; break;
182 }
183 return mask << shift;
184}
185
186//////////////////////////////////////////////////////////////////////////
187// return a 8-bits mask corresponding to the length parameter with bit order decreasing
188// ex: startBit = 2 and length = 3
189// mask will be 0b00000111
190inline unsigned char getMask8( const unsigned int length )
191{
192 unsigned char mask;
193 switch (length) {
194 case 1: mask = 0x01; break;
195 case 2: mask = 0x03; break;
196 case 3: mask = 0x07; break;
197 case 4: mask = 0x0F; break;
198 case 5: mask = 0x1F; break;
199 case 6: mask = 0x3F; break;
200 case 7: mask = 0x7F; break;
201 case 8: mask = 0xFF; break;
202 default: mask = 0; break;
203 }
204 return mask;
205}
206
207//////////////////////////////////////////////////////////////////////////
208// return a 16-bits shifted-left mask corresponding to the length parameter
209inline unsigned short getShiftMask16(const unsigned int shift, const unsigned int length)
210{
211 unsigned short mask;
212 switch (length) {
213 case 1: mask = 0x0001; break;
214 case 2: mask = 0x0003; break;
215 case 3: mask = 0x0007; break;
216 case 4: mask = 0x000F; break;
217 case 5: mask = 0x001F; break;
218 case 6: mask = 0x003F; break;
219 case 7: mask = 0x007F; break;
220 case 8: mask = 0x00FF; break;
221 case 9: mask = 0x01FF; break;
222 case 10: mask = 0x03FF; break;
223 case 11: mask = 0x07FF; break;
224 case 12: mask = 0x0FFF; break;
225 case 13: mask = 0x1FFF; break;
226 case 14: mask = 0x3FFF; break;
227 case 15: mask = 0x7FFF; break;
228 case 16: mask = 0xFFFF; break;
229 default: mask = 0; break;
230 }
231 return mask << shift;
232}
233
234//////////////////////////////////////////////////////////////////////////
235// return a 16-bits mask corresponding to the length parameter with bit order decreasing
236inline unsigned short getMask16( const unsigned int length )
237{
238 unsigned short mask;
239 switch (length) {
240 case 1: mask = 0x0001; break;
241 case 2: mask = 0x0003; break;
242 case 3: mask = 0x0007; break;
243 case 4: mask = 0x000F; break;
244 case 5: mask = 0x001F; break;
245 case 6: mask = 0x003F; break;
246 case 7: mask = 0x007F; break;
247 case 8: mask = 0x00FF; break;
248 case 9: mask = 0x01FF; break;
249 case 10: mask = 0x03FF; break;
250 case 11: mask = 0x07FF; break;
251 case 12: mask = 0x0FFF; break;
252 case 13: mask = 0x1FFF; break;
253 case 14: mask = 0x3FFF; break;
254 case 15: mask = 0x7FFF; break;
255 case 16: mask = 0xFFFF; break;
256 default: mask = 0; break;
257 }
258 return mask;
259}
260
261//////////////////////////////////////////////////////////////////////////
262// return a 32-bits shifted-left mask corresponding to the length parameter
263inline unsigned long getShiftMask32(const unsigned int shift, const unsigned int length)
264{
265 unsigned long mask;
266 switch (length) {
267 case 1: mask = 0x00000001; break;
268 case 2: mask = 0x00000003; break;
269 case 3: mask = 0x00000007; break;
270 case 4: mask = 0x0000000F; break;
271 case 5: mask = 0x0000001F; break;
272 case 6: mask = 0x0000003F; break;
273 case 7: mask = 0x0000007F; break;
274 case 8: mask = 0x000000FF; break;
275 case 9: mask = 0x000001FF; break;
276 case 10: mask = 0x000003FF; break;
277 case 11: mask = 0x000007FF; break;
278 case 12: mask = 0x00000FFF; break;
279 case 13: mask = 0x00001FFF; break;
280 case 14: mask = 0x00003FFF; break;
281 case 15: mask = 0x00007FFF; break;
282 case 16: mask = 0x0000FFFF; break;
283 case 17: mask = 0x0001FFFF; break;
284 case 18: mask = 0x0003FFFF; break;
285 case 19: mask = 0x0007FFFF; break;
286 case 20: mask = 0x000FFFFF; break;
287 case 21: mask = 0x001FFFFF; break;
288 case 22: mask = 0x003FFFFF; break;
289 case 23: mask = 0x007FFFFF; break;
290 case 24: mask = 0x00FFFFFF; break;
291 case 25: mask = 0x01FFFFFF; break;
292 case 26: mask = 0x03FFFFFF; break;
293 case 27: mask = 0x07FFFFFF; break;
294 case 28: mask = 0x0FFFFFFF; break;
295 case 29: mask = 0x1FFFFFFF; break;
296 case 30: mask = 0x3FFFFFFF; break;
297 case 31: mask = 0x7FFFFFFF; break;
298 case 32: mask = 0xFFFFFFFF; break;
299 default: mask = 0; break;
300 }
301 return mask << shift;
302}
303
304//////////////////////////////////////////////////////////////////////////
305// return a 32-bits mask corresponding to the length parameter with bit order decreasing
306inline unsigned long getMask32( const unsigned int length )
307{
308 unsigned long mask;
309 switch (length) {
310 case 1: mask = 0x00000001; break;
311 case 2: mask = 0x00000003; break;
312 case 3: mask = 0x00000007; break;
313 case 4: mask = 0x0000000F; break;
314 case 5: mask = 0x0000001F; break;
315 case 6: mask = 0x0000003F; break;
316 case 7: mask = 0x0000007F; break;
317 case 8: mask = 0x000000FF; break;
318 case 9: mask = 0x000001FF; break;
319 case 10: mask = 0x000003FF; break;
320 case 11: mask = 0x000007FF; break;
321 case 12: mask = 0x00000FFF; break;
322 case 13: mask = 0x00001FFF; break;
323 case 14: mask = 0x00003FFF; break;
324 case 15: mask = 0x00007FFF; break;
325 case 16: mask = 0x0000FFFF; break;
326 case 17: mask = 0x0001FFFF; break;
327 case 18: mask = 0x0003FFFF; break;
328 case 19: mask = 0x0007FFFF; break;
329 case 20: mask = 0x000FFFFF; break;
330 case 21: mask = 0x001FFFFF; break;
331 case 22: mask = 0x003FFFFF; break;
332 case 23: mask = 0x007FFFFF; break;
333 case 24: mask = 0x00FFFFFF; break;
334 case 25: mask = 0x01FFFFFF; break;
335 case 26: mask = 0x03FFFFFF; break;
336 case 27: mask = 0x07FFFFFF; break;
337 case 28: mask = 0x0FFFFFFF; break;
338 case 29: mask = 0x1FFFFFFF; break;
339 case 30: mask = 0x3FFFFFFF; break;
340 case 31: mask = 0x7FFFFFFF; break;
341 case 32: mask = 0xFFFFFFFF; break;
342 default: mask = 0; break;
343 }
344 return mask;
345}
346
347//////////////////////////////////////////////////////////////////////////
348// return a 64-bits mask corresponding to the length parameter with bit order decreasing
349inline unsigned long long getMask64( const unsigned int length )
350{
351 unsigned long long mask;
352 switch (length) {
353 case 1: mask = 0x0000000000000001ULL; break;
354 case 2: mask = 0x0000000000000003ULL; break;
355 case 3: mask = 0x0000000000000007ULL; break;
356 case 4: mask = 0x000000000000000FULL; break;
357 case 5: mask = 0x000000000000001FULL; break;
358 case 6: mask = 0x000000000000003FULL; break;
359 case 7: mask = 0x000000000000007FULL; break;
360 case 8: mask = 0x00000000000000FFULL; break;
361 case 9: mask = 0x00000000000001FFULL; break;
362 case 10: mask = 0x00000000000003FFULL; break;
363 case 11: mask = 0x00000000000007FFULL; break;
364 case 12: mask = 0x0000000000000FFFULL; break;
365 case 13: mask = 0x0000000000001FFFULL; break;
366 case 14: mask = 0x0000000000003FFFULL; break;
367 case 15: mask = 0x0000000000007FFFULL; break;
368 case 16: mask = 0x000000000000FFFFULL; break;
369 case 17: mask = 0x000000000001FFFFULL; break;
370 case 18: mask = 0x000000000003FFFFULL; break;
371 case 19: mask = 0x000000000007FFFFULL; break;
372 case 20: mask = 0x00000000000FFFFFULL; break;
373 case 21: mask = 0x00000000001FFFFFULL; break;
374 case 22: mask = 0x00000000003FFFFFULL; break;
375 case 23: mask = 0x00000000007FFFFFULL; break;
376 case 24: mask = 0x0000000000FFFFFFULL; break;
377 case 25: mask = 0x0000000001FFFFFFULL; break;
378 case 26: mask = 0x0000000003FFFFFFULL; break;
379 case 27: mask = 0x0000000007FFFFFFULL; break;
380 case 28: mask = 0x000000000FFFFFFFULL; break;
381 case 29: mask = 0x000000001FFFFFFFULL; break;
382 case 30: mask = 0x000000003FFFFFFFULL; break;
383 case 31: mask = 0x000000007FFFFFFFULL; break;
384 case 32: mask = 0x00000000FFFFFFFFULL; break;
385 case 33: mask = 0x00000001FFFFFFFFULL; break;
386 case 34: mask = 0x00000003FFFFFFFFULL; break;
387 case 35: mask = 0x00000007FFFFFFFFULL; break;
388 case 36: mask = 0x0000000FFFFFFFFFULL; break;
389 case 37: mask = 0x0000001FFFFFFFFFULL; break;
390 case 38: mask = 0x0000003FFFFFFFFFULL; break;
391 case 39: mask = 0x0000007FFFFFFFFFULL; break;
392 case 40: mask = 0x000000FFFFFFFFFFULL; break;
393 case 41: mask = 0x000001FFFFFFFFFFULL; break;
394 case 42: mask = 0x000003FFFFFFFFFFULL; break;
395 case 43: mask = 0x000007FFFFFFFFFFULL; break;
396 case 44: mask = 0x00000FFFFFFFFFFFULL; break;
397 case 45: mask = 0x00001FFFFFFFFFFFULL; break;
398 case 46: mask = 0x00003FFFFFFFFFFFULL; break;
399 case 47: mask = 0x00007FFFFFFFFFFFULL; break;
400 case 48: mask = 0x0000FFFFFFFFFFFFULL; break;
401 case 49: mask = 0x0001FFFFFFFFFFFFULL; break;
402 case 50: mask = 0x0003FFFFFFFFFFFFULL; break;
403 case 51: mask = 0x0007FFFFFFFFFFFFULL; break;
404 case 52: mask = 0x000FFFFFFFFFFFFFULL; break;
405 case 53: mask = 0x001FFFFFFFFFFFFFULL; break;
406 case 54: mask = 0x003FFFFFFFFFFFFFULL; break;
407 case 55: mask = 0x007FFFFFFFFFFFFFULL; break;
408 case 56: mask = 0x00FFFFFFFFFFFFFFULL; break;
409 case 57: mask = 0x01FFFFFFFFFFFFFFULL; break;
410 case 58: mask = 0x03FFFFFFFFFFFFFFULL; break;
411 case 59: mask = 0x07FFFFFFFFFFFFFFULL; break;
412 case 60: mask = 0x0FFFFFFFFFFFFFFFULL; break;
413 case 61: mask = 0x1FFFFFFFFFFFFFFFULL; break;
414 case 62: mask = 0x3FFFFFFFFFFFFFFFULL; break;
415 case 63: mask = 0x7FFFFFFFFFFFFFFFULL; break;
416 case 64: mask = 0xFFFFFFFFFFFFFFFFULL; break;
417 default: mask = 0; break;
418 }
419 return mask;
420}
421
422//////////////////////////////////////////////////////////////////////////
423/// Returns a 64-bits shifted-left mask corresponding to the length parameter
424inline unsigned long long getShiftMask64(const unsigned int shift, const unsigned int length)
425{
426 unsigned long long mask;
427 mask = getMask64( length );
428 mask <<= shift;
429 return mask;
430}
431
432//////////////////////////////////////////////////////////////////////////
433/// Big Endian - Motorola coding
434inline bool mDecodeToBool(const unsigned char * data, const unsigned int startBit)
435{
436 return (data[startBit>>3] & getShiftMask8(startBit&0x07,1)) != 0;
437}
438
439//////////////////////////////////////////////////////////////////////////
440// Big Endian - Motorola coding
441// to test ?
442inline bool mDecodeToUI64(unsigned long long * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
443{
444 if (length > 64) {
445 *result = 0;
446 return false;
447 }
448
449 if (length == 64) {
450 // only work if data are correctly byte-aligned
451 unsigned char c[8]; // c[0] = MSB
452 for (int i = 0 ; i < 8 ; i++)
453 c[i] = data[(startBit>>3) + i];
454
455 unsigned long long temp = 0;
456 for (int i = 0 ; i < 8 ; i++)
457 temp += (c[i] << ( 56 - (8*i) ) );
458 *result = temp;
459 return true;
460 } else {
461 unsigned char c[8], mask[8], nbBits[8]; // MSB = c[0]
462 nbBits[0] = (startBit & 0x07)+1;
463 mask[0] = getMask8( nbBits[0] );
464 c[0] = data[startBit>>3] & mask[0];
465 unsigned short nbBitsIncrement = nbBits[0];
466 for (int i = 1 ; i < 8 ; i++) {
467 nbBits[i] = static_cast<unsigned char>( (length - nbBitsIncrement) < 8 ? length - nbBitsIncrement : 8 );
468 nbBitsIncrement += nbBits[i];
469 mask[i] = getShiftMask8(8 - nbBits[i],nbBits[i]);
470 c[i] = data[(startBit>>3) + i] & mask[i];
471 }
472
473 unsigned long long temp = 0;
474 for (int i = 0 ; i < 8 ; i++)
475 temp += (c[i] << ( 56 - (8*i) ) );
476 *result = temp >> (56 + (startBit&0x07) + 1 - length);
477 return true;
478 }
479}
480
481//////////////////////////////////////////////////////////////////////////
482// Big Endian - Motorola coding
483// to test ?
484inline bool mDecodeToI64(long long *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
485{
486 if (length>64) {
487 *result = 0;
488 return false;
489 }
490
491 if (length == 64) {
492 // only work if data are correctly byte-aligned
493 unsigned char c[8]; // c[0] = MSB
494 for (int i = 0 ; i < 8 ; i++)
495 c[i] = data[(startBit>>3) + i];
496
497 for (int i = 0 ; i < 8 ; i++)
498 *result += (c[i] << ( 56 - (8*i) ) );
499
500 // need to be signed ??
501 return true;
502 } else {
503 unsigned char c[8], mask[8], nbBits[8]; // MSB = c[0]
504 nbBits[0] = (startBit & 0x07)+1;
505 mask[0] = getMask8( nbBits[0] );
506 c[0] = data[startBit>>3] & mask[0];
507 unsigned short nbBitsIncrement = nbBits[0];
508 for (int i = 1 ; i < 8 ; i++) {
509 nbBits[i] = static_cast<unsigned char>( (length - nbBitsIncrement) < 8 ? (length - nbBitsIncrement) : 8 );
510 nbBitsIncrement += nbBits[i];
511 mask[i] = getShiftMask8(8 - nbBits[i],nbBits[i]);
512 c[i] = data[(startBit>>3) + i] & mask[i];
513 }
514 unsigned long long temp = 0;
515 for (int i = 0 ; i < 8 ; i++)
516 temp += (c[i] << ( 56 - (8*i) ) );
517 temp >>= (56 + (startBit&0x07) + 1 - length);
518
519 if ( temp & getShiftMask64(length-1,1) )
520 // do the two's complement to get the signed value if the msb=1
521 *result = -1 * ( ( (~temp) + 1 ) & getMask64(length) );
522 else
523 *result = temp;
524
525 return true;
526 }
527}
528
529//////////////////////////////////////////////////////////////////////////
530// Big Endian - Motorola coding
531// ok
532inline bool mDecodeToUI32(unsigned long *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
533{
534 if (length>32) {
535 *result = 0;
536 return false;
537 }
538
539 // verify that the frame is not spread in 5 bytes
540 if (mSpreadOnMoreThan4Bytes(startBit, length)) {
541 // decode in a 64-bits integer
542 unsigned long long temp;
543 if (mDecodeToUI64(&temp,data,startBit,length))
544 {
545 *result = static_cast<unsigned long> (temp);
546 return true;
547 } else {
548 *result = 0;
549 return false;
550 }
551 } else {
552 if (length == 32) {
553 // only work if data are correctly byte-aligned
554 unsigned char c1, c2, c3, c4;
555 c1 = data[startBit>>3];
556 c2 = data[(startBit>>3) + 1];
557 c3 = data[(startBit>>3) + 2];
558 c4 = data[(startBit>>3) + 3];
559
560 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
561 return true;
562 } else {
563 unsigned char c[4], mask[4], nbBits[4]; // MSB = c[0]
564 nbBits[0] = (startBit & 0x07)+1;
565 nbBits[1] = static_cast<unsigned char>( (length - nbBits[0]) < 8 ? length - nbBits[0] : 8 );
566 nbBits[2] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1]) < 8 ? (length - nbBits[0] - nbBits[1]) : 8 );
567 nbBits[3] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1] - nbBits[2]) < 8 ? (length - nbBits[0] - nbBits[1] - nbBits[2]) : 8 );
568 mask[0] = getMask8( nbBits[0] );
569 mask[1] = getShiftMask8(8 - nbBits[1],nbBits[1]);
570 mask[2] = getShiftMask8(8 - nbBits[2],nbBits[2]);
571 mask[3] = getShiftMask8(8 - nbBits[3],nbBits[3]);
572 c[0] = data[startBit>>3] & mask[0];
573 c[1] = data[(startBit>>3) + 1] & mask[1];
574 c[2] = data[(startBit>>3) + 2] & mask[2];
575 c[3] = data[(startBit>>3) + 3] & mask[3];
576 *result = ( (c[0]<<24) + (c[1]<<16) + (c[2]<<8) + c[3]) >> (24 + (startBit&0x07) + 1 - length);
577 return true;
578 }
579 }
580}
581
582//////////////////////////////////////////////////////////////////////////
583// Big Endian - Motorola coding
584// ok
585inline bool mDecodeToI32(long *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
586{
587 if (length>32) {
588 *result = 0;
589 return false;
590 }
591
592 // verify that the frame is not spread in 5 bytes
593 if (mSpreadOnMoreThan4Bytes(startBit, length)) {
594 // decode in a 64-bits integer
595 long long temp;
596 if (mDecodeToI64(&temp,data,startBit,length))
597 {
598 *result = static_cast<long>(temp);
599 return true;
600 } else {
601 *result = 0;
602 return false;
603 }
604 } else {
605 if (length == 32)
606 {
607 // only work if data are correctly byte-aligned
608 unsigned char c1, c2, c3, c4;
609 c1 = data[startBit>>3];
610 c2 = data[(startBit>>3) + 1];
611 c3 = data[(startBit>>3) + 2];
612 c4 = data[(startBit>>3) + 3];
613
614 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
615 return true;
616 } else {
617 unsigned char c[4], mask[4], nbBits[4]; // MSB = c[0]
618 nbBits[0] = (startBit & 0x07) + 1;
619 nbBits[1] = static_cast<unsigned char>( (length - nbBits[0]) < 8 ? length - nbBits[0] : 8 );
620 nbBits[2] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1]) < 8 ? (length - nbBits[0] - nbBits[1]) : 8 );
621 nbBits[3] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1] - nbBits[2]) < 8 ? length - nbBits[0] - nbBits[1] - nbBits[2] : 8 );
622 mask[0] = getMask8( nbBits[0] );
623 mask[1] = getShiftMask8(8 - nbBits[1],nbBits[1]);
624 mask[2] = getShiftMask8(8 - nbBits[2],nbBits[2]);
625 mask[3] = getShiftMask8(8 - nbBits[3],nbBits[3]);
626 c[0] = data[startBit>>3] & mask[0];
627 c[1] = data[(startBit>>3) + 1] & mask[1];
628 c[2] = data[(startBit>>3) + 2] & mask[2];
629 c[3] = data[(startBit>>3) + 3] & mask[3];
630
631 unsigned long temp = ( (c[0]<<24) + (c[1]<<16) + (c[2]<<8) + c[3]) >> (24 + (startBit&0x07) + 1 - length);
632 if (temp & getShiftMask32(length-1, 1))
633 // do the two's complement to get the signed value if the msb=1
634 *result = -1 * ( ( (~temp) + 1 ) & getMask32(length) );
635 else
636 *result = temp;
637 return true;
638 }
639 }
640}
641
642
643
644//////////////////////////////////////////////////////////////////////////
645// Big Endian - Motorola coding
646// ok
647inline bool mDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
648{
649 if (length > 16) {
650 *result = 0;
651 return false;
652 }
653
654 // verify that the frame is not spread in 3 bytes
655 if (mSpreadOnMoreThan2Bytes(startBit, length)) {
656 // decode in a 32-bits integer
657 unsigned long temp;
658 if (mDecodeToUI32(&temp,data,startBit,length)) {
659 *result = static_cast<unsigned short>(temp);
660 return true;
661 } else {
662 *result = 0;
663 return false;
664 }
665 } else {
666 if (length == 16) {
667 // only work if data are correctly byte-aligned
668 unsigned char LSB, MSB;
669 MSB = data[startBit>>3];
670 LSB = data[(startBit>>3) + 1];
671
672 *result = ( (MSB << 8) + LSB );
673 return true;
674 } else {
675 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
676 nbBitsMSB = (startBit & 0x07) + 1; // the number of bits contained in the MSB
677 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
678 maskMSB = getMask8( nbBitsMSB );
679 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
680 MSB = data[startBit>>3] & maskMSB;
681 LSB = data[(startBit>>3) + 1] & maskLSB;
682
683 *result = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
684 return true;
685 }
686 }
687}
688
689//////////////////////////////////////////////////////////////////////////
690// Big Endian - Motorola coding
691// ok
692inline bool mDecodeToI16(short *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
693{
694 if (length > 16) {
695 *result = 0;
696 return false;
697 }
698
699 // verify that the frame is not spread in 3 bytes
700 if (mSpreadOnMoreThan2Bytes(startBit, length)) {
701 // decode in a 32-bits integer
702 long temp;
703 if (mDecodeToI32(&temp, data, startBit, length)) {
704 *result = (short)temp;
705 return true;
706 } else {
707 *result = 0;
708 return false;
709 }
710 } else {
711 // ok data are stored at most in 2 bytes
712 if (length == 16) {
713 // only work if data are correctly byte-aligned
714 unsigned char LSB, MSB;
715 MSB = data[startBit>>3];
716 LSB = data[(startBit>>3) + 1];
717 short temp = (MSB << 8) + LSB;
718
719 // Attention : a-t on besoin d'appliquer le signe ?
720 // n'est-il pas deja inclu dans la donn�e comme elle est correctement align�e sur l'octet ?
721 if (temp & 0x8000) {
722 // do the two's complement to get the signed value
723 *result = - ( ( (~temp) + 1 ) & 0xFFFF );
724 } else {
725 *result = temp;
726 }
727 return true;
728 } else {
729 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
730 nbBitsMSB = (startBit & 0x07) + 1; // the number of bits contained in the MSB
731 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
732 maskMSB = getMask8( nbBitsMSB );
733 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
734 MSB = data[startBit>>3] & maskMSB;
735 LSB = data[(startBit>>3) + 1] & maskLSB;
736 // assign the MSB and LSB char in the short integer value and right-shift
737 // to place the lsb to the bit 0
738 unsigned short temp = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
739 if (temp & getShiftMask16(length-1,1))
740 // do the two's complement to get the signed value if the msb=1
741 *result = -1 * ( ( (~temp) + 1 ) & getMask16(length) );
742 else
743 *result = temp;
744 return true;
745 }
746 }
747}
748
749//////////////////////////////////////////////////////////////////////////
750// Big Endian - Motorola coding
751// OK
752inline bool mDecodeToUI8(unsigned char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
753{
754 if (length > 8) {
755 *result = 0;
756 return false;
757 }
758
759 // verify that the frame is not spread in 2 bytes
760 if (mSpreadOnMoreThan1Byte(startBit, length)) {
761 // decode in a 16-bit integer
762 unsigned short temp;
763 if ( mDecodeToUI16(&temp, data, startBit, length) ) {
764 *result = static_cast<unsigned char>(temp);
765 return true;
766 } else {
767 *result = 0;
768 return true;
769 }
770 } else {
771 // ok data is stored at most in 1 byte
772 unsigned char c;
773 c = data[startBit>>3]; // >>3 <=> div 8
774 c >>= (8-((startBit & 0x07)+1)); // &0x07 <=> modulo 8
775 *result = c & getMask8( length );
776
777 return true;
778 }
779}
780
781//////////////////////////////////////////////////////////////////////////
782// Big Endian - Motorola coding
783// OK
784inline bool mDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
785{
786 if (length > 8) {
787 *result = 0;
788 return false;
789 }
790
791 // verify that the frame is not spread in 2 bytes
792 if (mSpreadOnMoreThan1Byte(startBit, length)) {
793 // decode in a 16-bit integer
794 short temp;
795 if ( mDecodeToI16(&temp, data, startBit, length) ) {
796 *result = static_cast<char>(temp);
797 return true;
798 } else {
799 *result = 0;
800 return true;
801 }
802 }
803 else {
804 // ok data is stored at most in 1 byte
805 char c;
806 c = data[startBit>>3];
807 c >>= (8-((startBit & 0x07)+1));
808 c = c & getMask8( length );
809
810 // a-t-on besoin d'appliquer le signe dans le cas ou length = 8
811 // la donnee est correctement alignee sur l'octet donc le signe est peut-etre compris
812 if (c & getShiftMask8(length-1,1))
813 // do the two's complement to get the signed value if the msb=1
814 *result = - ( ( (~c) + 1 ) & getMask8(length) );
815 else
816 *result = c;
817 return true;
818 }
819}
820
821//////////////////////////////////////////////////////////////////////////
822// Little Endian - Intel coding
823// ok
824inline bool iDecodeToBool(const unsigned char * data, const unsigned int startBit)
825{
826 mDecodeToBool(data, startBit);
827}
828
829//////////////////////////////////////////////////////////////////////////
830// Little Endian - Intel coding
831// pas de depassement possible - la trame CAN fait 64 bits max
832// gerer le signe
833inline bool iDecodeToUI64(unsigned long long * /*result*/, const unsigned char * /*data*/, const unsigned int /*startBit*/, const unsigned int /*length*/)
834{
835 return true;
836}
837
838//////////////////////////////////////////////////////////////////////////
839// Little Endian - Intel coding
840// pas de depassement possible - la trame CAN fait 64 bits max
841// gerer le signe
842inline bool iDecodeToI64(long long * /*result*/, const unsigned char * /*data*/, const unsigned int /*startBit*/, const unsigned int /*length*/)
843{
844 return true;
845}
846
847//////////////////////////////////////////////////////////////////////////
848// Little Endian - Intel coding
849// gerer le depassement sur plus de 4 octets : necessite la fonction de decodage 64 bits
850// verifier le depassement avant cette ligne : if (length == 32)
851inline bool iDecodeToUI32(unsigned long * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
852{
853 if (length>32) {
854 *result = 0;
855 return false;
856 }
857
858 if (length == 32) {
859 // only work if length == 32
860 unsigned char c1, c2, c3, c4;
861 c4 = data[startBit>>3]; // LSB
862 c3 = data[(startBit>>3) + 1];
863 c2 = data[(startBit>>3) + 2];
864 c1 = data[(startBit>>3) + 3]; // MSB
865
866 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
867 return true;
868 } else {
869 // todo
870 *result = 0;
871 return false;
872 }
873}
874
875//////////////////////////////////////////////////////////////////////////
876// Little Endian - Intel coding
877// gerer le signe
878// gerer le depassement sur plus de 4 octets : necessite la fonction de decodage 64 bits
879// verifier le depassement avant cette ligne : if (length == 32)
880inline bool iDecodeToI32(long * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
881{
882 if (length>32) {
883 *result = 0;
884 return false;
885 }
886
887 if (length == 32) {
888 // only work if length == 32
889 unsigned char c1, c2, c3, c4;
890 c4 = data[startBit>>3]; // LSB
891 c3 = data[(startBit>>3) + 1];
892 c2 = data[(startBit>>3) + 2];
893 c1 = data[(startBit>>3) + 3]; // MSB
894
895 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
896 return true;
897 } else {
898 // todo
899 *result = 0;
900 return false;
901 }
902}
903
904//////////////////////////////////////////////////////////////////////////
905// Little Endian - Intel coding
906// gerer le depassement sur plus de 2 octets
907// verifier le depassement avant cette ligne : if (length == 16)
908inline bool iDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
909{
910 if (length > 16) {
911 *result = 0;
912 return false;
913 }
914
915 if (length == 16) {
916 // only work if length == 16
917 unsigned char LSB, MSB;
918 LSB = data[startBit>>3];
919 MSB = data[(startBit>>3) + 1];
920
921 *result = (MSB << 8) + LSB;
922 return true;
923 } else {
924 // TODO
925 *result = 0;
926 return false;
927 }
928}
929
930//////////////////////////////////////////////////////////////////////////
931// Little Endian - Intel coding
932// gerer le signe
933// gerer le depassement sur plus de 2 octets
934// verifier le depassement avant cette ligne : if (length == 16)
935// manque le decalage
936inline bool iDecodeToI16(short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
937{
938 if (length > 16) {
939 *result = 0;
940 return false;
941 }
942
943 if (length == 16) {
944 // only work if length == 16
945 unsigned char LSB, MSB;
946 LSB = data[startBit>>3];
947 MSB = data[(startBit>>3) + 1];
948
949 *result = (MSB << 8) + LSB;
950 return true;
951 } else {
952 // todo
953 *result = 0;
954 return false;
955 }
956}
957
958//////////////////////////////////////////////////////////////////////////
959// Little Endian - Intel coding
960// OK
961inline bool iDecodeToUI8(unsigned char * result,const unsigned char * data, const unsigned int startBit, const unsigned int length)
962{
963 if (length > 8) {
964 *result = 0;
965 return false;
966 }
967
968 // verify that the frame is not spread in 2 bytes
969 if (iSpreadOnMoreThan1Byte(startBit, length)) {
970 // decode in a 16-bit integer
971 unsigned short temp;
972 if ( iDecodeToUI16(&temp, data, startBit, length) ) {
973 // and cast in an 8 bit integer
974 *result = (unsigned char) temp;
975 return true;
976 } else {
977 *result = 0;
978 return true;
979 }
980 } else {
981 // ok data is stored at most in 1 byte
982 unsigned char c;
983 c = data[startBit>>3];
984 c >>= (startBit & 0x07);
985 *result = c & getMask8( length );
986
987 return true;
988 }
989}
990
991//////////////////////////////////////////////////////////////////////////
992// Little Endian - Intel coding
993// OK
994inline bool iDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
995{
996 if (length > 8) {
997 *result = 0;
998 return false;
999 }
1000
1001 // verify that the frame is not spread in 2 bytes
1002 if (iSpreadOnMoreThan1Byte(startBit, length)) {
1003 // decode in a 16-bit integer
1004 short temp;
1005 if ( iDecodeToI16(&temp, data, startBit, length) ) {
1006 // and cast in an 8 bit integer
1007 *result = static_cast<char>(temp);
1008 return true;
1009 } else {
1010 *result = 0;
1011 return true;
1012 }
1013 } else {
1014 // ok data is stored at most in 1 byte
1015 char c;
1016 c = data[startBit>>3]; // >>3 <=> div 8
1017 c >>= (startBit & 0x07); // &0x07 <=> modulo 8
1018 c = c & getMask8( length );
1019 if (c & getShiftMask8(length-1,1))
1020 // do the two's complement to get the signed value if the msb=1
1021 *result = - ( ( (~c) + 1 ) & getMask8(length) );
1022 else
1023 *result = c;
1024
1025 return true;
1026 }
1027}
1028
1029//////////////////////////////////////////////////////////////////////////
1030// Big Endian - Motorola coding
1031// ok
1032inline bool mobileyemDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1033{
1034 if (length>16){ *result = 0; return false; }
1035
1036 // verify that the frame is not spread in 3 bytes
1037 /* if (mSpreadOnMoreThan2Bytes(startBit, length))
1038 {
1039 // decode in a 32-bits integer
1040 unsigned long temp;
1041 if (mDecodeToUI32(&temp,data,startBit,length))
1042 {
1043 *result = static_cast<unsigned short>(temp);
1044 return true;
1045 } else {
1046 *result = 0;
1047 return false;
1048 }
1049 }
1050 else
1051 {*/
1052 if (length == 16) {
1053 // only work if data are correctly byte-aligned
1054 unsigned char LSB, MSB;
1055 MSB = data[startBit>>3];
1056 LSB = data[(startBit>>3) + 1];
1057
1058 *result = ( (MSB << 8) + LSB );
1059 return true;
1060 } else {
1061 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1062 nbBitsMSB = (startBit & 0x07) + 1; // the number of bits contained in the MSB
1063 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
1064 maskMSB = getMask8( nbBitsMSB );
1065 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1066 MSB = data[startBit>>3] & maskMSB;
1067 LSB = data[(startBit>>3) + 1] & maskLSB;
1068
1069 *result = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
1070 return true;
1071 }
1072 //}
1073}
1074
1075//////////////////////////////////////////////////////////////////////////
1076// Big Endian - Motorola coding
1077// ok
1078inline bool mobileyemDecodeToI16(short *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1079{
1080 if (length>16) { *result = 0; return false; }
1081
1082 // verify that the frame is not spread in 3 bytes
1083 /* if (mSpreadOnMoreThan2Bytes(startBit, length))
1084 {
1085 // decode in a 32-bits integer
1086 long temp;
1087 if (mDecodeToI32(&temp, data, startBit, length)) {
1088 *result = (short)temp;
1089 return true;
1090 } else {
1091 *result = 0;
1092 return false;
1093 }
1094 }
1095 else // ok data are stored at most in 2 bytes
1096 {*/
1097 if (length == 16)
1098 {
1099 // only work if data are correctly byte-aligned
1100 unsigned char LSB, MSB;
1101 MSB = data[startBit>>3];
1102 LSB = data[(startBit>>3) + 1];
1103 short temp = (MSB << 8) + LSB;
1104
1105 // Attention : a-t on besoin d'appliquer le signe ?
1106 // n'est-il pas deja inclu dans la donn�e comme elle est correctement align�e sur l'octet ?
1107 if (temp & 0x8000) {
1108 // do the two's complement to get the signed value
1109 *result = - ( ( (~temp) + 1 ) & 0xFFFF );
1110 } else {
1111 *result = temp;
1112 }
1113 return true;
1114 } else {
1115 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1116 nbBitsMSB = (startBit & 0x07)+1; // the number of bits contained in the MSB
1117 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
1118 maskMSB = getMask8( nbBitsMSB );
1119 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1120 MSB = data[startBit>>3] & maskMSB;
1121 LSB = data[(startBit>>3) + 1] & maskLSB;
1122 // assign the MSB and LSB char in the short integer value and right-shift
1123 // to place the lsb to the bit 0
1124 unsigned short temp = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
1125 if (temp & getShiftMask16(length-1,1))
1126 // do the two's complement to get the signed value if the msb=1
1127 *result = -1 * ( ( (~temp) + 1 ) & getMask16(length) );
1128 else
1129 *result = temp;
1130 return true;
1131 }
1132 //}
1133}
1134
1135//////////////////////////////////////////////////////////////////////////
1136// Big Endian - Motorola coding
1137// OK
1138inline bool mobileyemDecodeToUI8(unsigned char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1139{
1140 if (length>8) { *result = 0; return false; }
1141
1142 // verify that the frame is not spread in 2 bytes
1143 if (mSpreadOnMoreThan1Byte(startBit, length))
1144 {
1145 // decode in a 16-bit integer
1146 unsigned short temp;
1147 if ( mDecodeToUI16(&temp, data, startBit, length) ) {
1148 *result = static_cast<unsigned char>(temp);
1149 return true;
1150 } else {
1151 *result = 0;
1152 return true;
1153 }
1154 }
1155 else // ok data is stored at most in 1 byte
1156 {
1157 unsigned char c;
1158 c = data[startBit>>3]; // >>3 <=> div 8
1159 c >>= (8-((startBit & 0x07)+1)); // &0x07 <=> modulo 8
1160 *result = c & getMask8( length );
1161
1162 return true;
1163 }
1164}
1165
1166//////////////////////////////////////////////////////////////////////////
1167// Big Endian - Motorola coding
1168// OK
1169inline bool mobileyemDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1170{
1171 if (length>8) { *result = 0; return false; }
1172
1173 // verify that the frame is not spread in 2 bytes
1174 if (mSpreadOnMoreThan1Byte(startBit, length))
1175 {
1176 // decode in a 16-bit integer
1177 short temp;
1178 if ( mDecodeToI16(&temp, data, startBit, length) ) {
1179 *result = static_cast<char>(temp);
1180 return true;
1181 } else {
1182 *result = 0;
1183 return true;
1184 }
1185 }
1186 else // ok data is stored at most in 1 byte
1187 {
1188 char c;
1189 c = data[startBit>>3];
1190 c >>= (8-((startBit & 0x07)+1));
1191 c = c & getMask8( length );
1192
1193 // a-t-on besoin d'appliquer le signe dans le cas ou length = 8
1194 // la donnee est correctement alignee sur l'octet donc le signe est peut-etre compris
1195 if (c & getShiftMask8(length-1,1))
1196 // do the two's complement to get the signed value if the msb=1
1197 *result = - ( ( (~c) + 1 ) & getMask8(length) );
1198 else
1199 *result = c;
1200 return true;
1201 }
1202}
1203
1204//////////////////////////////////////////////////////////////////////////
1205// Little Endian - Intel coding
1206// OK, mais gerer le depassement sur plus de 2 octets
1207inline bool mobileyeiDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1208{
1209 if (length>16) {
1210 *result = 0;
1211 return false;
1212 }
1213
1214 if (length == 16) {
1215 // only work if length == 16
1216 unsigned char LSB, MSB;
1217 LSB = data[startBit>>3];
1218 MSB = data[(startBit>>3) + 1];
1219
1220 *result = (unsigned short)((MSB << 8) + LSB);
1221 return true;
1222 } else {
1223 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1224
1225 nbBitsLSB = static_cast<unsigned char>(8*((startBit>>3) + 1) - startBit);
1226 nbBitsMSB = static_cast<unsigned char>(length - nbBitsLSB);
1227 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1228 maskMSB = getMask8( nbBitsMSB );
1229 LSB = data[startBit>>3] & maskLSB;
1230 MSB = data[(startBit>>3) + 1] & maskMSB;
1231
1232 *result = (unsigned short)((MSB<<8) + (LSB>>(startBit-8*(startBit>>3))));
1233
1234 return true;
1235 }
1236}
1237
1238//////////////////////////////////////////////////////////////////////////
1239// Little Endian - Intel coding
1240// gerer le signe
1241// gerer le depassement sur plus de 2 octets
1242// verifier le depassement avant cette ligne : if (length == 16)
1243// manque le decalage
1244inline bool mobileyeiDecodeToI16(short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1245{
1246 if (length > 16) {
1247 *result = 0;
1248 return false;
1249 }
1250
1251 if (length == 16) {
1252 // only work if length == 16
1253 unsigned char LSB, MSB;
1254 LSB = data[startBit>>3];
1255 MSB = data[(startBit>>3) + 1];
1256
1257 short temp = (MSB << 8) + LSB;
1258
1259 if (temp & 0x8000) {
1260 // do the two's complement to get the signed value
1261 *result = - ( ( (~temp) + 1 ) & 0xFFFF );
1262 } else {
1263 *result = temp;
1264 }
1265 return true;
1266 } else {
1267 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1268
1269 nbBitsLSB = static_cast<unsigned char>(8*((startBit>>3) + 1) - startBit);
1270 nbBitsMSB = static_cast<unsigned char>(length - nbBitsLSB);
1271 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1272 maskMSB = getMask8( nbBitsMSB );
1273 LSB = data[startBit>>3] & maskLSB;
1274 MSB = data[(startBit>>3) + 1] & maskMSB;
1275
1276 unsigned short temp = (unsigned short)((MSB<<8) + (LSB>>(startBit-8*(startBit>>3))));
1277
1278 if (temp & getShiftMask16(length-1,1))
1279 // do the two's complement to get the signed value if the msb=1
1280 *result = -1 * ( ( (~temp) + 1 ) & getMask16(length) );
1281 else
1282 *result = temp;
1283 return true;
1284 }
1285}
1286
1287//////////////////////////////////////////////////////////////////////////
1288// Little Endian - Intel coding
1289// OK
1290inline bool mobileyeiDecodeToUI8(unsigned char * result,const unsigned char * data, const unsigned int startBit, const unsigned int length)
1291{
1292 if (length>8) { *result = 0; return false; }
1293
1294 // verify that the frame is not spread in 2 bytes
1295 if (iSpreadOnMoreThan1Byte(startBit, length))
1296 {
1297 // decode in a 16-bit integer
1298 unsigned short temp;
1299 if ( iDecodeToUI16(&temp, data, startBit, length) )
1300 {
1301 // and cast in an 8 bit integer
1302 *result = (unsigned char) temp;
1303 return true;
1304 }
1305 else
1306 {
1307 *result = 0;
1308 return true;
1309 }
1310 }
1311 else // ok data is stored at most in 1 byte
1312 {
1313 unsigned char c;
1314 c = data[startBit>>3];
1315 c >>= (startBit & 0x07);
1316 *result = c & getMask8( length );
1317
1318 return true;
1319 }
1320
1321}
1322
1323//////////////////////////////////////////////////////////////////////////
1324// Little Endian - Intel coding
1325// OK
1326inline bool mobileyeiDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1327{
1328 if (length > 8) {
1329 *result = 0;
1330 return false;
1331 }
1332
1333 // verify that the frame is not spread in 2 bytes
1334 if (iSpreadOnMoreThan1Byte(startBit, length)) {
1335 // decode in a 16-bit integer
1336 short temp;
1337 if ( iDecodeToI16(&temp, data, startBit, length) ) {
1338 // and cast in an 8 bit integer
1339 *result = (char)(temp);
1340 return true;
1341 } else {
1342 *result = 0;
1343 return true;
1344 }
1345 } else {
1346 // ok data is stored at most in 1 byte
1347 char c;
1348 c = data[startBit>>3]; // >>3 <=> div 8
1349 c >>= (startBit & 0x07); // &0x07 <=> modulo 8
1350 c = c & getMask8( length );
1351 if (c & getShiftMask8(length-1,1))
1352 // do the two's complement to get the signed value if the msb=1
1353 *result = - ( ( (~c) + 1 ) & getMask8(length) );
1354 else
1355 *result = c;
1356
1357 return true;
1358 }
1359}
1360
1361inline int mobileyeDecodeCAN(unsigned char *data,unsigned char bigEndian,unsigned int startBit,unsigned int length,unsigned char Signed)
1362{
1363 int value;
1364 unsigned short ustemp16 = 0;
1365 unsigned char uctemp8 = 0;
1366 short stemp16 = 0;
1367 char ctemp8 = 0;
1368
1369 if(bigEndian) {
1370 if(length>8){
1371 if(Signed){mobileyemDecodeToI16(&stemp16,data, startBit, length);value = stemp16;}
1372 else {mobileyemDecodeToUI16(&ustemp16,data, startBit, length);value = ustemp16;}}
1373 else if(Signed) {mobileyemDecodeToI8(&ctemp8,data, startBit, length);value = ctemp8;}
1374 else {mobileyemDecodeToUI8(&uctemp8,data, startBit, length);value = uctemp8;}
1375 } else {
1376 if(length>8){
1377 if(Signed) {mobileyeiDecodeToI16(&stemp16,data, startBit, length);value = stemp16;}
1378 else {mobileyeiDecodeToUI16(&ustemp16,data, startBit, length);value = ustemp16;}}
1379 else if(Signed) {mobileyeiDecodeToI8(&ctemp8,data, startBit, length);value = ctemp8;}
1380 else {mobileyeiDecodeToUI8(&uctemp8,data, startBit, length);value = uctemp8;}
1381 }
1382
1383 return value;
1384}
1385
1386#ifdef __cplusplus
1387}
1388#endif // __cplusplus
1389
1390#endif // BINARYDECODER_H
Note: See TracBrowser for help on using the repository browser.