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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxpluginarchive.cpp,v 1.4.2.1 2004/07/09 02:07:27 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. #include "hxtypes.h"
  50. #include "hxcom.h"
  51. #include "hxccf.h" // IHXCommonClassFactory
  52. #include "ihxpckts.h" // IHXBuffer
  53. #include "hlxclib/fcntl.h"
  54. #include "chxdataf.h" // CHXDataFile
  55. #include "debug.h"
  56. #include "hxheap.h"
  57. #ifdef _DEBUG
  58. #undef HX_THIS_FILE
  59. static const char HX_THIS_FILE[] = __FILE__;
  60. #endif
  61. #include "hxpluginarchive.h"
  62. //
  63. // special chars; these need escaping if in value text
  64. //
  65. const char TERM_CHAR = ';';     // denotes end of value for most objects
  66. const char ESC_CHAR = '\';     // escape char
  67. HXPluginArchiveReader::HXPluginArchiveReader()
  68. : m_pFile(0)
  69. , m_idxFile(0)
  70. , m_pFactory(0)
  71. {
  72.   
  73. }
  74. HXPluginArchiveReader::~HXPluginArchiveReader()
  75. {
  76.     HX_DELETE(m_pFile);
  77.     HX_RELEASE(m_pFactory);
  78. }
  79. //
  80. // Open
  81. //
  82. HX_RESULT HXPluginArchiveReader::Open(IUnknown* pContext, const char* pszFile)
  83. {
  84.     DPRINTF(D_INFO, ("HXPluginArchiveReader::Open(): file = '%s'n", pszFile));
  85.     HX_RESULT hr = HXR_FAIL;
  86.     
  87.     HX_DELETE(m_pFile);
  88.     pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pFactory);
  89.     m_pFile = CHXDataFile::Construct();
  90.     if (m_pFile)
  91.     {
  92. hr = m_pFile->Open(pszFile, O_RDONLY, TRUE /*text*/);
  93.         if(SUCCEEDED(hr))
  94.         {
  95.             LoadFile();
  96.         }
  97.     }
  98.     else
  99.     {
  100.         hr = HXR_OUTOFMEMORY;
  101.     }
  102.     return hr;
  103. }
  104. void HXPluginArchiveReader::Close()
  105. {
  106.     HX_DELETE(m_pFile);
  107. }
  108. void HXPluginArchiveReader::LoadFile()
  109. {
  110.     #define BUF_SZ 0x0400 // read file in 1k chunks
  111.     CHXString strBuf;
  112.     char* buf = strBuf.GetBuffer(BUF_SZ + 1);
  113.     if( buf)
  114.     {
  115.         for(;;)
  116.         {
  117.             INT32 cch = (INT32)m_pFile->Read(buf, BUF_SZ);
  118.     if (cch <= 0)
  119.             {
  120.                 // end of file
  121.         break;
  122.             }
  123.         
  124.             buf[cch] = '';
  125.             m_strFile += buf;
  126.         }
  127.     }
  128.     m_strFile.TrimRight(); // ensure no trailing space so 'AtEnd()' is easier
  129.     m_idxFile = 0;
  130.    
  131. }
  132. void HXPluginArchiveReader::GetNextToken(CHXString& str, char chTerm)
  133. {
  134.     UINT32 cchFile = m_strFile.GetLength();
  135.     HX_ASSERT(chTerm != ESC_CHAR);
  136.     while( m_idxFile < cchFile)
  137.     {
  138.         char ch = m_strFile[m_idxFile];
  139.         if(chTerm == m_strFile[m_idxFile])
  140.         {
  141.             // found end of token; we're done
  142.             ++m_idxFile;
  143.             break;
  144.         }
  145.         if( ESC_CHAR == ch )
  146.         {
  147.             // skip escape to read in escaped char
  148.             ++m_idxFile;
  149.             if(m_idxFile == cchFile)
  150.             {
  151.                 // unexpected: EOF in middle of escape sequence
  152.                 HX_ASSERT(false);
  153.                 break;
  154.             }
  155.             ch = m_strFile[m_idxFile];
  156.         }
  157.         str += ch;
  158.         ++m_idxFile;
  159.     }
  160.     str.TrimLeft();
  161.     str.TrimRight();
  162. }
  163. //
  164. // read name;val;name;val;;
  165. //
  166. //
  167. bool HXPluginArchiveReader::Read(IHXValues*& pval)
  168. {
  169.     HX_ASSERT(!AtEnd());
  170.     UINT32 cchFile = m_strFile.GetLength();
  171.     HX_ASSERT(m_pFactory);
  172.     m_pFactory->CreateInstance(CLSID_IHXValues,(void**)&pval);
  173.     if(!pval)
  174.     {
  175.         return false;
  176.     }
  177.     CHXString strName;
  178.     CHXString strVal;
  179.     // collect name-value pairs until we reach closing double TERM_CHAR
  180.     for(;;)
  181.     {
  182.         strName = "";
  183.         GetNextToken(strName, TERM_CHAR);
  184.         if(strName.IsEmpty())
  185.         {
  186.             // end of list (ends with empty token, i.e., double TERM_CHAR
  187.             return true;
  188.         }
  189.         if(m_idxFile == cchFile)
  190.         {
  191.             // corrupt file; end of file after name
  192.             HX_ASSERT(false); 
  193.             return false;
  194.         }
  195.         
  196.         strVal = "";
  197.         GetNextToken(strVal, TERM_CHAR);
  198.         if(m_idxFile == cchFile)
  199.         {
  200.             // corrupt file
  201.             HX_ASSERT(false); 
  202.             return false;
  203.         }
  204.         if(strVal.IsEmpty())
  205.         {
  206.             // corrupt file
  207.             HX_ASSERT(false);
  208.             return false;
  209.         }
  210.  
  211.         char type = strVal[0];
  212.         CHXString strNakedVal = strVal.Mid(1);
  213.         switch(type)
  214.         {
  215.             case 'N':
  216.                 {
  217.                     int val = atoi(strNakedVal);
  218.                     pval->SetPropertyULONG32(strName, ULONG32(val));
  219.                 }
  220.                 break;
  221.             case 'B':
  222.                 {
  223.                     IHXBuffer* pbuff = HXBufferUtil::CreateBuffer(m_pFactory, strNakedVal);
  224.                     if( pbuff)
  225.                     {
  226.                         pval->SetPropertyBuffer(strName, pbuff);
  227.                         HX_RELEASE(pbuff);
  228.                     }
  229.                 }
  230.                 break;
  231.             case 'S':
  232.                 {
  233.                     IHXBuffer* pbuff = HXBufferUtil::CreateBuffer(m_pFactory, strNakedVal);
  234.                     if( pbuff)
  235.                     {
  236.                         pval->SetPropertyCString(strName, pbuff);
  237.                         HX_RELEASE(pbuff);
  238.                     }
  239.                 }
  240.                 break;
  241.             default:
  242.                 HX_ASSERT(false);
  243.                 return false;
  244.         }
  245.     }
  246.     HX_ASSERT(false);
  247.     return false;
  248. }
  249. void HXPluginArchiveReader::Read(bool& b)
  250. {
  251.     HX_ASSERT(!AtEnd());
  252.     UINT32 val = 0;
  253.     Read(val);
  254.     b = (val ? true : false);
  255. }
  256. void HXPluginArchiveReader::Read(UINT16& val)
  257. {
  258.     HX_ASSERT(!AtEnd());
  259.     UINT32 v;
  260.     Read(v);
  261.     HX_ASSERT(v <= 0xffff);
  262.     val = UINT16(v);
  263. }
  264. void HXPluginArchiveReader::Read(UINT32& val)
  265. {
  266.     HX_ASSERT(!AtEnd());
  267.     CHXString str;
  268.     GetNextToken(str, TERM_CHAR);
  269.     val = atoi(str);
  270. }
  271. void HXPluginArchiveReader::Read(CHXString& str)
  272. {
  273.     HX_ASSERT(!AtEnd());
  274.     GetNextToken(str, TERM_CHAR);
  275. }
  276. void HXPluginArchiveReader::Read(IHXBuffer*& pBuff)
  277. {
  278.     HX_ASSERT(!AtEnd());
  279.     CHXString str;
  280.     GetNextToken(str, TERM_CHAR);
  281.     pBuff = HXBufferUtil::CreateBuffer(m_pFactory, str);
  282. }
  283. //
  284. // HXPluginArchiveWriter
  285. //
  286. HXPluginArchiveWriter::HXPluginArchiveWriter()
  287. : m_pFile(0)
  288. , m_bAtLeastOneVal(false)
  289. {
  290.   
  291. }
  292. HXPluginArchiveWriter::~HXPluginArchiveWriter()
  293. {
  294.     HX_DELETE(m_pFile);
  295. }
  296. //
  297. // Open/create archive, wiping out existing if necessary
  298. //
  299. HX_RESULT HXPluginArchiveWriter::Open(IUnknown* pContext, const char* pszFile)
  300. {
  301.     DPRINTF(D_INFO, ("HXPluginArchiveWriter::Open(): file = '%s'n", pszFile));
  302.     HX_RESULT hr = HXR_FAIL;
  303.     HX_DELETE(m_pFile);
  304.     m_pFile = CHXDataFile::Construct();
  305.     if (m_pFile)
  306.     {
  307.         hr = m_pFile->Open(pszFile, O_WRONLY | O_CREAT | O_TRUNC, TRUE /*text*/);
  308.     }
  309.     else
  310.     {
  311.         hr = HXR_OUTOFMEMORY;
  312.     }
  313.     return hr;
  314. }
  315. void HXPluginArchiveWriter::Close()
  316. {
  317.     HX_DELETE(m_pFile);
  318. }
  319. void HXPluginArchiveWriter::EscapeValue(const CHXString& str, CHXString& strOut)
  320. {
  321.     //
  322.     // Escape special characters used for escaping and field termination
  323.     //
  324.     if( -1 == str.Find(ESC_CHAR) && -1 == str.Find(TERM_CHAR) )
  325.     {
  326.         // this may avoid copy if string class is optimized
  327.         strOut = str;
  328.     }
  329.     else
  330.     {
  331.         INT32 cch = str.GetLength();
  332.         for(INT32 idx = 0; idx < cch; ++idx)
  333.         {
  334.             char ch = str[idx];
  335.             if(ch == ESC_CHAR || ch == TERM_CHAR)
  336.             {
  337.                 strOut += ESC_CHAR;
  338.             }
  339.             strOut += ch;
  340.         }
  341.     }
  342. }
  343. // write line break (for sake of human consumption of file contents)
  344. void HXPluginArchiveWriter::Break()
  345. {
  346.     const char* const BREAK_STRING = "n";
  347.     const UINT32 CCH_BREAK_STRING = 1;
  348.     m_pFile->Write(BREAK_STRING, CCH_BREAK_STRING);
  349. }
  350. void HXPluginArchiveWriter::Write(const char* psz)
  351. {
  352.     CHXString strEscaped;
  353.     EscapeValue(psz, strEscaped);
  354.     HX_ASSERT(m_pFile);
  355.     strEscaped += TERM_CHAR;
  356.     m_pFile->Write(strEscaped, strEscaped.GetLength());  
  357. }
  358. void HXPluginArchiveWriter::Write(IHXBuffer* pBuffer)
  359. {
  360.     HX_ASSERT(pBuffer);
  361.     const char* psz = (const char*)pBuffer->GetBuffer();
  362.   
  363.     Write(psz);
  364. }
  365. void HXPluginArchiveWriter::Write(bool b)
  366. {
  367.     UINT32 val = (b ? 1 : 0);
  368.     Write(val);
  369. }
  370. void HXPluginArchiveWriter::Write(UINT32 val)
  371. {
  372.     CHXString str;
  373.     str.Format("%lu", val);
  374.     Write(str);
  375. }
  376. void HXPluginArchiveWriter::Write(UINT16 val)
  377. {
  378.     Write(UINT32(val));
  379. }
  380. void HXPluginArchiveWriter::Write(IHXValues* pval)
  381. {
  382.     HX_ASSERT(pval);
  383.     CHXString str;
  384.     ULONG32 ulValue;
  385.     const char* pszKey = NULL;
  386.     // Dump ULONG32 values
  387.     HX_RESULT hr = pval->GetFirstPropertyULONG32( pszKey, ulValue );
  388.     if( SUCCEEDED(hr) )
  389.     {
  390. do
  391. {
  392.             //key
  393.             Write(pszKey);
  394.             //value
  395.     str.Format("N%d",  ulValue);
  396.             Write(str);
  397.    
  398.     hr = pval->GetNextPropertyULONG32( pszKey, ulValue);
  399. }
  400. while( SUCCEEDED(hr) );
  401.     }
  402.     // Dump IHXBuffer values
  403.     IHXBuffer* pbuff;
  404.     hr = pval->GetFirstPropertyBuffer( pszKey, pbuff );
  405.     if( SUCCEEDED(hr) )
  406.     {
  407. do
  408. {
  409.             //key
  410.             Write(pszKey);
  411.             //value
  412.     str.Format("B%.*s",  pbuff->GetSize(), pbuff->GetBuffer() );
  413.             Write(str);
  414.            
  415.     HX_RELEASE(pbuff);
  416.     hr = pval->GetNextPropertyBuffer( pszKey,pbuff);
  417. }
  418. while( SUCCEEDED(hr) );
  419.     }
  420.     // Dump CString values
  421.     hr = pval->GetFirstPropertyCString( pszKey, pbuff );
  422.     if( SUCCEEDED(hr) )
  423.     {
  424. do
  425. {
  426.             //key
  427.             Write(pszKey);
  428.             //value
  429.     str.Format("S%.*s",  pbuff->GetSize(), pbuff->GetBuffer() );
  430.             Write(str);
  431.     HX_RELEASE(pbuff);
  432.     hr = pval->GetNextPropertyCString( pszKey, pbuff);
  433. }
  434. while( SUCCEEDED(hr) );
  435.     }
  436.     // empty value terminates list
  437.     Write("");
  438. }
  439. //XXXLCM util
  440. IHXBuffer* HXBufferUtil::CreateBuffer(IHXCommonClassFactory* pFact, const char* psz)
  441. {
  442.     if(!psz)
  443.     {
  444.         psz = "";
  445.     }
  446.     IHXBuffer* pbuff = 0;
  447.     HX_RESULT hr = pFact->CreateInstance(CLSID_IHXBuffer, (void**)&pbuff);
  448.     if( SUCCEEDED(hr) )
  449.     {
  450.         hr = pbuff->Set( (BYTE*)psz, strlen(psz) + 1);
  451.         if( FAILED(hr) )
  452.         {
  453.             HX_RELEASE(pbuff);
  454.         }
  455.     }
  456.     return pbuff;
  457. }