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

Last change on this file since 64 was 64, checked in by Marek Kurdej, 11 years ago

Modified property: added svn:keywords=Id.

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