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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: bufdataf.cpp,v 1.9.32.3 2004/07/09 01:44:51 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 "hlxclib/stdio.h"
  51. #if defined(_UNIX)
  52. #include <unistd.h>
  53. #endif // _UNIX
  54. #include "hlxclib/windows.h"
  55. #include "hlxclib/sys/stat.h"
  56. #include "hlxclib/sys/types.h"
  57. #include "hlxclib/fcntl.h"
  58. #include "hlxclib/errno.h"
  59. #include "hlxosstr.h"
  60. #include "hxcom.h"
  61. #include "hxresult.h"
  62. #include "ihxpckts.h"
  63. #include "hxbuffer.h"
  64. #include "debug.h"
  65. #include "hxdataf.h"
  66. #include "bufdataf.h"
  67. /////////////////////////////////////////////////////////////////////////
  68. //  Method:
  69. //      BufferedDataFile::QueryInterface
  70. //  Purpose:
  71. //      Implement this to export the interfaces supported by your
  72. //      object.
  73. //
  74. STDMETHODIMP
  75. BufferedDataFile::QueryInterface(REFIID riid, void** ppvObj)
  76. {
  77.     if (IsEqualIID(riid, IID_IHXDataFile))
  78.     {
  79.         AddRef();
  80.         *ppvObj = (IHXDataFile*)this;
  81.         return HXR_OK;
  82.     }
  83.     
  84.     *ppvObj = NULL;
  85.     return HXR_NOINTERFACE;
  86. }   
  87. /////////////////////////////////////////////////////////////////////////
  88. //  Method:
  89. //      BufferedDataFile::AddRef
  90. //  Purpose:
  91. //      Everyone usually implements this the same... feel free to use
  92. //      this implementation.
  93. //
  94. STDMETHODIMP_(ULONG32)
  95. BufferedDataFile::AddRef()
  96. {
  97.     DPRINTF(0x5d000000, ("UBDF::AddRef() = %ldn", m_lRefCount+1));
  98.     return InterlockedIncrement(&m_lRefCount);
  99. }   
  100. /////////////////////////////////////////////////////////////////////////
  101. //  Method:
  102. //      BufferedDataFile::Release
  103. //  Purpose:
  104. //      Everyone usually implements this the same... feel free to use
  105. //      this implementation.
  106. //
  107. STDMETHODIMP_(ULONG32)
  108. BufferedDataFile::Release()
  109. {
  110.     DPRINTF(0x5d000000, ("UBDF::Release() = %ldn", m_lRefCount-1));
  111.     if (InterlockedDecrement(&m_lRefCount) > 0)
  112.     {
  113.         return m_lRefCount;
  114.     }
  115.     
  116.     delete this;
  117.     return 0;
  118. }   
  119. BufferedDataFile::BufferedDataFile()
  120.   : m_lRefCount(0)
  121.   , m_ulLastError(HXR_OK)
  122.   , m_pFilename(new CHXBuffer)
  123.   , m_pFile(0)
  124. {
  125.     m_pFilename->AddRef();
  126.     DPRINTF(0x5d000000, ("BufferedDataFile::BufferedDataFile()n"));
  127. }
  128. // ~CHXFile should close the file if it is open
  129. BufferedDataFile::~BufferedDataFile()
  130.     // close the file if it is open
  131.     if (m_pFile)
  132.     {
  133.        fclose(m_pFile);
  134.        m_pFile = 0;
  135.     }
  136.     HX_RELEASE(m_pFilename);
  137.     DPRINTF(0x5d000000, ("BufferedDataFile::~BufferedDataFile()n"));
  138. }
  139. /*
  140.  *  IHXDataFile methods
  141.  */
  142. /* Bind DataFile Object with FileName */
  143. STDMETHODIMP_(void)
  144. BufferedDataFile::Bind(const char* pFilename)
  145. {
  146.     m_pFilename->Set((BYTE *)pFilename, strlen(pFilename)+1);
  147.     DPRINTF(0x5d000000, ("BufferedDataFile::Bind(%s)n", 
  148.     (const char *)m_pFilename->GetBuffer()));
  149. }
  150. /* Creates a datafile using the specified mode
  151.  * uOpenMode --- File Open mode - HX_FILEFLAG_READ/HX_FILEFLAG_WRITE/HX_FILEFLAG_BINARY
  152.  */
  153. STDMETHODIMP
  154. BufferedDataFile::Open(UINT16 uOpenMode)
  155. {
  156.     return _Create(uOpenMode, FALSE);
  157. }
  158. STDMETHODIMP
  159. BufferedDataFile::Create(UINT16 uOpenMode)
  160. {
  161.     return _Create(uOpenMode, TRUE);
  162. }
  163. /* Open will open a file with the specified mode
  164.  */
  165. HX_RESULT
  166. BufferedDataFile::_Create(UINT16 uOpenMode, BOOL bCreateFile)
  167. {
  168.     HX_RESULT retVal = HXR_OK;
  169.     m_ulLastError = HXR_OK;
  170.     DPRINTF(0x5d000000, ("BufferedDataFile::Open()n"));
  171.     char modeflags[4]; /* Flawfinder: ignore */
  172.     // close previous file if necessary
  173.     if (m_pFile)
  174.     {
  175. fclose(m_pFile);
  176. m_pFile = NULL;
  177.     }
  178.     modeflags[0] = 'r';
  179.     modeflags[1] = 0;
  180.     modeflags[2] = 0;
  181.  
  182. #ifdef HELIX_CONFIG_ALLFILES_BINARY
  183.     uOpenMode |= HX_FILEFLAG_BINARY;
  184. #endif // HELIX_CONFIG_ALLFILES_BINARY
  185.     if (((uOpenMode & HX_FILEFLAG_NOTRUNC) == 0) && bCreateFile)
  186.     {
  187. // Overwrite any existing file if in the way
  188. modeflags[0] = 'w';
  189. if (uOpenMode & HX_FILEFLAG_READ)
  190. {
  191.     modeflags[1] = '+';
  192. }
  193.     }
  194.     else
  195.     {
  196. modeflags[0] = 'r';
  197. if (uOpenMode & HX_FILEFLAG_WRITE)
  198. {
  199.     modeflags[1] = '+';
  200. }
  201.     }
  202.     if (uOpenMode & HX_FILEFLAG_BINARY)
  203.     {
  204. strcat(modeflags, "b"); /* Flawfinder: ignore */
  205.     }
  206.     // open file
  207.     if ((m_pFilename == NULL) ||
  208. (m_pFilename->GetSize() == 0))
  209.     {
  210. retVal = HXR_FAIL;
  211.     }
  212.     if (retVal == HXR_OK)
  213.     {
  214. m_pFile = fopen((const char *) m_pFilename->GetBuffer(), modeflags);
  215. if (m_pFile)
  216. {
  217.     if (bCreateFile && (uOpenMode & HX_FILEFLAG_NOTRUNC))
  218.     {
  219. fclose(m_pFile);
  220. m_pFile = NULL;
  221. retVal = HXR_FAIL;
  222. m_ulLastError = (UINT32)HXR_FAIL;
  223.     }
  224. }
  225. else
  226. {
  227.     retVal = HXR_DOC_MISSING;
  228.     m_ulLastError = (UINT32)HXR_DOC_MISSING;
  229. }
  230.     }
  231.     if (retVal == HXR_DOC_MISSING)
  232.     {
  233. if (bCreateFile && (uOpenMode & HX_FILEFLAG_NOTRUNC))
  234. {
  235.     // This a recovery on NO_TRUNC file creation
  236.     // Open failed so attempt to create file
  237.     modeflags[0] = 'w';
  238.     modeflags[1] = 0;
  239.     if (uOpenMode && HX_FILEFLAG_READ)
  240.     {
  241. modeflags[1] = '+';
  242. modeflags[2] = 0;
  243.     }
  244.     if (uOpenMode & HX_FILEFLAG_BINARY)
  245.     {
  246. strcat(modeflags, "b"); /* Flawfinder: ignore */
  247.     }
  248.     m_pFile = fopen((const char *) m_pFilename->GetBuffer(), modeflags);
  249.     if (m_pFile)
  250.     {
  251. retVal = m_ulLastError = HXR_OK;
  252.     }
  253.     else
  254.     {
  255. retVal = HXR_FAIL;
  256. m_ulLastError = (UINT32)retVal;
  257.     }
  258. }
  259.     }    
  260.     DPRINTF(0x5d000000, ("BDF::Open() -- %sn", modeflags));
  261.     return retVal;
  262. }
  263. /* Close closes a file 
  264.  * If the reference count on the IHXDataFile object is greater than 1, 
  265.  * then the underlying file cannot be safely closed, so Close() becomes 
  266.  * a noop in that case. Close it only when the object is destroyed. 
  267.  * This would be safe, but could lead to a file descriptor leak.
  268.  */
  269. STDMETHODIMP
  270. BufferedDataFile::Close()
  271. {
  272.     if (m_pFile)
  273.     {
  274. fclose(m_pFile);
  275. m_pFile = 0;
  276.     }
  277.     return HXR_OK;
  278. }
  279. /* Name returns the currently bound file name in FileName.
  280.  * and returns TRUE, if the a name has been bound.  Otherwise
  281.  * FALSE is returned.
  282.  */
  283. STDMETHODIMP_(BOOL)
  284. BufferedDataFile::Name(REF(IHXBuffer*) pFileName)
  285. {
  286.     BOOL bRetVal = FALSE;
  287.     if (m_pFilename && (m_pFilename->GetSize() != 0))
  288.     {
  289. pFileName = m_pFilename;
  290. m_pFilename->AddRef();
  291. bRetVal = TRUE;
  292.     }
  293.     return bRetVal;
  294. }
  295. /*
  296.  * IsOpen returns TRUE if file is open.  Otherwise FALSE.
  297.  */
  298. inline BOOL
  299. BufferedDataFile::IsOpen()
  300. {
  301.     return (m_pFile ? TRUE : FALSE);
  302. }
  303. /* Seek moves the current file position to the offset from the
  304.  * fromWhere specifier returns current position of file or -1 on
  305.  * error.
  306.  */
  307. STDMETHODIMP
  308. BufferedDataFile::Seek(ULONG32 offset, UINT16 fromWhere)
  309. {
  310.     if (m_pFile)
  311.     {
  312. m_ulLastError = HXR_OK;       
  313. if (fseek(m_pFile, offset, fromWhere) < 0)
  314. {
  315.     m_ulLastError = errno;
  316.     return HXR_INVALID_FILE;
  317. }
  318. return HXR_OK;
  319.     }
  320.     return HXR_INVALID_FILE;
  321. }
  322. /* Tell returns the current file position in the file */
  323. STDMETHODIMP_(ULONG32)
  324. BufferedDataFile::Tell()
  325. {
  326.     INT32 offset = -1;
  327.     m_ulLastError = (UINT32)HXR_FAIL;
  328.     if (m_pFile)
  329.     {
  330. // so we do this instead....
  331. if ((offset = ftell(m_pFile)) != -1)
  332. {
  333.     m_ulLastError = HXR_OK;       
  334. }
  335.     }
  336.     return (ULONG32) offset;
  337. }
  338. /* Read reads up to count bytes of data into buf.
  339.  * returns the number of bytes read, EOF, or -1 if the read failed 
  340.  */
  341. STDMETHODIMP_(ULONG32)
  342. BufferedDataFile::Read(REF(IHXBuffer*) pOutBuf, ULONG32 count)
  343. {
  344.     int ncnt = 0;           // number of bytes read
  345.     IHXBuffer* pBuf = NULL;
  346.     if (m_pFile)
  347.     {
  348. if (pOutBuf)
  349. {
  350.     pBuf = pOutBuf;
  351. }
  352. else
  353. {
  354.     m_ulLastError = (UINT32)HXR_OUTOFMEMORY;
  355.     pBuf = new CHXBuffer();
  356. }
  357. if (pBuf)
  358. {
  359.     pBuf->AddRef();
  360.     m_ulLastError = pBuf->SetSize(count);
  361. }
  362. if (m_ulLastError == HXR_OK)
  363. {
  364.     Tell();
  365. }
  366. if (m_ulLastError == HXR_OK)
  367. {
  368.     if ((ncnt = fread((void *)pBuf->GetBuffer(), sizeof(char), 
  369.       count, m_pFile)) < (int)count)
  370.     {
  371. m_ulLastError = ferror(m_pFile) ? HXR_FAIL : HXR_OK;
  372.     }
  373.     if (ncnt < (int)count)
  374.     {
  375. pBuf->SetSize(ncnt);
  376.     }
  377.     if (pBuf != pOutBuf)
  378.     {
  379. pOutBuf = pBuf;
  380. pBuf->AddRef();
  381.     }
  382. }
  383. if (pBuf)
  384. {
  385.     pBuf->Release();
  386. }
  387.     }
  388.     return (ULONG32)ncnt;
  389. }
  390. /* Write writes up to count bytes of data from buf.
  391.  * returns the number of bytes written, or -1 if the write failed 
  392.  */
  393. STDMETHODIMP_(ULONG32)
  394. BufferedDataFile::Write(REF(IHXBuffer *) pBuf)
  395. {
  396.     int ncnt = -1;           // number of bytes written
  397.     if (m_pFile)
  398.     {
  399. m_ulLastError = HXR_OK;
  400. if ((ncnt = fwrite(pBuf->GetBuffer(), sizeof(char), 
  401.     pBuf->GetSize(), m_pFile)) < (int)(pBuf->GetSize()))
  402. {
  403.     m_ulLastError = (UINT32)HXR_FAIL;
  404. }
  405.     }
  406.     return (ULONG32)ncnt;
  407. }
  408. /* Flush out the data in case of Buffered I/O
  409.  */
  410. STDMETHODIMP
  411. BufferedDataFile::Flush()
  412. {
  413.     if (m_pFile)
  414.     {
  415. m_ulLastError = HXR_OK;       
  416. if (fflush(m_pFile) == 0)
  417. {
  418.     return HXR_OK;
  419. }
  420. m_ulLastError = (UINT32)HXR_FAIL;
  421. return HXR_FAIL;
  422.     }
  423.     return HXR_INVALID_FILE;
  424. }
  425. /*
  426.  * Return info about the data file such as permissions, time of creation
  427.  * size in bytes, etc.
  428.  */
  429. STDMETHODIMP
  430. BufferedDataFile::Stat(struct stat* statbuf)
  431. {
  432. #ifndef WIN32_PLATFORM_PSPC
  433.     if (m_pFile)
  434.     {
  435. if (!fstat(fileno(m_pFile), statbuf))
  436.     return HXR_OK;
  437.     } else
  438. #endif
  439.     if (m_pFilename->GetSize())
  440.     {
  441. if (!stat((const char *)m_pFilename->GetBuffer(), statbuf))
  442.     return HXR_OK;
  443.     }
  444.     return HXR_FAIL;
  445. }
  446. /* Return the file descriptor */
  447. inline INT16
  448. BufferedDataFile::GetFd()
  449. {
  450.     return m_pFile ? (INT16) fileno(m_pFile) : -1;
  451. }
  452. /* GetLastError returns the platform specific file error */
  453. STDMETHODIMP
  454. BufferedDataFile::GetLastError()
  455. {
  456.     return m_ulLastError;
  457. }
  458. /* GetLastError returns the platform specific file error in
  459.  * string form.
  460.  */
  461. STDMETHODIMP_(void)
  462. BufferedDataFile::GetLastError(REF(IHXBuffer*) err)
  463. {
  464. }
  465. STDMETHODIMP
  466. BufferedDataFile::Delete()
  467. {
  468.     Close();
  469.     if ((!m_pFilename) || (m_pFilename->GetSize() == 0))
  470.     {
  471. return HXR_UNEXPECTED;
  472.     }
  473. #if defined(_WINDOWS)
  474.     if (DeleteFile(OS_STRING(m_pFilename->GetBuffer())))
  475.     {
  476. return HXR_OK;
  477.     }
  478. #elif defined(_UNIX)
  479.     if (unlink(OS_STRING(m_pFilename->GetBuffer())) == 0)
  480.     {
  481. return HXR_OK;
  482.     }
  483. #endif // _UNIX
  484.     return HXR_FAIL;
  485. }