LTKCPP-- LLRP Toolkit C Plus Plus Library
|
00001 00002 /* 00003 ***************************************************************************** 00004 * * 00005 * IMPINJ CONFIDENTIAL AND PROPRIETARY * 00006 * * 00007 * This source code is the sole property of Impinj, Inc. Reproduction or * 00008 * utilization of this source code in whole or in part is forbidden without * 00009 * the prior written consent of Impinj, Inc. * 00010 * * 00011 * (c) Copyright Impinj, Inc. 2007,2008. All rights reserved. * 00012 * * 00013 *****************************************************************************/ 00014 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 */