bufdataf.cpp
Upload User: zhongxx05
Upload Date: 2007-06-06
Package Size: 33641k
Code Size: 12k
Category:

Symbian

Development Platform:

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