ltkcpp_xmltextdecode.cpp

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

Generated on Wed Jun 6 11:55:49 2012 for LTKCPP-- LLRP Toolkit C Plus Plus Library by  doxygen 1.5.9