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

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