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

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

corrected conflict problems

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