hxpluginarchive.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:13k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: hxpluginarchive.cpp,v 1.4.2.1 2004/07/09 02:07:27 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxtypes.h"
- #include "hxcom.h"
- #include "hxccf.h" // IHXCommonClassFactory
- #include "ihxpckts.h" // IHXBuffer
- #include "hlxclib/fcntl.h"
- #include "chxdataf.h" // CHXDataFile
- #include "debug.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #include "hxpluginarchive.h"
- //
- // special chars; these need escaping if in value text
- //
- const char TERM_CHAR = ';'; // denotes end of value for most objects
- const char ESC_CHAR = '\'; // escape char
- HXPluginArchiveReader::HXPluginArchiveReader()
- : m_pFile(0)
- , m_idxFile(0)
- , m_pFactory(0)
- {
-
- }
- HXPluginArchiveReader::~HXPluginArchiveReader()
- {
- HX_DELETE(m_pFile);
- HX_RELEASE(m_pFactory);
- }
- //
- // Open
- //
- HX_RESULT HXPluginArchiveReader::Open(IUnknown* pContext, const char* pszFile)
- {
- DPRINTF(D_INFO, ("HXPluginArchiveReader::Open(): file = '%s'n", pszFile));
- HX_RESULT hr = HXR_FAIL;
-
- HX_DELETE(m_pFile);
- pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pFactory);
- m_pFile = CHXDataFile::Construct();
- if (m_pFile)
- {
- hr = m_pFile->Open(pszFile, O_RDONLY, TRUE /*text*/);
- if(SUCCEEDED(hr))
- {
- LoadFile();
- }
- }
- else
- {
- hr = HXR_OUTOFMEMORY;
- }
- return hr;
- }
- void HXPluginArchiveReader::Close()
- {
- HX_DELETE(m_pFile);
- }
- void HXPluginArchiveReader::LoadFile()
- {
- #define BUF_SZ 0x0400 // read file in 1k chunks
- CHXString strBuf;
- char* buf = strBuf.GetBuffer(BUF_SZ + 1);
- if( buf)
- {
- for(;;)
- {
- INT32 cch = (INT32)m_pFile->Read(buf, BUF_SZ);
- if (cch <= 0)
- {
- // end of file
- break;
- }
-
- buf[cch] = ' ';
- m_strFile += buf;
- }
- }
- m_strFile.TrimRight(); // ensure no trailing space so 'AtEnd()' is easier
- m_idxFile = 0;
-
- }
- void HXPluginArchiveReader::GetNextToken(CHXString& str, char chTerm)
- {
- UINT32 cchFile = m_strFile.GetLength();
- HX_ASSERT(chTerm != ESC_CHAR);
- while( m_idxFile < cchFile)
- {
- char ch = m_strFile[m_idxFile];
- if(chTerm == m_strFile[m_idxFile])
- {
- // found end of token; we're done
- ++m_idxFile;
- break;
- }
- if( ESC_CHAR == ch )
- {
- // skip escape to read in escaped char
- ++m_idxFile;
- if(m_idxFile == cchFile)
- {
- // unexpected: EOF in middle of escape sequence
- HX_ASSERT(false);
- break;
- }
- ch = m_strFile[m_idxFile];
- }
- str += ch;
- ++m_idxFile;
- }
- str.TrimLeft();
- str.TrimRight();
- }
- //
- // read name;val;name;val;;
- //
- //
- bool HXPluginArchiveReader::Read(IHXValues*& pval)
- {
- HX_ASSERT(!AtEnd());
- UINT32 cchFile = m_strFile.GetLength();
- HX_ASSERT(m_pFactory);
- m_pFactory->CreateInstance(CLSID_IHXValues,(void**)&pval);
- if(!pval)
- {
- return false;
- }
- CHXString strName;
- CHXString strVal;
- // collect name-value pairs until we reach closing double TERM_CHAR
- for(;;)
- {
- strName = "";
- GetNextToken(strName, TERM_CHAR);
- if(strName.IsEmpty())
- {
- // end of list (ends with empty token, i.e., double TERM_CHAR
- return true;
- }
- if(m_idxFile == cchFile)
- {
- // corrupt file; end of file after name
- HX_ASSERT(false);
- return false;
- }
-
- strVal = "";
- GetNextToken(strVal, TERM_CHAR);
- if(m_idxFile == cchFile)
- {
- // corrupt file
- HX_ASSERT(false);
- return false;
- }
- if(strVal.IsEmpty())
- {
- // corrupt file
- HX_ASSERT(false);
- return false;
- }
-
- char type = strVal[0];
- CHXString strNakedVal = strVal.Mid(1);
- switch(type)
- {
- case 'N':
- {
- int val = atoi(strNakedVal);
- pval->SetPropertyULONG32(strName, ULONG32(val));
- }
- break;
- case 'B':
- {
- IHXBuffer* pbuff = HXBufferUtil::CreateBuffer(m_pFactory, strNakedVal);
- if( pbuff)
- {
- pval->SetPropertyBuffer(strName, pbuff);
- HX_RELEASE(pbuff);
- }
- }
- break;
- case 'S':
- {
- IHXBuffer* pbuff = HXBufferUtil::CreateBuffer(m_pFactory, strNakedVal);
- if( pbuff)
- {
- pval->SetPropertyCString(strName, pbuff);
- HX_RELEASE(pbuff);
- }
- }
- break;
- default:
- HX_ASSERT(false);
- return false;
- }
- }
- HX_ASSERT(false);
- return false;
- }
- void HXPluginArchiveReader::Read(bool& b)
- {
- HX_ASSERT(!AtEnd());
- UINT32 val = 0;
- Read(val);
- b = (val ? true : false);
- }
- void HXPluginArchiveReader::Read(UINT16& val)
- {
- HX_ASSERT(!AtEnd());
- UINT32 v;
- Read(v);
- HX_ASSERT(v <= 0xffff);
- val = UINT16(v);
- }
- void HXPluginArchiveReader::Read(UINT32& val)
- {
- HX_ASSERT(!AtEnd());
- CHXString str;
- GetNextToken(str, TERM_CHAR);
- val = atoi(str);
- }
- void HXPluginArchiveReader::Read(CHXString& str)
- {
- HX_ASSERT(!AtEnd());
- GetNextToken(str, TERM_CHAR);
- }
- void HXPluginArchiveReader::Read(IHXBuffer*& pBuff)
- {
- HX_ASSERT(!AtEnd());
- CHXString str;
- GetNextToken(str, TERM_CHAR);
- pBuff = HXBufferUtil::CreateBuffer(m_pFactory, str);
- }
- //
- // HXPluginArchiveWriter
- //
- HXPluginArchiveWriter::HXPluginArchiveWriter()
- : m_pFile(0)
- , m_bAtLeastOneVal(false)
- {
-
- }
- HXPluginArchiveWriter::~HXPluginArchiveWriter()
- {
- HX_DELETE(m_pFile);
- }
- //
- // Open/create archive, wiping out existing if necessary
- //
- HX_RESULT HXPluginArchiveWriter::Open(IUnknown* pContext, const char* pszFile)
- {
- DPRINTF(D_INFO, ("HXPluginArchiveWriter::Open(): file = '%s'n", pszFile));
- HX_RESULT hr = HXR_FAIL;
- HX_DELETE(m_pFile);
- m_pFile = CHXDataFile::Construct();
- if (m_pFile)
- {
- hr = m_pFile->Open(pszFile, O_WRONLY | O_CREAT | O_TRUNC, TRUE /*text*/);
- }
- else
- {
- hr = HXR_OUTOFMEMORY;
- }
- return hr;
- }
- void HXPluginArchiveWriter::Close()
- {
- HX_DELETE(m_pFile);
- }
- void HXPluginArchiveWriter::EscapeValue(const CHXString& str, CHXString& strOut)
- {
- //
- // Escape special characters used for escaping and field termination
- //
- if( -1 == str.Find(ESC_CHAR) && -1 == str.Find(TERM_CHAR) )
- {
- // this may avoid copy if string class is optimized
- strOut = str;
- }
- else
- {
- INT32 cch = str.GetLength();
- for(INT32 idx = 0; idx < cch; ++idx)
- {
- char ch = str[idx];
- if(ch == ESC_CHAR || ch == TERM_CHAR)
- {
- strOut += ESC_CHAR;
- }
- strOut += ch;
- }
- }
- }
- // write line break (for sake of human consumption of file contents)
- void HXPluginArchiveWriter::Break()
- {
- const char* const BREAK_STRING = "n";
- const UINT32 CCH_BREAK_STRING = 1;
- m_pFile->Write(BREAK_STRING, CCH_BREAK_STRING);
- }
- void HXPluginArchiveWriter::Write(const char* psz)
- {
- CHXString strEscaped;
- EscapeValue(psz, strEscaped);
- HX_ASSERT(m_pFile);
- strEscaped += TERM_CHAR;
- m_pFile->Write(strEscaped, strEscaped.GetLength());
- }
- void HXPluginArchiveWriter::Write(IHXBuffer* pBuffer)
- {
- HX_ASSERT(pBuffer);
- const char* psz = (const char*)pBuffer->GetBuffer();
-
- Write(psz);
- }
- void HXPluginArchiveWriter::Write(bool b)
- {
- UINT32 val = (b ? 1 : 0);
- Write(val);
- }
- void HXPluginArchiveWriter::Write(UINT32 val)
- {
- CHXString str;
- str.Format("%lu", val);
- Write(str);
- }
- void HXPluginArchiveWriter::Write(UINT16 val)
- {
- Write(UINT32(val));
- }
- void HXPluginArchiveWriter::Write(IHXValues* pval)
- {
- HX_ASSERT(pval);
- CHXString str;
- ULONG32 ulValue;
- const char* pszKey = NULL;
- // Dump ULONG32 values
- HX_RESULT hr = pval->GetFirstPropertyULONG32( pszKey, ulValue );
- if( SUCCEEDED(hr) )
- {
- do
- {
- //key
- Write(pszKey);
- //value
- str.Format("N%d", ulValue);
- Write(str);
-
- hr = pval->GetNextPropertyULONG32( pszKey, ulValue);
- }
- while( SUCCEEDED(hr) );
- }
- // Dump IHXBuffer values
- IHXBuffer* pbuff;
- hr = pval->GetFirstPropertyBuffer( pszKey, pbuff );
- if( SUCCEEDED(hr) )
- {
- do
- {
- //key
- Write(pszKey);
- //value
- str.Format("B%.*s", pbuff->GetSize(), pbuff->GetBuffer() );
- Write(str);
-
- HX_RELEASE(pbuff);
- hr = pval->GetNextPropertyBuffer( pszKey,pbuff);
- }
- while( SUCCEEDED(hr) );
- }
- // Dump CString values
- hr = pval->GetFirstPropertyCString( pszKey, pbuff );
- if( SUCCEEDED(hr) )
- {
- do
- {
- //key
- Write(pszKey);
- //value
- str.Format("S%.*s", pbuff->GetSize(), pbuff->GetBuffer() );
- Write(str);
- HX_RELEASE(pbuff);
- hr = pval->GetNextPropertyCString( pszKey, pbuff);
- }
- while( SUCCEEDED(hr) );
- }
- // empty value terminates list
- Write("");
- }
- //XXXLCM util
- IHXBuffer* HXBufferUtil::CreateBuffer(IHXCommonClassFactory* pFact, const char* psz)
- {
- if(!psz)
- {
- psz = "";
- }
- IHXBuffer* pbuff = 0;
- HX_RESULT hr = pFact->CreateInstance(CLSID_IHXBuffer, (void**)&pbuff);
- if( SUCCEEDED(hr) )
- {
- hr = pbuff->Set( (BYTE*)psz, strlen(psz) + 1);
- if( FAILED(hr) )
- {
- HX_RELEASE(pbuff);
- }
- }
- return pbuff;
- }