source: pacpusframework/trunk/include/Pacpus/PacpusTools/BinaryDecoder.h@ 297

Last change on this file since 297 was 295, checked in by DHERBOMEZ Gérald, 11 years ago

Bug fix in BinaryDecoder.h file, notably for the mDecodeToUI8 function (error when decoding UI8 whose the size(in bits) < 8 bits )

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