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

Last change on this file since 305 was 305, checked in by phudelai, 10 years ago

BinaryDecoder.h corrected

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