bufdataf.cpp
Upload User: zhongxx05
Upload Date: 2007-06-06
Package Size: 33641k
Code Size: 10k
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 <stdio.h>
  36. #include <stat.h>
  37. #include <types.h>
  38. #include <fcntl.h>
  39. #include <errno.h>
  40. #include <unix.mac.h>  // Anyone using this file MUST #undef _UNIX
  41. #undef _UNIX
  42. #include "hxtypes.h"
  43. #include "hxcom.h"
  44. #include "hxresult.h"
  45. #include "ihxpckts.h"
  46. #include "hxbuffer.h"
  47. #include "debug.h"
  48. #include "hxdataf.h"
  49. #include "datffact.h"
  50. #include "bufdataf.h"
  51. /////////////////////////////////////////////////////////////////////////
  52. //  Method:
  53. //      BufferedDataFile::QueryInterface
  54. //  Purpose:
  55. //      Implement this to export the interfaces supported by your
  56. //      object.
  57. //
  58. STDMETHODIMP
  59. BufferedDataFile::QueryInterface(REFIID riid, void** ppvObj)
  60. {
  61.     if (IsEqualIID(riid, IID_IHXDataFile))
  62.     {
  63.         AddRef();
  64.         *ppvObj = (IHXDataFile*)this;
  65.         return HXR_OK;
  66.     }
  67.     
  68.     *ppvObj = NULL;
  69.     return HXR_NOINTERFACE;
  70. }   
  71. /////////////////////////////////////////////////////////////////////////
  72. //  Method:
  73. //      BufferedDataFile::AddRef
  74. //  Purpose:
  75. //      Everyone usually implements this the same... feel free to use
  76. //      this implementation.
  77. //
  78. STDMETHODIMP_(ULONG32)
  79. BufferedDataFile::AddRef()
  80. {
  81.     DPRINTF(0x5d000000, ("UBDF::AddRef() = %ldn", m_lRefCount+1));
  82.     return InterlockedIncrement(&m_lRefCount);
  83. }   
  84. /////////////////////////////////////////////////////////////////////////
  85. //  Method:
  86. //      BufferedDataFile::Release
  87. //  Purpose:
  88. //      Everyone usually implements this the same... feel free to use
  89. //      this implementation.
  90. //
  91. STDMETHODIMP_(ULONG32)
  92. BufferedDataFile::Release()
  93. {
  94.     DPRINTF(0x5d000000, ("UBDF::Release() = %ldn", m_lRefCount-1));
  95.     if (InterlockedDecrement(&m_lRefCount) > 0)
  96.     {
  97.         return m_lRefCount;
  98.     }
  99.     
  100.     delete this;
  101.     return 0;
  102. }   
  103. BufferedDataFile::BufferedDataFile()
  104.   : m_lRefCount(0)
  105.   , m_ulLastError(HXR_OK)
  106.   , m_pFilename(new CHXBuffer)
  107.   , m_pFile(0)
  108. {
  109.     m_pFilename->AddRef();
  110.     DPRINTF(0x5d000000, ("BufferedDataFile::BufferedDataFile()n"));
  111. }
  112. // ~CHXFile should close the file if it is open
  113. BufferedDataFile::~BufferedDataFile()
  114.     // close the file if it is open
  115.     if (m_pFile)
  116.     {
  117.        fclose(m_pFile);
  118.        m_pFile = 0;
  119.     }
  120.     HX_RELEASE(m_pFilename);
  121.     DPRINTF(0x5d000000, ("BufferedDataFile::~BufferedDataFile()n"));
  122. }
  123. /*
  124.  *  IHXDataFile methods
  125.  */
  126. /* Bind DataFile Object with FileName */
  127. STDMETHODIMP_(void)
  128. BufferedDataFile::Bind(const char* pFilename)
  129. {
  130.     m_pFilename->Set((BYTE *)pFilename, strlen(pFilename)+1);
  131.     DPRINTF(0x5d000000, ("BufferedDataFile::Bind(%s)n", 
  132.     (const char *)m_pFilename->GetBuffer()));
  133. }
  134. /* Creates a datafile using the specified mode
  135.  * uOpenMode --- File Open mode - HX_FILEFLAG_READ/HX_FILEFLAG_WRITE/HX_FILEFLAG_BINARY
  136.  */
  137. STDMETHODIMP
  138. BufferedDataFile::Create(UINT16 uOpenMode)
  139. {
  140.     return HXR_NOTIMPL;
  141. }
  142. /* Open will open a file with the specified mode
  143.  */
  144. STDMETHODIMP
  145. BufferedDataFile::Open(UINT16 uOpenMode)
  146. {
  147.     DPRINTF(0x5d000000, ("BufferedDataFile::Open()n"));
  148.     char modeflags[4]; /* Flawfinder: ignore */
  149.  
  150.     if(uOpenMode & HX_FILEFLAG_READ)
  151.     {
  152.         modeflags[0] = 'r';
  153.         modeflags[1] = 0;
  154.         if(uOpenMode & HX_FILEFLAG_WRITE)
  155.         {
  156.             modeflags[1] = '+';
  157.             modeflags[2] = 0;
  158.         }
  159.         if(uOpenMode & HX_FILEFLAG_BINARY)
  160.             strcat(modeflags, "b"); /* Flawfinder: ignore */
  161.     }
  162.     else if(uOpenMode & HX_FILEFLAG_WRITE)
  163.     {
  164.         modeflags[0] = 'w';
  165.         modeflags[1] = 0;
  166.         if(uOpenMode & HX_FILEFLAG_BINARY)
  167.             strcat(modeflags, "b"); /* Flawfinder: ignore */
  168.     }
  169.     else if(!uOpenMode)
  170.     {
  171.         uOpenMode = HX_FILEFLAG_READ | HX_FILEFLAG_BINARY;
  172.         modeflags[0] = 'r';
  173.         modeflags[1] = 'b';
  174.         modeflags[2] = 0;
  175.     }
  176.     else
  177.     {
  178.         return HXR_INVALID_PARAMETER;
  179.     }
  180.     // close previous file if necessary
  181.     if (m_pFile)
  182. fclose(m_pFile);
  183.     DPRINTF(0x5d000000, ("BDF::Open() -- %sn", modeflags));
  184.     // open file
  185.     m_ulLastError = HXR_OK;
  186.     if ((m_pFile = fopen((const char *)m_pFilename->GetBuffer(), modeflags)) == NULL)
  187.     {
  188. m_ulLastError = errno;
  189. return HXR_DOC_MISSING;
  190.     }
  191.     return HXR_OK;
  192. }
  193. /* Close closes a file 
  194.  * If the reference count on the IHXDataFile object is greater than 1, 
  195.  * then the underlying file cannot be safely closed, so Close() becomes 
  196.  * a noop in that case. Close it only when the object is destroyed. 
  197.  * This would be safe, but could lead to a file descriptor leak.
  198.  */
  199. STDMETHODIMP
  200. BufferedDataFile::Close()
  201. {
  202.     if (m_pFile)
  203.     {
  204. fclose(m_pFile);
  205. m_pFile = 0;
  206.     }
  207.     return HXR_OK;
  208. }
  209. /* Name returns the currently bound file name in FileName.
  210.  * and returns TRUE, if the a name has been bound.  Otherwise
  211.  * FALSE is returned.
  212.  */
  213. STDMETHODIMP_(BOOL)
  214. BufferedDataFile::Name(REF(IHXBuffer*) pFileName)
  215. {
  216.     return HXR_NOTIMPL;
  217. }
  218. /*
  219.  * IsOpen returns TRUE if file is open.  Otherwise FALSE.
  220.  */
  221. inline BOOL
  222. BufferedDataFile::IsOpen()
  223. {
  224.     return (m_pFile ? TRUE : FALSE);
  225. }
  226. /* Seek moves the current file position to the offset from the
  227.  * fromWhere specifier returns current position of file or -1 on
  228.  * error.
  229.  */
  230. STDMETHODIMP
  231. BufferedDataFile::Seek(ULONG32 offset, UINT16 fromWhere)
  232. {
  233.     if (m_pFile)
  234.     {
  235. m_ulLastError = HXR_OK;       
  236. if (fseek(m_pFile, offset, fromWhere) < 0)
  237. {
  238.     m_ulLastError = errno;
  239.     return HXR_INVALID_FILE;
  240. }
  241. return HXR_OK;
  242.     }
  243.     return HXR_INVALID_FILE;
  244. }
  245. /* Tell returns the current file position in the file */
  246. STDMETHODIMP_(ULONG32)
  247. BufferedDataFile::Tell()
  248. {
  249.     INT32 offset = -1;
  250.     if (m_pFile)
  251.     {
  252. m_ulLastError = HXR_OK;       
  253. // so we do this instead....
  254. if ((offset = fseek(m_pFile, 0, SEEK_CUR)) < 0)
  255. {
  256.     m_ulLastError = errno;
  257. }
  258.     }
  259.     return (ULONG32)offset;
  260. }
  261. /* Read reads up to count bytes of data into buf.
  262.  * returns the number of bytes read, EOF, or -1 if the read failed 
  263.  */
  264. STDMETHODIMP_(ULONG32)
  265. BufferedDataFile::Read(REF(IHXBuffer *) pBuf, ULONG32 count)
  266. {
  267.     HX_ASSERT(pBuf);
  268.     pBuf->AddRef();
  269.     int ncnt = 0;           // number of bytes read
  270.     if (m_pFile)
  271.     { 
  272. m_ulLastError = HXR_OK;
  273. ULONG32 tmpCheck = Tell();
  274. if ((ncnt = fread((void *)pBuf->GetBuffer(), sizeof(char), 
  275.     count, m_pFile)) < count)
  276. {
  277.     m_ulLastError = errno;
  278. }
  279.     }
  280.     pBuf->Release();
  281.     return (ULONG32)ncnt;
  282. }
  283. /* Write writes up to count bytes of data from buf.
  284.  * returns the number of bytes written, or -1 if the write failed 
  285.  */
  286. STDMETHODIMP_(ULONG32)
  287. BufferedDataFile::Write(REF(IHXBuffer *) pBuf)
  288. {
  289.     HX_ASSERT(pBuf);
  290.     pBuf->AddRef();
  291.     int ncnt = -1;           // number of bytes written
  292.     int count = pBuf->GetSize();
  293.     if (m_pFile)
  294.     {
  295. m_ulLastError = HXR_OK;
  296. if ((ncnt = fwrite((const char *)pBuf->GetBuffer(), sizeof(char),
  297.     count, m_pFile)) < count)
  298. {
  299.     m_ulLastError = errno;
  300. }
  301.     }
  302.     pBuf->Release();
  303.     return (ULONG32)ncnt;
  304. }
  305. /* Flush out the data in case of Buffered I/O
  306.  */
  307. STDMETHODIMP
  308. BufferedDataFile::Flush()
  309. {
  310.     if (m_pFile)
  311.     {
  312. m_ulLastError = HXR_OK;       
  313. if (!fflush(m_pFile))
  314. {
  315.     m_ulLastError = errno;
  316.     return HXR_INVALID_FILE;
  317. }
  318. return HXR_OK;
  319.     }
  320.     return HXR_INVALID_FILE;
  321. }
  322. /*
  323.  * Return info about the data file such as permissions, time of creation
  324.  * size in bytes, etc.
  325.  */
  326. STDMETHODIMP
  327. BufferedDataFile::Stat(struct stat* statbuf)
  328. {
  329.     if (m_pFile)
  330.     {
  331. if (!fstat(fileno(m_pFile), statbuf))
  332.     return HXR_OK;
  333.     }
  334.     else if (m_pFilename->GetSize())
  335.     {
  336. if (!stat((const char *)m_pFilename->GetBuffer(), statbuf))
  337.     return HXR_OK;
  338.     }
  339.     return HXR_FAIL;
  340. }
  341. /* Return the file descriptor */
  342. inline INT16
  343. BufferedDataFile::GetFd()
  344. {
  345.     return m_pFile ? fileno(m_pFile) : -1;
  346. }
  347. /* GetLastError returns the platform specific file error */
  348. STDMETHODIMP
  349. BufferedDataFile::GetLastError()
  350. {
  351.     return HXR_NOTIMPL;
  352. }
  353. /* GetLastError returns the platform specific file error in
  354.  * string form.
  355.  */
  356. STDMETHODIMP_(void)
  357. BufferedDataFile::GetLastError(REF(IHXBuffer*) err)
  358. {
  359. }