source: pacpusframework/branches/0.1.x/include/Pacpus/PacpusTools/BinaryDecoder.h@ 253

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

Update: added dll export/import macros for PacpusTools.

  • Property svn:executable set to *
File size: 49.1 KB
Line 
1// %pacpus:license{
2// This file is part of the PACPUS framework distributed under the
3// CECILL-C License, Version 1.0.
4// %pacpus:license}
5/// @file
6/// @author Gerald Dherbomez <firstname.surname@utc.fr>
7/// @date July, 2008
8/// @version $Id: BinaryDecoder.h 76 2013-01-10 17:05:10Z kurdejma $
9/// @copyright Copyright (c) UTC/CNRS Heudiasyc 2006 - 2013. All rights reserved.
10/// @brief Extracts data of specified type in a string.
11///
12/// Purpose: Extract data of specified type in a string (char *)
13/// Usage:
14/// bool xDecodeToXXX(T* result, const char * data, const unsigned int startBit, const unsigned int length)
15/// => x = format (i:Intel, Little Endian)
16/// (m:Motorola, Big Endian)
17/// => XXX = type of return value
18/// (Bool = bool)
19/// (I8 = char - 8 bits)
20/// (UI8 = unsigned char - 8 bits)
21/// (I16 = short - 16 bits)
22/// (UI16 = unsigned short - 16 bits)
23/// (I32 = long - 32 bits)
24/// (UI32 = unsigned long - 32 bits)
25/// (I64 = long long - 64 bits)
26/// (UI16 = unisgned long long - 64 bits)
27///
28/// ex: inline bool mDecodeToUI16(r, str, 8, 12);
29
30#ifndef BINARYDECODER_H
31#define BINARYDECODER_H
32
33#include "PacpusToolsConfig.h"
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif // __cplusplus
39
40#include <stdio.h>
41
42//////////////////////////////////////////////////////////////////////////
43// print the data in the hexadecimal format in the console
44inline void displayData(const unsigned char * data, const unsigned long length, const int id)
45{
46 printf("\ndata = ");
47 for (unsigned int i = 0;i< length;++i )
48 printf("%02x ",data[i]);
49 printf(" dlc = %ld ID = 0x%x\n", length, id);
50}
51
52//////////////////////////////////////////////////////////////////////////
53// for Big Endian - Motorola coding
54//------------------------------------------------------------------------
55// return true if the signal is spread on more than 1 byte
56// ie if length is greater than ((startBit%8) + 1)
57// example:
58// 7654 3210
59// 0 .... ..||
60// 1 |||| ....
61// startBit is 1 and the length is 8: result gives (1%8)+1 = 2 < length(=6)
62inline bool mSpreadOnMoreThan1Byte(const unsigned int startBit, const unsigned int length)
63{
64 if ( (length > (startBit & 0x07) + 1) ) {
65 return true;
66 } else {
67 return false;
68 }
69}
70
71//////////////////////////////////////////////////////////////////////////
72// for Little Endian - Intel coding
73//------------------------------------------------------------------------
74// return true if the signal is spread on more than 1 byte
75// ie if length is greater than 8-(startBit%8)
76// example:
77// 7654 3210
78// 0 ||.. ....
79// 1 .... ||||
80// startBit is 6 and the length is 6: result gives 8-((6%8)) = 2 < length(=6)
81inline bool iSpreadOnMoreThan1Byte(const unsigned int startBit, const unsigned int length)
82{
83 if ( length > 8 - (startBit & 0x07) ) {
84 return true;
85 } else {
86 return false;
87 }
88}
89
90//////////////////////////////////////////////////////////////////////////
91// for Big Endian - Motorola coding
92//------------------------------------------------------------------------
93// return true if the signal is spread on more than 2 bytes
94// ie if (length - ((startBit%8) + 1) is greater than 8
95// example:
96// 7654 3210
97// 0 .... ...|
98// 1 |||| ||||
99// 2 ||.. ....
100// the start bit is 0 and the length is 11: result gives 11 - (0%8+1) = 10 (>8)
101//////////////////////////////////////////////////////////////////////////
102inline bool mSpreadOnMoreThan2Bytes(const unsigned int startBit, const unsigned int length)
103{
104 if ( length - ((startBit & 0x07) + 1) > 8 )
105 return true;
106 else
107 return false;
108}
109
110//////////////////////////////////////////////////////////////////////////
111// for Little Endian - Intel coding
112//------------------------------------------------------------------------
113// return true if the signal is spread on more than 2 bytes
114// ie if (length - (8 - startBit)) is greater than 8
115// example:
116// 7654 3210
117// 0 |... ....
118// 1 |||| ||||
119// 2 .... ..||
120// the start bit is 7 and the length is 11: result gives 11 - (8 - 7) = 10 (>8)
121//////////////////////////////////////////////////////////////////////////
122inline bool iSpreadOnMoreThan2Bytes(const unsigned int startBit, const unsigned int length)
123{
124 if ( length - (8 - (startBit & 0x07)) > 8 )
125 return true;
126 else
127 return false;
128}
129
130//////////////////////////////////////////////////////////////////////////
131// for Big Endian - Motorola coding
132//------------------------------------------------------------------------
133// return true if the signal is spread on more than 4 bytes
134// ie if length is greater than ((startBit%8) + 1)
135// example:
136// 7654 3210
137// 0 .... ..||
138// 1 |||| ||||
139// 2 |||| ||||
140// 3 |||| ||||
141// 4 |||. ....
142// startBit is 1 and the length is 29: result gives 29 - ((1%8)+1) = 27 (> 24)
143inline bool mSpreadOnMoreThan4Bytes(const unsigned int startBit, const unsigned int length)
144{
145 return (3*8) < (length - ((startBit & 0x07) + 1));
146}
147
148//////////////////////////////////////////////////////////////////////////
149// for Little Endian - Intel coding
150//------------------------------------------------------------------------
151// return true if the signal is spread on more than 4 bytes
152// ie if length is greater than 8-(startBit%8)
153// example:
154// 7654 3210
155// 0 ||.. ....
156// 1 |||| ||||
157// 2 |||| ||||
158// 3 |||| ||||
159// 4 .... ..||
160// startBit is 6 and the length is 28: result gives 28 - (8-((6%8))) = 26 (>24)
161inline bool iSpreadOnMoreThan4Bytes(const unsigned int startBit, const unsigned int length)
162{
163 return (3*8) < (length - (8 - (startBit & 0x07)));
164}
165
166//////////////////////////////////////////////////////////////////////////
167// return a 8-bits shifted-left mask corresponding to the length parameter
168// ex: shift = 2 and length = 3
169// mask will be 0b00011100
170inline unsigned char getShiftMask8(const unsigned int shift, const unsigned int length)
171{
172 unsigned char mask;
173 switch (length)
174 {
175 case 1: mask = 0x01; break;
176 case 2: mask = 0x03; break;
177 case 3: mask = 0x07; break;
178 case 4: mask = 0x0F; break;
179 case 5: mask = 0x1F; break;
180 case 6: mask = 0x3F; break;
181 case 7: mask = 0x7F; break;
182 case 8: mask = 0xFF; break;
183 default: mask = 0; break;
184 }
185 return mask << shift;
186}
187
188//////////////////////////////////////////////////////////////////////////
189// return a 8-bits mask corresponding to the length parameter with bit order decreasing
190// ex: startBit = 2 and length = 3
191// mask will be 0b00000111
192inline unsigned char getMask8( const unsigned int length )
193{
194 unsigned char mask;
195 switch (length) {
196 case 1: mask = 0x01; break;
197 case 2: mask = 0x03; break;
198 case 3: mask = 0x07; break;
199 case 4: mask = 0x0F; break;
200 case 5: mask = 0x1F; break;
201 case 6: mask = 0x3F; break;
202 case 7: mask = 0x7F; break;
203 case 8: mask = 0xFF; break;
204 default: mask = 0; break;
205 }
206 return mask;
207}
208
209//////////////////////////////////////////////////////////////////////////
210// return a 16-bits shifted-left mask corresponding to the length parameter
211inline unsigned short getShiftMask16(const unsigned int shift, const unsigned int length)
212{
213 unsigned short mask;
214 switch (length) {
215 case 1: mask = 0x0001; break;
216 case 2: mask = 0x0003; break;
217 case 3: mask = 0x0007; break;
218 case 4: mask = 0x000F; break;
219 case 5: mask = 0x001F; break;
220 case 6: mask = 0x003F; break;
221 case 7: mask = 0x007F; break;
222 case 8: mask = 0x00FF; break;
223 case 9: mask = 0x01FF; break;
224 case 10: mask = 0x03FF; break;
225 case 11: mask = 0x07FF; break;
226 case 12: mask = 0x0FFF; break;
227 case 13: mask = 0x1FFF; break;
228 case 14: mask = 0x3FFF; break;
229 case 15: mask = 0x7FFF; break;
230 case 16: mask = 0xFFFF; break;
231 default: mask = 0; break;
232 }
233 return mask << shift;
234}
235
236//////////////////////////////////////////////////////////////////////////
237// return a 16-bits mask corresponding to the length parameter with bit order decreasing
238inline unsigned short getMask16( const unsigned int length )
239{
240 unsigned short mask;
241 switch (length) {
242 case 1: mask = 0x0001; break;
243 case 2: mask = 0x0003; break;
244 case 3: mask = 0x0007; break;
245 case 4: mask = 0x000F; break;
246 case 5: mask = 0x001F; break;
247 case 6: mask = 0x003F; break;
248 case 7: mask = 0x007F; break;
249 case 8: mask = 0x00FF; break;
250 case 9: mask = 0x01FF; break;
251 case 10: mask = 0x03FF; break;
252 case 11: mask = 0x07FF; break;
253 case 12: mask = 0x0FFF; break;
254 case 13: mask = 0x1FFF; break;
255 case 14: mask = 0x3FFF; break;
256 case 15: mask = 0x7FFF; break;
257 case 16: mask = 0xFFFF; break;
258 default: mask = 0; break;
259 }
260 return mask;
261}
262
263//////////////////////////////////////////////////////////////////////////
264// return a 32-bits shifted-left mask corresponding to the length parameter
265inline unsigned long getShiftMask32(const unsigned int shift, const unsigned int length)
266{
267 unsigned long mask;
268 switch (length) {
269 case 1: mask = 0x00000001; break;
270 case 2: mask = 0x00000003; break;
271 case 3: mask = 0x00000007; break;
272 case 4: mask = 0x0000000F; break;
273 case 5: mask = 0x0000001F; break;
274 case 6: mask = 0x0000003F; break;
275 case 7: mask = 0x0000007F; break;
276 case 8: mask = 0x000000FF; break;
277 case 9: mask = 0x000001FF; break;
278 case 10: mask = 0x000003FF; break;
279 case 11: mask = 0x000007FF; break;
280 case 12: mask = 0x00000FFF; break;
281 case 13: mask = 0x00001FFF; break;
282 case 14: mask = 0x00003FFF; break;
283 case 15: mask = 0x00007FFF; break;
284 case 16: mask = 0x0000FFFF; break;
285 case 17: mask = 0x0001FFFF; break;
286 case 18: mask = 0x0003FFFF; break;
287 case 19: mask = 0x0007FFFF; break;
288 case 20: mask = 0x000FFFFF; break;
289 case 21: mask = 0x001FFFFF; break;
290 case 22: mask = 0x003FFFFF; break;
291 case 23: mask = 0x007FFFFF; break;
292 case 24: mask = 0x00FFFFFF; break;
293 case 25: mask = 0x01FFFFFF; break;
294 case 26: mask = 0x03FFFFFF; break;
295 case 27: mask = 0x07FFFFFF; break;
296 case 28: mask = 0x0FFFFFFF; break;
297 case 29: mask = 0x1FFFFFFF; break;
298 case 30: mask = 0x3FFFFFFF; break;
299 case 31: mask = 0x7FFFFFFF; break;
300 case 32: mask = 0xFFFFFFFF; break;
301 default: mask = 0; break;
302 }
303 return mask << shift;
304}
305
306//////////////////////////////////////////////////////////////////////////
307// return a 32-bits mask corresponding to the length parameter with bit order decreasing
308inline unsigned long getMask32( const unsigned int length )
309{
310 unsigned long mask;
311 switch (length) {
312 case 1: mask = 0x00000001; break;
313 case 2: mask = 0x00000003; break;
314 case 3: mask = 0x00000007; break;
315 case 4: mask = 0x0000000F; break;
316 case 5: mask = 0x0000001F; break;
317 case 6: mask = 0x0000003F; break;
318 case 7: mask = 0x0000007F; break;
319 case 8: mask = 0x000000FF; break;
320 case 9: mask = 0x000001FF; break;
321 case 10: mask = 0x000003FF; break;
322 case 11: mask = 0x000007FF; break;
323 case 12: mask = 0x00000FFF; break;
324 case 13: mask = 0x00001FFF; break;
325 case 14: mask = 0x00003FFF; break;
326 case 15: mask = 0x00007FFF; break;
327 case 16: mask = 0x0000FFFF; break;
328 case 17: mask = 0x0001FFFF; break;
329 case 18: mask = 0x0003FFFF; break;
330 case 19: mask = 0x0007FFFF; break;
331 case 20: mask = 0x000FFFFF; break;
332 case 21: mask = 0x001FFFFF; break;
333 case 22: mask = 0x003FFFFF; break;
334 case 23: mask = 0x007FFFFF; break;
335 case 24: mask = 0x00FFFFFF; break;
336 case 25: mask = 0x01FFFFFF; break;
337 case 26: mask = 0x03FFFFFF; break;
338 case 27: mask = 0x07FFFFFF; break;
339 case 28: mask = 0x0FFFFFFF; break;
340 case 29: mask = 0x1FFFFFFF; break;
341 case 30: mask = 0x3FFFFFFF; break;
342 case 31: mask = 0x7FFFFFFF; break;
343 case 32: mask = 0xFFFFFFFF; break;
344 default: mask = 0; break;
345 }
346 return mask;
347}
348
349//////////////////////////////////////////////////////////////////////////
350// return a 64-bits mask corresponding to the length parameter with bit order decreasing
351inline unsigned long long getMask64( const unsigned int length )
352{
353 unsigned long long mask;
354 switch (length) {
355 case 1: mask = 0x0000000000000001ULL; break;
356 case 2: mask = 0x0000000000000003ULL; break;
357 case 3: mask = 0x0000000000000007ULL; break;
358 case 4: mask = 0x000000000000000FULL; break;
359 case 5: mask = 0x000000000000001FULL; break;
360 case 6: mask = 0x000000000000003FULL; break;
361 case 7: mask = 0x000000000000007FULL; break;
362 case 8: mask = 0x00000000000000FFULL; break;
363 case 9: mask = 0x00000000000001FFULL; break;
364 case 10: mask = 0x00000000000003FFULL; break;
365 case 11: mask = 0x00000000000007FFULL; break;
366 case 12: mask = 0x0000000000000FFFULL; break;
367 case 13: mask = 0x0000000000001FFFULL; break;
368 case 14: mask = 0x0000000000003FFFULL; break;
369 case 15: mask = 0x0000000000007FFFULL; break;
370 case 16: mask = 0x000000000000FFFFULL; break;
371 case 17: mask = 0x000000000001FFFFULL; break;
372 case 18: mask = 0x000000000003FFFFULL; break;
373 case 19: mask = 0x000000000007FFFFULL; break;
374 case 20: mask = 0x00000000000FFFFFULL; break;
375 case 21: mask = 0x00000000001FFFFFULL; break;
376 case 22: mask = 0x00000000003FFFFFULL; break;
377 case 23: mask = 0x00000000007FFFFFULL; break;
378 case 24: mask = 0x0000000000FFFFFFULL; break;
379 case 25: mask = 0x0000000001FFFFFFULL; break;
380 case 26: mask = 0x0000000003FFFFFFULL; break;
381 case 27: mask = 0x0000000007FFFFFFULL; break;
382 case 28: mask = 0x000000000FFFFFFFULL; break;
383 case 29: mask = 0x000000001FFFFFFFULL; break;
384 case 30: mask = 0x000000003FFFFFFFULL; break;
385 case 31: mask = 0x000000007FFFFFFFULL; break;
386 case 32: mask = 0x00000000FFFFFFFFULL; break;
387 case 33: mask = 0x00000001FFFFFFFFULL; break;
388 case 34: mask = 0x00000003FFFFFFFFULL; break;
389 case 35: mask = 0x00000007FFFFFFFFULL; break;
390 case 36: mask = 0x0000000FFFFFFFFFULL; break;
391 case 37: mask = 0x0000001FFFFFFFFFULL; break;
392 case 38: mask = 0x0000003FFFFFFFFFULL; break;
393 case 39: mask = 0x0000007FFFFFFFFFULL; break;
394 case 40: mask = 0x000000FFFFFFFFFFULL; break;
395 case 41: mask = 0x000001FFFFFFFFFFULL; break;
396 case 42: mask = 0x000003FFFFFFFFFFULL; break;
397 case 43: mask = 0x000007FFFFFFFFFFULL; break;
398 case 44: mask = 0x00000FFFFFFFFFFFULL; break;
399 case 45: mask = 0x00001FFFFFFFFFFFULL; break;
400 case 46: mask = 0x00003FFFFFFFFFFFULL; break;
401 case 47: mask = 0x00007FFFFFFFFFFFULL; break;
402 case 48: mask = 0x0000FFFFFFFFFFFFULL; break;
403 case 49: mask = 0x0001FFFFFFFFFFFFULL; break;
404 case 50: mask = 0x0003FFFFFFFFFFFFULL; break;
405 case 51: mask = 0x0007FFFFFFFFFFFFULL; break;
406 case 52: mask = 0x000FFFFFFFFFFFFFULL; break;
407 case 53: mask = 0x001FFFFFFFFFFFFFULL; break;
408 case 54: mask = 0x003FFFFFFFFFFFFFULL; break;
409 case 55: mask = 0x007FFFFFFFFFFFFFULL; break;
410 case 56: mask = 0x00FFFFFFFFFFFFFFULL; break;
411 case 57: mask = 0x01FFFFFFFFFFFFFFULL; break;
412 case 58: mask = 0x03FFFFFFFFFFFFFFULL; break;
413 case 59: mask = 0x07FFFFFFFFFFFFFFULL; break;
414 case 60: mask = 0x0FFFFFFFFFFFFFFFULL; break;
415 case 61: mask = 0x1FFFFFFFFFFFFFFFULL; break;
416 case 62: mask = 0x3FFFFFFFFFFFFFFFULL; break;
417 case 63: mask = 0x7FFFFFFFFFFFFFFFULL; break;
418 case 64: mask = 0xFFFFFFFFFFFFFFFFULL; break;
419 default: mask = 0; break;
420 }
421 return mask;
422}
423
424//////////////////////////////////////////////////////////////////////////
425/// Returns a 64-bits shifted-left mask corresponding to the length parameter
426inline unsigned long long getShiftMask64(const unsigned int shift, const unsigned int length)
427{
428 unsigned long long mask;
429 mask = getMask64( length );
430 mask <<= shift;
431 return mask;
432}
433
434//////////////////////////////////////////////////////////////////////////
435/// Big Endian - Motorola coding
436inline bool mDecodeToBool(const unsigned char * data, const unsigned int startBit)
437{
438 return (data[startBit>>3] & getShiftMask8(startBit&0x07,1)) != 0;
439}
440
441//////////////////////////////////////////////////////////////////////////
442// Big Endian - Motorola coding
443// to test ?
444inline bool mDecodeToUI64(unsigned long long * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
445{
446 if (length > 64) {
447 *result = 0;
448 return false;
449 }
450
451 if (length == 64) {
452 // only work if data are correctly byte-aligned
453 unsigned char c[8]; // c[0] = MSB
454 for (int i = 0 ; i < 8 ; i++)
455 c[i] = data[(startBit>>3) + i];
456
457 unsigned long long temp = 0;
458 for (int i = 0 ; i < 8 ; i++)
459 temp += (c[i] << ( 56 - (8*i) ) );
460 *result = temp;
461 return true;
462 } else {
463 unsigned char c[8], mask[8], nbBits[8]; // MSB = c[0]
464 nbBits[0] = (startBit & 0x07)+1;
465 mask[0] = getMask8( nbBits[0] );
466 c[0] = data[startBit>>3] & mask[0];
467 unsigned short nbBitsIncrement = nbBits[0];
468 for (int i = 1 ; i < 8 ; i++) {
469 nbBits[i] = static_cast<unsigned char>( (length - nbBitsIncrement) < 8 ? length - nbBitsIncrement : 8 );
470 nbBitsIncrement += nbBits[i];
471 mask[i] = getShiftMask8(8 - nbBits[i],nbBits[i]);
472 c[i] = data[(startBit>>3) + i] & mask[i];
473 }
474
475 unsigned long long temp = 0;
476 for (int i = 0 ; i < 8 ; i++)
477 temp += (c[i] << ( 56 - (8*i) ) );
478 *result = temp >> (56 + (startBit&0x07) + 1 - length);
479 return true;
480 }
481}
482
483//////////////////////////////////////////////////////////////////////////
484// Big Endian - Motorola coding
485// to test ?
486inline bool mDecodeToI64(long long *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
487{
488 if (length>64) {
489 *result = 0;
490 return false;
491 }
492
493 if (length == 64) {
494 // only work if data are correctly byte-aligned
495 unsigned char c[8]; // c[0] = MSB
496 for (int i = 0 ; i < 8 ; i++)
497 c[i] = data[(startBit>>3) + i];
498
499 for (int i = 0 ; i < 8 ; i++)
500 *result += (c[i] << ( 56 - (8*i) ) );
501
502 // need to be signed ??
503 return true;
504 } else {
505 unsigned char c[8], mask[8], nbBits[8]; // MSB = c[0]
506 nbBits[0] = (startBit & 0x07)+1;
507 mask[0] = getMask8( nbBits[0] );
508 c[0] = data[startBit>>3] & mask[0];
509 unsigned short nbBitsIncrement = nbBits[0];
510 for (int i = 1 ; i < 8 ; i++) {
511 nbBits[i] = static_cast<unsigned char>( (length - nbBitsIncrement) < 8 ? (length - nbBitsIncrement) : 8 );
512 nbBitsIncrement += nbBits[i];
513 mask[i] = getShiftMask8(8 - nbBits[i],nbBits[i]);
514 c[i] = data[(startBit>>3) + i] & mask[i];
515 }
516 unsigned long long temp = 0;
517 for (int i = 0 ; i < 8 ; i++)
518 temp += (c[i] << ( 56 - (8*i) ) );
519 temp >>= (56 + (startBit&0x07) + 1 - length);
520
521 if ( temp & getShiftMask64(length-1,1) )
522 // do the two's complement to get the signed value if the msb=1
523 *result = -1 * ( ( (~temp) + 1 ) & getMask64(length) );
524 else
525 *result = temp;
526
527 return true;
528 }
529}
530
531//////////////////////////////////////////////////////////////////////////
532// Big Endian - Motorola coding
533// ok
534inline bool mDecodeToUI32(unsigned long *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
535{
536 if (length>32) {
537 *result = 0;
538 return false;
539 }
540
541 // verify that the frame is not spread in 5 bytes
542 if (mSpreadOnMoreThan4Bytes(startBit, length)) {
543 // decode in a 64-bits integer
544 unsigned long long temp;
545 if (mDecodeToUI64(&temp,data,startBit,length))
546 {
547 *result = static_cast<unsigned long> (temp);
548 return true;
549 } else {
550 *result = 0;
551 return false;
552 }
553 } else {
554 if (length == 32) {
555 // only work if data are correctly byte-aligned
556 unsigned char c1, c2, c3, c4;
557 c1 = data[startBit>>3];
558 c2 = data[(startBit>>3) + 1];
559 c3 = data[(startBit>>3) + 2];
560 c4 = data[(startBit>>3) + 3];
561
562 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
563 return true;
564 } else {
565 unsigned char c[4], mask[4], nbBits[4]; // MSB = c[0]
566 nbBits[0] = (startBit & 0x07)+1;
567 nbBits[1] = static_cast<unsigned char>( (length - nbBits[0]) < 8 ? length - nbBits[0] : 8 );
568 nbBits[2] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1]) < 8 ? (length - nbBits[0] - nbBits[1]) : 8 );
569 nbBits[3] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1] - nbBits[2]) < 8 ? (length - nbBits[0] - nbBits[1] - nbBits[2]) : 8 );
570 mask[0] = getMask8( nbBits[0] );
571 mask[1] = getShiftMask8(8 - nbBits[1],nbBits[1]);
572 mask[2] = getShiftMask8(8 - nbBits[2],nbBits[2]);
573 mask[3] = getShiftMask8(8 - nbBits[3],nbBits[3]);
574 c[0] = data[startBit>>3] & mask[0];
575 c[1] = data[(startBit>>3) + 1] & mask[1];
576 c[2] = data[(startBit>>3) + 2] & mask[2];
577 c[3] = data[(startBit>>3) + 3] & mask[3];
578 *result = ( (c[0]<<24) + (c[1]<<16) + (c[2]<<8) + c[3]) >> (24 + (startBit&0x07) + 1 - length);
579 return true;
580 }
581 }
582}
583
584//////////////////////////////////////////////////////////////////////////
585// Big Endian - Motorola coding
586// ok
587inline bool mDecodeToI32(long *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
588{
589 if (length>32) {
590 *result = 0;
591 return false;
592 }
593
594 // verify that the frame is not spread in 5 bytes
595 if (mSpreadOnMoreThan4Bytes(startBit, length)) {
596 // decode in a 64-bits integer
597 long long temp;
598 if (mDecodeToI64(&temp,data,startBit,length))
599 {
600 *result = static_cast<long>(temp);
601 return true;
602 } else {
603 *result = 0;
604 return false;
605 }
606 } else {
607 if (length == 32)
608 {
609 // only work if data are correctly byte-aligned
610 unsigned char c1, c2, c3, c4;
611 c1 = data[startBit>>3];
612 c2 = data[(startBit>>3) + 1];
613 c3 = data[(startBit>>3) + 2];
614 c4 = data[(startBit>>3) + 3];
615
616 *result = (c1 << 24) + (c2 << 16) + (c3 << 8) + c4;
617 return true;
618 } else {
619 unsigned char c[4], mask[4], nbBits[4]; // MSB = c[0]
620 nbBits[0] = (startBit & 0x07) + 1;
621 nbBits[1] = static_cast<unsigned char>( (length - nbBits[0]) < 8 ? length - nbBits[0] : 8 );
622 nbBits[2] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1]) < 8 ? (length - nbBits[0] - nbBits[1]) : 8 );
623 nbBits[3] = static_cast<unsigned char>( (length - nbBits[0] - nbBits[1] - nbBits[2]) < 8 ? length - nbBits[0] - nbBits[1] - nbBits[2] : 8 );
624 mask[0] = getMask8( nbBits[0] );
625 mask[1] = getShiftMask8(8 - nbBits[1],nbBits[1]);
626 mask[2] = getShiftMask8(8 - nbBits[2],nbBits[2]);
627 mask[3] = getShiftMask8(8 - nbBits[3],nbBits[3]);
628 c[0] = data[startBit>>3] & mask[0];
629 c[1] = data[(startBit>>3) + 1] & mask[1];
630 c[2] = data[(startBit>>3) + 2] & mask[2];
631 c[3] = data[(startBit>>3) + 3] & mask[3];
632
633 unsigned long temp = ( (c[0]<<24) + (c[1]<<16) + (c[2]<<8) + c[3]) >> (24 + (startBit&0x07) + 1 - length);
634 if (temp & getShiftMask32(length-1, 1))
635 // do the two's complement to get the signed value if the msb=1
636 *result = -1 * ( ( (~temp) + 1 ) & getMask32(length) );
637 else
638 *result = temp;
639 return true;
640 }
641 }
642}
643
644
645
646//////////////////////////////////////////////////////////////////////////
647// Big Endian - Motorola coding
648// ok
649inline bool mDecodeToUI16(unsigned short * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
650{
651 if (length > 16) {
652 *result = 0;
653 return false;
654 }
655
656 // verify that the frame is not spread in 3 bytes
657 if (mSpreadOnMoreThan2Bytes(startBit, length)) {
658 // decode in a 32-bits integer
659 unsigned long temp;
660 if (mDecodeToUI32(&temp,data,startBit,length)) {
661 *result = static_cast<unsigned short>(temp);
662 return true;
663 } else {
664 *result = 0;
665 return false;
666 }
667 } else {
668 if (length == 16) {
669 // only work if data are correctly byte-aligned
670 unsigned char LSB, MSB;
671 MSB = data[startBit>>3];
672 LSB = data[(startBit>>3) + 1];
673
674 *result = ( (MSB << 8) + LSB );
675 return true;
676 } else {
677 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
678 nbBitsMSB = (startBit & 0x07) + 1; // the number of bits contained in the MSB
679 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
680 maskMSB = getMask8( nbBitsMSB );
681 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
682 MSB = data[startBit>>3] & maskMSB;
683 LSB = data[(startBit>>3) + 1] & maskLSB;
684
685 *result = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
686 return true;
687 }
688 }
689}
690
691//////////////////////////////////////////////////////////////////////////
692// Big Endian - Motorola coding
693// ok
694inline bool mDecodeToI16(short *result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
695{
696 if (length > 16) {
697 *result = 0;
698 return false;
699 }
700
701 // verify that the frame is not spread in 3 bytes
702 if (mSpreadOnMoreThan2Bytes(startBit, length)) {
703 // decode in a 32-bits integer
704 long temp;
705 if (mDecodeToI32(&temp, data, startBit, length)) {
706 *result = (short)temp;
707 return true;
708 } else {
709 *result = 0;
710 return false;
711 }
712 } else {
713 // ok data are stored at most in 2 bytes
714 if (length == 16) {
715 // only work if data are correctly byte-aligned
716 unsigned char LSB, MSB;
717 MSB = data[startBit>>3];
718 LSB = data[(startBit>>3) + 1];
719 short temp = (MSB << 8) + LSB;
720
721 // Attention : a-t on besoin d'appliquer le signe ?
722 // n'est-il pas deja inclu dans la donn�e comme elle est correctement align�e sur l'octet ?
723 if (temp & 0x8000) {
724 // do the two's complement to get the signed value
725 *result = - ( ( (~temp) + 1 ) & 0xFFFF );
726 } else {
727 *result = temp;
728 }
729 return true;
730 } else {
731 unsigned char LSB, MSB, maskMSB, maskLSB, nbBitsMSB, nbBitsLSB;
732 nbBitsMSB = (startBit & 0x07) + 1; // the number of bits contained in the MSB
733 nbBitsLSB = static_cast<unsigned char>(length - nbBitsMSB);
734 maskMSB = getMask8( nbBitsMSB );
735 maskLSB = getShiftMask8(8 - nbBitsLSB , nbBitsLSB);
736 MSB = data[startBit>>3] & maskMSB;
737 LSB = data[(startBit>>3) + 1] & maskLSB;
738 // assign the MSB and LSB char in the short integer value and right-shift
739 // to place the lsb to the bit 0
740 unsigned short temp = ( (MSB << 8) + LSB ) >> (8 + (startBit&0x07) + 1 - length);
741 if (temp & getShiftMask16(length-1,1))
742 // do the two's complement to get the signed value if the msb=1
743 *result = -1 * ( ( (~temp) + 1 ) & getMask16(length) );
744 else
745 *result = temp;
746 return true;
747 }
748 }
749}
750
751//////////////////////////////////////////////////////////////////////////
752// Big Endian - Motorola coding
753// OK
754inline bool mDecodeToUI8(unsigned char * result, const unsigned char * data, const unsigned int startBit, const unsigned int length)
755{
756 if (length > 8) {
757 *result = 0;
758 return false;
759 }
760
761 // verify that the frame is not spread in 2 bytes
762 if (mSpreadOnMoreThan1Byte(startBit, length)) {
763 // decode in a 16-bit integer
764 unsigned short temp;
765 if ( mDecodeToUI16(&temp, data, startBit, length) ) {
766 *result = static_cast<unsigned char>(temp);
767 return true;
768 } else {
769 *result = 0;
770 return true;
771 }
772 } else {
773 // ok data is stored at most in 1 byte
774 unsigned char c;
775 c = data[startBit>>3]; // >>3 <=> div 8
776 c >>= (8-((startBit & 0x07)+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 true;
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.