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

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

Documentation: file info.

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