LTKCPP-- LLRP Toolkit C Plus Plus Library
ltkcpp_frameencode.cpp
1 
2 /*
3  *****************************************************************************
4  * *
5  * IMPINJ CONFIDENTIAL AND PROPRIETARY *
6  * *
7  * This source code is the sole property of Impinj, Inc. Reproduction or *
8  * utilization of this source code in whole or in part is forbidden without *
9  * the prior written consent of Impinj, Inc. *
10  * *
11  * (c) Copyright Impinj, Inc. 2007,2008. All rights reserved. *
12  * *
13  *****************************************************************************/
14 
15 
16 
17 #include <assert.h>
18 
19 #include "ltkcpp_platform.h"
20 #include "ltkcpp_base.h"
21 #include "ltkcpp_frame.h"
22 
23 
24 namespace LLRP
25 {
26 
27 CFrameEncoder::CFrameEncoder (
28  unsigned char * pBuffer,
29  unsigned int nBuffer)
30  : CEncoder()
31 {
32  m_pBuffer = pBuffer;
33  m_nBuffer = nBuffer;
34 
35  m_iNext = 0;
36  m_BitFieldBuffer = 0;
37  m_nBitFieldResid = 0;
38 }
39 
40 CFrameEncoder::~CFrameEncoder (void)
41 {
42 }
43 
44 void
45 CFrameEncoder::encodeElement (
46  const CElement * pElement)
47 {
48  CFrameEncoderStream MyEncoderStream(this);
49 
50  MyEncoderStream.putElement(pElement);
51 }
52 
53 unsigned int
54 CFrameEncoder::getLength(void)
55 {
56  return m_iNext;
57 }
58 
59 void
60 CFrameEncoderStream::putRequiredSubParameter (
61  const CParameter * pParameter,
62  const CTypeDescriptor * pRefType)
63 {
64  if(NULL == pParameter)
65  {
66  CErrorDetails * pError = &m_pEncoder->m_ErrorDetails;
67 
68  pError->missingParameter(pRefType);
69 
70  return;
71  }
72 
73  CFrameEncoderStream NestEncoderStream(this);
74 
75  NestEncoderStream.putElement(pParameter);
76 }
77 
78 void
79 CFrameEncoderStream::putOptionalSubParameter (
80  const CParameter * pParameter,
81  const CTypeDescriptor * pRefType)
82 {
83  if(NULL == pParameter)
84  {
85  return;
86  }
87 
88  CFrameEncoderStream NestEncoderStream(this);
89 
90  NestEncoderStream.putElement(pParameter);
91 }
92 
93 void
94 CFrameEncoderStream::putRequiredSubParameterList (
95  const tListOfParameters * pParameterList,
96  const CTypeDescriptor * pRefType)
97 {
98  if(pParameterList->empty())
99  {
100  CErrorDetails * pError = &m_pEncoder->m_ErrorDetails;
101 
102  pError->missingParameter(pRefType);
103 
104  return;
105  }
106 
107  for(
108  tListOfParameters::const_iterator Cur = pParameterList->begin();
109  Cur != pParameterList->end();
110  Cur++)
111  {
112  putRequiredSubParameter(*Cur, pRefType);
113  }
114 }
115 
116 void
117 CFrameEncoderStream::putOptionalSubParameterList (
118  const tListOfParameters * pParameterList,
119  const CTypeDescriptor * pRefType)
120 {
121  for(
122  tListOfParameters::const_iterator Cur = pParameterList->begin();
123  Cur != pParameterList->end();
124  Cur++)
125  {
126  putRequiredSubParameter(*Cur, pRefType);
127  }
128 }
129 
130 
131 void
132 CFrameEncoder::next_u8 (
133  llrp_u8_t Value)
134 {
135  assert(m_iNext + 1u <= m_nBuffer);
136 
137  m_pBuffer[m_iNext++] = Value;
138 }
139 
140 void
141 CFrameEncoder::next_u16 (
142  llrp_u16_t Value)
143 {
144  assert(m_iNext + 2u <= m_nBuffer);
145 
146  m_pBuffer[m_iNext++] = Value >> 8u;
147  m_pBuffer[m_iNext++] = Value >> 0u;
148 }
149 
150 void
151 CFrameEncoder::next_u32 (
152  llrp_u32_t Value)
153 {
154  assert(m_iNext + 4u <= m_nBuffer);
155 
156  m_pBuffer[m_iNext++] = Value >> 24u;
157  m_pBuffer[m_iNext++] = Value >> 16u;
158  m_pBuffer[m_iNext++] = Value >> 8u;
159  m_pBuffer[m_iNext++] = Value >> 0u;
160 }
161 
162 void
163 CFrameEncoder::next_u64 (
164  llrp_u64_t Value)
165 {
166  assert(m_iNext + 8u <= m_nBuffer);
167 
168  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 56u);
169  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 48u);
170  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 40u);
171  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 32u);
172  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 24u);
173  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 16u);
174  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 8u);
175  m_pBuffer[m_iNext++] = (llrp_byte_t)(Value >> 0u);
176 }
177 
178 /*
179  * 8-bit types
180  */
181 
182 void
183 CFrameEncoderStream::put_u8 (
184  llrp_u8_t Value,
185  const CFieldDescriptor * pFieldDescriptor)
186 {
187  if(checkAvailable(1u, pFieldDescriptor))
188  {
189  m_pEncoder->next_u8(Value);
190  }
191 }
192 
193 void
194 CFrameEncoderStream::put_s8 (
195  llrp_s8_t Value,
196  const CFieldDescriptor * pFieldDescriptor)
197 {
198  if(checkAvailable(1u, pFieldDescriptor))
199  {
200  m_pEncoder->next_u8(Value);
201  }
202 }
203 
204 void
205 CFrameEncoderStream::put_u8v (
206  llrp_u8v_t Value,
207  const CFieldDescriptor * pFieldDescriptor)
208 {
209  unsigned int nByte;
210 
211  nByte = 2u + Value.m_nValue * 1u;
212 
213  if(checkAvailable(nByte, pFieldDescriptor))
214  {
215  unsigned int i;
216 
217  m_pEncoder->next_u16(Value.m_nValue);
218  for(i = 0; i < Value.m_nValue; i++)
219  {
220  m_pEncoder->next_u8(Value.m_pValue[i]);
221  }
222  }
223 }
224 
225 void
226 CFrameEncoderStream::put_s8v (
227  llrp_s8v_t Value,
228  const CFieldDescriptor * pFieldDescriptor)
229 {
230  unsigned int nByte;
231 
232  nByte = 2u + Value.m_nValue * 1u;
233 
234  if(checkAvailable(nByte, pFieldDescriptor))
235  {
236  unsigned int i;
237 
238  m_pEncoder->next_u16(Value.m_nValue);
239  for(i = 0; i < Value.m_nValue; i++)
240  {
241  m_pEncoder->next_u8(Value.m_pValue[i]);
242  }
243  }
244 }
245 
246 /*
247  * 16-bit types
248  */
249 
250 void
251 CFrameEncoderStream::put_u16 (
252  llrp_u16_t Value,
253  const CFieldDescriptor * pFieldDescriptor)
254 {
255  if(checkAvailable(2u, pFieldDescriptor))
256  {
257  m_pEncoder->next_u16(Value);
258  }
259 }
260 
261 void
262 CFrameEncoderStream::put_s16 (
263  llrp_s16_t Value,
264  const CFieldDescriptor * pFieldDescriptor)
265 {
266  if(checkAvailable(2u, pFieldDescriptor))
267  {
268  m_pEncoder->next_u16(Value);
269  }
270 }
271 
272 void
273 CFrameEncoderStream::put_u16v (
274  llrp_u16v_t Value,
275  const CFieldDescriptor * pFieldDescriptor)
276 {
277  unsigned int nByte;
278 
279  nByte = 2u + Value.m_nValue * 2u;
280 
281  if(checkAvailable(nByte, pFieldDescriptor))
282  {
283  unsigned int i;
284 
285  m_pEncoder->next_u16(Value.m_nValue);
286  for(i = 0; i < Value.m_nValue; i++)
287  {
288  m_pEncoder->next_u16(Value.m_pValue[i]);
289  }
290  }
291 }
292 
293 void
294 CFrameEncoderStream::put_s16v (
295  llrp_s16v_t Value,
296  const CFieldDescriptor * pFieldDescriptor)
297 {
298  unsigned int nByte;
299 
300  nByte = 2u + Value.m_nValue * 2u;
301 
302  if(checkAvailable(nByte, pFieldDescriptor))
303  {
304  unsigned int i;
305 
306  m_pEncoder->next_u16(Value.m_nValue);
307  for(i = 0; i < Value.m_nValue; i++)
308  {
309  m_pEncoder->next_u16(Value.m_pValue[i]);
310  }
311  }
312 }
313 
314 /*
315  * 32-bit types
316  */
317 
318 void
319 CFrameEncoderStream::put_u32 (
320  llrp_u32_t Value,
321  const CFieldDescriptor * pFieldDescriptor)
322 {
323  if(checkAvailable(4u, pFieldDescriptor))
324  {
325  m_pEncoder->next_u32(Value);
326  }
327 }
328 
329 void
330 CFrameEncoderStream::put_s32 (
331  llrp_s32_t Value,
332  const CFieldDescriptor * pFieldDescriptor)
333 {
334  if(checkAvailable(4u, pFieldDescriptor))
335  {
336  m_pEncoder->next_u32(Value);
337  }
338 }
339 
340 void
341 CFrameEncoderStream::put_u32v (
342  llrp_u32v_t Value,
343  const CFieldDescriptor * pFieldDescriptor)
344 {
345  unsigned int nByte;
346 
347  nByte = 2u + Value.m_nValue * 4u;
348 
349  if(checkAvailable(nByte, pFieldDescriptor))
350  {
351  unsigned int i;
352 
353  m_pEncoder->next_u16(Value.m_nValue);
354  for(i = 0; i < Value.m_nValue; i++)
355  {
356  m_pEncoder->next_u32(Value.m_pValue[i]);
357  }
358  }
359 }
360 
361 void
362 CFrameEncoderStream::put_s32v (
363  llrp_s32v_t Value,
364  const CFieldDescriptor * pFieldDescriptor)
365 {
366  unsigned int nByte;
367 
368  nByte = 2u + Value.m_nValue * 4u;
369 
370  if(checkAvailable(nByte, pFieldDescriptor))
371  {
372  unsigned int i;
373 
374  m_pEncoder->next_u16(Value.m_nValue);
375  for(i = 0; i < Value.m_nValue; i++)
376  {
377  m_pEncoder->next_u32(Value.m_pValue[i]);
378  }
379  }
380 }
381 
382 /*
383  * 64-bit types
384  */
385 
386 void
387 CFrameEncoderStream::put_u64 (
388  llrp_u64_t Value,
389  const CFieldDescriptor * pFieldDescriptor)
390 {
391  if(checkAvailable(8u, pFieldDescriptor))
392  {
393  m_pEncoder->next_u64(Value);
394  }
395 }
396 
397 void
398 CFrameEncoderStream::put_s64 (
399  llrp_s64_t Value,
400  const CFieldDescriptor * pFieldDescriptor)
401 {
402  if(checkAvailable(8u, pFieldDescriptor))
403  {
404  m_pEncoder->next_u64(Value);
405  }
406 }
407 
408 void
409 CFrameEncoderStream::put_u64v (
410  llrp_u64v_t Value,
411  const CFieldDescriptor * pFieldDescriptor)
412 {
413  unsigned int nByte;
414 
415  nByte = 2u + Value.m_nValue * 8u;
416 
417  if(checkAvailable(nByte, pFieldDescriptor))
418  {
419  unsigned int i;
420 
421  m_pEncoder->next_u16(Value.m_nValue);
422  for(i = 0; i < Value.m_nValue; i++)
423  {
424  m_pEncoder->next_u64(Value.m_pValue[i]);
425  }
426  }
427 }
428 
429 void
430 CFrameEncoderStream::put_s64v (
431  llrp_s64v_t Value,
432  const CFieldDescriptor * pFieldDescriptor)
433 {
434  unsigned int nByte;
435 
436  nByte = 2u + Value.m_nValue * 8u;
437 
438  if(checkAvailable(nByte, pFieldDescriptor))
439  {
440  unsigned int i;
441 
442  m_pEncoder->next_u16(Value.m_nValue);
443  for(i = 0; i < Value.m_nValue; i++)
444  {
445  m_pEncoder->next_u64(Value.m_pValue[i]);
446  }
447  }
448 }
449 
450 /*
451  * Special types
452  */
453 
454 void
455 CFrameEncoderStream::put_u1 (
456  llrp_u1_t Value,
457  const CFieldDescriptor * pFieldDescriptor)
458 {
459  putBitField(1u, Value, pFieldDescriptor);
460 }
461 
462 void
463 CFrameEncoderStream::put_u1v (
464  llrp_u1v_t Value,
465  const CFieldDescriptor * pFieldDescriptor)
466 {
467  unsigned int nByte;
468 
469  nByte = (Value.m_nBit + 7u) / 8u;
470 
471  if(checkAvailable(2u + nByte, pFieldDescriptor))
472  {
473  unsigned int i;
474 
475  m_pEncoder->next_u16(Value.m_nBit);
476  for(i = 0; i < nByte; i++)
477  {
478  m_pEncoder->next_u8(Value.m_pValue[i]);
479  }
480  }
481 }
482 
483 void
484 CFrameEncoderStream::put_u2 (
485  llrp_u2_t Value,
486  const CFieldDescriptor * pFieldDescriptor)
487 {
488  putBitField(2u, Value, pFieldDescriptor);
489 }
490 
491 void
492 CFrameEncoderStream::put_u96 (
493  llrp_u96_t Value,
494  const CFieldDescriptor * pFieldDescriptor)
495 {
496  if(checkAvailable(12u, pFieldDescriptor))
497  {
498  unsigned int i;
499 
500  for(i = 0; i < 12u; i++)
501  {
502  m_pEncoder->next_u8(Value.m_aValue[i]);
503  }
504  }
505 }
506 
507 void
508 CFrameEncoderStream::put_utf8v (
509  llrp_utf8v_t Value,
510  const CFieldDescriptor * pFieldDescriptor)
511 {
512  unsigned int nByte;
513 
514  nByte = 2u + Value.m_nValue * 1u;
515 
516  if(checkAvailable(nByte, pFieldDescriptor))
517  {
518  unsigned int i;
519 
520  m_pEncoder->next_u16(Value.m_nValue);
521  for(i = 0; i < Value.m_nValue; i++)
522  {
523  m_pEncoder->next_u8(Value.m_pValue[i]);
524  }
525  }
526 }
527 
528 void
529 CFrameEncoderStream::put_bytesToEnd (
530  llrp_bytesToEnd_t Value,
531  const CFieldDescriptor * pFieldDescriptor)
532 {
533  unsigned int nByte;
534 
535  nByte = Value.m_nValue * 1u;
536 
537  if(checkAvailable(nByte, pFieldDescriptor))
538  {
539  unsigned int i;
540 
541  for(i = 0; i < Value.m_nValue; i++)
542  {
543  m_pEncoder->next_u8(Value.m_pValue[i]);
544  }
545  }
546 }
547 
548 /*
549  * Enumerated types of various sizes
550  */
551 
552 void
553 CFrameEncoderStream::put_e1 (
554  int eValue,
555  const CFieldDescriptor * pFieldDescriptor)
556 {
557  put_u1((llrp_u1_t)eValue, pFieldDescriptor);
558 }
559 
560 void
561 CFrameEncoderStream::put_e2 (
562  int eValue,
563  const CFieldDescriptor * pFieldDescriptor)
564 {
565  put_u2((llrp_u2_t)eValue, pFieldDescriptor);
566 }
567 
568 void
569 CFrameEncoderStream::put_e8 (
570  int eValue,
571  const CFieldDescriptor * pFieldDescriptor)
572 {
573  put_u8((llrp_u8_t)eValue, pFieldDescriptor);
574 }
575 
576 void
577 CFrameEncoderStream::put_e16 (
578  int eValue,
579  const CFieldDescriptor * pFieldDescriptor)
580 {
581  put_u16((llrp_u16_t)eValue, pFieldDescriptor);
582 }
583 
584 void
585 CFrameEncoderStream::put_e32 (
586  int eValue,
587  const CFieldDescriptor * pFieldDescriptor)
588 {
589  put_u32((llrp_u32_t)eValue, pFieldDescriptor);
590 }
591 
592 void
593 CFrameEncoderStream::put_e8v (
594  llrp_u8v_t Value,
595  const CFieldDescriptor * pFieldDescriptor)
596 {
597  put_u8v(Value, pFieldDescriptor);
598 }
599 
600 /*
601  * Reserved types are some number of bits
602  */
603 
604 void
605 CFrameEncoderStream::put_reserved (
606  unsigned int nBits)
607 {
608  CErrorDetails * pError = &m_pEncoder->m_ErrorDetails;
609 
610  if(RC_OK != pError->m_eResultCode)
611  {
612  return;
613  }
614 
615  while(nBits > 0)
616  {
617  unsigned int Step = 7u & nBits;
618 
619  if(0 != m_pEncoder->m_nBitFieldResid)
620  {
621  if(Step != m_pEncoder->m_nBitFieldResid)
622  {
623  pError->m_eResultCode = RC_UnalignedReservedBits;
624  pError->m_pWhatStr = "unaligned reserved bits";
625  pError->m_pRefType = m_pRefType;
626  pError->m_pRefField = NULL;
627  pError->m_OtherDetail = m_pEncoder->m_iNext;
628  return;
629  }
630 
631  m_pEncoder->next_u8(m_pEncoder->m_BitFieldBuffer);
632  nBits -= Step;
633  m_pEncoder->m_BitFieldBuffer = 0;
634  m_pEncoder->m_nBitFieldResid = 0;
635  }
636  else
637  {
638  if(0 != Step)
639  {
640  pError->m_eResultCode = RC_UnalignedReservedBits;
641  pError->m_pWhatStr = "unaligned reserved bits";
642  pError->m_pRefType = m_pRefType;
643  pError->m_pRefField = NULL;
644  pError->m_OtherDetail = m_pEncoder->m_iNext;
645  return;
646  }
647 
648  if(m_pEncoder->m_iNext >= m_pEncoder->m_nBuffer)
649  {
650  pError->m_eResultCode = RC_ReservedBitsOverrun;
651  pError->m_pWhatStr = "overrun at reserved bits";
652  pError->m_pRefType = m_pRefType;
653  pError->m_pRefField = NULL;
654  pError->m_OtherDetail = m_pEncoder->m_iNext;
655  return;
656  }
657 
658  m_pEncoder->next_u8(0);
659  nBits -= 8;
660  }
661  }
662 }
663 
664 CFrameEncoderStream::CFrameEncoderStream (
665  CFrameEncoder * pEncoder)
666 {
667  m_pEncoder = pEncoder;
668  m_pEnclosingEncoderStream = NULL;
669  m_iBegin = m_pEncoder->m_iNext;
670  m_pRefType = NULL;
671 }
672 
673 CFrameEncoderStream::CFrameEncoderStream (
674  CFrameEncoderStream * pEnclosingEncoderStream)
675 {
676  m_pEncoder = pEnclosingEncoderStream->m_pEncoder;
677  m_pEnclosingEncoderStream = pEnclosingEncoderStream;
678  m_iBegin = m_pEncoder->m_iNext;
679  m_pRefType = NULL;
680 }
681 
682 void
683 CFrameEncoderStream::putElement (
684  const CElement * pElement)
685 {
686  CErrorDetails * pError = &m_pEncoder->m_ErrorDetails;
687  enum { MSG, TLV, TV, CUST_MSG, CUST_TLV } eFormat;
688 
689  if(RC_OK != pError->m_eResultCode)
690  {
691  return;
692  }
693 
694  m_pRefType = pElement->m_pType;
695 
697  {
698  eFormat = (NULL == m_pRefType->m_pVendorDescriptor) ? MSG : CUST_MSG;
699  }
700  else if(NULL == m_pRefType->m_pVendorDescriptor &&
701  128 > m_pRefType->m_TypeNum)
702  {
703  /* TV parameter, never custom, no length */
704  eFormat = TV;
705  }
706  else
707  {
708  /* TLV parameter */
709  eFormat = (NULL == m_pRefType->m_pVendorDescriptor) ? TLV : CUST_TLV;
710  }
711 
712  /*
713  * Format the element header. The length part, if one,
714  * is a place holder and back-patched later.
715  */
716  switch(eFormat)
717  {
718  default:
719  assert(0);
720  break;
721 
722  case MSG:
723  {
724  llrp_u16_t VersType;
725 
726  VersType = (1u << 10u) | m_pRefType->m_TypeNum;
727  put_u16(VersType, &g_fdMessageHeader_Type);
728  put_u32(0, &g_fdMessageHeader_Length);
729  put_u32(((const CMessage *)pElement)->getMessageID(),
730  &g_fdMessageHeader_MessageID);
731  }
732  break;
733 
734  case CUST_MSG:
735  {
736  llrp_u16_t VersType;
737 
738  /* Custom message */
739  VersType = (1u << 10u) | 1023u;
740  put_u16(VersType,
741  &g_fdMessageHeader_Type);
742  /* length is a placeholder */
743  put_u32(0, &g_fdMessageHeader_Length);
744  put_u32(((const CMessage *)pElement)->getMessageID(),
745  &g_fdMessageHeader_MessageID);
746  put_u32(
748  &g_fdMessageHeader_VendorPEN);
749  put_u8(m_pRefType->m_TypeNum, &g_fdMessageHeader_Subtype);
750  }
751  break;
752 
753  case TV:
754  put_u8(m_pRefType->m_TypeNum | 0x80u, &g_fdParameterHeader_TVType);
755  break;
756 
757  case TLV:
758  /* Standard parameter */
759  put_u16(m_pRefType->m_TypeNum, &g_fdParameterHeader_TLVType);
760  put_u16(0, &g_fdParameterHeader_TLVLength);
761  break;
762 
763  case CUST_TLV:
764  /* Custom parameter */
765  put_u16(1023u, &g_fdParameterHeader_TLVType);
766  put_u16(0, &g_fdParameterHeader_TLVLength);
767  put_u32(
769  &g_fdParameterHeader_VendorPEN);
770  put_u32(m_pRefType->m_TypeNum, &g_fdParameterHeader_Subtype);
771  break;
772  }
773 
774  if(RC_OK != pError->m_eResultCode)
775  {
776  return;
777  }
778 
779  pElement->encode(this);
780 
781  unsigned int nLength;
782  unsigned char * pLen;
783 
784  nLength = m_pEncoder->m_iNext - m_iBegin;
785  pLen = &m_pEncoder->m_pBuffer[m_iBegin];
786 
787  switch(eFormat)
788  {
789  default:
790  assert(0);
791  break;
792 
793  case MSG:
794  case CUST_MSG:
795  assert(nLength >= 10);
796  pLen += 2;
797  pLen[0] = nLength >> 24u;
798  pLen[1] = nLength >> 16u;
799  pLen[2] = nLength >> 8u;
800  pLen[3] = nLength >> 0u;
801  break;
802 
803  case TV:
804  break;
805 
806  case TLV:
807  case CUST_TLV:
808  assert(nLength >= 4);
809  pLen += 2;
810  pLen[0] = nLength >> 8u;
811  pLen[1] = nLength >> 0u;
812  break;
813  }
814 }
815 
816 llrp_bool_t
817 CFrameEncoderStream::checkAvailable (
818  unsigned int nByte,
819  const CFieldDescriptor * pFieldDescriptor)
820 {
821  CErrorDetails * pError = &m_pEncoder->m_ErrorDetails;
822 
823  if(RC_OK != pError->m_eResultCode)
824  {
825  return FALSE;
826  }
827 
828  if(m_pEncoder->m_iNext + nByte > m_pEncoder->m_nBuffer)
829  {
830  pError->m_eResultCode = RC_FieldOverrun;
831  pError->m_pRefField = pFieldDescriptor;
832  pError->m_pRefType = m_pRefType;
833  pError->m_pWhatStr = "overrun at field";
834  pError->m_OtherDetail = m_pEncoder->m_iNext;
835 
836  return FALSE;
837  }
838 
839  if(0 != m_pEncoder->m_nBitFieldResid)
840  {
841  pError->m_eResultCode = RC_UnalignedBitField;
842  pError->m_pRefField = pFieldDescriptor;
843  pError->m_pRefType = m_pRefType;
844  pError->m_pWhatStr = "unalign/incomplete bit field";
845  pError->m_OtherDetail = m_pEncoder->m_iNext;
846 
847  return FALSE;
848  }
849 
850  return TRUE;
851 }
852 
853 llrp_bool_t
854 CFrameEncoderStream::putBitField (
855  unsigned int nBit,
856  unsigned int Value,
857  const CFieldDescriptor * pFieldDescriptor)
858 {
859  CErrorDetails * pError = &m_pEncoder->m_ErrorDetails;
860 
861  if(0 == m_pEncoder->m_nBitFieldResid)
862  {
863  if(!checkAvailable(1u, pFieldDescriptor))
864  {
865  return FALSE;
866  }
867  m_pEncoder->m_BitFieldBuffer = 0;
868  m_pEncoder->m_nBitFieldResid = 8u;
869  }
870 
871  if(m_pEncoder->m_nBitFieldResid < nBit)
872  {
873  pError->m_eResultCode = RC_UnalignedBitField;
874  pError->m_pWhatStr = "unalign/incomplete bit field";
875  pError->m_pRefType = m_pRefType;
876  pError->m_pRefField = pFieldDescriptor;
877  pError->m_OtherDetail = m_pEncoder->m_iNext;
878  return FALSE;
879  }
880 
881  m_pEncoder->m_nBitFieldResid -= nBit;
882 
883  Value &= (1u << nBit) - 1u;
884 
885  m_pEncoder->m_BitFieldBuffer |= Value << m_pEncoder->m_nBitFieldResid;
886 
887 
888  if(0 == m_pEncoder->m_nBitFieldResid)
889  {
890  m_pEncoder->next_u8(m_pEncoder->m_BitFieldBuffer);
891  m_pEncoder->m_BitFieldBuffer = 0;
892  m_pEncoder->m_nBitFieldResid = 0;
893  }
894 
895  return TRUE;
896 }
897 
898 };
const CTypeDescriptor * m_pRefType
If non-NULL this is the type descriptors for the errored type.
Definition: ltkcpp_base.h:639
Based type descriptions for the LTKCPP library.
llrp_u32_t m_TypeNum
Type number or, for custom, subtype number.
Definition: ltkcpp_base.h:772
Classes to encode and decod LLRP binary frames.
Based types for the LKTCPP library.
CErrorDetails(void)
Default Constructor.
const CVendorDescriptor * m_pVendorDescriptor
NULL=>standard LLRP, !NULL=>Vendor (PEN) of custom message or parameter.
Definition: ltkcpp_base.h:766
llrp_u32_t m_VendorID
Vendor PEN of a custom message or parameter.
Definition: ltkcpp_base.h:692
Definition: ltkcpp.h:45
llrp_bool_t m_bIsMessage
TRUE for a message type, FALSE for a parameter type.
Definition: ltkcpp_base.h:759