Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

ltkcpp_xmltextencode.cpp

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

Generated on Wed Nov 26 12:27:45 2008 for LTKCPP-- LLRP Toolkit C Plus Plus Library by  doxygen 1.3.9.1