ltkcpp_xmltextencode.cpp

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 
00015 
00016 #include <stdio.h>
00017 #include <stdarg.h>
00018 #include <time.h>
00019 
00020 #include "ltkcpp_platform.h"
00021 #include "ltkcpp_base.h"
00022 #include "ltkcpp_xmltext.h"
00023 
00024 
00025 
00026 namespace LLRP
00027 {
00028 
00029 /*
00030  * Structures used by discoverNamespaces() and putElement().
00031  */
00032 #define MAX_NS      10
00033 struct NamespaceList
00034 {
00035     const CNamespaceDescriptor *apNamespaceDescriptor[MAX_NS];
00036     int                         nNamespaceDescriptor;
00037 };
00038 typedef struct NamespaceList    tNamespaceList;
00039 
00040 /* forward */
00041 static int
00042 discoverNamespaces (
00043   const CElement *              pElement,
00044   void *                        pArg);
00045 
00046 
00047 CXMLTextEncoder::CXMLTextEncoder (
00048   char *                        pBuffer,
00049   int                           nBuffer)
00050 {
00051     m_pBuffer = pBuffer;
00052     m_nBuffer = nBuffer;
00053     m_iNext = 0;
00054     m_bOverflow = 0;
00055 }
00056 
00057 CXMLTextEncoder::~CXMLTextEncoder (void)
00058 {
00059 }
00060 
00061 void
00062 CXMLTextEncoder::encodeElement (
00063   const CElement *              pElement)
00064 {
00065     CXMLTextEncoderStream         MyEncoderStream(this);
00066 
00067     MyEncoderStream.putElement(pElement);
00068 }
00069 
00070 void
00071 CXMLTextEncoderStream::putRequiredSubParameter (
00072   const CParameter *            pParameter,
00073   const CTypeDescriptor *       pRefType)
00074 {
00075     if(NULL == pParameter)
00076     {
00077         appendFormat("warning: missing %s\n",
00078             (NULL == pRefType) ? "<something>" : pRefType->m_pName);
00079         return;
00080     }
00081 
00082     CXMLTextEncoderStream         NestEncoderStream(this);
00083 
00084     NestEncoderStream.putElement(pParameter);
00085 }
00086 
00087 void
00088 CXMLTextEncoderStream::putOptionalSubParameter (
00089   const CParameter *            pParameter,
00090   const CTypeDescriptor *       pRefType)
00091 {
00092     if(NULL == pParameter)
00093     {
00094         return;
00095     }
00096 
00097     CXMLTextEncoderStream         NestEncoderStream(this);
00098 
00099     NestEncoderStream.putElement(pParameter);
00100 }
00101 
00102 void
00103 CXMLTextEncoderStream::putRequiredSubParameterList (
00104   const tListOfParameters *     pParameterList,
00105   const CTypeDescriptor *       pRefType)
00106 {
00107     if(pParameterList->empty())
00108     {
00109         appendFormat("warning: missing list of %s\n",
00110             (NULL == pRefType) ? "<something>" : pRefType->m_pName);
00111         return;
00112     }
00113 
00114     for(
00115         tListOfParameters::const_iterator Cur = pParameterList->begin();
00116         Cur != pParameterList->end();
00117         Cur++)
00118     {
00119         putRequiredSubParameter(*Cur, pRefType);
00120     }
00121 }
00122 
00123 void
00124 CXMLTextEncoderStream::putOptionalSubParameterList (
00125   const tListOfParameters *     pParameterList,
00126   const CTypeDescriptor *       pRefType)
00127 {
00128     for(
00129         tListOfParameters::const_iterator Cur = pParameterList->begin();
00130         Cur != pParameterList->end();
00131         Cur++)
00132     {
00133         putRequiredSubParameter(*Cur, pRefType);
00134     }
00135 }
00136 
00137 
00138 /*
00139  * 8-bit types
00140  */
00141 
00142 void
00143 CXMLTextEncoderStream::put_u8 (
00144   llrp_u8_t                     Value,
00145   const CFieldDescriptor *      pFieldDescriptor)
00146 {
00147     const char *                pFieldName = pFieldDescriptor->m_pName;
00148 
00149     appendOpenTag(pFieldName);
00150     switch(pFieldDescriptor->m_eFieldFormat)
00151     {
00152     case CFieldDescriptor::FMT_NORMAL:
00153     case CFieldDescriptor::FMT_DEC:
00154     default:
00155         appendFormat("%u", Value);
00156         break;
00157 
00158     case CFieldDescriptor::FMT_HEX:
00159         appendFormat("%02X", Value);
00160         break;
00161     }
00162     appendCloseTag(pFieldName);
00163 }
00164 
00165 void
00166 CXMLTextEncoderStream::put_s8 (
00167   llrp_s8_t                     Value,
00168   const CFieldDescriptor *      pFieldDescriptor)
00169 {
00170     const char *                pFieldName = pFieldDescriptor->m_pName;
00171 
00172     appendOpenTag(pFieldName);
00173     switch(pFieldDescriptor->m_eFieldFormat)
00174     {
00175     case CFieldDescriptor::FMT_NORMAL:
00176     case CFieldDescriptor::FMT_DEC:
00177     default:
00178         appendFormat("%d", Value);
00179         break;
00180 
00181     case CFieldDescriptor::FMT_HEX:
00182         appendFormat("%02X", 0xFF & Value);
00183         break;
00184     }
00185     appendCloseTag(pFieldName);
00186 }
00187 
00188 void
00189 CXMLTextEncoderStream::put_u8v (
00190   llrp_u8v_t                    Value,
00191   const CFieldDescriptor *      pFieldDescriptor)
00192 {
00193     const char *                pFieldName = pFieldDescriptor->m_pName;
00194 
00195     appendOpenTag(pFieldName);
00196     for(int i = 0; i < Value.m_nValue; i++)
00197     {
00198         switch(pFieldDescriptor->m_eFieldFormat)
00199         {
00200         case CFieldDescriptor::FMT_NORMAL:
00201         case CFieldDescriptor::FMT_DEC:
00202         default:
00203             if(0 < i)
00204             {
00205                 appendFormat(" ");
00206             }
00207             appendFormat("%u", Value.m_pValue[i]);
00208             break;
00209 
00210         case CFieldDescriptor::FMT_HEX:
00211             appendFormat("%02X", 0xFF & Value.m_pValue[i]);
00212             break;
00213         }
00214     }
00215     appendCloseTag(pFieldName);
00216 }
00217 
00218 void
00219 CXMLTextEncoderStream::put_s8v (
00220   llrp_s8v_t                    Value,
00221   const CFieldDescriptor *      pFieldDescriptor)
00222 {
00223     const char *                pFieldName = pFieldDescriptor->m_pName;
00224 
00225     appendOpenTag(pFieldName);
00226     for(int i = 0; i < Value.m_nValue; i++)
00227     {
00228         switch(pFieldDescriptor->m_eFieldFormat)
00229         {
00230         case CFieldDescriptor::FMT_NORMAL:
00231         case CFieldDescriptor::FMT_DEC:
00232         default:
00233             if(0 < i)
00234             {
00235                 appendFormat(" ");
00236             }
00237             appendFormat("%d", Value.m_pValue[i]);
00238             break;
00239 
00240         case CFieldDescriptor::FMT_HEX:
00241             appendFormat("%02X", 0xFF & Value.m_pValue[i]);
00242             break;
00243         }
00244     }
00245     appendCloseTag(pFieldName);
00246 }
00247 
00248 /*
00249  * 16-bit types
00250  */
00251 
00252 void
00253 CXMLTextEncoderStream::put_u16 (
00254   llrp_u16_t                    Value,
00255   const CFieldDescriptor *      pFieldDescriptor)
00256 {
00257     const char *                pFieldName = pFieldDescriptor->m_pName;
00258 
00259     appendOpenTag(pFieldName);
00260     switch(pFieldDescriptor->m_eFieldFormat)
00261     {
00262     case CFieldDescriptor::FMT_NORMAL:
00263     case CFieldDescriptor::FMT_DEC:
00264     default:
00265         appendFormat("%u", Value);
00266         break;
00267 
00268     case CFieldDescriptor::FMT_HEX:
00269         appendFormat("%04X", Value);
00270         break;
00271     }
00272     appendCloseTag(pFieldName);
00273 }
00274 
00275 void
00276 CXMLTextEncoderStream::put_s16 (
00277   llrp_s16_t                    Value,
00278   const CFieldDescriptor *      pFieldDescriptor)
00279 {
00280     const char *                pFieldName = pFieldDescriptor->m_pName;
00281 
00282     appendOpenTag(pFieldName);
00283     switch(pFieldDescriptor->m_eFieldFormat)
00284     {
00285     case CFieldDescriptor::FMT_NORMAL:
00286     case CFieldDescriptor::FMT_DEC:
00287     default:
00288         appendFormat("%d", Value);
00289         break;
00290 
00291     case CFieldDescriptor::FMT_HEX:
00292         appendFormat("%04X", 0xFFFF & Value);
00293         break;
00294     }
00295     appendCloseTag(pFieldName);
00296 }
00297 
00298 void
00299 CXMLTextEncoderStream::put_u16v (
00300   llrp_u16v_t                   Value,
00301   const CFieldDescriptor *      pFieldDescriptor)
00302 {
00303     const char *                pFieldName = pFieldDescriptor->m_pName;
00304 
00305     appendOpenTag(pFieldName);
00306     for(int i = 0; i < Value.m_nValue; i++)
00307     {
00308         if(0 < i)
00309         {
00310             appendFormat(" ");
00311         }
00312         switch(pFieldDescriptor->m_eFieldFormat)
00313         {
00314         case CFieldDescriptor::FMT_NORMAL:
00315         case CFieldDescriptor::FMT_DEC:
00316         default:
00317             appendFormat("%u", Value.m_pValue[i]);
00318             break;
00319 
00320         case CFieldDescriptor::FMT_HEX:
00321             appendFormat("%04X", 0xFFFF & Value.m_pValue[i]);
00322             break;
00323         }
00324     }
00325     appendCloseTag(pFieldName);
00326 }
00327 
00328 void
00329 CXMLTextEncoderStream::put_s16v (
00330   llrp_s16v_t                   Value,
00331   const CFieldDescriptor *      pFieldDescriptor)
00332 {
00333     const char *                pFieldName = pFieldDescriptor->m_pName;
00334 
00335     appendOpenTag(pFieldName);
00336     for(int i = 0; i < Value.m_nValue; i++)
00337     {
00338         if(0 < i)
00339         {
00340             appendFormat(" ");
00341         }
00342         switch(pFieldDescriptor->m_eFieldFormat)
00343         {
00344         case CFieldDescriptor::FMT_NORMAL:
00345         case CFieldDescriptor::FMT_DEC:
00346         default:
00347             appendFormat("%d", Value.m_pValue[i]);
00348             break;
00349 
00350         case CFieldDescriptor::FMT_HEX:
00351             appendFormat("%04X", 0xFFFF & Value.m_pValue[i]);
00352             break;
00353         }
00354     }
00355     appendCloseTag(pFieldName);
00356 }
00357 
00358 /*
00359  * 32-bit types
00360  */
00361 
00362 void
00363 CXMLTextEncoderStream::put_u32 (
00364   llrp_u32_t                    Value,
00365   const CFieldDescriptor *      pFieldDescriptor)
00366 {
00367     const char *                pFieldName = pFieldDescriptor->m_pName;
00368 
00369     appendOpenTag(pFieldName);
00370     switch(pFieldDescriptor->m_eFieldFormat)
00371     {
00372     case CFieldDescriptor::FMT_NORMAL:
00373     case CFieldDescriptor::FMT_DEC:
00374     default:
00375         appendFormat("%u", Value);
00376         break;
00377 
00378     case CFieldDescriptor::FMT_HEX:
00379         appendFormat("%08X", Value);
00380         break;
00381     }
00382     appendCloseTag(pFieldName);
00383 }
00384 
00385 void
00386 CXMLTextEncoderStream::put_s32 (
00387   llrp_s32_t                    Value,
00388   const CFieldDescriptor *      pFieldDescriptor)
00389 {
00390     const char *                pFieldName = pFieldDescriptor->m_pName;
00391 
00392     appendOpenTag(pFieldName);
00393     switch(pFieldDescriptor->m_eFieldFormat)
00394     {
00395     case CFieldDescriptor::FMT_NORMAL:
00396     case CFieldDescriptor::FMT_DEC:
00397     default:
00398         appendFormat("%d", Value);
00399         break;
00400 
00401     case CFieldDescriptor::FMT_HEX:
00402         appendFormat("%08X", Value);
00403         break;
00404     }
00405     appendCloseTag(pFieldName);
00406 }
00407 
00408 void
00409 CXMLTextEncoderStream::put_u32v (
00410   llrp_u32v_t                   Value,
00411   const CFieldDescriptor *      pFieldDescriptor)
00412 {
00413     const char *                pFieldName = pFieldDescriptor->m_pName;
00414 
00415     appendOpenTag(pFieldName);
00416     for(int i = 0; i < Value.m_nValue; i++)
00417     {
00418         if(0 < i)
00419         {
00420             appendFormat(" ");
00421         }
00422         switch(pFieldDescriptor->m_eFieldFormat)
00423         {
00424         case CFieldDescriptor::FMT_NORMAL:
00425         case CFieldDescriptor::FMT_DEC:
00426         default:
00427             appendFormat("%u", Value.m_pValue[i]);
00428             break;
00429 
00430         case CFieldDescriptor::FMT_HEX:
00431             appendFormat("%08X", Value.m_pValue[i]);
00432             break;
00433         }
00434     }
00435     appendCloseTag(pFieldName);
00436 }
00437 
00438 void
00439 CXMLTextEncoderStream::put_s32v (
00440   llrp_s32v_t                   Value,
00441   const CFieldDescriptor *      pFieldDescriptor)
00442 {
00443     const char *                pFieldName = pFieldDescriptor->m_pName;
00444 
00445     appendOpenTag(pFieldName);
00446     for(int i = 0; i < Value.m_nValue; i++)
00447     {
00448         if(0 < i)
00449         {
00450             appendFormat(" ");
00451         }
00452         switch(pFieldDescriptor->m_eFieldFormat)
00453         {
00454         case CFieldDescriptor::FMT_NORMAL:
00455         case CFieldDescriptor::FMT_DEC:
00456         default:
00457             appendFormat("%d", Value.m_pValue[i]);
00458             break;
00459 
00460         case CFieldDescriptor::FMT_HEX:
00461             appendFormat("%08X", Value.m_pValue[i]);
00462             break;
00463         }
00464     }
00465     appendCloseTag(pFieldName);
00466 }
00467 
00468 /*
00469  * 64-bit types
00470  */
00471 
00472 void
00473 CXMLTextEncoderStream::put_u64 (
00474   llrp_u64_t                    Value,
00475   const CFieldDescriptor *      pFieldDescriptor)
00476 {
00477     const char *                pFieldName = pFieldDescriptor->m_pName;
00478 
00479     appendOpenTag(pFieldName);
00480     switch(pFieldDescriptor->m_eFieldFormat)
00481     {
00482     case CFieldDescriptor::FMT_NORMAL:
00483     case CFieldDescriptor::FMT_DEC:
00484     default:
00485 #ifdef WIN32
00486         appendFormat("%I64u", Value);
00487 #else
00488         appendFormat("%llu", Value);
00489 #endif
00490         break;
00491 
00492     case CFieldDescriptor::FMT_HEX:
00493 #ifdef WIN32
00494         appendFormat("%016I64X", Value);
00495 #else
00496         appendFormat("%016llX", Value);
00497 #endif
00498         break;
00499 
00500     case CFieldDescriptor::FMT_DATETIME:
00501         {
00502             char                aBuf[64];
00503             time_t              CurSec  = (time_t)(Value / 1000000u);
00504             llrp_u32_t          CurUSec = (llrp_u32_t)(Value % 1000000u);
00505             struct tm *         pGMTime;
00506 
00507             pGMTime = gmtime(&CurSec);
00508             strftime(aBuf, sizeof aBuf, "%Y-%m-%dT%H:%M:%S", pGMTime);
00509             appendFormat("%s.%06dZ", aBuf, CurUSec);
00510         }
00511         break;
00512     }
00513     appendCloseTag(pFieldName);
00514 }
00515 
00516 void
00517 CXMLTextEncoderStream::put_s64 (
00518   llrp_s64_t                    Value,
00519   const CFieldDescriptor *      pFieldDescriptor)
00520 {
00521     const char *                pFieldName = pFieldDescriptor->m_pName;
00522 
00523     appendOpenTag(pFieldName);
00524     switch(pFieldDescriptor->m_eFieldFormat)
00525     {
00526     case CFieldDescriptor::FMT_NORMAL:
00527     case CFieldDescriptor::FMT_DEC:
00528     default:
00529 #ifdef WIN32
00530         appendFormat("%I64d", Value);
00531 #else
00532         appendFormat("%lld", Value);
00533 #endif
00534         break;
00535 
00536     case CFieldDescriptor::FMT_HEX:
00537 #ifdef WIN32
00538         appendFormat("%016I64X", Value);
00539 #else
00540         appendFormat("%016llX", Value);
00541 #endif
00542         break;
00543     }
00544     appendCloseTag(pFieldName);
00545 }
00546 
00547 void
00548 CXMLTextEncoderStream::put_u64v (
00549   llrp_u64v_t                   Value,
00550   const CFieldDescriptor *      pFieldDescriptor)
00551 {
00552     const char *                pFieldName = pFieldDescriptor->m_pName;
00553 
00554     appendOpenTag(pFieldName);
00555     for(int i = 0; i < Value.m_nValue; i++)
00556     {
00557         if(0 < i)
00558         {
00559             appendFormat(" ");
00560         }
00561         switch(pFieldDescriptor->m_eFieldFormat)
00562         {
00563         case CFieldDescriptor::FMT_NORMAL:
00564         case CFieldDescriptor::FMT_DEC:
00565         default:
00566 #ifdef WIN32
00567             appendFormat("%I64u", Value.m_pValue[i]);
00568 #else
00569             appendFormat("%llu", Value.m_pValue[i]);
00570 #endif
00571             break;
00572 
00573         case CFieldDescriptor::FMT_HEX:
00574 #ifdef WIN32
00575             appendFormat("%016I64X", Value.m_pValue[i]);
00576 #else
00577             appendFormat("%016llX", Value.m_pValue[i]);
00578 #endif
00579             break;
00580         }
00581     }
00582     appendCloseTag(pFieldName);
00583 }
00584 
00585 void
00586 CXMLTextEncoderStream::put_s64v (
00587   llrp_s64v_t                   Value,
00588   const CFieldDescriptor *      pFieldDescriptor)
00589 {
00590     const char *                pFieldName = pFieldDescriptor->m_pName;
00591 
00592     appendOpenTag(pFieldName);
00593     for(int i = 0; i < Value.m_nValue; i++)
00594     {
00595         if(0 < i)
00596         {
00597             appendFormat(" ");
00598         }
00599         switch(pFieldDescriptor->m_eFieldFormat)
00600         {
00601         case CFieldDescriptor::FMT_NORMAL:
00602         case CFieldDescriptor::FMT_DEC:
00603         default:
00604 #ifdef WIN32
00605             appendFormat("%I64d", Value.m_pValue[i]);
00606 #else
00607             appendFormat("%lld", Value.m_pValue[i]);
00608 #endif
00609             break;
00610 
00611         case CFieldDescriptor::FMT_HEX:
00612 #ifdef WIN32
00613             appendFormat("%016I64X", Value.m_pValue[i]);
00614 #else
00615             appendFormat("%016llX", Value.m_pValue[i]);
00616 #endif
00617             break;
00618         }
00619     }
00620     appendCloseTag(pFieldName);
00621 }
00622 
00623 /*
00624  * Special types
00625  */
00626 
00627 void
00628 CXMLTextEncoderStream::put_u1 (
00629   llrp_u1_t                     Value,
00630   const CFieldDescriptor *      pFieldDescriptor)
00631 {
00632     const char *                pFieldName = pFieldDescriptor->m_pName;
00633 
00634     appendOpenTag(pFieldName);
00635     switch(pFieldDescriptor->m_eFieldFormat)
00636     {
00637     case CFieldDescriptor::FMT_NORMAL:
00638     default:
00639         appendFormat("%s", (Value & 1) ? "true" : "false");
00640         break;
00641 
00642     case CFieldDescriptor::FMT_DEC:
00643     case CFieldDescriptor::FMT_HEX:
00644         appendFormat("%d", Value & 1);
00645         break;
00646     }
00647     appendCloseTag(pFieldName);
00648 }
00649 
00650 void
00651 CXMLTextEncoderStream::put_u1v (
00652   llrp_u1v_t                    Value,
00653   const CFieldDescriptor *      pFieldDescriptor)
00654 {
00655     const char *                pFieldName = pFieldDescriptor->m_pName;
00656     int                         nByte;
00657 
00658     nByte = (Value.m_nBit + 7u) / 8u;
00659 
00660     indent();
00661     appendFormat("<");
00662     appendPrefixedTagName(pFieldName);
00663     appendFormat(" Count='%d'>", Value.m_nBit);
00664 
00665     for(int i = 0; i < nByte; i++)
00666     {
00667         appendFormat("%02X", Value.m_pValue[i]);
00668     }
00669 
00670     appendCloseTag(pFieldName);
00671 }
00672 
00673 void
00674 CXMLTextEncoderStream::put_u2 (
00675   llrp_u2_t                     Value,
00676   const CFieldDescriptor *      pFieldDescriptor)
00677 {
00678     const char *                pFieldName = pFieldDescriptor->m_pName;
00679 
00680     appendOpenTag(pFieldName);
00681     appendFormat("%d", Value & 3);
00682     appendCloseTag(pFieldName);
00683 }
00684 
00685 void
00686 CXMLTextEncoderStream::put_u96 (
00687   llrp_u96_t                    Value,
00688   const CFieldDescriptor *      pFieldDescriptor)
00689 {
00690     const char *                pFieldName = pFieldDescriptor->m_pName;
00691 
00692     appendOpenTag(pFieldName);
00693     for(int i = 0; i < 12; i++)
00694     {
00695         appendFormat("%02X", Value.m_aValue[i]);
00696     }
00697     appendCloseTag(pFieldName);
00698 }
00699 
00700 void
00701 CXMLTextEncoderStream::put_utf8v (
00702   llrp_utf8v_t                  Value,
00703   const CFieldDescriptor *      pFieldDescriptor)
00704 {
00705     const char *                pFieldName = pFieldDescriptor->m_pName;
00706 
00707     appendOpenTag(pFieldName);
00708     for(int i = 0; i < Value.m_nValue; i++)
00709     {
00710         int         c = Value.m_pValue[i];
00711 
00712         if(0 == c && i+1 == Value.m_nValue)
00713         {
00714             continue;
00715         }
00716         if(' ' <= c && c < 0x7F)
00717         {
00718             appendFormat("%c", c);
00719         }
00720         else
00721         {
00722             appendFormat("\\%03o", c);
00723         }
00724     }
00725     appendCloseTag(pFieldName);
00726 }
00727 
00728 void
00729 CXMLTextEncoderStream::put_bytesToEnd (
00730   llrp_bytesToEnd_t             Value,
00731   const CFieldDescriptor *      pFieldDescriptor)
00732 {
00733     const char *                pFieldName = pFieldDescriptor->m_pName;
00734 
00735     appendOpenTag(pFieldName);
00736     for(int i = 0; i < Value.m_nValue; i++)
00737     {
00738         appendFormat("%02X", Value.m_pValue[i]);
00739     }
00740     appendCloseTag(pFieldName);
00741 }
00742 
00743 /*
00744  * Enumerated types of various sizes
00745  */
00746 
00747 void
00748 CXMLTextEncoderStream::put_e1 (
00749   int                           eValue,
00750   const CFieldDescriptor *      pFieldDescriptor)
00751 {
00752     put_enum(eValue, pFieldDescriptor);
00753 }
00754 
00755 void
00756 CXMLTextEncoderStream::put_e2 (
00757   int                           eValue,
00758   const CFieldDescriptor *      pFieldDescriptor)
00759 {
00760     put_enum(eValue, pFieldDescriptor);
00761 }
00762 
00763 void
00764 CXMLTextEncoderStream::put_e8 (
00765   int                           eValue,
00766   const CFieldDescriptor *      pFieldDescriptor)
00767 {
00768     put_enum(eValue, pFieldDescriptor);
00769 }
00770 
00771 void
00772 CXMLTextEncoderStream::put_e16 (
00773   int                           eValue,
00774   const CFieldDescriptor *      pFieldDescriptor)
00775 {
00776     put_enum(eValue, pFieldDescriptor);
00777 }
00778 
00779 void
00780 CXMLTextEncoderStream::put_e32 (
00781   int                           eValue,
00782   const CFieldDescriptor *      pFieldDescriptor)
00783 {
00784     put_enum(eValue, pFieldDescriptor);
00785 }
00786 
00787 void
00788 CXMLTextEncoderStream::put_e8v (
00789   llrp_u8v_t                    Value,
00790   const CFieldDescriptor *      pFieldDescriptor)
00791 {
00792     const char *                pFieldName = pFieldDescriptor->m_pName;
00793 
00794     appendOpenTag(pFieldName);
00795     for(int i = 0; i < Value.m_nValue; i++)
00796     {
00797         int                     eValue = Value.m_pValue[i];
00798         const SEnumTableEntry * pEntry;
00799 
00800         for(pEntry = pFieldDescriptor->m_pEnumTable;
00801             NULL != pEntry->pName;
00802             pEntry++)
00803         {
00804             if(pEntry->Value == eValue)
00805             {
00806                 break;
00807             }
00808         }
00809 
00810         if(0 < i)
00811         {
00812             appendFormat(" ");
00813         }
00814 
00815         if(NULL != pEntry->pName)
00816         {
00817             appendFormat("%s", pEntry->pName);
00818         }
00819         else
00820         {
00821             appendFormat("%d", eValue);
00822         }
00823     }
00824     appendCloseTag(pFieldName);
00825 }
00826 
00827 /*
00828  * Reserved types are some number of bits
00829  */
00830 
00831 void
00832 CXMLTextEncoderStream::put_reserved (
00833   unsigned int                  nBits)
00834 {
00835     indent();
00836     appendFormat("<!-- reserved %d bits -->\n", nBits);
00837 }
00838 
00839 
00840 CXMLTextEncoderStream::CXMLTextEncoderStream (
00841   CXMLTextEncoder *               pEncoder)
00842 {
00843     m_pEncoder                  = pEncoder;
00844     m_pEnclosingEncoderStream   = NULL;
00845     m_pRefType                  = NULL;
00846     m_nDepth                    = 1;
00847 }
00848 
00849 CXMLTextEncoderStream::CXMLTextEncoderStream (
00850   CXMLTextEncoderStream *         pEnclosingEncoderStream)
00851 {
00852     m_pEncoder                  = pEnclosingEncoderStream->m_pEncoder;
00853     m_pEnclosingEncoderStream   = pEnclosingEncoderStream;
00854     m_pRefType                  = NULL;
00855     m_nDepth                    = pEnclosingEncoderStream->m_nDepth+1;
00856 }
00857 
00858 void
00859 CXMLTextEncoderStream::putElement (
00860   const CElement *              pElement)
00861 {
00862     m_pRefType = pElement->m_pType;
00863 
00864     indent(-1);
00865     appendFormat("<");
00866     appendPrefixedTagName(m_pRefType->m_pName);
00867     if(m_pRefType->m_bIsMessage)
00868     {
00869         appendFormat(" MessageID='%u'",
00870             ((const CMessage *)pElement)->getMessageID());
00871     }
00872 
00873     if(NULL == m_pEnclosingEncoderStream)
00874     {
00875         tNamespaceList          NamespaceList;
00876         const CNamespaceDescriptor *pNamespaceDescriptor;
00877         int                     iNSD;
00878 
00879         memset(&NamespaceList, 0, sizeof NamespaceList);
00880 
00881         pElement->walk(discoverNamespaces, (void*)&NamespaceList,
00882             0, 12);
00883 
00884         /* Emit the namespace cookie for each */
00885         for(iNSD = 0; iNSD < NamespaceList.nNamespaceDescriptor; iNSD++)
00886         {
00887             pNamespaceDescriptor = NamespaceList.apNamespaceDescriptor[iNSD];
00888 
00889             appendFormat("\n");
00890             indent(0);
00891             appendFormat("xmlns:%s='%s'",
00892                 pNamespaceDescriptor->m_pPrefix,
00893                 pNamespaceDescriptor->m_pURI);
00894             /*
00895              * If this is the default namespace then emit the assigment.
00896              */
00897             if(0 == strcmp(pNamespaceDescriptor->m_pPrefix, "llrp"))
00898             {
00899                 appendFormat("\n");
00900                 indent(0);
00901                 appendFormat("xmlns='%s'", pNamespaceDescriptor->m_pURI);
00902             }
00903         }
00904     }
00905     appendFormat(">\n");
00906 
00907     pElement->encode(this);
00908 
00909     indent(-1);
00910     appendCloseTag(m_pRefType->m_pName);
00911 }
00912 
00913 static int
00914 discoverNamespaces (
00915   const CElement *              pElement,
00916   void *                        pArg)
00917 {
00918     tNamespaceList *            pNSL = (tNamespaceList *) pArg;
00919     const CNamespaceDescriptor *pNamespaceDescriptor;
00920     int                         iNSD;
00921 
00922     pNamespaceDescriptor = pElement->m_pType->m_pNamespaceDescriptor;
00923 
00924     for(iNSD = 0; iNSD < pNSL->nNamespaceDescriptor; iNSD++)
00925     {
00926         if(pNSL->apNamespaceDescriptor[iNSD] == pNamespaceDescriptor)
00927         {
00928             /* Already have it */
00929             return 0;
00930         }
00931     }
00932 
00933     /* if we get here this namespace isn't already in the list */
00934     if(MAX_NS > pNSL->nNamespaceDescriptor)
00935     {
00936         iNSD = pNSL->nNamespaceDescriptor++;
00937         pNSL->apNamespaceDescriptor[iNSD] = pNamespaceDescriptor;
00938     }
00939 
00940     return 0;
00941 }
00942 
00943 
00944 void
00945 CXMLTextEncoderStream::put_enum (
00946   int                           eValue,
00947   const CFieldDescriptor *      pFieldDescriptor)
00948 {
00949     const char *                pFieldName = pFieldDescriptor->m_pName;
00950     const SEnumTableEntry *     pEntry;
00951 
00952     appendOpenTag(pFieldName);
00953 
00954     for(pEntry = pFieldDescriptor->m_pEnumTable;
00955         NULL != pEntry->pName;
00956         pEntry++)
00957     {
00958         if(pEntry->Value == eValue)
00959         {
00960             break;
00961         }
00962     }
00963 
00964     if(NULL != pEntry->pName)
00965     {
00966         appendFormat("%s", pEntry->pName);
00967     }
00968     else
00969     {
00970         appendFormat("%d", eValue);
00971     }
00972 
00973     appendCloseTag(pFieldName);
00974 }
00975 
00976 void
00977 CXMLTextEncoderStream::indent (
00978   int                           adjust)
00979 {
00980     int                         n = m_nDepth + adjust;
00981 
00982     for(int i = 0; i < n; i++)
00983     {
00984         appendFormat("  ");
00985     }
00986 }
00987 
00988 void
00989 CXMLTextEncoderStream::appendOpenTag (
00990   const char *                  pName)
00991 {
00992     indent(0);
00993     appendFormat("<");
00994     appendPrefixedTagName(pName);
00995     appendFormat(">");
00996 }
00997 
00998 void
00999 CXMLTextEncoderStream::appendCloseTag (
01000   const char *                  pName)
01001 {
01002     appendFormat("</");
01003     appendPrefixedTagName(pName);
01004     appendFormat(">\n");
01005 }
01006 
01007 void
01008 CXMLTextEncoderStream::appendPrefixedTagName (
01009   const char *                  pName)
01010 {
01011     const CTypeDescriptor *     pRefType = m_pRefType;
01012     const char *                pPrefix =
01013                                   pRefType->m_pNamespaceDescriptor->m_pPrefix;
01014 
01015     if(0 != strcmp("llrp", pPrefix))
01016     {
01017         appendFormat("%s:%s", pPrefix, pName);
01018     }
01019     else
01020     {
01021         appendFormat("%s", pName);
01022     }
01023 }
01024 
01025 void
01026 CXMLTextEncoderStream::appendFormat (
01027   char *                        pFmtStr,
01028                                 ...)
01029 {
01030     char                        aHoldBuf[256u];
01031     int                         nHoldBuf;
01032     va_list                     ap;
01033 
01034     /* If overflow already detected, bail */
01035     if(m_pEncoder->m_bOverflow)
01036     {
01037         return;
01038     }
01039 
01040     va_start(ap, pFmtStr);
01041 #ifdef WIN32
01042     _vsnprintf(aHoldBuf, sizeof aHoldBuf, pFmtStr, ap);
01043 #else
01044     vsnprintf(aHoldBuf, sizeof aHoldBuf, pFmtStr, ap);
01045 #endif
01046     va_end(ap);
01047 
01048     nHoldBuf = (int)strlen(aHoldBuf);
01049 
01050     if(m_pEncoder->m_iNext + nHoldBuf >= m_pEncoder->m_nBuffer)
01051     {
01052         m_pEncoder->m_bOverflow = 1;
01053         return;
01054     }
01055 
01056     strcpy(&m_pEncoder->m_pBuffer[m_pEncoder->m_iNext], aHoldBuf);
01057 
01058     m_pEncoder->m_iNext += nHoldBuf;
01059 }
01060 
01061 
01078 EResultCode
01079 CElement::toXMLString (
01080   char *                        pBuffer,
01081   int                           nBuffer)
01082 {
01083     return LLRP::toXMLString(this, pBuffer, nBuffer);
01084 }
01085 
01086 EResultCode
01087 toXMLString (
01088   const CElement *              pElement,
01089   char *                        pBuffer,
01090   int                           nBuffer)
01091 {
01092     CXMLTextEncoder *           pXMLEncoder;
01093     const CErrorDetails *       pError;
01094 
01095     /*
01096      * Make sure the element is not NULL.
01097      */
01098     if(NULL == pElement)
01099     {
01100         strcpy(pBuffer, "ERROR: NULL pMessage to printXMLMessage\n");
01101         return RC_MiscError;
01102     }
01103 
01104     /*
01105      * Construct an XML encoder
01106      */
01107     pXMLEncoder = new CXMLTextEncoder(pBuffer, nBuffer);
01108     if(NULL == pXMLEncoder)
01109     {
01110         printf("ERROR: XMLTextEncoder_construct failed\n");
01111         return RC_MiscError;
01112     }
01113 
01114     /*
01115      * Now let the encoding mechanism do its thing.
01116      */
01117     pXMLEncoder->encodeElement(pElement);
01118 
01119     /*
01120      * Check the outcome in the error details.
01121      * If there is a problem, return the error rather
01122      * than the assumed to be useless string.
01123      */
01124     pError = &pXMLEncoder->m_ErrorDetails;
01125 
01126     if(RC_OK != pError->m_eResultCode)
01127     {
01128         sprintf(pBuffer, "ERROR: %s XML text failed, %s\n",
01129             pElement->m_pType->m_pName,
01130             pError->m_pWhatStr ? pError->m_pWhatStr : "no reason given");
01131 
01132         delete pXMLEncoder;
01133 
01134         return pError->m_eResultCode;
01135     }
01136 
01137     /*
01138      * Check if the XML fit in the buffer.
01139      */
01140     if(pXMLEncoder->m_bOverflow)
01141     {
01142         strcpy(pBuffer, "ERROR: Buffer overflow\n");
01143         delete pXMLEncoder;
01144         return RC_MiscError;
01145     }
01146 
01147     /*
01148      * Done with the XML encoder.
01149      */
01150     delete pXMLEncoder;
01151 
01152     return RC_OK;
01153 }
01154 
01155 
01156 }; /* namespace LLRP */

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