LTKCPP-- LLRP Toolkit C Plus Plus Library
|
00001 00002 /* 00003 ***************************************************************************** 00004 * * 00005 * IMPINJ CONFIDENTIAL AND PROPRIETARY * 00006 * * 00007 * This source code is the sole property of Impinj, Inc. Reproduction or * 00008 * utilization of this source code in whole or in part is forbidden without * 00009 * the prior written consent of Impinj, Inc. * 00010 * * 00011 * (c) Copyright Impinj, Inc. 2007,2008. All rights reserved. * 00012 * * 00013 *****************************************************************************/ 00014 00027 #include <assert.h> 00028 #include <ctype.h> 00029 #include <string.h> 00030 #include <time.h> 00031 #include <stdio.h> 00032 00033 #include "ltkcpp_platform.h" 00034 #include "ltkcpp_base.h" 00035 00036 #include "libxml/parser.h" 00037 #include "libxml/tree.h" 00038 00039 #include "ltkcpp_xmltext.h" 00040 00041 00042 namespace LLRP 00043 { 00044 00045 CXMLTextDecoder::CXMLTextDecoder ( 00046 const CTypeRegistry * pTypeRegistry, 00047 char * pBuffer, 00048 int nBuffer) : CDecoder(pTypeRegistry) 00049 00050 { 00051 /* set the line numbers for error reporting */ 00052 xmlLineNumbersDefault(1); 00053 00054 /* Read in the XML from the buffer into the XML Reader */ 00055 m_pDoc = xmlReadMemory((char*) pBuffer, nBuffer, "noName.xml", NULL, 00056 XML_PARSE_COMPACT | XML_PARSE_NONET); 00057 00058 if(NULL != m_pDoc) 00059 { 00060 /* Initialize the other decoder state variables */ 00061 m_pxmlNodeTree = xmlDocGetRootElement(m_pDoc); 00062 } 00063 else 00064 { 00065 fprintf(stderr, "could not parse XML memory buffer"); 00066 } 00067 } 00068 00069 CXMLTextDecoder::CXMLTextDecoder ( 00070 const CTypeRegistry * pTypeRegistry, 00071 struct _xmlNode * pNodeTree) : CDecoder(pTypeRegistry) 00072 { 00073 /* set the line numbers for error reporting */ 00074 xmlLineNumbersDefault(1); 00075 00076 /* Read in the XML from the buffer into the XML Reader */ 00077 m_pDoc = NULL; 00078 /* Initialize the other decoder state variables */ 00079 m_pxmlNodeTree = pNodeTree; 00080 } 00081 00082 CXMLTextDecoder::CXMLTextDecoder ( 00083 const CTypeRegistry * pTypeRegistry, 00084 char * fname) : CDecoder(pTypeRegistry) 00085 { 00086 /* set the line numbers for error reporting */ 00087 xmlLineNumbersDefault(1); 00088 00089 /* Read in the XML from the file into the XML Reader */ 00090 m_pDoc = xmlReadFile(fname, 00091 NULL, 00092 XML_PARSE_COMPACT | XML_PARSE_NONET); 00093 00094 if(NULL != m_pDoc) 00095 { 00096 /* Initialize the other decoder state variables */ 00097 m_pxmlNodeTree = xmlDocGetRootElement(m_pDoc); 00098 } 00099 else 00100 { 00101 fprintf(stderr, "could not parse XML file"); 00102 } 00103 } 00104 00105 CXMLTextDecoder::~CXMLTextDecoder (void) 00106 { 00107 if(NULL != m_pDoc) 00108 { 00109 xmlFreeDoc(m_pDoc); 00110 m_pDoc = NULL; 00111 } 00112 m_pxmlNodeTree = NULL; 00113 } 00114 00115 CMessage * 00116 CXMLTextDecoder::decodeMessage (void) 00117 { 00118 CMessage * pMessage; 00119 CXMLTextDecoderStream DecoderStream(this); 00120 CErrorDetails *pError = &m_ErrorDetails; 00121 00122 if(NULL == m_pxmlNodeTree) 00123 { 00124 pError->m_eResultCode = RC_MiscError; 00125 pError->m_pWhatStr = "Unable to Extract XML Node Tree"; 00126 pError->m_pRefType = NULL; 00127 pError->m_pRefField = NULL; 00128 pError->m_OtherDetail = (int) 0; 00129 return NULL; 00130 } 00131 pMessage = (CMessage *) DecoderStream.decodeElement(TRUE, TRUE); 00132 00133 return pMessage; 00134 } 00135 00136 void 00137 CXMLTextDecoder::cleanupParser (void) 00138 { 00139 xmlCleanupParser(); 00140 } 00141 00142 CXMLTextDecoderStream::CXMLTextDecoderStream ( 00143 CXMLTextDecoder * pDecoder) 00144 { 00145 00146 m_pDecoder = pDecoder; 00147 m_pEnclosingDecoderStream = NULL; 00148 m_pRefType = NULL; 00149 m_pTargetNode = pDecoder->m_pxmlNodeTree; 00150 m_pCurrentChildNode = NULL; 00151 } 00152 00153 CXMLTextDecoderStream::CXMLTextDecoderStream ( 00154 CXMLTextDecoderStream * pEnclosingDecoderStream) 00155 { 00156 m_pDecoder = pEnclosingDecoderStream->m_pDecoder; 00157 m_pEnclosingDecoderStream = pEnclosingDecoderStream; 00158 m_pRefType = pEnclosingDecoderStream->m_pRefType; 00159 m_pTargetNode = pEnclosingDecoderStream->m_pCurrentChildNode; 00160 m_pCurrentChildNode = NULL; 00161 } 00162 00163 CElement * 00164 CXMLTextDecoderStream::decodeElement ( 00165 int bAllowMessage, 00166 int bSkipBlanks) 00167 { 00168 CErrorDetails *pError = &m_pDecoder->m_ErrorDetails; 00169 const CTypeDescriptor* pTypeDescriptor; 00170 llrp_u32_t MessageID = 0; 00171 CElement * pElement; 00172 00173 if(RC_OK != pError->m_eResultCode) 00174 { 00175 return NULL; 00176 } 00177 00178 /* get the first interesting node as the target node */ 00179 if(bSkipBlanks) 00180 { 00181 while ((NULL != m_pTargetNode) && 00182 ( isInsignificantNode(m_pTargetNode) || 00183 xmlIsBlankNode(m_pTargetNode))) 00184 { 00185 m_pTargetNode = m_pTargetNode->next; 00186 } 00187 } 00188 00189 /* no interestig target node found. THis is OK as its an empty decode */ 00190 if(NULL == m_pTargetNode) 00191 { 00192 return NULL; 00193 } 00194 00195 /* first interesting node had better be an element */ 00196 if(m_pTargetNode->type != XML_ELEMENT_NODE) 00197 { 00198 pError->m_eResultCode = RC_XMLInvalidNodeType; 00199 pError->m_pWhatStr = "unexpected XML node type"; 00200 pError->m_pRefType = m_pRefType; 00201 pError->m_pRefField = NULL; 00202 pError->m_OtherDetail = (int) m_pTargetNode->line; 00203 return NULL; 00204 } 00205 00206 /* look up the type descriptor*/ 00207 pTypeDescriptor = m_pDecoder->m_pRegistry->lookupByName( 00208 (char*) m_pTargetNode->name); 00209 00210 if(NULL == pTypeDescriptor) 00211 { 00212 pError->m_eResultCode = RC_UnknownParameterType; 00213 pError->m_pWhatStr = "unknown message or parameter type"; 00214 pError->m_pRefType = m_pRefType; 00215 pError->m_pRefField = NULL; 00216 pError->m_OtherDetail = (int) m_pTargetNode->line; 00217 return NULL; 00218 } 00219 00220 m_pRefType = pTypeDescriptor; 00221 00222 /* process messages a bit specially */ 00223 if(pTypeDescriptor->m_bIsMessage) 00224 { 00225 xmlChar * pMessageIDStr; 00226 00227 if(!bAllowMessage) 00228 { 00229 pError->m_eResultCode = RC_MiscError; 00230 pError->m_pWhatStr = "message as subparameter"; 00231 pError->m_pRefType = m_pRefType; 00232 pError->m_pRefField = NULL; 00233 pError->m_OtherDetail = (int) m_pTargetNode->line; 00234 return NULL; 00235 } 00236 00237 /* get the messageID Attribute */ 00238 pMessageIDStr = xmlGetProp(m_pTargetNode, 00239 (xmlChar*) "MessageID"); 00240 if(NULL != pMessageIDStr) 00241 { 00242 char * pArg = (char *) pMessageIDStr; 00243 char * pTail = pArg + strlen((char*) pMessageIDStr); 00244 char * pTmp; 00245 cleanString((const llrp_u8_t **) &pArg, (const llrp_u8_t **) &pTail); 00246 MessageID = strtoul(pArg, &pTmp, 10); 00247 xmlFree(pMessageIDStr); 00248 00249 if(pTail != pTmp) 00250 { 00251 /* malformed */ 00252 pError->m_eResultCode = RC_MiscError; 00253 pError->m_pWhatStr = "malformed MessageID"; 00254 pError->m_pRefType = m_pRefType; 00255 pError->m_pRefField = NULL; 00256 pError->m_OtherDetail = (int) m_pTargetNode->line; 00257 return NULL; 00258 } 00259 } 00260 } 00261 00262 /* create our element to hold the information */ 00263 pElement = pTypeDescriptor->constructElement(); 00264 00265 if(NULL == pElement) 00266 { 00267 pError->m_eResultCode = RC_MessageAllocationFailed; 00268 pError->m_pWhatStr = "element allocation failed"; 00269 pError->m_pRefType = m_pRefType; 00270 pError->m_pRefField = NULL; 00271 pError->m_OtherDetail = (int) m_pTargetNode->line; 00272 return NULL; 00273 } 00274 00275 /* only write the message ID for messages */ 00276 if(pTypeDescriptor->m_bIsMessage) 00277 { 00278 ((CMessage *) pElement)->setMessageID(MessageID); 00279 } 00280 00281 /* now switch to decode the children which are the 00282 * fields and sub-parameters of this element */ 00283 m_pCurrentChildNode = m_pTargetNode->children; 00284 00285 /* decode the fields first */ 00286 pTypeDescriptor->m_pfDecodeFields(this, pElement); 00287 00288 if(RC_OK != pError->m_eResultCode) 00289 { 00290 delete pElement; 00291 return NULL; 00292 } 00293 00294 /* 00295 * Subparameters. 00296 * 00297 * loop through all the remaining children of the target node and try to find sub-parameters. 00298 * We are done when we don't have any more or error 00299 */ 00300 for(; m_pCurrentChildNode != NULL; 00301 m_pCurrentChildNode = m_pCurrentChildNode->next) 00302 { 00303 CElement * pSubElement; 00304 CParameter * pParameter; 00305 00306 if(isInsignificantNode(m_pCurrentChildNode)) 00307 { 00308 continue; 00309 } 00310 00311 if(xmlIsBlankNode(m_pCurrentChildNode)) 00312 { 00313 continue; 00314 } 00315 00316 CXMLTextDecoderStream NestStream(this); 00317 00318 pSubElement = NestStream.decodeElement(FALSE, FALSE); 00319 00320 /* nothing more to decode as a sub-element or failure */ 00321 if(NULL == pSubElement) 00322 { 00323 break; 00324 } 00325 00326 pParameter = (CParameter *) pSubElement; 00327 00328 pParameter->m_pParent = pElement; 00329 pElement->addSubParameterToAllList(pParameter); 00330 } 00331 00332 if(RC_OK != pError->m_eResultCode) 00333 { 00334 delete pElement; 00335 return NULL; 00336 } 00337 00338 pElement->assimilateSubParameters(pError); 00339 00340 if(RC_OK != pError->m_eResultCode) 00341 { 00342 delete pElement; 00343 return NULL; 00344 } 00345 00346 return pElement; 00347 } 00348 00350 llrp_u8_t 00351 CXMLTextDecoderStream::get_u8 ( 00352 const CFieldDescriptor * pFieldDesc) 00353 { 00354 llrp_u8_t Value; 00355 Value = (llrp_u8_t) getIntegerField(pFieldDesc, MIN_U8, MAX_U8); 00356 return Value; 00357 } 00358 00360 llrp_s8_t 00361 CXMLTextDecoderStream::get_s8 ( 00362 const CFieldDescriptor * pFieldDesc) 00363 { 00364 llrp_s8_t Value; 00365 Value = (llrp_s8_t) getIntegerField(pFieldDesc, MIN_S8, MAX_S8); 00366 return Value; 00367 } 00368 00370 llrp_u8v_t 00371 CXMLTextDecoderStream::get_u8v ( 00372 const CFieldDescriptor * pFieldDesc) 00373 { 00374 CErrorDetails * pError; 00375 llrp_u8v_t Value; 00376 llrp_s64v_t Tmp; 00377 00378 pError = &m_pDecoder->m_ErrorDetails; 00379 00380 switch(pFieldDesc->m_eFieldFormat) 00381 { 00382 /* assume normal format here is decimal */ 00383 case CFieldDescriptor::FMT_NORMAL: 00384 case CFieldDescriptor::FMT_DEC: 00385 Tmp = getSpacedVectorField(pFieldDesc, MIN_U8, MAX_U8); 00386 break; 00387 case CFieldDescriptor::FMT_HEX: 00388 Tmp = getFixedVectorField(pFieldDesc, 2, MIN_U8, MAX_U8); 00389 break; 00390 default: 00391 case CFieldDescriptor::FMT_UTF8: 00392 case CFieldDescriptor::FMT_DATETIME: 00393 if(NULL != pError) 00394 { 00395 pError->m_eResultCode = RC_MiscError; 00396 pError->m_pWhatStr = "Format type not support for field"; 00397 pError->m_pRefType = m_pRefType; 00398 pError->m_pRefField = pFieldDesc; 00399 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00400 } 00401 break; 00402 } 00403 00404 if(Tmp.m_nValue) 00405 { 00406 llrp_u16_t nValue; 00407 00408 nValue = Tmp.m_nValue; 00409 Value = llrp_u8v_t(nValue); 00410 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00411 { 00412 unsigned int Ix; 00413 00414 for(Ix = 0; Ix < nValue; Ix++) 00415 { 00416 Value.m_pValue[Ix] = (llrp_u8_t) Tmp.m_pValue[Ix]; 00417 } 00418 } 00419 } 00420 00421 return Value; 00422 } 00423 00425 llrp_s8v_t 00426 CXMLTextDecoderStream::get_s8v ( 00427 const CFieldDescriptor * pFieldDesc) 00428 { 00429 CErrorDetails * pError; 00430 llrp_s8v_t Value; 00431 llrp_s64v_t Tmp; 00432 00433 pError = &m_pDecoder->m_ErrorDetails; 00434 00435 switch(pFieldDesc->m_eFieldFormat) 00436 { 00437 /* assume normal format here is decimal */ 00438 case CFieldDescriptor::FMT_NORMAL: 00439 case CFieldDescriptor::FMT_DEC: 00440 Tmp = getSpacedVectorField(pFieldDesc, MIN_S8, MAX_S8); 00441 break; 00442 case CFieldDescriptor::FMT_HEX: 00443 Tmp = getFixedVectorField(pFieldDesc, 2, MIN_S8, MAX_S8); 00444 break; 00445 default: 00446 case CFieldDescriptor::FMT_UTF8: 00447 case CFieldDescriptor::FMT_DATETIME: 00448 if(NULL != pError) 00449 { 00450 pError->m_eResultCode = RC_MiscError; 00451 pError->m_pWhatStr = "Format type not support for field"; 00452 pError->m_pRefType = m_pRefType; 00453 pError->m_pRefField = pFieldDesc; 00454 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00455 } 00456 break; 00457 } 00458 00459 if(Tmp.m_nValue) 00460 { 00461 llrp_u16_t nValue; 00462 00463 nValue = Tmp.m_nValue; 00464 Value = llrp_s8v_t(nValue); 00465 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00466 { 00467 unsigned int Ix; 00468 00469 for(Ix = 0; Ix < nValue; Ix++) 00470 { 00471 Value.m_pValue[Ix] = (llrp_s8_t) Tmp.m_pValue[Ix]; 00472 } 00473 } 00474 } 00475 00476 return Value; 00477 } 00478 00479 /* 00480 * 16-bit types 00481 */ 00482 00484 llrp_u16_t 00485 CXMLTextDecoderStream::get_u16 ( 00486 const CFieldDescriptor * pFieldDesc) 00487 { 00488 llrp_u16_t Value; 00489 Value = (llrp_u16_t) getIntegerField(pFieldDesc, MIN_U16, MAX_U16); 00490 return Value; 00491 } 00492 00494 llrp_s16_t 00495 CXMLTextDecoderStream::get_s16 ( 00496 const CFieldDescriptor * pFieldDesc) 00497 { 00498 llrp_s16_t Value; 00499 Value = (llrp_s16_t) getIntegerField(pFieldDesc, MIN_S16, MAX_S16); 00500 return Value; 00501 } 00502 00504 llrp_u16v_t 00505 CXMLTextDecoderStream::get_u16v ( 00506 const CFieldDescriptor * pFieldDesc) 00507 { 00508 CErrorDetails * pError; 00509 llrp_u16v_t Value; 00510 llrp_s64v_t Tmp; 00511 00512 pError = &m_pDecoder->m_ErrorDetails; 00513 00514 switch(pFieldDesc->m_eFieldFormat) 00515 { 00516 /* assume normal format here is decimal */ 00517 case CFieldDescriptor::FMT_NORMAL: 00518 case CFieldDescriptor::FMT_DEC: 00519 case CFieldDescriptor::FMT_HEX: 00520 Tmp = getSpacedVectorField(pFieldDesc, MIN_U16, MAX_U16); 00521 break; 00522 default: 00523 case CFieldDescriptor::FMT_UTF8: 00524 case CFieldDescriptor::FMT_DATETIME: 00525 if(NULL != pError) 00526 { 00527 pError->m_eResultCode = RC_MiscError; 00528 pError->m_pWhatStr = "Format type not support for field"; 00529 pError->m_pRefType = m_pRefType; 00530 pError->m_pRefField = pFieldDesc; 00531 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00532 } 00533 break; 00534 } 00535 00536 if(Tmp.m_nValue) 00537 { 00538 llrp_u16_t nValue; 00539 00540 nValue = Tmp.m_nValue; 00541 Value = llrp_u16v_t(nValue); 00542 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00543 { 00544 unsigned int Ix; 00545 00546 for(Ix = 0; Ix < nValue; Ix++) 00547 { 00548 Value.m_pValue[Ix] = (llrp_u16_t) Tmp.m_pValue[Ix]; 00549 } 00550 } 00551 } 00552 return Value; 00553 } 00554 00556 llrp_s16v_t 00557 CXMLTextDecoderStream::get_s16v ( 00558 const CFieldDescriptor * pFieldDesc) 00559 { 00560 CErrorDetails * pError; 00561 llrp_s16v_t Value; 00562 llrp_s64v_t Tmp; 00563 00564 pError = &m_pDecoder->m_ErrorDetails; 00565 00566 switch(pFieldDesc->m_eFieldFormat) 00567 { 00568 /* assume normal format here is decimal */ 00569 case CFieldDescriptor::FMT_NORMAL: 00570 case CFieldDescriptor::FMT_DEC: 00571 case CFieldDescriptor::FMT_HEX: 00572 Tmp = getSpacedVectorField(pFieldDesc, MIN_S16, MAX_S16); 00573 break; 00574 default: 00575 case CFieldDescriptor::FMT_UTF8: 00576 case CFieldDescriptor::FMT_DATETIME: 00577 if(NULL != pError) 00578 { 00579 pError->m_eResultCode = RC_MiscError; 00580 pError->m_pWhatStr = "Format type not support for field"; 00581 pError->m_pRefType = m_pRefType; 00582 pError->m_pRefField = pFieldDesc; 00583 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00584 } 00585 break; 00586 } 00587 00588 if(Tmp.m_nValue) 00589 { 00590 llrp_u16_t nValue; 00591 00592 nValue = Tmp.m_nValue; 00593 Value = llrp_s16v_t(nValue); 00594 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00595 { 00596 unsigned int Ix; 00597 00598 for(Ix = 0; Ix < nValue; Ix++) 00599 { 00600 Value.m_pValue[Ix] = (llrp_s16_t) Tmp.m_pValue[Ix]; 00601 } 00602 } 00603 } 00604 return Value; 00605 } 00606 00607 /* 00608 * 32-bit types 00609 */ 00610 00612 llrp_u32_t 00613 CXMLTextDecoderStream::get_u32 ( 00614 const CFieldDescriptor * pFieldDesc) 00615 { 00616 llrp_u32_t Value; 00617 Value = (llrp_u32_t) getIntegerField(pFieldDesc, MIN_U32, MAX_U32); 00618 return Value; 00619 } 00620 00622 llrp_s32_t 00623 CXMLTextDecoderStream::get_s32 ( 00624 const CFieldDescriptor * pFieldDesc) 00625 { 00626 llrp_s32_t Value; 00627 Value = (llrp_s32_t) getIntegerField(pFieldDesc, MIN_S32, MAX_S32); 00628 return Value; 00629 } 00630 00632 llrp_u32v_t 00633 CXMLTextDecoderStream::get_u32v ( 00634 const CFieldDescriptor * pFieldDesc) 00635 { 00636 CErrorDetails * pError; 00637 llrp_u32v_t Value; 00638 llrp_s64v_t Tmp; 00639 00640 pError = &m_pDecoder->m_ErrorDetails; 00641 00642 switch(pFieldDesc->m_eFieldFormat) 00643 { 00644 /* assume normal format here is decimal */ 00645 case CFieldDescriptor::FMT_NORMAL: 00646 case CFieldDescriptor::FMT_DEC: 00647 case CFieldDescriptor::FMT_HEX: 00648 Tmp = getSpacedVectorField(pFieldDesc, MIN_U32, MAX_U32); 00649 break; 00650 default: 00651 case CFieldDescriptor::FMT_UTF8: 00652 case CFieldDescriptor::FMT_DATETIME: 00653 if(NULL != pError) 00654 { 00655 pError->m_eResultCode = RC_MiscError; 00656 pError->m_pWhatStr = "Format type not support for field"; 00657 pError->m_pRefType = m_pRefType; 00658 pError->m_pRefField = pFieldDesc; 00659 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00660 } 00661 break; 00662 } 00663 00664 if(Tmp.m_nValue) 00665 { 00666 llrp_u16_t nValue; 00667 00668 nValue = Tmp.m_nValue; 00669 Value = llrp_u32v_t(nValue); 00670 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00671 { 00672 unsigned int Ix; 00673 00674 for(Ix = 0; Ix < nValue; Ix++) 00675 { 00676 Value.m_pValue[Ix] = (llrp_u32_t) Tmp.m_pValue[Ix]; 00677 } 00678 } 00679 } 00680 return Value; 00681 } 00682 00684 llrp_s32v_t 00685 CXMLTextDecoderStream::get_s32v ( 00686 const CFieldDescriptor * pFieldDesc) 00687 { 00688 CErrorDetails * pError; 00689 llrp_s32v_t Value; 00690 llrp_s64v_t Tmp; 00691 00692 pError = &m_pDecoder->m_ErrorDetails; 00693 00694 switch(pFieldDesc->m_eFieldFormat) 00695 { 00696 /* assume normal format here is decimal */ 00697 case CFieldDescriptor::FMT_NORMAL: 00698 case CFieldDescriptor::FMT_DEC: 00699 case CFieldDescriptor::FMT_HEX: 00700 Tmp = getSpacedVectorField(pFieldDesc, MIN_S32, MAX_S32); 00701 break; 00702 default: 00703 case CFieldDescriptor::FMT_UTF8: 00704 case CFieldDescriptor::FMT_DATETIME: 00705 if(NULL != pError) 00706 { 00707 pError->m_eResultCode = RC_MiscError; 00708 pError->m_pWhatStr = "Format type not support for field"; 00709 pError->m_pRefType = m_pRefType; 00710 pError->m_pRefField = pFieldDesc; 00711 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00712 } 00713 break; 00714 } 00715 00716 if(Tmp.m_nValue) 00717 { 00718 llrp_u16_t nValue; 00719 00720 nValue = Tmp.m_nValue; 00721 Value = llrp_s32v_t(nValue); 00722 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00723 { 00724 unsigned int Ix; 00725 00726 for(Ix = 0; Ix < nValue; Ix++) 00727 { 00728 Value.m_pValue[Ix] = (llrp_s32_t) Tmp.m_pValue[Ix]; 00729 } 00730 } 00731 } 00732 return Value; 00733 } 00734 00735 /* 00736 * 64-bit types 00737 */ 00738 00740 llrp_u64_t 00741 CXMLTextDecoderStream::get_u64 ( 00742 const CFieldDescriptor * pFieldDesc) 00743 { 00744 llrp_u64_t Value; 00745 Value = (llrp_u64_t) getIntegerField(pFieldDesc, MIN_U64, MAX_U64); 00746 return Value; 00747 } 00748 00750 llrp_s64_t 00751 CXMLTextDecoderStream::get_s64 ( 00752 const CFieldDescriptor * pFieldDesc) 00753 { 00754 llrp_s64_t Value; 00755 Value = (llrp_s64_t) getIntegerField(pFieldDesc, MIN_S64, MAX_S64); 00756 return Value; 00757 } 00758 00760 llrp_u64v_t 00761 CXMLTextDecoderStream::get_u64v ( 00762 const CFieldDescriptor * pFieldDesc) 00763 { 00764 CErrorDetails * pError; 00765 llrp_u64v_t Value; 00766 llrp_s64v_t Tmp; 00767 00768 pError = &m_pDecoder->m_ErrorDetails; 00769 00770 switch(pFieldDesc->m_eFieldFormat) 00771 { 00772 /* assume normal format here is decimal */ 00773 case CFieldDescriptor::FMT_NORMAL: 00774 case CFieldDescriptor::FMT_DEC: 00775 case CFieldDescriptor::FMT_HEX: 00776 case CFieldDescriptor::FMT_DATETIME: 00777 Tmp = getSpacedVectorField(pFieldDesc, MIN_U64, MAX_U64); 00778 break; 00779 default: 00780 case CFieldDescriptor::FMT_UTF8: 00781 if(NULL != pError) 00782 { 00783 pError->m_eResultCode = RC_MiscError; 00784 pError->m_pWhatStr = "Format type not support for field"; 00785 pError->m_pRefType = m_pRefType; 00786 pError->m_pRefField = pFieldDesc; 00787 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00788 } 00789 break; 00790 } 00791 00792 if(Tmp.m_nValue) 00793 { 00794 llrp_u16_t nValue; 00795 00796 nValue = Tmp.m_nValue; 00797 Value = llrp_u64v_t(nValue); 00798 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00799 { 00800 unsigned int Ix; 00801 00802 for(Ix = 0; Ix < nValue; Ix++) 00803 { 00804 Value.m_pValue[Ix] = (llrp_u64_t) Tmp.m_pValue[Ix]; 00805 } 00806 } 00807 } 00808 return Value; 00809 } 00810 00812 llrp_s64v_t 00813 CXMLTextDecoderStream::get_s64v ( 00814 const CFieldDescriptor * pFieldDesc) 00815 { 00816 llrp_s64v_t Value; 00817 Value = getSpacedVectorField(pFieldDesc, MIN_S64, MAX_S64); 00818 return Value; 00819 } 00820 00821 /* 00822 * Special types 00823 */ 00824 00826 llrp_u1_t 00827 CXMLTextDecoderStream::get_u1 ( 00828 const CFieldDescriptor * pFieldDesc) 00829 { 00830 llrp_u1_t Value; 00831 Value = (llrp_u1_t) getIntegerField(pFieldDesc, 0, 1); 00832 return Value; 00833 } 00834 00836 llrp_u1v_t 00837 CXMLTextDecoderStream::get_u1v ( 00838 const CFieldDescriptor * pFieldDesc) 00839 { 00840 CErrorDetails * pError; 00841 llrp_u1v_t Value; 00842 llrp_s64v_t Tmp; 00843 00844 pError = &m_pDecoder->m_ErrorDetails; 00845 Tmp = getFixedVectorField(pFieldDesc, 2, 0, 255); 00846 00847 if(Tmp.m_nValue) 00848 { 00849 llrp_u16_t nValue; 00850 00851 nValue = Tmp.m_nValue; 00852 Value = llrp_u1v_t(nValue*8); 00853 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00854 { 00855 unsigned int Ix; 00856 xmlChar * pCountStr; 00857 00858 for(Ix = 0; Ix < nValue; Ix++) 00859 { 00860 Value.m_pValue[Ix] = (llrp_u1_t) Tmp.m_pValue[Ix]; 00861 } 00862 /* bit length could be shorter than this. Use this if there 00863 * is no attribute */ 00864 Value.m_nBit = Tmp.m_nValue * 8; 00865 00866 /* find the XML attribute for Count and fix the array */ 00867 if(NULL != m_pLastFieldNode) 00868 { 00869 pCountStr = xmlGetProp(m_pLastFieldNode, 00870 (xmlChar*) "Count"); 00871 if(NULL != pCountStr) 00872 { 00873 char * pArg = (char *) pCountStr; 00874 char * pTail = pArg + strlen((char*) pCountStr); 00875 llrp_u16_t nBits; 00876 00877 nBits = (llrp_u16_t) strtoul(pArg, &pTail, 10); 00878 if( (*pTail != 0) || 00879 (nBits > (Tmp.m_nValue * 8))) 00880 { 00881 /* malformed */ 00882 pError->m_eResultCode = RC_MiscError; 00883 pError->m_pWhatStr = "malformed Count Attribute"; 00884 pError->m_pRefType = m_pRefType; 00885 pError->m_pRefField = pFieldDesc; 00886 pError->m_OtherDetail = (int) m_pLastFieldNode->line; 00887 } 00888 else 00889 { 00890 llrp_u16_t lastByteBits; 00891 llrp_u8_t lastByteMask; 00892 00893 Value.m_nBit = nBits; 00894 00895 /* zero off the last bits if they were non-zero */ 00896 lastByteBits = nBits % 8; 00897 if(lastByteBits) 00898 { 00899 /* convert the bit position to a mask */ 00900 lastByteBits = 8 - lastByteBits; 00901 lastByteMask = (1 << lastByteBits) - 1; 00902 /* invert mask */ 00903 lastByteMask = ~lastByteMask; 00904 /* clear bits */ 00905 Value.m_pValue[Ix] &= lastByteMask; 00906 } 00907 } 00908 xmlFree(pCountStr); 00909 } 00910 } 00911 } 00912 } 00913 return Value; 00914 } 00915 00917 llrp_u2_t 00918 CXMLTextDecoderStream::get_u2 ( 00919 const CFieldDescriptor * pFieldDesc) 00920 { 00921 llrp_u2_t Value; 00922 Value = (llrp_u2_t) getIntegerField(pFieldDesc, 0, 3); 00923 return Value; 00924 } 00925 00927 llrp_u96_t 00928 CXMLTextDecoderStream::get_u96 ( 00929 const CFieldDescriptor * pFieldDesc) 00930 { 00931 CErrorDetails * pError; 00932 llrp_u96_t Value; 00933 llrp_s64v_t Tmp; 00934 unsigned int Ix; 00935 00936 pError = &m_pDecoder->m_ErrorDetails; 00937 00938 Tmp = getFixedVectorField( pFieldDesc, 2, 0, 255); 00939 00940 if((RC_OK != pError->m_eResultCode) && (Tmp.m_nValue != 12)) 00941 { 00942 if(NULL != pError) 00943 { 00944 pError->m_eResultCode = RC_MiscError; 00945 pError->m_pWhatStr = "Illegal length u96 field"; 00946 pError->m_pRefType = m_pRefType; 00947 pError->m_pRefField = pFieldDesc; 00948 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 00949 } 00950 return Value; 00951 } 00952 00953 /* convert to this type */ 00954 for(Ix = 0; Ix < Tmp.m_nValue; Ix++) 00955 { 00956 Value.m_aValue[Ix] = (llrp_u8_t) Tmp.m_pValue[Ix]; 00957 } 00958 00959 return Value; 00960 } 00961 00963 llrp_utf8v_t 00964 CXMLTextDecoderStream::get_utf8v ( 00965 const CFieldDescriptor * pFieldDesc) 00966 { 00967 llrp_utf8v_t Value; 00968 llrp_u16_t nValue; 00969 const llrp_u8_t * pbuf; 00970 const llrp_u8_t * pend; 00971 00972 if(getFieldStringPtr(pFieldDesc, &pbuf, &pend)) 00973 { 00974 nValue = (llrp_u16_t) strlen((char*) pbuf); 00975 Value = llrp_utf8v_t(nValue); 00976 00977 if(verifyVectorAllocation(Value.m_pValue, pFieldDesc)) 00978 { 00979 unsigned int Ix; 00980 00981 for(Ix = 0; Ix < nValue; Ix++) 00982 { 00983 Value.m_pValue[Ix] = pbuf[Ix]; 00984 } 00985 } 00986 } 00987 else 00988 { 00989 /* its valid for UTF8 strings to be empty */ 00990 Value.m_nValue=0; 00991 Value.m_pValue=NULL; 00992 } 00993 return Value; 00994 } 00995 00997 llrp_bytesToEnd_t 00998 CXMLTextDecoderStream::get_bytesToEnd ( 00999 const CFieldDescriptor * pFieldDesc) 01000 { 01001 llrp_bytesToEnd_t Value; 01002 llrp_s64v_t Tmp; 01003 unsigned int Ix; 01004 01005 Tmp = getFixedVectorField( pFieldDesc, 2, 0, 255); 01006 01007 if(verifyVectorAllocation(Tmp.m_pValue, pFieldDesc)) 01008 { 01009 /* build and convert */ 01010 Value = llrp_bytesToEnd_t(Tmp.m_nValue); 01011 if(verifyVectorAllocation(Tmp.m_pValue, pFieldDesc)) 01012 { 01013 /* convert to this type */ 01014 for(Ix = 0; Ix < Tmp.m_nValue; Ix++) 01015 { 01016 Value.m_pValue[Ix] = (llrp_byte_t) Tmp.m_pValue[Ix]; 01017 } 01018 Value.m_nValue = Tmp.m_nValue; 01019 } 01020 } 01021 return Value; 01022 } 01023 01024 /* 01025 * Enumerated types of various sizes 01026 */ 01027 01029 int 01030 CXMLTextDecoderStream::get_e1 ( 01031 const CFieldDescriptor * pFieldDesc) 01032 { 01033 int Value; 01034 Value = (int) getIntegerField(pFieldDesc, 0, 1); 01035 return Value; 01036 } 01037 01039 int 01040 CXMLTextDecoderStream::get_e2 ( 01041 const CFieldDescriptor * pFieldDesc) 01042 { 01043 int Value; 01044 Value = (int) getIntegerField(pFieldDesc, 0, 3); 01045 return Value; 01046 } 01047 01049 int 01050 CXMLTextDecoderStream::get_e8 ( 01051 const CFieldDescriptor * pFieldDesc) 01052 { 01053 int Value; 01054 Value = (int) getIntegerField(pFieldDesc, MIN_U8, MAX_U8); 01055 return Value; 01056 } 01057 01059 int 01060 CXMLTextDecoderStream::get_e16 ( 01061 const CFieldDescriptor * pFieldDesc) 01062 { 01063 int Value; 01064 Value = (int) getIntegerField(pFieldDesc, MIN_U16, MAX_U16); 01065 return Value; 01066 } 01067 01069 int 01070 CXMLTextDecoderStream::get_e32 ( 01071 const CFieldDescriptor * pFieldDesc) 01072 { 01073 int Value; 01074 Value = (int) getIntegerField(pFieldDesc, MIN_U32, MAX_U32); 01075 return Value; 01076 } 01077 01079 llrp_u8v_t 01080 CXMLTextDecoderStream::get_e8v ( 01081 const CFieldDescriptor * pFieldDesc) 01082 { 01083 llrp_u8v_t Value; 01084 llrp_s64v_t Tmp; 01085 01086 Tmp = getSpacedVectorField( pFieldDesc, MIN_U8, MAX_U8); 01087 if(Tmp.m_nValue) 01088 { 01089 llrp_u16_t nValue; 01090 01091 nValue = Tmp.m_nValue; 01092 Value = llrp_u8v_t(nValue); 01093 if(verifyVectorAllocation(Value.m_pValue,pFieldDesc)) 01094 { 01095 unsigned int Ix; 01096 01097 for(Ix = 0; Ix < nValue; Ix++) 01098 { 01099 Value.m_pValue[Ix] = (llrp_u8_t) Tmp.m_pValue[Ix]; 01100 } 01101 } 01102 } 01103 return Value; 01104 } 01105 01106 /* @brief skips a number of reserved bits and discards during the encode/decode process */ 01107 void 01108 CXMLTextDecoderStream::get_reserved ( 01109 unsigned int nBits) 01110 { 01111 return; 01112 } 01113 01114 llrp_bool_t 01115 CXMLTextDecoderStream::verifyVectorAllocation ( 01116 const void * pValue, 01117 const CFieldDescriptor * pFieldDescriptor) 01118 { 01119 if(NULL == pValue) 01120 { 01121 CErrorDetails * pError = &m_pDecoder->m_ErrorDetails; 01122 01123 pError->m_eResultCode = RC_FieldAllocationFailed; 01124 pError->m_pWhatStr = "field allocation failed"; 01125 pError->m_pRefType = m_pRefType; 01126 pError->m_pRefField = pFieldDescriptor; 01127 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01128 01129 return FALSE; 01130 } 01131 else 01132 { 01133 return TRUE; 01134 } 01135 } 01136 01137 int 01138 CXMLTextDecoderStream::isInsignificantNode ( 01139 struct _xmlNode * pnode) 01140 { 01141 switch(pnode->type) 01142 { 01143 /* don't process comments or notations */ 01144 case XML_COMMENT_NODE: 01145 case XML_NOTATION_NODE: 01146 /* ignore includes */ 01147 case XML_XINCLUDE_START: 01148 case XML_XINCLUDE_END: 01149 /* don't read processing instructions */ 01150 case XML_PI_NODE: 01151 return 1; 01152 01153 /* hopefully we only see these type of nodes */ 01154 case XML_ELEMENT_NODE: 01155 case XML_ATTRIBUTE_NODE: 01156 case XML_TEXT_NODE: 01157 01158 /* we should error if we see a cdata */ 01159 case XML_CDATA_SECTION_NODE: 01160 01161 /* we don't understand entities, so we should error */ 01162 case XML_ENTITY_REF_NODE: 01163 case XML_ENTITY_NODE: 01164 case XML_ENTITY_DECL: 01165 01166 /* we should have already gotten the doc node , but should error out on these*/ 01167 case XML_DOCUMENT_NODE: 01168 case XML_DOCUMENT_TYPE_NODE: 01169 case XML_DOCUMENT_FRAG_NODE: 01170 case XML_HTML_DOCUMENT_NODE: 01171 case XML_DTD_NODE: 01172 01173 /* not sure yet about these, but I think they are irellevant */ 01174 case XML_ELEMENT_DECL: 01175 case XML_ATTRIBUTE_DECL: 01176 case XML_NAMESPACE_DECL: 01177 01178 /* anything new we should error */ 01179 default: 01180 return 0; 01181 } 01182 } 01183 01184 /* some class member field helpers */ 01185 int 01186 CXMLTextDecoderStream::getFieldStringPtr( 01187 const CFieldDescriptor * pFieldDescriptor, 01188 const llrp_u8_t ** pbuf, 01189 const llrp_u8_t ** pend) 01190 { 01191 CErrorDetails * pError = &m_pDecoder->m_ErrorDetails; 01192 xmlNode * pSave; 01193 01194 *pbuf = NULL; 01195 *pend = NULL; 01196 01197 /* clear this out as its not valid anymore */ 01198 m_pLastFieldNode = NULL; 01199 01200 if(RC_OK != pError->m_eResultCode) 01201 { 01202 return 0; 01203 } 01204 01205 /* get the first interesting node */ 01206 while ((NULL != m_pCurrentChildNode) && 01207 (isInsignificantNode(m_pCurrentChildNode) || 01208 xmlIsBlankNode(m_pCurrentChildNode))) 01209 { 01210 m_pCurrentChildNode = m_pCurrentChildNode->next; 01211 } 01212 01213 if(NULL == m_pCurrentChildNode) 01214 { 01215 pError->m_eResultCode = RC_FieldUnderrun; 01216 pError->m_pWhatStr = "underrun at field"; 01217 pError->m_pRefType = m_pRefType; 01218 pError->m_pRefField = pFieldDescriptor; 01219 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01220 return 0; 01221 } 01222 01223 /* first interesting node had better be an element */ 01224 if(m_pCurrentChildNode->type != XML_ELEMENT_NODE) 01225 { 01226 pError->m_eResultCode = RC_XMLInvalidNodeType; 01227 pError->m_pWhatStr = "unexpected field value"; 01228 pError->m_pRefType = m_pRefType; 01229 pError->m_pRefField = pFieldDescriptor; 01230 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01231 return 0; 01232 } 01233 01234 /* better match our field value */ 01235 if(0 != strcmp((char*) m_pCurrentChildNode->name, 01236 pFieldDescriptor->m_pName)) 01237 { 01238 pError->m_eResultCode = RC_XMLMissingField; 01239 pError->m_pWhatStr = "missing field value"; 01240 pError->m_pRefType = m_pRefType; 01241 pError->m_pRefField = pFieldDescriptor; 01242 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01243 return 0; 01244 } 01245 01246 /* save this in case someone wants to explore attributes */ 01247 m_pLastFieldNode = m_pCurrentChildNode; 01248 01249 /* use this to decode the field values */ 01250 pSave = m_pCurrentChildNode->children; 01251 01252 /* advance to the next one for the next field */ 01253 m_pCurrentChildNode = m_pCurrentChildNode->next; 01254 01255 /* get the first interesting node */ 01256 while ((NULL !=pSave) && 01257 (isInsignificantNode(pSave) || 01258 xmlIsBlankNode(pSave))) 01259 { 01260 pSave = pSave->next; 01261 } 01262 01263 if(NULL == pSave) 01264 { 01265 /* its possible that this is an empty field value, which is 01266 * allowed in many cases in LLRP-XML. Let the condition 01267 * percolate and error out specifically where it is not 01268 * allowed */ 01269 return 0; 01270 } 01271 01272 if(XML_TEXT_NODE != pSave->type) 01273 { 01274 pError->m_eResultCode = RC_XMLInvalidNodeType; 01275 pError->m_pWhatStr = "invalid XML Node found during field decode"; 01276 pError->m_pRefType = m_pRefType; 01277 pError->m_pRefField = pFieldDescriptor; 01278 pError->m_OtherDetail = (int) pSave->line; 01279 return 0; 01280 } 01281 01282 *pbuf = pSave->content; 01283 01284 /* make sure there are no more interesting nodes */ 01285 pSave = pSave->next; 01286 while ((NULL !=pSave) && 01287 (isInsignificantNode(pSave) || 01288 xmlIsBlankNode(pSave))) 01289 { 01290 pSave = pSave->next; 01291 } 01292 01293 if(pSave != NULL) 01294 { 01295 pError->m_eResultCode = RC_XMLExtraNode; 01296 pError->m_pWhatStr = "extra XML node found"; 01297 pError->m_pRefType = m_pRefType; 01298 pError->m_pRefField = pFieldDescriptor; 01299 pError->m_OtherDetail = (int) pSave->line; 01300 return 0; 01301 } 01302 01303 *pend = *pbuf + strlen((char*) *pbuf); 01304 return 1; 01305 } 01306 01307 llrp_s64v_t 01308 CXMLTextDecoderStream::getSpacedVectorField ( 01309 const CFieldDescriptor * pFieldDescriptor, 01310 llrp_s64_t minValue, 01311 llrp_s64_t maxValue) 01312 { 01313 CErrorDetails * pError = &m_pDecoder->m_ErrorDetails; 01314 const llrp_u8_t * pTok; 01315 const llrp_u8_t * pEnd; 01316 const llrp_u8_t * pTokEnd; 01317 llrp_u16_t length; 01318 llrp_u16_t elementCount; 01319 llrp_s64v_t Value; 01320 llrp_u16_t count; 01321 01322 if(RC_OK != pError->m_eResultCode) 01323 { 01324 /* already errd */ 01325 return Value; 01326 } 01327 01328 /* get the NULL terminates string from XML */ 01329 if(!getFieldStringPtr(pFieldDescriptor, &pTok, &pEnd)) 01330 { 01331 /* many of these (e.g. ReadData) are allowed to be empty */ 01332 return Value; 01333 } 01334 01335 length = cleanString(&pTok, &pEnd); 01336 elementCount = countElements((char *) pTok, length); 01337 01338 /* create the final storage entity */ 01339 Value = llrp_s64v_t(elementCount); 01340 01341 for(count = 0;count <elementCount ; count++) 01342 { 01343 /* find the next starting token */ 01344 while(isspace(*pTok) && (pTok < pEnd)) 01345 { 01346 pTok++; 01347 } 01348 01349 /* find the next ending token */ 01350 for(pTokEnd = pTok; (!isspace(*pTokEnd)) && (*pTokEnd != '\0'); pTokEnd++) 01351 { 01352 /* nothing */ 01353 } 01354 01355 /* get a single integer */ 01356 Value.m_pValue[count] = getInteger(pFieldDescriptor, 01357 pTok, 01358 pTokEnd, 01359 pError, 01360 minValue, 01361 maxValue); 01362 if(RC_OK != pError->m_eResultCode) 01363 { 01364 break; 01365 } 01366 /* get the next value */ 01367 pTok = pTokEnd; 01368 } 01369 01370 /* mark the length */ 01371 Value.m_nValue = count; 01372 01373 return Value; 01374 } 01375 01376 llrp_s64v_t 01377 CXMLTextDecoderStream::getFixedVectorField ( 01378 const CFieldDescriptor * pFieldDescriptor, 01379 unsigned int vectorSize, 01380 llrp_s64_t minValue, 01381 llrp_s64_t maxValue) 01382 { 01383 CErrorDetails * pError = &m_pDecoder->m_ErrorDetails; 01384 const llrp_u8_t * pTok; 01385 const llrp_u8_t * pEnd; 01386 llrp_u16_t length; 01387 llrp_u16_t elementCount; 01388 llrp_s64v_t Value; 01389 llrp_u16_t count; 01390 01391 if(RC_OK != pError->m_eResultCode) 01392 { 01393 /* already errd */ 01394 return Value; 01395 } 01396 01397 if(!getFieldStringPtr(pFieldDescriptor, &pTok, &pEnd)) 01398 { 01399 /* these values are allowed to be empty */ 01400 Value.m_nValue = 0; 01401 Value.m_pValue = NULL; 01402 return Value; 01403 } 01404 01405 length = cleanString(&pTok, &pEnd); 01406 01407 /* size should match exactly */ 01408 if (length % vectorSize) 01409 { 01410 pError->m_eResultCode = RC_FieldAllocationFailed; 01411 pError->m_pWhatStr = "field size must be multiple of basic type"; 01412 pError->m_pRefType = m_pRefType; 01413 pError->m_pRefField = pFieldDescriptor; 01414 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01415 return Value; 01416 } 01417 01418 /* round up for element count */ 01419 elementCount = (length + vectorSize - 1)/vectorSize; 01420 01421 /* create the final storage entity */ 01422 Value = llrp_s64v_t(elementCount); 01423 01424 for(count = 0;count <elementCount ; count++, pTok += vectorSize) 01425 { 01426 pEnd = pTok + vectorSize; 01427 01428 /* get a single integer */ 01429 Value.m_pValue[count] = getInteger(pFieldDescriptor, 01430 pTok, 01431 pEnd, 01432 pError, 01433 minValue, 01434 maxValue); 01435 01436 if(RC_OK != pError->m_eResultCode) 01437 { 01438 break; 01439 } 01440 } 01441 01442 /* mark the length */ 01443 Value.m_nValue = count; 01444 01445 return Value; 01446 } 01447 01448 01449 llrp_s64_t 01450 CXMLTextDecoderStream::getIntegerField ( 01451 const CFieldDescriptor * pFieldDescriptor, 01452 llrp_s64_t minValue, 01453 llrp_s64_t maxValue) 01454 { 01455 CErrorDetails * pError = &m_pDecoder->m_ErrorDetails; 01456 const llrp_u8_t * pbuf; 01457 const llrp_u8_t * pend; 01458 llrp_s64_t Value; 01459 01460 memset(&Value, 0x00, sizeof(Value)); 01461 01462 if(RC_OK != pError->m_eResultCode) 01463 { 01464 /* already errd */ 01465 return Value; 01466 } 01467 01468 if(getFieldStringPtr(pFieldDescriptor, &pbuf, &pend)) 01469 { 01470 cleanString(&pbuf, &pend); 01471 Value = getInteger(pFieldDescriptor, 01472 pbuf, 01473 pend, 01474 pError, 01475 minValue, 01476 maxValue); 01477 } 01478 else 01479 { 01480 pError->m_eResultCode = RC_FieldUnderrun; 01481 pError->m_pWhatStr = "underrun at field no characters"; 01482 pError->m_pRefType = m_pRefType; 01483 pError->m_pRefField = pFieldDescriptor; 01484 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01485 return 0; 01486 } 01487 01488 return Value; 01489 } 01490 01491 01492 llrp_s64_t CXMLTextDecoderStream::getInteger( 01493 const CFieldDescriptor * pFieldDescriptor, 01494 const llrp_u8_t * pbuf, 01495 const llrp_u8_t * pend, 01496 CErrorDetails * pError, 01497 llrp_s64_t minValue, 01498 llrp_s64_t maxValue) 01499 { 01500 llrp_s64_t Value; 01501 const llrp_u8_t * endPtr = NULL; 01502 01503 01504 if(pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_U1) 01505 /* special case for U1 types as they can be 01506 * 'true' and 'false' strings */ 01507 { 01508 endPtr = getSingleU1(pbuf, pend, &Value); 01509 } 01510 else if((pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_E1 ) || 01511 (pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_E2 ) || 01512 (pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_E8 ) || 01513 (pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_E16 ) || 01514 (pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_E32 ) || 01515 (pFieldDescriptor->m_eFieldType == CFieldDescriptor::FT_E8V ) ) 01516 /* special case for enumerated fields as they are strings in XML*/ 01517 { 01518 endPtr = getSingleEnum(pFieldDescriptor, pbuf, pend, &Value); 01519 } 01520 else switch(pFieldDescriptor->m_eFieldFormat) 01521 { 01522 /* assume default is decimal for new formats */ 01523 default: 01524 case CFieldDescriptor::FMT_NORMAL: 01525 case CFieldDescriptor::FMT_DEC: 01526 endPtr = getSingleDecimal(pbuf, pend, &Value); 01527 break; 01528 case CFieldDescriptor::FMT_HEX: 01529 endPtr = getSingleHexidecimal(pbuf, pend, &Value); 01530 break; 01531 case CFieldDescriptor::FMT_UTF8: 01532 { 01533 const llrp_u8_t *ptr; 01534 /* not sure what to do for UTF 8 encoding as integer */ 01535 for(ptr = pbuf; ptr < pend; ptr++) 01536 { 01537 Value = 256*Value + *ptr; 01538 } 01539 } 01540 break; 01541 case CFieldDescriptor::FMT_DATETIME: 01542 endPtr = getSingleTimestamp(pbuf, pend, &Value); 01543 break; 01544 } 01545 01546 if(endPtr == pbuf) 01547 /* if we didn't get any thing, it means there are illegal characters 01548 * and we could not import a field value */ 01549 { 01550 pError->m_eResultCode = RC_XMLInvalidFieldCharacters; 01551 pError->m_pWhatStr = "Illegal field value"; 01552 pError->m_pRefType = m_pRefType; 01553 pError->m_pRefField = pFieldDescriptor; 01554 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01555 Value = 0; 01556 } 01557 else if (endPtr != pend) 01558 /* if these don't match, there is still extra stuff 01559 * at the end. This is always an error */ 01560 { 01561 pError->m_eResultCode = RC_FieldOverrun; 01562 pError->m_pWhatStr = "overrun at field extra characters"; 01563 pError->m_pRefType = m_pRefType; 01564 pError->m_pRefField = pFieldDescriptor; 01565 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01566 Value = 0; 01567 } 01568 /* make sure the value is in range */ 01569 else if((Value > maxValue) || (Value < minValue)) 01570 /* we have an out of range value. This is always an error */ 01571 { 01572 pError->m_eResultCode = RC_XMLOutOfRange; 01573 pError->m_pWhatStr = "out of range value"; 01574 pError->m_pRefType = m_pRefType; 01575 pError->m_pRefField = pFieldDescriptor; 01576 pError->m_OtherDetail = (int) m_pCurrentChildNode->line; 01577 Value = 0; 01578 } 01579 return Value; 01580 } 01581 01582 /* static string helpers */ 01583 01584 const llrp_u8_t * 01585 CXMLTextDecoderStream::getSingleU1( 01586 const llrp_u8_t * pbuf, 01587 const llrp_u8_t * pend, 01588 llrp_s64_t * pValue) 01589 { 01590 const llrp_u8_t * endPtr = pbuf; 01591 const int len = (int) (pend - pbuf); 01592 01593 if((len >= 4) && (0 == strncasecmp("true", (char*) pbuf, 4))) 01594 { 01595 *pValue = 1; 01596 endPtr = pbuf + 4; 01597 } 01598 else if ((len >= 5) && (0 == strncasecmp("false", (char*) pbuf, 5))) 01599 { 01600 *pValue = 0; 01601 endPtr = pbuf + 5; 01602 } 01603 else if ((len >= 1) && (*pbuf == '0')) 01604 { 01605 *pValue = 0; 01606 endPtr = pbuf + 1; 01607 } 01608 else if ((len >= 1) && (*pbuf == '1')) 01609 { 01610 *pValue = 0; 01611 endPtr = pbuf + 1; 01612 } 01613 return endPtr; 01614 } 01615 01616 const llrp_u8_t * 01617 CXMLTextDecoderStream::getSingleEnum( 01618 const CFieldDescriptor * pFieldDescriptor, 01619 const llrp_u8_t * pbuf, 01620 const llrp_u8_t * pend, 01621 llrp_s64_t * pValue) 01622 { 01623 const llrp_u8_t * endPtr = pbuf; 01624 const int length = (int) (pend - pbuf); 01625 const SEnumTableEntry * pEntry; 01626 01627 *pValue = 0; 01628 01629 for( 01630 pEntry = pFieldDescriptor->m_pEnumTable; 01631 NULL != pEntry->pName; 01632 pEntry++) 01633 { 01634 int len = (int) strlen(pEntry->pName); 01635 if((len == length) && 01636 (memcmp(pbuf, pEntry->pName, len) == 0)) 01637 { 01638 break; 01639 } 01640 } 01641 01642 if(NULL == pEntry->pName) 01643 { 01644 return pbuf; 01645 } 01646 01647 *pValue = pEntry->Value; 01648 endPtr = pbuf + length; 01649 return endPtr; 01650 } 01651 01652 const llrp_u8_t * 01653 CXMLTextDecoderStream::getSingleDecimal( 01654 const llrp_u8_t * pbuf, 01655 const llrp_u8_t * pend, 01656 llrp_s64_t * pValue) 01657 { 01658 int bNeg = 0; 01659 const llrp_u8_t * endPtr; 01660 01661 *pValue = 0; 01662 01663 for(endPtr = pbuf; endPtr < pend; endPtr++) 01664 { 01665 if(*endPtr == '-') 01666 { 01667 bNeg = 1; 01668 } else if (isdigit(*endPtr)) 01669 { 01670 *pValue = 10 * *pValue + (*endPtr - '0'); 01671 } 01672 else 01673 { 01674 /* a character not allowed in a decimal integer */ 01675 break; 01676 } 01677 } 01678 if(bNeg) 01679 { 01680 *pValue *= -1; 01681 } 01682 01683 return endPtr; 01684 } 01685 01686 01687 const llrp_u8_t * 01688 CXMLTextDecoderStream::getSingleHexidecimal( 01689 const llrp_u8_t * pbuf, 01690 const llrp_u8_t * pend, 01691 llrp_s64_t * pValue) 01692 { 01693 const llrp_u8_t * endPtr; 01694 01695 *pValue = 0; 01696 for(endPtr = pbuf; endPtr < pend; endPtr++) 01697 { 01698 if(isdigit(*endPtr)) 01699 { 01700 *pValue = 16 * *pValue + (*endPtr - '0'); 01701 } 01702 else if (*endPtr >= 'A' && *endPtr <= 'F') 01703 { 01704 *pValue = 16 * *pValue + (*endPtr - 'A' + 10); 01705 } 01706 else if (*endPtr >= 'a' && *endPtr <= 'f') 01707 { 01708 *pValue = 16 * *pValue + (*endPtr - 'a' + 10); 01709 } 01710 else 01711 { 01712 /* a character not allowed in a decimal integer */ 01713 break; 01714 } 01715 } 01716 return endPtr; 01717 } 01718 01719 01720 int 01721 CXMLTextDecoderStream::cleanString( 01722 const llrp_u8_t ** ppbuf, 01723 const llrp_u8_t ** ppend) 01724 { 01725 /* skip leading spaces */ 01726 while( isspace(**ppbuf) && (*ppbuf <= *ppend)) 01727 { 01728 (*ppbuf)++; 01729 } 01730 /* skip trailing spaces except last separator */ 01731 /* last separator could be space or NULL. */ 01732 while((*ppend > *ppbuf) && (isspace(*(*ppend-1)) || (*(*ppend-1) == '\0'))) 01733 { 01734 (*ppend)--; 01735 } 01736 return (int) (*ppend - *ppbuf); 01737 } 01738 01739 /* gets a single char value from a non-NULL terminated buffer buffer. 01740 * If it fails to get one, reutrn value should == pbuf, other 01741 * wise EndPtr should point to one past amount consumed */ 01742 static const llrp_u8_t * 01743 getSingleChar( 01744 const llrp_u8_t * pbuf, 01745 const llrp_u8_t * pend, 01746 llrp_s64_t * pValue) 01747 { 01748 const llrp_u8_t * endPtr = pbuf; 01749 const int len = pend - pbuf; 01750 01751 if(len >= 1) 01752 { 01753 *pValue = *pbuf; 01754 endPtr = pbuf + 1; 01755 } 01756 01757 return endPtr; 01758 } 01759 01760 const llrp_u8_t * 01761 CXMLTextDecoderStream::getSingleTimestamp( 01762 const llrp_u8_t * pbuf, 01763 const llrp_u8_t * pend, 01764 llrp_s64_t * pValue) 01765 { 01766 const llrp_u8_t * endPtr; 01767 const llrp_u8_t * tmpPtr; 01768 struct tm importTime; 01769 llrp_s64_t micros = 0; 01770 llrp_s64_t temp = 0; 01771 time_t tt; 01772 int utc = 0; 01773 llrp_s64_t offset = 0; 01774 01775 memset(&importTime, 0x00, sizeof(importTime)); 01776 01777 tmpPtr = pbuf; 01778 endPtr = (llrp_u8_t*) strptime((char*) tmpPtr, "%Y-%m-%dT%T", &importTime); 01779 01780 if(endPtr == NULL) 01781 { 01782 goto timeParseError; 01783 } 01784 01785 /* we have a valid timestamp, but there may be more stuff */ 01786 tmpPtr = endPtr; 01787 if((endPtr = getSingleChar(tmpPtr, pend, &temp)) == tmpPtr) 01788 { 01789 goto timeParseDone; 01790 } 01791 01792 if(temp == '.') 01793 { 01794 int length; 01795 01796 /* try to get the microsecond value */ 01797 tmpPtr = endPtr; 01798 if((endPtr = getSingleDecimal(tmpPtr, pend, µs)) == tmpPtr) 01799 { 01800 goto timeParseError; 01801 } 01802 01803 length = endPtr - tmpPtr; 01804 /* may not contain 6 decimal places */ 01805 while(length < 6) 01806 { 01807 micros *= 10; 01808 length++; 01809 } 01810 01811 if(length > 6) 01812 { 01813 goto timeParseError; 01814 } 01815 01816 /* look for more stuff that is optional */ 01817 tmpPtr = endPtr; 01818 if((endPtr = getSingleChar(tmpPtr, pend, &temp)) == tmpPtr) 01819 { 01820 goto timeParseDone; 01821 } 01822 } 01823 01824 /* timestamp could either have offset or Z for UTC (Zulu) */ 01825 if(temp == '-' || temp == '+') 01826 { 01827 int scale = 1; 01828 /* offset formats are hh or hh:mm from UTC */ 01829 if(temp == '+') 01830 { 01831 scale = -1; 01832 /* The time is offset positively from UTC, which means we have to 01833 ** subtract to get to UTC time */ 01834 } 01835 utc = 1; 01836 tmpPtr = endPtr; 01837 if((endPtr = getSingleDecimal(tmpPtr, pend, &temp)) == (tmpPtr+2)) 01838 { 01839 goto timeParseError; 01840 } 01841 01842 offset = scale*temp*60*60; 01843 01844 tmpPtr = endPtr; 01845 if((endPtr = getSingleChar(tmpPtr, pend, &temp)) == tmpPtr) 01846 { 01847 goto timeParseDone; 01848 } 01849 01850 if(temp != ':') { 01851 goto timeParseError; 01852 } 01853 01854 tmpPtr = endPtr; 01855 if((endPtr = getSingleDecimal(tmpPtr, pend, &temp)) == (tmpPtr+2)) 01856 { 01857 goto timeParseError; 01858 } 01859 01860 offset += (scale * temp * 60); 01861 01862 } 01863 else if ((temp == 'z') || (temp == 'Z')) 01864 { 01865 utc = 1; 01866 } 01867 /* fall through */ 01868 01869 timeParseDone: 01870 01871 if(utc) 01872 { 01873 tt = timegm(&importTime); 01874 } else 01875 { 01876 tt = timelocal(&importTime); 01877 } 01878 01879 /* make this into time since epoch at GMT (UTC) */ 01880 if(tt != (time_t) -1) 01881 { 01882 /* LLRP format is 64-bit microseconds UTC. Conver */ 01883 *pValue = 1000000ll * (llrp_s64_t) (tt + offset) + micros; 01884 return endPtr; 01885 } 01886 /* fall through if time wasn't valid */ 01887 timeParseError: 01888 endPtr = pbuf; 01889 return endPtr; 01890 } 01891 01892 01893 llrp_u16_t 01894 CXMLTextDecoderStream::countElements( 01895 const char * pval, 01896 int nval) 01897 { 01898 const llrp_u8_t * pTok; 01899 const llrp_u8_t * pEnd; 01900 llrp_u8_t lastChar; 01901 llrp_u16_t elements = 0; 01902 01903 /* find out how many possible tokens there are. 01904 * This should limit our size of array we need */ 01905 01906 pTok = (llrp_u8_t*) &pval[0]; 01907 pEnd = pTok + nval; 01908 01909 /* skip leading spaces */ 01910 for(lastChar = ' '; pTok < pEnd; pTok++) 01911 { 01912 if((!isspace(*pTok)) && (isspace(lastChar))) 01913 { 01914 elements++; 01915 } 01916 lastChar = *pTok; 01917 } 01918 01919 return elements; 01920 } 01921 01922 };