hxinfcod.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:37k
源码类别:

Symbian

开发平台:

Visual C++

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