hxinfcod.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:37k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  *
  37.  * This file contains implementation of classes that support
  38.  * the encoding of raw bytes of upgrade negotiation messages
  39.  * into a clear text representaion of the raw data.
  40.  *
  41.  */
  42. #include "hxinfcod.h"
  43. #include "hxassert.h"
  44. #include "hlxclib/string.h"
  45. //#include "hlxclib/stdio.h"
  46. #include "netbyte.h"
  47. #include "hxheap.h"
  48. #ifdef _DEBUG
  49. #undef HX_THIS_FILE
  50. static const char HX_THIS_FILE[] = __FILE__;
  51. #endif
  52. /////////////////////////////////////////////////////////////////////
  53. static UINT16  FourByteAlign(UINT16 number)
  54. {
  55. return( ((number+3)>>2)<<2 );
  56. }
  57. //*******************************************************************
  58. // CHXInfoEncoder
  59. //*******************************************************************
  60. // IUnknown interface listing
  61. BEGIN_INTERFACE_LIST(CHXInfoEncoder)
  62.     INTERFACE_LIST_ENTRY(IID_IHXObjOutStream, IHXObjOutStream)
  63. END_INTERFACE_LIST
  64. /////////////////////////////////////////////////////////////////////
  65. CHXInfoEncoder::CHXInfoEncoder()
  66. {
  67. m_FinalBuffer = NULL;
  68. m_bFinalBufferAllocFlag = FALSE;
  69. m_nFinalLen = 0;
  70. m_nOffset = 0;
  71. }
  72. /////////////////////////////////////////////////////////////////////
  73. // get ptr to encoded data - either the data buffer that's been Dump()'d
  74. // to, or a secondary buffer where data was further encoded (ie,
  75. // Hex'd or perplex'd).
  76. STDMETHODIMP_(const char*) CHXInfoEncoder::GetBuffer()
  77. {
  78. if (m_FinalBuffer)
  79. return((char*)m_FinalBuffer);
  80. return((char*)m_Buffer.GetPtr());
  81. }
  82. /////////////////////////////////////////////////////////////////////
  83. STDMETHODIMP_(UINT32) CHXInfoEncoder::GetLength()
  84. {
  85. if (m_FinalBuffer)
  86. return(m_nFinalLen);
  87. return(m_nOffset);
  88. }
  89. /////////////////////////////////////////////////////////////////////
  90. CHXInfoEncoder::~CHXInfoEncoder()
  91. {
  92. if ( (m_bFinalBufferAllocFlag==TRUE) && (m_FinalBuffer!=NULL) )
  93.     {
  94. delete [] m_FinalBuffer;
  95.     }
  96. }
  97. /////////////////////////////////////////////////////////////////////
  98. void CHXInfoEncoder::EncodeObj(IHXStreamableObj* pObj)
  99. {
  100. this->Initialize();
  101. this->WriteObj(pObj);
  102. }
  103. /////////////////////////////////////////////////////////////////////
  104. void CHXInfoEncoder::PerplexEncodeObj(IHXStreamableObj* pObj)
  105. {
  106. this->Initialize();
  107. this->WriteObj(pObj);
  108. this->Perplex();
  109. }
  110. /////////////////////////////////////////////////////////////////////
  111. BOOL CHXInfoEncoder::Perplex()
  112. {
  113. // no data to perplex?
  114. if (m_nOffset==0) return(FALSE);
  115. // if final buffer already exists, return error.....
  116. // That means we already did an encoding, and the user should
  117. // call Initialize() before the encoder is reused.
  118. if (m_FinalBuffer!=NULL) return(FALSE);
  119. // Make sure we're 4byte aligned. Needed by Perplex alg.
  120.     UINT32 nAlign =  (m_nOffset) % sizeof(ULONG32);
  121.     if (nAlign > 0)
  122.     {
  123. m_Buffer.EnsureValidOffset(m_nOffset+sizeof(ULONG32)-nAlign);
  124. for (; nAlign < sizeof(ULONG32); nAlign++)
  125. {
  126. m_Buffer.SetUCHAR(m_nOffset++,0);
  127. }
  128.     }
  129. // calc size of Perplexed buffer.
  130.     m_nFinalLen = m_nOffset * Perplex_PER_ULONG32 / sizeof(ULONG32);
  131. // alloc mem for final perplexed buffer
  132. // Add one to length 'cause low level perplex adds
  133. // a '' to the resulting string
  134. m_bFinalBufferAllocFlag = TRUE;
  135. m_FinalBuffer = new UCHAR[m_nFinalLen+1];
  136. HX_ASSERT(m_FinalBuffer!=NULL);
  137.     if( m_FinalBuffer==NULL)
  138.     {
  139. m_nFinalLen=0;
  140. return(FALSE);
  141.     }
  142. else
  143.     {
  144.         CHXInfoEncoder::DumpToPerplex((char*)m_FinalBuffer, m_nFinalLen+1, m_Buffer.GetPtr(), m_nOffset);
  145.     }
  146. return(TRUE);
  147. }
  148. /////////////////////////////////////////////////////////////////////
  149. void CHXInfoEncoder::HexEncodeObj(IHXStreamableObj* pObj)
  150. {
  151. this->Initialize();
  152. this->WriteObj(pObj);
  153. this->Hex();
  154. }
  155. /////////////////////////////////////////////////////////////////////
  156. BOOL CHXInfoEncoder::Hex()
  157. {
  158. // no data to perplex?
  159. if (m_nOffset==0) return(FALSE);
  160. // if final buffer already exists, return error.....
  161. // That means we already did an encoding, and the user should
  162. // call Initialize() before the encoder is reused.
  163. if (m_FinalBuffer!=NULL) return(FALSE);
  164. // calc size of hexed buffer.
  165.     m_nFinalLen = m_nOffset * 2;
  166. // alloc mem for final perplexed buffer
  167. m_bFinalBufferAllocFlag = TRUE;
  168. // Add one to length 'cause low level perplex adds
  169. // a '' to the resulting string
  170. m_FinalBuffer = new UCHAR[m_nFinalLen+1];
  171. HX_ASSERT(m_FinalBuffer!=NULL);
  172.     if( m_FinalBuffer==NULL)
  173.     {
  174. m_nFinalLen=0;
  175. return(FALSE);
  176.     }
  177. else
  178.     {
  179.         CHXInfoEncoder::DumpToHex((char*)m_FinalBuffer, m_Buffer.GetPtr(), m_nOffset);
  180.     }
  181. return(TRUE);
  182. }
  183. /////////////////////////////////////////////////////////////////////
  184. STDMETHODIMP CHXInfoEncoder::Initialize()
  185. {
  186. if (m_bFinalBufferAllocFlag==TRUE)
  187.     {
  188. if (m_FinalBuffer!=NULL)
  189. delete [] m_FinalBuffer;
  190.     }
  191. m_bFinalBufferAllocFlag = FALSE;
  192. m_FinalBuffer = NULL;
  193. m_nFinalLen    = 0;
  194. m_Buffer.Free();
  195. m_nOffset=0;
  196. return(HXR_OK);
  197. }
  198. /////////////////////////////////////////////////////////////////////
  199. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteObj(IHXStreamableObj* pObj) 
  200. {
  201. UINT32 nLen=this->GetOffset();
  202. if (pObj->WriteObjToBits(this)==HXR_OK)
  203. return this->GetOffset()-nLen;
  204. #if 0
  205. // reading object
  206. this->Seek(nLen);
  207. #endif
  208. return(0);
  209. }
  210. /////////////////////////////////////////////////////////////////////
  211. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteUCHAR(UCHAR nValue)
  212. {
  213.     m_Buffer.SafeMemCopy(m_nOffset,&nValue, sizeof(nValue));
  214. m_nOffset += sizeof(nValue);
  215.     return sizeof(nValue);
  216. }
  217. /////////////////////////////////////////////////////////////////////
  218. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteUINT16(UINT16 nValue)
  219. {
  220.     UINT16 temp16 = WToNet(nValue);
  221.     m_Buffer.SafeMemCopy(m_nOffset,&temp16, sizeof(temp16));
  222. m_nOffset += sizeof(temp16);
  223.     return sizeof(temp16);
  224. }
  225. /////////////////////////////////////////////////////////////////////
  226. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteUINT32(UINT32 nValue)
  227. {
  228.     UINT32 temp32 = DwToNet(nValue);
  229. m_Buffer.SafeMemCopy(m_nOffset, &temp32, sizeof(temp32));
  230. m_nOffset += sizeof(temp32);
  231.     return sizeof(temp32);
  232. }
  233. /////////////////////////////////////////////////////////////////////
  234. // Dump at a specific position. Doesn't advance offset pointer
  235. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteUINT16At(UINT32 nOffset, UINT16 nValue)
  236. {
  237.     UINT16 temp16 = WToNet(nValue);
  238. if (m_Buffer.IsValidOffset(nOffset+sizeof(temp16))==TRUE)
  239.     {
  240.      m_Buffer.MemCopy(nOffset,&temp16, sizeof(temp16));
  241.     }
  242.     return sizeof(temp16);
  243. }
  244. /////////////////////////////////////////////////////////////////////
  245. // Dump at a specific position. Doesn't advance offset pointer
  246. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteUINT32At(UINT32 nOffset, UINT32 nValue)
  247. {
  248.     UINT32 temp32 = DwToNet(nValue);
  249. if (m_Buffer.IsValidOffset(nOffset+sizeof(temp32))==TRUE)
  250.     {
  251. m_Buffer.MemCopy(nOffset, &temp32, sizeof(temp32));
  252.     }
  253.     return sizeof(temp32);
  254. }
  255. /////////////////////////////////////////////////////////////////////
  256. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteString(const char* szValue)
  257. {
  258. if (szValue==NULL)
  259.     {
  260. szValue="";
  261.     }
  262.     UINT32 FieldLen = strlen(szValue);
  263.     HX_ASSERT(FieldLen < 0xFF);
  264. // ensure the buffer has enough room for us.
  265. if (m_Buffer.EnsureValidOffset(m_nOffset+FieldLen+1)==TRUE)
  266.     {
  267. m_Buffer.SetUCHAR(m_nOffset, (UCHAR)FieldLen );
  268.         m_Buffer.MemCopy(m_nOffset + 1, szValue, FieldLen);
  269.     }
  270.     FieldLen ++; //account for first SIZE byte
  271. m_nOffset += FieldLen;
  272.     return FieldLen;
  273. }
  274. /////////////////////////////////////////////////////////////////////
  275. // Similar to DumpString, except this one is handy when you need
  276. // to concat 2 or 3 strings and Dump them. Instead of allocating
  277. // a buffer, concating the strings and calling DumpString, use
  278. // this routine instead. It will take 2 or 3 strings as a parameters,
  279. // and dump them concatenated. The original strings are not modified.
  280. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteStringCat(const char* szValue1,const char* szValue2,const char* szValue3)
  281. {
  282. if (szValue1==NULL) { szValue1=""; }
  283. if (szValue2==NULL) { szValue2=""; }
  284. if (szValue3==NULL) { szValue3=""; }
  285.     UINT16 nLen1=strlen(szValue1);
  286.     UINT16 nLen2=strlen(szValue2);
  287.     UINT16 nLen3=strlen(szValue3);
  288.     UINT32 FieldLen = nLen1 + nLen2 + nLen3;
  289.     HX_ASSERT(FieldLen < 0xFF);
  290. // ensure the buffer has enough room for us.
  291. if (m_Buffer.EnsureValidOffset(m_nOffset+FieldLen+1)==TRUE)
  292.     {
  293. m_Buffer.SetUCHAR(m_nOffset, (UCHAR)FieldLen );
  294. m_nOffset++;
  295. if (nLen1)
  296.         {
  297.         m_Buffer.MemCopy(m_nOffset, szValue1, nLen1);
  298. m_nOffset+=nLen1;
  299.         }
  300. if (nLen2)
  301.         {
  302.         m_Buffer.MemCopy(m_nOffset, szValue2, nLen2);
  303. m_nOffset+=nLen2;
  304.         }
  305. if (nLen3)
  306.         {
  307.         m_Buffer.MemCopy(m_nOffset, szValue3, nLen3);
  308. m_nOffset+=nLen3;
  309.         }
  310.     }
  311.     FieldLen ++; //account for first SIZE byte
  312.     return FieldLen;
  313. }
  314. /////////////////////////////////////////////////////////////////////
  315. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteLargeString(const char* szValue)
  316. {
  317. if (szValue==NULL)
  318.     {
  319. szValue="";
  320.     }
  321. // get the length of the string
  322.     UINT32 FieldLen = strlen(szValue);
  323.     HX_ASSERT(FieldLen < 0xFFFF);
  324. // dump the size (this increments m_nOffset for us too)
  325. UINT32 nSize = WriteUINT16((UINT16)FieldLen);
  326.     m_Buffer.SafeMemCopy(m_nOffset, szValue, FieldLen);
  327. m_nOffset += FieldLen;
  328.     return (FieldLen+nSize);
  329. }
  330. /////////////////////////////////////////////////////////////////////
  331. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteBuffer(const char* szBuffer, UINT32 nSize)
  332. {
  333. HX_ASSERT(szBuffer!=NULL);
  334. if (szBuffer!=NULL)
  335.     {
  336.      m_Buffer.SafeMemCopy(m_nOffset, szBuffer, nSize);
  337.     }
  338. m_nOffset += nSize;
  339.     return (nSize);
  340. }
  341. #if 0
  342. /////////////////////////////////////////////////////////////////////
  343. STDMETHODIMP_(UINT32) CHXInfoEncoder::WriteUTCTime(UTCTimeRep& TimeRep)
  344. {
  345. return(this->WriteUINT32( TimeRep.asUTCTimeT() ));
  346. //    return this->WriteString(( TimeRep.asUTCString() );
  347. }
  348. #endif
  349. //*******************************************************************
  350. // CHXInfoDecoder
  351. //*******************************************************************
  352. // IUnknown interface listing
  353. BEGIN_INTERFACE_LIST(CHXInfoDecoder)
  354.     INTERFACE_LIST_ENTRY(IID_IHXObjInStream, IHXObjInStream)
  355. END_INTERFACE_LIST
  356. /////////////////////////////////////////////////////////////////////
  357. BOOL  CHXInfoDecoder::DecodeObj(const UCHAR* buffer, UINT32 nSize, IHXStreamableObj* pObj)
  358. {
  359. HX_ASSERT(buffer!=NULL);
  360. if (buffer==NULL)
  361.     {
  362. return(FALSE);
  363.     }
  364. this->Initialize();
  365. // Casting away the const, so we must promise not to mess with the
  366. // contents...
  367. m_Buffer = (UCHAR *)buffer;
  368. m_nDecodedLen = nSize;
  369. // ReadObj returns 0 on failure
  370. return (this->ReadObj(pObj)>0);
  371. }
  372. /////////////////////////////////////////////////////////////////////
  373. BOOL  CHXInfoDecoder::PerplexDecodeObj(const char* szPerplex, IHXStreamableObj* pObj)
  374. {
  375. if (szPerplex)
  376.     {
  377. return this->PerplexDecodeObj(szPerplex,strlen(szPerplex),pObj);
  378.     }
  379. return(FALSE);
  380. }
  381. /////////////////////////////////////////////////////////////////////
  382. // We'll unperplex the data into our own buffer, then decode the obj.
  383. BOOL  CHXInfoDecoder::PerplexDecodeObj(const char* szPerplex, UINT32 nPlexLen, IHXStreamableObj* pObj)
  384. {
  385. UINT32 nBitLen  = nPlexLen * sizeof(ULONG32) / Perplex_PER_ULONG32;
  386. UCHAR* Buffer = new UCHAR[nBitLen + 4];
  387. HX_ASSERT(Buffer!=NULL);
  388. if (Buffer==NULL) return(FALSE);
  389.     UINT32 nBitLenActual = CHXInfoDecoder::SetFromPerplex(szPerplex, Buffer, nBitLen+4, nPlexLen);
  390. BOOL bRetVal = FALSE;
  391. if (nBitLenActual==nBitLen)
  392.     {
  393. bRetVal  = this->DecodeObj(Buffer, nBitLen, pObj);
  394.     }
  395. delete [] Buffer;
  396.     return bRetVal;
  397. }
  398. /////////////////////////////////////////////////////////////////////
  399. BOOL  CHXInfoDecoder::HexDecodeObj(const char* szHex, IHXStreamableObj* pObj)
  400. {
  401. if (szHex)
  402.     {
  403. return this->HexDecodeObj(szHex,strlen(szHex),pObj);
  404.     }
  405. return(FALSE);
  406. }
  407. /////////////////////////////////////////////////////////////////////
  408. BOOL  CHXInfoDecoder::HexDecodeObj(const char* szHex, UINT32 nHexLen, IHXStreamableObj* pObj)
  409. {
  410. UINT32 nBitLen  = nHexLen>>1; // unhexed length is 1/2 of hex'd length
  411. UCHAR* Buffer=new UCHAR[nBitLen];
  412. HX_ASSERT(Buffer!=NULL);
  413. if (Buffer==NULL) return(FALSE);
  414.     UINT32 nBitLenActual = CHXInfoDecoder::SetFromHex(szHex, Buffer, nHexLen);
  415. BOOL bRetVal = FALSE;
  416. if (nBitLenActual==nBitLen)
  417.     {
  418. bRetVal  = this->DecodeObj(Buffer,nBitLen,pObj);
  419.     }
  420. delete [] Buffer;
  421.     return bRetVal;
  422. }
  423. /////////////////////////////////////////////////////////////////////
  424. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadObj(IHXStreamableObj* pObj) 
  425. {
  426. UINT32 nLen=this->GetOffset();
  427. if (pObj->ReadObjFromBits(this)==HXR_OK)
  428. return this->GetOffset()-nLen;
  429. #if 0
  430. // reading object
  431. this->Seek(nLen);
  432. #endif
  433. return(0);
  434. }
  435. /////////////////////////////////////////////////////////////////////
  436. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadUCHAR(UCHAR& nValue)
  437. {
  438.     UCHAR temp;
  439.     memcpy(&temp, m_Buffer+m_nOffset, sizeof(temp)); /* Flawfinder: ignore */
  440.     nValue = temp;
  441. m_nOffset += sizeof(temp);
  442.     return sizeof(temp);
  443. }
  444. /////////////////////////////////////////////////////////////////////
  445. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadUINT16(UINT16& nValue)
  446. {
  447.     UINT16 temp16;
  448.     memcpy(&temp16, m_Buffer+m_nOffset, sizeof(temp16)); /* Flawfinder: ignore */
  449.     nValue = WToHost(temp16);
  450. m_nOffset += sizeof(temp16);
  451.     return sizeof(temp16);
  452. }
  453. /////////////////////////////////////////////////////////////////////
  454. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadUINT32(UINT32& nValue)
  455. {
  456.     UINT32 temp32;
  457.     memcpy(&temp32, m_Buffer+m_nOffset, sizeof(temp32)); /* Flawfinder: ignore */
  458.     nValue = DwToHost(temp32);
  459. m_nOffset += sizeof(temp32);
  460.     return sizeof(temp32);
  461. }
  462. /////////////////////////////////////////////////////////////////////
  463. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadString(CHXString& strValue)
  464. {
  465.     UINT32 FieldLen = *(m_Buffer+m_nOffset++);
  466.     char* pBuffer = strValue.GetBuffer((int)FieldLen);
  467.     memcpy(pBuffer, m_Buffer+m_nOffset, (int)FieldLen); /* Flawfinder: ignore */
  468.     pBuffer[FieldLen] = '';
  469.     strValue.ReleaseBuffer();
  470. m_nOffset += FieldLen;
  471.     return FieldLen+1;
  472. }
  473. /////////////////////////////////////////////////////////////////////
  474. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadAndAllocCString(char*& pszValue)
  475. {
  476.     UINT32 FieldLen = *(m_Buffer+m_nOffset++);
  477.     pszValue = new char[FieldLen+1];
  478.     memcpy(pszValue, m_Buffer+m_nOffset, (int)FieldLen); /* Flawfinder: ignore */
  479.     pszValue[FieldLen] = '';
  480. m_nOffset += FieldLen;
  481.     return FieldLen+1;
  482. }
  483. /////////////////////////////////////////////////////////////////////
  484. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadLargeString(CHXString& strValue)
  485. {
  486.     UINT16 FieldLen = 0;
  487.     UINT32 nSize = ReadUINT16(FieldLen);
  488.     char* pBuffer = strValue.GetBuffer(FieldLen);
  489.     memcpy(pBuffer, m_Buffer+m_nOffset, FieldLen); /* Flawfinder: ignore */
  490.     pBuffer[FieldLen] = '';
  491.     strValue.ReleaseBuffer();
  492. m_nOffset += FieldLen;
  493.     return nSize+FieldLen;
  494. }
  495. /////////////////////////////////////////////////////////////////////
  496. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadAndAllocLargeCString(char*& pszValue)
  497. {
  498.     UINT16 FieldLen = 0;
  499.     UINT32 nSize = ReadUINT16(FieldLen);
  500.     pszValue = new char[FieldLen+1];
  501.     memcpy(pszValue, m_Buffer+m_nOffset, FieldLen); /* Flawfinder: ignore */
  502.     pszValue[FieldLen] = '';
  503. m_nOffset += FieldLen;
  504.     return nSize+FieldLen;
  505. }
  506. /////////////////////////////////////////////////////////////////////
  507. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadBuffer(char* szBuffer, UINT32 nSize)
  508. {
  509.     memcpy(szBuffer, m_Buffer+m_nOffset, (int)nSize); /* Flawfinder: ignore */
  510. m_nOffset += nSize;
  511.     return nSize;
  512. }
  513. #if 0
  514. /////////////////////////////////////////////////////////////////////
  515. STDMETHODIMP_(UINT32) CHXInfoDecoder::ReadUTCTime(UTCTimeRep& TimeRep)
  516. {
  517. UINT32 time, nSize;
  518. nSize = ReadUINT32(time);
  519. TimeRep.SetUTCTime(time);
  520. return(nSize);
  521. }
  522. #endif
  523. /////////////////////////////////////////////////////////////////////
  524. STDMETHODIMP CHXInfoDecoder::Seek(UINT32 nPos)
  525. {
  526. if (nPos<=m_nDecodedLen)
  527.     {
  528. m_nOffset = nPos;
  529.     }
  530. return(HXR_OK);
  531. }
  532. /////////////////////////////////////////////////////////////////////
  533. STDMETHODIMP CHXInfoDecoder::SkipForward(UINT32 nAmount)
  534. {
  535. m_nOffset += nAmount;
  536. if (m_nOffset>m_nDecodedLen)
  537.     {
  538. m_nOffset = m_nDecodedLen;
  539.     }
  540. return(HXR_OK);
  541. }
  542. /////////////////////////////////////////////////////////////////////
  543. STDMETHODIMP_(BOOL) CHXInfoDecoder::IsEndOfData()
  544. {
  545. if (m_nDecodedLen<Perplex_ALIGNMENT)
  546. {
  547. return(TRUE);
  548. }
  549. if (m_nOffset>(m_nDecodedLen-Perplex_ALIGNMENT))
  550. return(TRUE);
  551. else
  552. return(FALSE);
  553. }
  554. /////////////////////////////////////////////////////////////////////////////
  555. //
  556. // Function:
  557. //
  558. // FromHexNibble()
  559. //
  560. // Purpose:
  561. //
  562. //
  563. // Parameters:
  564. //
  565. // char hexChar
  566. // Character representing a hex encoding of a nibble.
  567. //
  568. // Return:
  569. //
  570. // UCHAR
  571. // Actual value of the nibble encoded by hexChar.
  572. //
  573. UCHAR CHXInfoDecoder::FromHexNibble(char hexChar)
  574. {
  575. UCHAR value = 0;
  576. if (hexChar >= '0' && hexChar <= '9')
  577. {
  578. value = hexChar - '0';
  579. }
  580. else if (hexChar >= 'A' && hexChar <= 'F')
  581. {
  582. value = hexChar - 'A' + 10;
  583. }
  584. else if (hexChar >= 'a' && hexChar <= 'f')
  585. {
  586. value = hexChar - 'a' + 10;
  587. }
  588. #ifdef _DEBUG
  589. else
  590. {
  591. // Bad hex character!
  592. HX_ASSERT(FALSE);
  593. }
  594. #endif
  595. return value;
  596. }
  597. /////////////////////////////////////////////////////////////////////////////
  598. //
  599. // Function:
  600. //
  601. // HXClientLicense::SetFromHex()
  602. //
  603. // Purpose:
  604. //
  605. // Sets items of the license key from a hexidecimal encoding of the
  606. // license key bits.
  607. //
  608. // Parameters:
  609. //
  610. // const char* hex
  611. // Pointer to a buffer that contains a hexidecimal encoding of the
  612. // license key.
  613. //
  614. // UCHAR* Bits
  615. // Pointer to a buffer that will be filled on output with a bitwise
  616. // decoding of the license key.
  617. //
  618. // UINT32 nSize
  619. // Size of the hex string on input
  620. //
  621. // Return:
  622. //
  623. // int
  624. // Size in bytes of decoded size!
  625. //
  626. // Note:
  627. //
  628. //  Hex representations of the License Key consist of the
  629. //  representation of the bits in human readable form in a
  630. //  HEX encoding. This basically uses a pointer to a memory
  631. //  buffer of charcters encoded as hex representing the bits.
  632. //  Valid characters are 0-9,A-F. Buffers out will be upper
  633. //  case letters, buffers in will be converted to upper case.
  634. //
  635. //  These char's are hex encoding. They are never DBCS, the only
  636. // valid characters are 0-9,A-F
  637. //
  638. UINT32 CHXInfoDecoder::SetFromHex(const char* hex, UCHAR* Bits, UINT32 nSize)
  639. {
  640. UINT32 ndxBits;
  641. UINT32 ndxHex = 0;
  642. UCHAR nibble1;
  643. UCHAR nibble2;
  644. UCHAR byte;
  645. for (ndxBits = 0; ndxHex < nSize; ndxBits++)
  646. {
  647. nibble1 = FromHexNibble(hex[ndxHex]);
  648. nibble1 = nibble1 << 4;
  649. ndxHex++;
  650. nibble2 = FromHexNibble(hex[ndxHex]);
  651. byte = nibble1 | nibble2;
  652. ndxHex++;
  653. Bits[ndxBits] = byte;
  654. }
  655. return ndxBits;
  656. }
  657. /////////////////////////////////////////////////////////////////////////////
  658. //
  659. // Function:
  660. //
  661. // ToHexNibble()
  662. //
  663. // Purpose:
  664. //
  665. // Converts a nibble into the appropriate character for Hex encoding.
  666. //
  667. // Parameters:
  668. //
  669. // UCHAR hexValue
  670. // Value of the nibble.
  671. //
  672. // Return:
  673. //
  674. // char
  675. // Character representing the hex encoding of the nibble.
  676. //
  677. char CHXInfoEncoder::ToHexNibble(UCHAR hexValue)
  678. {
  679. char hexChar = '0';
  680. if (hexValue <= 0x9)
  681. {
  682. hexChar = '0' + hexValue;
  683. }
  684. else if (hexValue >= 0xA && hexValue <= 0xF)
  685. {
  686. hexChar = 'A' + (hexValue - 10);
  687. }
  688. #ifdef _DEBUG
  689. else
  690. {
  691. // Bad hex character!
  692. HX_ASSERT(FALSE);
  693. }
  694. #endif
  695. return hexChar;
  696. }
  697. /////////////////////////////////////////////////////////////////////////////
  698. //
  699. // Function:
  700. //
  701. // DumpToHex()
  702. //
  703. // Purpose:
  704. //
  705. // Formats the license key in human readable hexadecimal encoding.
  706. //
  707. // Parameters:
  708. //
  709. // char* hex
  710. // Pointer to buffer to be filled with hexadecimal encoding of
  711. // license key
  712. //
  713. // Return:
  714. //
  715. // None.
  716. //
  717. void CHXInfoEncoder::DumpToHex(char* hex, UCHAR* Bits, UINT32 nSize)
  718. {
  719. UINT32 ndxBits;
  720. UINT32 ndxHex = 0;
  721. UCHAR nibble1;
  722. UCHAR nibble2;
  723. UCHAR byte;
  724. for (ndxBits = 0; ndxBits < nSize; ndxBits++)
  725. {
  726. byte = Bits[ndxBits];
  727. nibble1 = (byte & 0xF0) >> 4;
  728. nibble2 = (byte & 0x0F);
  729. hex[ndxHex] = ToHexNibble(nibble1);
  730. ndxHex++;
  731. hex[ndxHex] = ToHexNibble(nibble2);
  732. ndxHex++;
  733. }
  734. hex[ndxHex] = '';
  735. }
  736. /////////////////////////////////////////////////////////////////////////////
  737. //
  738. // Function:
  739. //
  740. // MapFromPerplex()
  741. //
  742. // Purpose:
  743. //
  744. // Converts appropriate characters for Perplex encoding into a ULONG32.
  745. //
  746. #ifdef _WIN16
  747. extern char* zPerplexChars;
  748. #else
  749. // A copy of this is kept in in pnmiscpubwinpnmisc16.h.  If you change 
  750. // this (which is very unlikely), then be sure to change it there.  
  751. static const char zPerplexChars[] =
  752. {
  753. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  754. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  755. 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  756. 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
  757. 'E'
  758. };
  759. static const char zDePerplexMap[] = 
  760. { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  761. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  762. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  763. 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,
  764. 0,36,37,38,39,40,0,0,0,0,0,0,0,0,0,0,
  765. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  766. 0,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
  767. 25,26,27,28,29,30,31,32,33,34,35,0,0,0,0,0,
  768. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  769. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  770. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  771. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  772. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  773. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  774. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  775. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  776. };
  777. #endif /* _WIN16 */
  778. UCHAR CHXInfoDecoder::MapFromPerplex(char Perplex)
  779. {
  780.     return zDePerplexMap[Perplex];
  781. }
  782. /////////////////////////////////////////////////////////////////////////////
  783. //
  784. // Function:
  785. //
  786. // MapToPerplex()
  787. //
  788. // Purpose:
  789. //
  790. // Converts a digit ordinal to the Perplex digit...
  791. //
  792. char CHXInfoEncoder::MapToPerplex(UCHAR Perplex)
  793. {                                                  
  794. #ifdef _DEBUG
  795. #ifndef _WIN16
  796. // On win16, zPerplexChars is a char *, rather than an array, so this
  797. // doesn't work.
  798. int size_zPerplexChars  = sizeof(zPerplexChars); 
  799. int size_zPerplexChars0 = sizeof(zPerplexChars[0]);
  800. HX_ASSERT(Perplex < size_zPerplexChars/size_zPerplexChars0);
  801. #endif
  802. #endif
  803. return zPerplexChars[Perplex];
  804. }
  805. /////////////////////////////////////////////////////////////////////////////
  806. //
  807. // Function:
  808. //
  809. // FromPerplex()
  810. //
  811. // Purpose:
  812. //
  813. // Converts appropriate characters for Perplex encoding into a ULONG32.
  814. //
  815. ULONG32 CHXInfoDecoder::FromPerplex(const char* Perplex)
  816. {
  817. ULONG32 value = 0;
  818. ULONG32 PerplexBase = 1;
  819. for (int n = 0; n < Perplex_PER_ULONG32; n++)
  820. {
  821. value += MapFromPerplex(Perplex[n]) * PerplexBase;
  822. PerplexBase *= Perplex_BASE;
  823. }
  824. // Convert to local byte order!
  825. value = DwToHost(value);
  826. return value;
  827. }
  828. /////////////////////////////////////////////////////////////////////////////
  829. //
  830. // Function:
  831. //
  832. // ToPerplexNibble()
  833. //
  834. // Purpose:
  835. //
  836. // Converts a ULONG32 into the appropriate characters for Perplex encoding.
  837. //
  838. void CHXInfoEncoder::ToPerplex(ULONG32 Input, char* Perplex)
  839. {
  840. ULONG32 value;
  841. UCHAR charValue;
  842. // Convert to net byte order!
  843. value = DwToNet(Input);
  844. for (int n = 0; n < Perplex_PER_ULONG32; n++)
  845. {
  846. charValue = (UCHAR)(value % Perplex_BASE);
  847. Perplex[n] = MapToPerplex(charValue);
  848. value = value / Perplex_BASE;
  849. }
  850. }
  851. /////////////////////////////////////////////////////////////////////////////
  852. //
  853. // Function:
  854. //
  855. // HXClientLicense::SetFromPerplex()
  856. //
  857. // Purpose:
  858. //
  859. // Sets items of the license key from a Perplexidecimal encoding of the
  860. // license key bits.
  861. //
  862. // Parameters:
  863. //
  864. // const char* Perplex
  865. // Pointer to a buffer that contains a Perplexidecimal encoding of the
  866. // license key.
  867. //
  868. // UCHAR* Bits
  869. // Pointer to a buffer that will contain decoded bytes of information
  870. //
  871. //              UINT32 ulBitsLen
  872. //              Number of bytes in Bits output buffer
  873. //
  874. // int nSize
  875. // Input size in bytes
  876. //
  877. // Return:
  878. //
  879. // int
  880. // Size in bytes of decoded information
  881. //
  882. // Note:
  883. //
  884. //  Perplex representations of the License Key consist of the
  885. //  representation of the bits in human readable form in a
  886. //  Perplex encoding. This basically uses a pointer to a memory
  887. //  buffer of charcters encoded as Perplex representing the bits.
  888. //  Valid characters are 0-9,A-F. Buffers out will be upper
  889. //  case letters, buffers in will be converted to upper case.
  890. //
  891. //  These char's are Perplex encoding. They are never DBCS, the only
  892. // valid characters are 0-9,A-F
  893. //
  894. UINT32 CHXInfoDecoder::SetFromPerplex(const char* Perplex, UCHAR* Bits, UINT32 ulBitsLen, UINT32 nSize)
  895. {
  896. UINT32 ndxBits;
  897. UINT32 ndxPerplex = 0;
  898. ULONG32 temp32;
  899. for (ndxBits = 0; ndxPerplex < nSize; )
  900. {
  901. temp32 = FromPerplex(&Perplex[ndxPerplex]);
  902. ndxPerplex+=Perplex_PER_ULONG32;
  903. if (ndxBits+4 <= ulBitsLen) memcpy(&Bits[ndxBits],&temp32,sizeof(temp32)); /* Flawfinder: ignore */
  904. ndxBits+=sizeof(temp32);
  905. }
  906. return ndxBits;
  907. }
  908. /////////////////////////////////////////////////////////////////////////////
  909. //
  910. // Function:
  911. //
  912. // DumpToPerplex()
  913. //
  914. // Purpose:
  915. //
  916. // Formats the license key in human readable Perplexadecimal encoding.
  917. //
  918. // Parameters:
  919. //
  920. // char* Perplex
  921. // Pointer to buffer to be filled with Perplexadecimal encoding of
  922. // license key
  923. //
  924. // Return:
  925. //
  926. // None.
  927. //
  928. void CHXInfoEncoder::DumpToPerplex(char* Perplex, UINT32 ulPerplexSize, UCHAR* Bits, UINT32 nSize)
  929. {
  930. UINT32 ndxBits;
  931. UINT32 ndxPerplex = 0;
  932. ULONG32 temp32;
  933. for (ndxBits = 0; ndxBits < nSize; )
  934. {
  935. if (ndxBits+4 <= nSize) memcpy(&temp32,&Bits[ndxBits],sizeof(temp32)); /* Flawfinder: ignore */
  936.                 ndxBits+=sizeof(temp32);
  937. if (ndxPerplex+Perplex_PER_ULONG32 <= ulPerplexSize) ToPerplex(temp32,&Perplex[ndxPerplex]);
  938. ndxPerplex+=Perplex_PER_ULONG32;
  939. }
  940. Perplex[ndxPerplex] = '';
  941. }
  942. /////////////////////////////////////////////////////////////////////////////
  943. //
  944. // Function:
  945. //
  946. // MapFromMIMEBase64()
  947. //
  948. // Purpose:
  949. //
  950. // Converts appropriate characters for MIME-Base64 encoding into a the
  951. // Base64 ordinal.
  952. //
  953. #ifdef _WIN16
  954. extern char* zMIMEBase64Chars;
  955. #else
  956. // A copy of this is kept in in pnmiscpubwinpnmisc16.h.  If you change 
  957. // this (which is very unlikely), then be sure to change it there.  
  958. static const char zMIMEBase64Chars[] =
  959. {
  960. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  961. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  962. 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  963. 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  964. 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  965. 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
  966. '8', '9', '+', '/'
  967. };
  968. #endif /* _WIN16 */
  969. #define MIME_BASE64_PADDING '='
  970. #define FROM_MIME_BASE64_BYTES_IN 4
  971. #define FROM_MIME_BASE64_BYTES_OUT 3
  972. #define TO_MIME_BASE64_BYTES_IN FROM_MIME_BASE64_BYTES_OUT
  973. #define TO_MIME_BASE64_BYTES_OUT FROM_MIME_BASE64_BYTES_IN
  974. UCHAR CHXInfoDecoder::MapFromMIMEBase64(char MIMEBase64)
  975. {
  976. for (UCHAR n = 0; n < sizeof(zMIMEBase64Chars)/sizeof(zMIMEBase64Chars[0]); n++)
  977. {
  978. if (MIMEBase64 == zMIMEBase64Chars[n])
  979. {
  980. return n;
  981. }
  982. }
  983. HX_ASSERT(FALSE);
  984. return 0;
  985. }
  986. /////////////////////////////////////////////////////////////////////////////
  987. //
  988. // Function:
  989. //
  990. // MapToMIMEBase64()
  991. //
  992. // Purpose:
  993. //
  994. // Converts a digit ordinal to the MIMEBase64 digit...
  995. //
  996. char CHXInfoEncoder::MapToMIMEBase64(UCHAR MIMEBase64)
  997. {
  998. HX_ASSERT( MIMEBase64 < sizeof(zMIMEBase64Chars)/sizeof(zMIMEBase64Chars[0]));
  999. return zMIMEBase64Chars[MIMEBase64];
  1000. }
  1001. /////////////////////////////////////////////////////////////////////////////
  1002. //
  1003. // Function:
  1004. //
  1005. // SetFromMIMEBase64()
  1006. //
  1007. // Purpose:
  1008. //
  1009. // ...
  1010. //
  1011. // Parameters:
  1012. //
  1013. // ...
  1014. //
  1015. // Return:
  1016. //
  1017. // int
  1018. // Size in bytes of decoded information
  1019. //
  1020. UINT32 CHXInfoDecoder::SetFromMIMEBase64(const char* MIMEBase64, char* Bits, UINT32 nSize)
  1021. {
  1022. UINT32 ndxBits = 0;
  1023. UINT32 ndxMIMEBase64 = 0;
  1024. BOOL bDone = FALSE;
  1025. UINT32 ndxTempIn = 0;
  1026. UCHAR tempBitsIn [FROM_MIME_BASE64_BYTES_IN];
  1027. UINT32 padding = 0;
  1028. HX_ASSERT(strlen(MIMEBase64) <= nSize);
  1029. while (!bDone)
  1030. {
  1031. HX_ASSERT(ndxMIMEBase64 <= nSize);
  1032. HX_ASSERT(ndxBits <= nSize);
  1033. // Fill in our "temporary" in buffer with the Base64 characters.
  1034. for ( ndxTempIn = 0;
  1035. ndxTempIn < FROM_MIME_BASE64_BYTES_IN && (padding == 0);
  1036. ndxTempIn++
  1037. )
  1038. {
  1039. HX_ASSERT(ndxMIMEBase64 <= nSize);
  1040. UCHAR MIMEBase64char = MIMEBase64[ndxMIMEBase64];
  1041. switch (MIMEBase64char)
  1042. {
  1043. case MIME_BASE64_PADDING:
  1044. case '':
  1045. {
  1046. tempBitsIn[ndxTempIn] = 0;
  1047. bDone = TRUE;
  1048. padding = (FROM_MIME_BASE64_BYTES_IN - ndxTempIn);
  1049. }
  1050. break;
  1051. default:
  1052. {
  1053. tempBitsIn[ndxTempIn] = MapFromMIMEBase64(MIMEBase64char);
  1054. }
  1055. break;
  1056. }
  1057. ndxMIMEBase64++;
  1058. }
  1059. HX_ASSERT(padding == 2 || padding == 1 || padding == 0);
  1060. // Map the Base64 in buffer to the the output buffer...
  1061. // This should map the 6 pertinate bits of each IN byte, to the
  1062. // the correct bits of the OUT byte.
  1063. {
  1064. Bits[ndxBits] = (tempBitsIn[0] << 2) + (tempBitsIn[1]>>4);
  1065. ndxBits++;
  1066. if (padding < 2)
  1067. {
  1068. Bits[ndxBits] = (tempBitsIn[1] << 4) + (tempBitsIn[2]>>2);
  1069. ndxBits++;
  1070. }
  1071. if (padding < 1)
  1072. {
  1073. Bits[ndxBits] = (tempBitsIn[2] << 6) + (tempBitsIn[3]);
  1074. ndxBits++;
  1075. }
  1076. }
  1077. }
  1078. Bits[ndxBits] = '';
  1079. return ndxBits;
  1080. }
  1081. /////////////////////////////////////////////////////////////////////////////
  1082. //
  1083. // Function:
  1084. //
  1085. // DumpToMIMEBase64()
  1086. //
  1087. // Purpose:
  1088. //
  1089. // ...
  1090. //
  1091. // Parameters:
  1092. //
  1093. // ...
  1094. //
  1095. // Return:
  1096. //
  1097. // None.
  1098. //
  1099. void CHXInfoEncoder::DumpToMIMEBase64(char* MIMEBase64, const char* Bits, UINT32 nSize)
  1100. {
  1101. UINT32 ndxBits = 0;
  1102. UINT32 ndxMIMEBase64 = 0;
  1103. BOOL bDone = FALSE;
  1104. UINT32 ndxTempIn = 0;
  1105. UINT32 ndxTempOut = 0;
  1106. UCHAR tempBitsIn [TO_MIME_BASE64_BYTES_IN];
  1107. UINT32 padding = 0;
  1108. HX_ASSERT(strlen(Bits) <= nSize);
  1109. while (!bDone)
  1110. {
  1111. HX_ASSERT(ndxMIMEBase64 <= nSize);
  1112. HX_ASSERT(ndxBits <= nSize);
  1113. // Fill in our "temporary" out buffer with the 6 bit chunks of the input.
  1114. for ( ndxTempIn = 0;
  1115. ndxTempIn < TO_MIME_BASE64_BYTES_IN && (padding == 0);
  1116. ndxTempIn++
  1117. )
  1118. {
  1119. UCHAR rawChar = Bits[ndxBits];
  1120. if (rawChar != '')
  1121. {
  1122. switch (ndxTempIn)
  1123. {
  1124. case 0:
  1125. {
  1126. tempBitsIn[0] = rawChar >> 2;
  1127. tempBitsIn[1] = (rawChar & 0x3) << 4;
  1128. }
  1129. break;
  1130. case 1:
  1131. {
  1132. tempBitsIn[1] += rawChar >> 4;
  1133. tempBitsIn[2] = (rawChar & 0xF) << 2;
  1134. }
  1135. break;
  1136. case 2:
  1137. {
  1138. tempBitsIn[2] += rawChar >> 6;
  1139. tempBitsIn[3] = (rawChar & 0x3F);
  1140. }
  1141. break;
  1142. }
  1143. }
  1144. else
  1145. {
  1146. bDone = TRUE;
  1147. padding = (TO_MIME_BASE64_BYTES_IN - ndxTempIn);
  1148. }
  1149. ndxBits++;
  1150. }
  1151. HX_ASSERT(padding == 2 || padding == 1 || padding == 0);
  1152. // Map the Base64 in buffer to the output buffer...
  1153. // This should map the 6 pertinate bits of each IN byte, as an
  1154. // entire OUT byte
  1155. for ( ndxTempOut = 0;
  1156. ndxTempOut < TO_MIME_BASE64_BYTES_OUT;
  1157. ndxTempOut++
  1158. )
  1159. {
  1160. if (ndxTempOut < (TO_MIME_BASE64_BYTES_OUT-padding))
  1161. {
  1162. MIMEBase64[ndxMIMEBase64] = MapToMIMEBase64(tempBitsIn[ndxTempOut]);
  1163. }
  1164. else
  1165. {
  1166. MIMEBase64[ndxMIMEBase64] = MIME_BASE64_PADDING;
  1167. }
  1168. ndxMIMEBase64++;
  1169. }
  1170. }
  1171. MIMEBase64[ndxMIMEBase64] = '';
  1172. }
  1173. //*******************************************************************
  1174. //  CHXSimpleBuffer
  1175. //*******************************************************************
  1176. /////////////////////////////////////////////////////////////////////
  1177. CHXSimpleBuffer::CHXSimpleBuffer()
  1178. :  m_nSize(0), m_pData(NULL), m_nGrowBy(DEFAULT_GROW_SIZE)
  1179. {
  1180. }
  1181. /////////////////////////////////////////////////////////////////////
  1182. CHXSimpleBuffer::CHXSimpleBuffer(UINT32 nSize, UINT32 nGrowBy)
  1183. :  m_nSize(0), m_pData(NULL), m_nGrowBy(nGrowBy)
  1184. {
  1185. Resize(nSize);
  1186. }
  1187. /////////////////////////////////////////////////////////////////////
  1188. CHXSimpleBuffer::~CHXSimpleBuffer()
  1189. {
  1190. Free();
  1191. }
  1192. /////////////////////////////////////////////////////////////////////
  1193. BOOL CHXSimpleBuffer::IsValidOffset(UINT32 n) const
  1194. {
  1195. if (n<m_nSize)
  1196. return(TRUE);
  1197. else return(FALSE);
  1198. }
  1199. /////////////////////////////////////////////////////////////////////
  1200. // make sure that pPos is in the buffer.
  1201. // If not, the buffer is automatically resized and contents copied.
  1202. // pPos must be > pData.
  1203. BOOL CHXSimpleBuffer::EnsureValidOffset(UINT32 n)
  1204. {
  1205. if (IsValidOffset(n)==TRUE)
  1206.     {
  1207. return(TRUE);
  1208.     }
  1209. return (this->Resize(n));
  1210. }
  1211. /////////////////////////////////////////////////////////////////////
  1212. // copy data into the buffer at the given offset, and if the buffer
  1213. // is too small we'll resize the buffer first.
  1214. BOOL CHXSimpleBuffer::SafeMemCopy(UINT32 nOffset, const void* data, UINT32 len)
  1215. {
  1216.     if ((len > 0) && (EnsureValidOffset(nOffset+len-1)==TRUE))
  1217.     {
  1218.      memcpy( m_pData+nOffset, data, (int)len ); /* Flawfinder: ignore */
  1219. return(TRUE);
  1220.     }
  1221.     return(FALSE);
  1222. }
  1223. /////////////////////////////////////////////////////////////////////
  1224. BOOL CHXSimpleBuffer::Resize(UINT32 nNewSize)
  1225. {
  1226. if (nNewSize==0)
  1227.     {
  1228. Free();
  1229. return(TRUE);
  1230.     }
  1231. nNewSize = RoundUpToGrowSize(nNewSize);
  1232. UCHAR* pNewBuffer = new UCHAR[nNewSize];
  1233. if (pNewBuffer==NULL) return(FALSE);
  1234. if (m_pData!=NULL)
  1235.     {
  1236. // copy MIN(oldSize,newSize) elements
  1237. memcpy(pNewBuffer,m_pData, (nNewSize<m_nSize) ? (int)nNewSize : (int)m_nSize); /* Flawfinder: ignore */
  1238. delete [] m_pData;
  1239.     }
  1240. m_pData = pNewBuffer;
  1241. m_nSize = nNewSize;
  1242. return(TRUE);
  1243. }
  1244. /////////////////////////////////////////////////////////////////////
  1245. UINT32 CHXSimpleBuffer::RoundUpToGrowSize(UINT32 nSize)
  1246. {
  1247. // check for div-by-zero errors (as long as DEFAULT!=0)
  1248. if (m_nGrowBy==0)
  1249. {
  1250. m_nGrowBy = DEFAULT_GROW_SIZE;
  1251. }
  1252. return ( (int)(nSize/m_nGrowBy)+1 ) * m_nGrowBy;
  1253. }
  1254. /////////////////////////////////////////////////////////////////////
  1255. void CHXSimpleBuffer::Free()
  1256. {
  1257. if (m_pData!=NULL)
  1258. delete [] m_pData;
  1259. m_pData=NULL;
  1260. m_nSize=0;
  1261. }