source: pacpusframework/branches/0.0.x/include/Pacpus/PacpusTools/BinaryDecoder.h@ 296

Last change on this file since 296 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:keywords set to Id
File size: 47.8 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 295 2014-03-31 13:24:03Z gdherbom $
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 false;
769 }
770 } else {
771 // ok data is stored at most in 1 byte
772 unsigned char c;
773
774 c = data[startBit>>3]; // >>3 <=> div 8
775 //c >>= (8-((startBit & 0x07)+1)); // &0x07 <=> modulo 8
776 c >>= startBit & 0x07 - (length - 1); // &0x07 <=> modulo 8
777 *result = c & getMask8( length );
778
779 return true;
780 }
781}
782
783//////////////////////////////////////////////////////////////////////////
784// Big Endian - Motorola coding
785// OK
786inline bool mDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
787{
788 if (length > 8) {
789 *result = 0;
790 return false;
791 }
792
793 // verify that the frame is not spread in 2 bytes
794 if (mSpreadOnMoreThan1Byte(startBit, length)) {
795 // decode in a 16-bit integer
796 short temp;
797 if ( mDecodeToI16(&temp, data, startBit, length) ) {
798 *result = static_cast<char>(temp);
799 return true;
800 } else {
801 *result = 0;
802 return false;
803 }
804 }
805 else {
806 // ok data is stored at most in 1 byte
807 char c;
808 c = data[startBit>>3];
809 c >>= (8-((startBit & 0x07)+1));
810 c = c & getMask8( length );
811
812 // a-t-on besoin d'appliquer le signe dans le cas ou length = 8
813 // la donnee est correctement alignee sur l'octet donc le signe est peut-etre compris
814 if (c & getShiftMask8(length-1,1))
815 // do the two's complement to get the signed value if the msb=1
816 *result = - ( ( (~c) + 1 ) & getMask8(length) );
817 else
818 *result = c;
819 return true;
820 }
821}
822
823//////////////////////////////////////////////////////////////////////////
824// Little Endian - Intel coding
825// ok
826inline bool iDecodeToBool(const unsigned char * data, const unsigned int startBit)
827{
828 mDecodeToBool(data, startBit);
829}
830
831//////////////////////////////////////////////////////////////////////////
832// Little Endian - Intel coding
833// pas de depassement possible - la trame CAN fait 64 bits max
834// gerer le signe
835inline bool iDecodeToUI64(unsigned long long * /*result*/, const unsigned char * /*data*/, const unsigned int /*startBit*/, const unsigned int /*length*/)
836{
837 return true;
838}
839
840//////////////////////////////////////////////////////////////////////////
841// Little Endian - Intel coding
842// pas de depassement possible - la trame CAN fait 64 bits max
843// gerer le signe
844inline bool iDecodeToI64(long long * /*result*/, const unsigned char * /*data*/, const unsigned int /*startBit*/, const unsigned int /*length*/)
845{
846 return true;
847}
848
849//////////////////////////////////////////////////////////////////////////
850// Little Endian - Intel coding
851// gerer le depassement sur plus de 4 octets : necessite la fonction de decodage 64 bits
852// verifier le depassement avant cette ligne : if (length == 32)
853inline bool iDecodeToUI32(unsigned long * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
854{
855 if (length>32) {
856 *result = 0;
857 return false;
858 }
859
860 if (length == 32) {
861 // only work if length == 32
862 unsigned char c1, c2, c3, c4;
863 c4 = data[startBit>>3]; // LSB
864 c3 = data[(startBit>>3) + 1];
865 c2 = data[(startBit>>3) + 2];
866 c1 = data[(startBit>>3) + 3]; // MSB
867
868 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
869 return true;
870 } else {
871 // todo
872 *result = 0;
873 return false;
874 }
875}
876
877//////////////////////////////////////////////////////////////////////////
878// Little Endian - Intel coding
879// gerer le signe
880// gerer le depassement sur plus de 4 octets : necessite la fonction de decodage 64 bits
881// verifier le depassement avant cette ligne : if (length == 32)
882inline bool iDecodeToI32(long * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
883{
884 if (length>32) {
885 *result = 0;
886 return false;
887 }
888
889 if (length == 32) {
890 // only work if length == 32
891 unsigned char c1, c2, c3, c4;
892 c4 = data[startBit>>3]; // LSB
893 c3 = data[(startBit>>3) + 1];
894 c2 = data[(startBit>>3) + 2];
895 c1 = data[(startBit>>3) + 3]; // MSB
896
897 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
898 return true;
899 } else {
900 // todo
901 *result = 0;
902 return false;
903 }
904}
905
906//////////////////////////////////////////////////////////////////////////
907// Little Endian - Intel coding
908// gerer le depassement sur plus de 2 octets
909// verifier le depassement avant cette ligne : if (length == 16)
910inline bool iDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
911{
912 if (length > 16) {
913 *result = 0;
914 return false;
915 }
916
917 if (length == 16) {
918 // only work if length == 16
919 unsigned char LSB, MSB;
920 LSB = data[startBit>>3];
921 MSB = data[(startBit>>3) + 1];
922
923 *result = (MSB << 8) + LSB;
924 return true;
925 } else {
926 // TODO
927 *result = 0;
928 return false;
929 }
930}
931
932//////////////////////////////////////////////////////////////////////////
933// Little Endian - Intel coding
934// gerer le signe
935// gerer le depassement sur plus de 2 octets
936// verifier le depassement avant cette ligne : if (length == 16)
937// manque le decalage
938inline bool iDecodeToI16(short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
939{
940 if (length > 16) {
941 *result = 0;
942 return false;
943 }
944
945 if (length == 16) {
946 // only work if length == 16
947 unsigned char LSB, MSB;
948 LSB = data[startBit>>3];
949 MSB = data[(startBit>>3) + 1];
950
951 *result = (MSB << 8) + LSB;
952 return true;
953 } else {
954 // todo
955 *result = 0;
956 return false;
957 }
958}
959
960//////////////////////////////////////////////////////////////////////////
961// Little Endian - Intel coding
962// OK
963inline bool iDecodeToUI8(unsigned char * result,const unsigned char * data, const unsigned int startBit, const unsigned int length)
964{
965 if (length > 8) {
966 *result = 0;
967 return false;
968 }
969
970 // verify that the frame is not spread in 2 bytes
971 if (iSpreadOnMoreThan1Byte(startBit, length)) {
972 // decode in a 16-bit integer
973 unsigned short temp;
974 if ( iDecodeToUI16(&temp, data, startBit, length) ) {
975 // and cast in an 8 bit integer
976 *result = (unsigned char) temp;
977 return true;
978 } else {
979 *result = 0;
980 return true;
981 }
982 } else {
983 // ok data is stored at most in 1 byte
984 unsigned char c;
985 c = data[startBit>>3];
986 c >>= (startBit & 0x07);
987 *result = c & getMask8( length );
988
989 return true;
990 }
991}
992
993//////////////////////////////////////////////////////////////////////////
994// Little Endian - Intel coding
995// OK
996inline bool iDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
997{
998 if (length > 8) {
999 *result = 0;
1000 return false;
1001 }
1002
1003 // verify that the frame is not spread in 2 bytes
1004 if (iSpreadOnMoreThan1Byte(startBit, length)) {
1005 // decode in a 16-bit integer
1006 short temp;
1007 if ( iDecodeToI16(&temp, data, startBit, length) ) {
1008 // and cast in an 8 bit integer
1009 *result = static_cast<char>(temp);
1010 return true;
1011 } else {
1012 *result = 0;
1013 return true;
1014 }
1015 } else {
1016 // ok data is stored at most in 1 byte
1017 char c;
1018 c = data[startBit>>3]; // >>3 <=> div 8
1019 c >>= (startBit & 0x07); // &0x07 <=> modulo 8
1020 c = c & getMask8( length );
1021 if (c & getShiftMask8(length-1,1))
1022 // do the two's complement to get the signed value if the msb=1
1023 *result = - ( ( (~c) + 1 ) & getMask8(length) );
1024 else
1025 *result = c;
1026
1027 return true;
1028 }
1029}
1030
1031//////////////////////////////////////////////////////////////////////////
1032// Big Endian - Motorola coding
1033// ok
1034inline bool mobileyemDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1035{
1036 if (length>16){ *result = 0; return false; }
1037
1038 // verify that the frame is not spread in 3 bytes
1039 /* if (mSpreadOnMoreThan2Bytes(startBit, length))
1040 {
1041 // decode in a 32-bits integer
1042 unsigned long temp;
1043 if (mDecodeToUI32(&temp,data,startBit,length))
1044 {
1045 *result = static_cast<unsigned short>(temp);
1046 return true;
1047 } else {
1048 *result = 0;
1049 return false;
1050 }
1051 }
1052 else
1053 {*/
1054 if (length == 16) {
1055 // only work if data are correctly byte-aligned
1056 unsigned char LSB, MSB;
1057 MSB = data[startBit>>3];
1058 LSB = data[(startBit>>3) + 1];
1059
1060 *result = ( (MSB << 8) + LSB );
1061 return true;
1062 } else {
1063 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1064 nbBitsMSB = (startBit & 0x07) + 1; // the number of bits contained in the MSB
1065 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
1066 maskMSB = getMask8( nbBitsMSB );
1067 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1068 MSB = data[startBit>>3] & maskMSB;
1069 LSB = data[(startBit>>3) + 1] & maskLSB;
1070
1071 *result = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
1072 return true;
1073 }
1074 //}
1075}
1076
1077//////////////////////////////////////////////////////////////////////////
1078// Big Endian - Motorola coding
1079// ok
1080inline bool mobileyemDecodeToI16(short *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1081{
1082 if (length>16) { *result = 0; return false; }
1083
1084 // verify that the frame is not spread in 3 bytes
1085 /* if (mSpreadOnMoreThan2Bytes(startBit, length))
1086 {
1087 // decode in a 32-bits integer
1088 long temp;
1089 if (mDecodeToI32(&temp, data, startBit, length)) {
1090 *result = (short)temp;
1091 return true;
1092 } else {
1093 *result = 0;
1094 return false;
1095 }
1096 }
1097 else // ok data are stored at most in 2 bytes
1098 {*/
1099 if (length == 16)
1100 {
1101 // only work if data are correctly byte-aligned
1102 unsigned char LSB, MSB;
1103 MSB = data[startBit>>3];
1104 LSB = data[(startBit>>3) + 1];
1105 short temp = (MSB << 8) + LSB;
1106
1107 // Attention : a-t on besoin d'appliquer le signe ?
1108 // n'est-il pas deja inclu dans la donn�e comme elle est correctement align�e sur l'octet ?
1109 if (temp & 0x8000) {
1110 // do the two's complement to get the signed value
1111 *result = - ( ( (~temp) + 1 ) & 0xFFFF );
1112 } else {
1113 *result = temp;
1114 }
1115 return true;
1116 } else {
1117 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1118 nbBitsMSB = (startBit & 0x07)+1; // the number of bits contained in the MSB
1119 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
1120 maskMSB = getMask8( nbBitsMSB );
1121 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1122 MSB = data[startBit>>3] & maskMSB;
1123 LSB = data[(startBit>>3) + 1] & maskLSB;
1124 // assign the MSB and LSB char in the short integer value and right-shift
1125 // to place the lsb to the bit 0
1126 unsigned short temp = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
1127 if (temp & getShiftMask16(length-1,1))
1128 // do the two's complement to get the signed value if the msb=1
1129 *result = -1 * ( ( (~temp) + 1 ) & getMask16(length) );
1130 else
1131 *result = temp;
1132 return true;
1133 }
1134 //}
1135}
1136
1137//////////////////////////////////////////////////////////////////////////
1138// Big Endian - Motorola coding
1139// OK
1140inline bool mobileyemDecodeToUI8(unsigned char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1141{
1142 if (length>8) { *result = 0; return false; }
1143
1144 // verify that the frame is not spread in 2 bytes
1145 if (mSpreadOnMoreThan1Byte(startBit, length))
1146 {
1147 // decode in a 16-bit integer
1148 unsigned short temp;
1149 if ( mDecodeToUI16(&temp, data, startBit, length) ) {
1150 *result = static_cast<unsigned char>(temp);
1151 return true;
1152 } else {
1153 *result = 0;
1154 return true;
1155 }
1156 }
1157 else // ok data is stored at most in 1 byte
1158 {
1159 unsigned char c;
1160 c = data[startBit>>3]; // >>3 <=> div 8
1161 c >>= (8-((startBit & 0x07)+1)); // &0x07 <=> modulo 8
1162 *result = c & getMask8( length );
1163
1164 return true;
1165 }
1166}
1167
1168//////////////////////////////////////////////////////////////////////////
1169// Big Endian - Motorola coding
1170// OK
1171inline bool mobileyemDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1172{
1173 if (length>8) { *result = 0; return false; }
1174
1175 // verify that the frame is not spread in 2 bytes
1176 if (mSpreadOnMoreThan1Byte(startBit, length))
1177 {
1178 // decode in a 16-bit integer
1179 short temp;
1180 if ( mDecodeToI16(&temp, data, startBit, length) ) {
1181 *result = static_cast<char>(temp);
1182 return true;
1183 } else {
1184 *result = 0;
1185 return true;
1186 }
1187 }
1188 else // ok data is stored at most in 1 byte
1189 {
1190 char c;
1191 c = data[startBit>>3];
1192 c >>= (8-((startBit & 0x07)+1));
1193 c = c & getMask8( length );
1194
1195 // a-t-on besoin d'appliquer le signe dans le cas ou length = 8
1196 // la donnee est correctement alignee sur l'octet donc le signe est peut-etre compris
1197 if (c & getShiftMask8(length-1,1))
1198 // do the two's complement to get the signed value if the msb=1
1199 *result = - ( ( (~c) + 1 ) & getMask8(length) );
1200 else
1201 *result = c;
1202 return true;
1203 }
1204}
1205
1206//////////////////////////////////////////////////////////////////////////
1207// Little Endian - Intel coding
1208// OK, mais gerer le depassement sur plus de 2 octets
1209inline bool mobileyeiDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1210{
1211 if (length>16) {
1212 *result = 0;
1213 return false;
1214 }
1215
1216 if (length == 16) {
1217 // only work if length == 16
1218 unsigned char LSB, MSB;
1219 LSB = data[startBit>>3];
1220 MSB = data[(startBit>>3) + 1];
1221
1222 *result = (unsigned short)((MSB << 8) + LSB);
1223 return true;
1224 } else {
1225 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1226
1227 nbBitsLSB = static_cast<unsigned char>(8*((startBit>>3) + 1) - startBit);
1228 nbBitsMSB = static_cast<unsigned char>(length - nbBitsLSB);
1229 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1230 maskMSB = getMask8( nbBitsMSB );
1231 LSB = data[startBit>>3] & maskLSB;
1232 MSB = data[(startBit>>3) + 1] & maskMSB;
1233
1234 *result = (unsigned short)((MSB<<8) + (LSB>>(startBit-8*(startBit>>3))));
1235
1236 return true;
1237 }
1238}
1239
1240//////////////////////////////////////////////////////////////////////////
1241// Little Endian - Intel coding
1242// gerer le signe
1243// gerer le depassement sur plus de 2 octets
1244// verifier le depassement avant cette ligne : if (length == 16)
1245// manque le decalage
1246inline bool mobileyeiDecodeToI16(short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1247{
1248 if (length > 16) {
1249 *result = 0;
1250 return false;
1251 }
1252
1253 if (length == 16) {
1254 // only work if length == 16
1255 unsigned char LSB, MSB;
1256 LSB = data[startBit>>3];
1257 MSB = data[(startBit>>3) + 1];
1258
1259 short temp = (MSB << 8) + LSB;
1260
1261 if (temp & 0x8000) {
1262 // do the two's complement to get the signed value
1263 *result = - ( ( (~temp) + 1 ) & 0xFFFF );
1264 } else {
1265 *result = temp;
1266 }
1267 return true;
1268 } else {
1269 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
1270
1271 nbBitsLSB = static_cast<unsigned char>(8*((startBit>>3) + 1) - startBit);
1272 nbBitsMSB = static_cast<unsigned char>(length - nbBitsLSB);
1273 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
1274 maskMSB = getMask8( nbBitsMSB );
1275 LSB = data[startBit>>3] & maskLSB;
1276 MSB = data[(startBit>>3) + 1] & maskMSB;
1277
1278 unsigned short temp = (unsigned short)((MSB<<8) + (LSB>>(startBit-8*(startBit>>3))));
1279
1280 if (temp & getShiftMask16(length-1,1))
1281 // do the two's complement to get the signed value if the msb=1
1282 *result = -1 * ( ( (~temp) + 1 ) & getMask16(length) );
1283 else
1284 *result = temp;
1285 return true;
1286 }
1287}
1288
1289//////////////////////////////////////////////////////////////////////////
1290// Little Endian - Intel coding
1291// OK
1292inline bool mobileyeiDecodeToUI8(unsigned char * result,const unsigned char * data, const unsigned int startBit, const unsigned int length)
1293{
1294 if (length>8) { *result = 0; return false; }
1295
1296 // verify that the frame is not spread in 2 bytes
1297 if (iSpreadOnMoreThan1Byte(startBit, length))
1298 {
1299 // decode in a 16-bit integer
1300 unsigned short temp;
1301 if ( iDecodeToUI16(&temp, data, startBit, length) )
1302 {
1303 // and cast in an 8 bit integer
1304 *result = (unsigned char) temp;
1305 return true;
1306 }
1307 else
1308 {
1309 *result = 0;
1310 return true;
1311 }
1312 }
1313 else // ok data is stored at most in 1 byte
1314 {
1315 unsigned char c;
1316 c = data[startBit>>3];
1317 c >>= (startBit & 0x07);
1318 *result = c & getMask8( length );
1319
1320 return true;
1321 }
1322
1323}
1324
1325//////////////////////////////////////////////////////////////////////////
1326// Little Endian - Intel coding
1327// OK
1328inline bool mobileyeiDecodeToI8(char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
1329{
1330 if (length > 8) {
1331 *result = 0;
1332 return false;
1333 }
1334
1335 // verify that the frame is not spread in 2 bytes
1336 if (iSpreadOnMoreThan1Byte(startBit, length)) {
1337 // decode in a 16-bit integer
1338 short temp;
1339 if ( iDecodeToI16(&temp, data, startBit, length) ) {
1340 // and cast in an 8 bit integer
1341 *result = (char)(temp);
1342 return true;
1343 } else {
1344 *result = 0;
1345 return true;
1346 }
1347 } else {
1348 // ok data is stored at most in 1 byte
1349 char c;
1350 c = data[startBit>>3]; // >>3 <=> div 8
1351 c >>= (startBit & 0x07); // &0x07 <=> modulo 8
1352 c = c & getMask8( length );
1353 if (c & getShiftMask8(length-1,1))
1354 // do the two's complement to get the signed value if the msb=1
1355 *result = - ( ( (~c) + 1 ) & getMask8(length) );
1356 else
1357 *result = c;
1358
1359 return true;
1360 }
1361}
1362
1363inline int mobileyeDecodeCAN(unsigned char *data,unsigned char bigEndian,unsigned int startBit,unsigned int length,unsigned char Signed)
1364{
1365 int value;
1366 unsigned short ustemp16 = 0;
1367 unsigned char uctemp8 = 0;
1368 short stemp16 = 0;
1369 char ctemp8 = 0;
1370
1371 if(bigEndian) {
1372 if(length>8){
1373 if(Signed){mobileyemDecodeToI16(&stemp16,data, startBit, length);value = stemp16;}
1374 else {mobileyemDecodeToUI16(&ustemp16,data, startBit, length);value = ustemp16;}}
1375 else if(Signed) {mobileyemDecodeToI8(&ctemp8,data, startBit, length);value = ctemp8;}
1376 else {mobileyemDecodeToUI8(&uctemp8,data, startBit, length);value = uctemp8;}
1377 } else {
1378 if(length>8){
1379 if(Signed) {mobileyeiDecodeToI16(&stemp16,data, startBit, length);value = stemp16;}
1380 else {mobileyeiDecodeToUI16(&ustemp16,data, startBit, length);value = ustemp16;}}
1381 else if(Signed) {mobileyeiDecodeToI8(&ctemp8,data, startBit, length);value = ctemp8;}
1382 else {mobileyeiDecodeToUI8(&uctemp8,data, startBit, length);value = uctemp8;}
1383 }
1384
1385 return value;
1386}
1387
1388#ifdef __cplusplus
1389}
1390#endif // __cplusplus
1391
1392#endif // BINARYDECODER_H
Note: See TracBrowser for help on using the repository browser.