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

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 "hlxclib/sys/types.h"
  36. #include "hlxclib/sys/stat.h"
  37. #include "hlxclib/fcntl.h"
  38. #include "hlxclib/errno.h"
  39. #include "hxtypes.h"
  40. #include "hxcom.h"
  41. #include "hxresult.h"
  42. #include "ihxpckts.h"
  43. #include "hxbuffer.h"
  44. #include "debug.h"
  45. #include "hxbufdataf.h"
  46. #include "op_fs.h"
  47. /////////////////////////////////////////////////////////////////////////
  48. //
  49. //  Method:
  50. //      HXBufferedDataFile::QueryInterface
  51. //  Purpose:
  52. //      Implement this to export the interfaces supported by your
  53. //      object.
  54. //
  55. STDMETHODIMP
  56. HXBufferedDataFile::QueryInterface(REFIID riid, void** ppvObj)
  57. {
  58.     if (IsEqualIID(riid, IID_IHXDataFile))
  59.     {
  60.         AddRef();
  61.         *ppvObj = (IHXDataFile*)this;
  62.         return HXR_OK;
  63.     }
  64.     
  65.     *ppvObj = NULL;
  66.     return HXR_NOINTERFACE;
  67. }   
  68. /////////////////////////////////////////////////////////////////////////
  69. //
  70. //  Method:
  71. //      HXBufferedDataFile::AddRef
  72. //  Purpose:
  73. //      Everyone usually implements this the same... feel free to use
  74. //      this implementation.
  75. //
  76. STDMETHODIMP_(ULONG32)
  77. HXBufferedDataFile::AddRef()
  78. {
  79.     return InterlockedIncrement(&m_lRefCount);
  80. }   
  81. /////////////////////////////////////////////////////////////////////////
  82. //
  83. //  Method:
  84. //      HXBufferedDataFile::Release
  85. //  Purpose:
  86. //      Everyone usually implements this the same... feel free to use
  87. //      this implementation.
  88. //
  89. STDMETHODIMP_(ULONG32)
  90. HXBufferedDataFile::Release()
  91. {
  92.     if (InterlockedDecrement(&m_lRefCount) > 0)
  93.     {
  94.         return m_lRefCount;
  95.     }
  96.     
  97.     delete this;
  98.     return 0;
  99. }   
  100. HXBufferedDataFile::HXBufferedDataFile()
  101.     : m_lRefCount(0),
  102.       m_LastError(0),
  103.       m_pFileName(0),
  104.       m_Fd(-1),
  105.       m_Flags(0),
  106.       m_Begin(0),
  107.       m_BufSize(0),
  108.       m_BufFill(0),
  109.       m_Offset(0),
  110.       m_FileOffset(0),
  111.       m_FlushSize(0),
  112.       m_pBuf(0),
  113.       m_Dirty(0)
  114. {
  115.     m_pFileName = new CHXBuffer;
  116.     m_pFileName->AddRef();
  117.     m_BufSize = GetPageSize();
  118. }
  119. HXBufferedDataFile::~HXBufferedDataFile()
  120. {
  121.     Close();
  122.     FreeBuf();
  123.     HX_RELEASE(m_pFileName);
  124.     m_pFileName = 0;
  125. }
  126. /////////////////////////////////////////////////////////////////////////
  127. //
  128. // Method:
  129. //     HXBufferedDataFile::Bind:
  130. // Purpose:
  131. //     Cache the file name for opening.
  132. //     If file already open, close it.
  133. //
  134. STDMETHODIMP_(void)
  135. HXBufferedDataFile::Bind(const char* pFileName)
  136. {
  137.     if (m_Fd >= 0)
  138. Close();
  139.     m_pFileName->Set((BYTE *)pFileName, ::strlen(pFileName)+1);
  140. }
  141. /////////////////////////////////////////////////////////////////////////
  142. //
  143. // Method:
  144. //     HXBufferedDataFile::Create
  145. // Purpose:
  146. //     Creates a datafile using the specified mode
  147. //     uOpenMode - File Open mode - HX_FILEFLAG_READ/HX_FILEFLAG_WRITE/HX_FILEFLAG_BINARY
  148. //
  149. STDMETHODIMP
  150. HXBufferedDataFile::Create(UINT16 uOpenMode)
  151. {
  152.     return HXR_NOTIMPL;
  153. }
  154. /////////////////////////////////////////////////////////////////////////
  155. //
  156. //  Method:
  157. //      HXBufferedDatatFile::Open
  158. //  Purpose:
  159. //      Open for buffered i/o.  If file is already open, ignore this
  160. //      open and return HXR_OK status.  Flags can have 3 possible values
  161. //
  162. //    HX_FILEFLAG_READ:     Open file read only
  163. //
  164. //    HX_FILEFLAG_WRITE:    Open file for writing.  If file does not
  165. //      exists, it is created.
  166. //
  167. //    HX_FILEFLAG_READ|HX_FILEFLAG_WRITE:                
  168. //                           Open file for both read and writing.
  169. //
  170. //  Note:
  171. //      HX_FILEFLAG_WRITE implies both reads and writes to the file.  It
  172. //      also implies the file can be randomly updated any where in the
  173. //      file as well as appended onto the end. If the file exists,
  174. //      then the file contents are buffered in before updating.  As a
  175. //      result, writing implies both system reads and writes.
  176. //
  177. //      If open succeeds, returns HXR_OK, otherwise HXR_FAIL.
  178. //
  179. STDMETHODIMP
  180. HXBufferedDataFile::Open(UINT16 flags)
  181. {
  182. // flags don't match close and reopen
  183.     if (m_Fd >= 0 && flags != m_Flags)
  184.     {
  185. Close();
  186.     }
  187.     int status = HXR_OK;
  188.     if (m_Fd < 0)
  189.     {
  190. int oflags = 0;
  191. m_Flags = flags;
  192. m_LastError = 0;
  193. if (m_Flags & HX_FILEFLAG_WRITE)
  194. {
  195.     oflags = (O_CREAT|O_RDWR);
  196.     if (!(m_Flags & HX_FILEFLAG_NOTRUNC))
  197.     {
  198. oflags |= O_TRUNC;
  199.     }
  200. }
  201. else if (m_Flags & HX_FILEFLAG_READ)
  202.     oflags = O_RDONLY;
  203. else
  204.     return HXR_FAIL;
  205. if ((m_Fd =
  206.      //::open((const char*) m_pFileName->GetBuffer(), oflags, 0644)) < 0)
  207.              OpFsOpen((const char*) m_pFileName->GetBuffer(), oflags, 0)) == kOpFsErrAny)
  208. {
  209.     status = HXR_FAIL;
  210.     m_LastError = errno;
  211. }
  212. else // open ok: initialize
  213. {
  214.     if (m_pBuf == 0)
  215. AllocBuf();
  216.     m_Begin = 0;
  217.     m_BufFill = 0;
  218.     m_Offset = 0;
  219.     m_FileOffset = 0;
  220.     m_FlushSize = 0;
  221.     m_LastError = 0;
  222.     m_Dirty = 0;
  223. }
  224.     }
  225.     return status;
  226. }
  227. /////////////////////////////////////////////////////////////////////////
  228. //
  229. // Method:
  230. //     HXBufferedDataFile::Close:
  231. //  Purpose:
  232. //     Flush the file buffer (if open of writing and close the file.
  233. //     Note that file is not closed when there are multiple references
  234. //     to this object.
  235. //
  236. STDMETHODIMP
  237. HXBufferedDataFile::Close()
  238. {
  239.     int status = HXR_OK;
  240.     if (m_Fd >= 0 && m_lRefCount <= 1)
  241.     {
  242. if (m_Flags & HX_FILEFLAG_WRITE)
  243.     FlushBuf();
  244. //if (::close(m_Fd) == -1)
  245. if (OpFsClose( m_Fd ) != kOpFsErrOk )
  246. {
  247.     status = HXR_FAIL;
  248.     m_LastError = errno;
  249. }
  250. m_Fd = -1;
  251.     }
  252.     return status;
  253. }
  254. /////////////////////////////////////////////////////////////////////////
  255. //
  256. // Method:
  257. //     HXBufferedDataFile::Name
  258. // Purpose:
  259. //     Name returns the currently bound file name in FileName.
  260. //     and returns TRUE, if the a name has been bound.  Otherwise
  261. //     FALSE is returned.
  262. //
  263. STDMETHODIMP_(BOOL)
  264. HXBufferedDataFile::Name(REF(IHXBuffer*) pFileName)
  265. {
  266.     if (m_pFileName && m_pFileName->GetSize())
  267.     {
  268. pFileName = m_pFileName;
  269. pFileName->AddRef();
  270. return TRUE;
  271.     }
  272.     return FALSE;
  273. }
  274. /////////////////////////////////////////////////////////////////////////
  275. //
  276. // Method:
  277. //     HXBufferedDataFile::IsOpen()
  278. // Purpose:
  279. //     IsOpen returns TRUE if file is open.  Otherwise FALSE.
  280. //
  281. BOOL
  282. HXBufferedDataFile::IsOpen()
  283. {
  284.     return (m_Fd >= 0 ? TRUE : FALSE);
  285. }
  286. /////////////////////////////////////////////////////////////////////////
  287. //
  288. // Method
  289. //     HXBufferedDataFile::Seek:
  290. // Purpose:
  291. //     Just move the seek offset according to the value of whense.
  292. //     This only sets the local idea of the current offset, no system
  293. //     level seek is performed.  If seek is ok, the current value of
  294. //     seek offset is returned.  Otherwise -1 is returned.
  295. //
  296. //     XXXBH:  24-Mar-99
  297. //       Note that most of callers expect HXR_OK as return value, not
  298. //       the current offset.  So the above comment is a noop.   Also
  299. //       the offset is passed in as an unsigned, it should be signed to
  300. //       allow seeks in both directions.  Right now we do the ugly cast.
  301. //
  302. STDMETHODIMP
  303. HXBufferedDataFile::Seek(ULONG32 offset, UINT16 whense)
  304. {
  305.     ULONG32 size = 0;
  306.     LONG32 signed_offset = (LONG32) offset;
  307.     if (whense == SEEK_SET && signed_offset >= 0)
  308. m_Offset = signed_offset;
  309.     else if (whense == SEEK_CUR && (LONG32) m_Offset + signed_offset >= 0)
  310. m_Offset += signed_offset;
  311.     else if (whense == SEEK_END &&
  312.      (LONG32) (size = LogicalSize()) + signed_offset >= 0)
  313. m_Offset = size + signed_offset;
  314.     else
  315. return HXR_FAIL;
  316.     return HXR_OK;
  317. }
  318. /////////////////////////////////////////////////////////////////////////
  319. //
  320. // Method:
  321. //     HXBufferedDataFile::Tell()
  322. // Purpose:
  323. //      Tell returns the current (logical) file position in the file
  324. //
  325. STDMETHODIMP_(ULONG32)
  326. HXBufferedDataFile::Tell()
  327. {
  328.     return m_Offset;
  329. }
  330. /////////////////////////////////////////////////////////////////////////
  331. //
  332. // Method:
  333. //     HXBufferedDataFile::Read:
  334. // Purpose
  335. //     Read nbytes into the supplied buffer.  Values returned:
  336. //
  337. //        Actual bytes read.  The smaller of the number bytes requested
  338. //        and  the number of bytes between the current seek offset and the
  339. //        end of file is returned.
  340. //
  341. //        0, if the current seek pointer is at or beyond the end of file.
  342. //      
  343. //        -1, if errors occure.  The LastError() member function returns
  344. //        the errno of the last system request.
  345. //
  346. STDMETHODIMP_(ULONG32)
  347. HXBufferedDataFile::Read(REF(IHXBuffer *) pBuf, ULONG32 count)
  348. {
  349.     if (m_Fd >= 0)
  350.     {
  351. pBuf->AddRef();
  352. ULONG32 nleft = count;
  353. INT32 rval = 0;
  354. unsigned char* buf = pBuf->GetBuffer();
  355. while (nleft > 0)
  356. {
  357. // If we enter this block, m_Offset
  358. // lies within the mapped buffer.
  359.     if (m_Begin <= m_Offset && m_Offset < m_Begin + m_BufFill ||
  360. (m_Offset < FlushSize() && (rval = NewBuf()) > 0))
  361.     {
  362. UINT32 off = m_Offset - m_Begin;  // offset within buffer
  363.  // and how much to copy
  364. UINT32 ncopy = m_Begin + m_BufFill - m_Offset;
  365. if (nleft < ncopy)
  366.     ncopy = nleft;
  367. ::memcpy((void*) buf, (const void*) (m_pBuf+off), ncopy); /* Flawfinder: ignore */
  368. nleft -= ncopy;
  369. m_Offset += ncopy;
  370. buf += ncopy;
  371.     }
  372. // NewBuf() could not make the above
  373. // assertion, true.  m_Offset is either
  374. // at or beyond EOF, or an error occured.
  375.     else
  376. break;
  377. }
  378. pBuf->Release();
  379. return rval >= 0 ? count - nleft : HXR_FAIL;
  380.     }
  381.     return HXR_FAIL;
  382. }
  383. /////////////////////////////////////////////////////////////////////////
  384. //
  385. // Method:
  386. //     HXBufferedDataFile::Write:
  387. // Purpose:
  388. //      Write the requested number of bytes.  The number of bytes
  389. //      written are return.  If errors occur, -1 is returned.  The
  390. //      LastError() member function returns the value of errno from
  391. //      the last system request.
  392. //
  393. STDMETHODIMP_(ULONG32)
  394. HXBufferedDataFile::Write(REF(IHXBuffer *) pBuf)
  395. {
  396.     if (m_Fd >= 0)
  397.     {
  398. pBuf->AddRef();
  399. ULONG32 count = pBuf->GetSize();
  400. ULONG32 nleft = count;
  401. INT32 rval = 0;
  402. const unsigned char* buf = pBuf->GetBuffer();
  403. while (nleft > 0)
  404. {
  405. // If we enter this block, m_Offset
  406. // lies within the current buffer.
  407.     if (m_Begin <= m_Offset && m_Offset < m_Begin + m_BufSize ||
  408. (rval = NewBuf()) >= 0)
  409.     {
  410. UINT32 off = m_Offset - m_Begin;  // offset within buffer
  411.   // and how much to copy
  412. UINT32 ncopy = m_Begin + m_BufSize - m_Offset;
  413. if (nleft < ncopy)
  414.     ncopy = nleft;
  415. ::memcpy((void*) (m_pBuf+off), (const void*) buf, ncopy); /* Flawfinder: ignore */
  416. m_Dirty = 1;
  417. nleft -= ncopy;
  418. m_Offset += ncopy;
  419. buf += ncopy;
  420. // data extend beyond what was read in
  421. if (m_Offset-m_Begin > m_BufFill)
  422.     m_BufFill = m_Offset-m_Begin;
  423.     }
  424. // NewBuf() could not make the above
  425. // assertion, true because an error occured.
  426.     else
  427. break;
  428. }
  429. pBuf->Release();
  430. return rval >= 0 ? count - nleft : HXR_FAIL;
  431.     }
  432.     return HXR_FAIL;
  433. }
  434. /////////////////////////////////////////////////////////////////////////
  435. //
  436. // Method:
  437. //     HXBufferedDataFile::Flush()
  438. // Purpose:
  439. //     Flush out the data in case of buffered I/O
  440. //  
  441. STDMETHODIMP
  442. HXBufferedDataFile::Flush()
  443. {
  444.     if (m_Flags & HX_FILEFLAG_WRITE)
  445. return FlushBuf() > 0 ? HXR_OK : HXR_FAIL;
  446.     return HXR_OK;
  447. }
  448. /////////////////////////////////////////////////////////////////////////
  449. //
  450. // Method:
  451. //     HXBufferedDataFile::Stat
  452. // Purpose:
  453. //     Return info about the data file such as permissions, time of
  454. //     creation size in bytes, etc.  Note that if this method is
  455. //     called with unflushed extensions to the file, the st_size field
  456. //     will not be correct.  We could Flush before filling in the stat
  457. //     data, but this is a const function.  The other alternative is
  458. //     to set the st.st_size field to the value returned by
  459. //     LogicalSize() (which includes unflushed extensions to the
  460. //     file).
  461. //
  462. STDMETHODIMP
  463. HXBufferedDataFile::Stat(struct stat* buf)
  464. {
  465.     return GetFileStat(buf);
  466. }
  467. STDMETHODIMP_(INT16)
  468. HXBufferedDataFile::GetFd()
  469. {   
  470.     return m_Fd;
  471. }
  472. /////////////////////////////////////////////////////////////////////////
  473. //
  474. // Method:
  475. //     HXBufferedDataFile::GetLastError:
  476. // Purpose:
  477. //     Returns the value of errno from the last system request.
  478. //
  479. STDMETHODIMP
  480. HXBufferedDataFile::GetLastError()
  481. {
  482.     return m_LastError;
  483. }
  484. STDMETHODIMP_(void) 
  485. HXBufferedDataFile::GetLastError(REF(IHXBuffer*) err)
  486. {
  487.     char* str = ::strerror(m_LastError);
  488.     err = new CHXBuffer;
  489.     err->Set((BYTE*) str, ::strlen(str)+1);
  490.     err->AddRef();
  491. }
  492. /////////////////////////////////////////////////////////////////////////
  493. //
  494. //  Method:
  495. //      HXBufferedDataFile::FlushSize():
  496. //  Purpose:
  497. //       Return flushed file size.  We assume that only this object
  498. //       has changed the size of the file.  The size returned does NOT
  499. //       include bytes in the buffer not yet flushed to the file.
  500. //
  501. ULONG32
  502. HXBufferedDataFile::FlushSize()
  503. {
  504.     if (m_FlushSize == 0)
  505.     {
  506. struct stat st;
  507. if (GetFileStat(&st) == HXR_OK)
  508.     m_FlushSize = st.st_size;
  509.     }
  510.     return m_FlushSize;
  511. }
  512. /////////////////////////////////////////////////////////////////////////
  513. //
  514. //  Method:
  515. //      HXBufferedDataFile::LogicalSize():
  516. //  Purpose:
  517. //       Return logical file size.  We assume that only this object
  518. //       has changed the size of the file.  The size returned includes
  519. //       bytes in the buffer not yet flushed to the file.
  520. //
  521. ULONG32
  522. HXBufferedDataFile::LogicalSize()
  523. {
  524. // If the flushed size is <= the
  525. // beginning of the current buffer,
  526. // we have extended the file, but
  527. // have not flushed it.
  528.     ULONG32 size = FlushSize();
  529.     if (size <= m_Begin)
  530.     {
  531. size = m_Begin + m_BufFill;
  532.     }
  533.     return size;
  534. }
  535. /////////////////////////////////////////////////////////////////////////
  536. //
  537. // Method:
  538. //     HXBufferedDataFile::NewBuf:
  539. //  Purpose:
  540. //      Utility method.
  541. //      Request an new i/o buffer.  If the file is open for writing,
  542. //      the buffer is flushed if marked dirty.  If the file is open
  543. //      for reading a new buffer containing the current seek offset is
  544. //      read in from the file.  Note for files open for writing, the
  545. //      current buffer is flushed, before the new buffer is read in.
  546. //      Returns vales:
  547. //
  548. //         1       Buffer was successfully refreshed.
  549. //         0       If file is open for reading, cureent seek offset
  550. //                 is at or beyond EOF.
  551. //        -1       Error occured during flushing or filling.
  552. //
  553. INT32 HXBufferedDataFile::NewBuf()
  554. {
  555.     int status = 1;
  556. // if writing flush the current buffer 
  557.     if (m_Flags & HX_FILEFLAG_WRITE)
  558.     {
  559. status = FlushBuf();
  560.     }
  561. // fill buffer from file
  562.     if (status > 0)
  563.     {
  564. status = FillBuf();
  565.     }
  566.     return status;
  567. }
  568. /////////////////////////////////////////////////////////////////////////
  569. //
  570. // Method:
  571. //     HXBufferedDataFile::FillBuf:
  572. //
  573. // Purpose   
  574. //      Utility method:
  575. //      Fill buffer with file contents at current offset.
  576. //      Returns:
  577. //         1   Buffer filled.  If End of Buffer is beyond EOF,
  578. //             buffer is partially filled.  m_BufFill is set
  579. //             to how much of buffer is filled.
  580. //         0   End of File
  581. //        -1   Read or seek error, or file not open
  582. //
  583. INT32
  584. HXBufferedDataFile::FillBuf()
  585. {
  586.     int status = -1;
  587.     m_LastError = 0;
  588.     if (m_Fd >= 0)
  589.     {
  590. // Get beginning of buffer on a
  591. // m_BufSize boundry.  If the beginning
  592. // of the buffer is less then the current
  593. // flushed file size, seek and read it in.
  594. m_Begin = (m_Offset/m_BufSize)*m_BufSize;
  595. m_BufFill = 0;
  596. if (m_Begin < FlushSize())
  597. {
  598.     INT32 rval = -1;
  599.     m_BufFill = 0;
  600.     if ((rval = Pread((void*) m_pBuf, m_BufSize, m_Begin)) > 0)
  601.     {
  602. m_BufFill = rval;
  603. status = 1;
  604.     }
  605.     else if (rval < 0) // lseek or read error
  606.     {
  607. m_LastError = errno;
  608. status = -1;
  609.     }
  610.     else // EOF: zero buffer
  611.     {
  612. ::memset((void*) m_pBuf, 0, m_BufSize);
  613. status = 0;
  614.     }
  615. }
  616. else // m_Begin is beyond EOF: zero buffer
  617. {
  618.     ::memset((void*) m_pBuf, 0, m_BufSize);
  619.     status = 0;
  620. }
  621.     }
  622.     return status;
  623. }
  624. /////////////////////////////////////////////////////////////////////////
  625. //
  626. // Method:
  627. //     HXBufferedDataFile::FlushBuf:
  628. // Purpose:
  629. //    Utility method:
  630. //    If file is open for writing and the current i/o buffer is dirty,
  631. //    write the contents to the file.
  632. //    Returns:
  633. //         1   Buffer Flushed.
  634. //        -1   Read or seek error, or file not open or read only.
  635. //
  636. INT32
  637. HXBufferedDataFile::FlushBuf()
  638. {
  639.     int status = -1;
  640.     m_LastError = 0;
  641.     if (m_Fd >= 0 && (m_Flags & HX_FILEFLAG_WRITE))
  642.     {
  643. // buffer has been scribbled on.
  644. if (m_Dirty && m_BufFill > 0)
  645. {
  646.     int rval = -1;
  647.     if ((rval = Pwrite((const void*) m_pBuf, m_BufFill, m_Begin)) > 0)
  648.     {
  649. status = 1;
  650. m_Dirty = 0;
  651.     }
  652.     else
  653.     {
  654. status = -1;
  655. m_LastError = errno;
  656.     }
  657. }
  658. else // already flushed.
  659.     status = 1;
  660.     }
  661.     return status;
  662. }
  663. /////////////////////////////////////////////////////////////////////////
  664. //
  665. // Method:
  666. //     HXBufferedDataFile::AllocBuf:
  667. // Purpose:
  668. //     Allocate  the i/o buffer off of heap.
  669. //
  670. void
  671. HXBufferedDataFile::AllocBuf()
  672. {
  673.     if (m_pBuf == 0)
  674.     {
  675. m_pBuf = new char[m_BufSize];
  676.     }
  677. }
  678. /////////////////////////////////////////////////////////////////////////
  679. //
  680. // Method:
  681. //     HXBufferedDataFile::FreeBuf:
  682. //  Purpose:
  683. //     Free the i/o buffer.
  684. //
  685. void
  686. HXBufferedDataFile::FreeBuf()
  687. {
  688.     delete [] m_pBuf;
  689.     m_pBuf = 0;
  690.     m_BufFill = 0;
  691.     m_Begin = 0;
  692. }
  693. /////////////////////////////////////////////////////////////////////////
  694. //
  695. // Method:
  696. //     HXBufferedDataFile::Pread:
  697. // Purpose:
  698. //     Read data at requrested position.
  699. //     Number of bytes read is returned 0 if at EOF, or -1 on error
  700. //
  701. INT32
  702. HXBufferedDataFile::Pread(void* buf, INT32 nbytes, ULONG32 offset)
  703. {
  704.     //INT32 nread = -1;
  705. OpFsSize nread = kOpFsErrAny;
  706.     m_LastError = 0;
  707.     if (m_Fd >= 0)
  708.     {
  709. if (m_FileOffset == offset ||
  710.    // ::lseek(m_Fd, offset, SEEK_SET) != -1)
  711.    OpFsSeek( m_Fd, (OpFsSize)offset, SEEK_SET) != kOpFsErrAny)
  712. {
  713.     m_FileOffset = offset;
  714.     //if ((nread = ::read(m_Fd, buf, nbytes)) > 0)
  715. if ((nread = OpFsRead( m_Fd, buf, nbytes)) != kOpFsErrAny)
  716. m_FileOffset += nread;
  717.     else if (nread < 0)
  718. m_LastError = errno;
  719. }
  720.     }
  721.     return nread;
  722. }
  723. /////////////////////////////////////////////////////////////////////////
  724. //
  725. // Method:
  726. //     HXBufferedDataFile::Pwrite:
  727. // Purpose:
  728. //     Write data at requrested position.
  729. //     Number of bytes read is returned, or -1 on error
  730. //
  731. INT32
  732. HXBufferedDataFile::Pwrite(const void* buf, INT32 nbytes, ULONG32 offset)
  733. {
  734.     //INT32 nwrite = -1;
  735. OpFsSize nwrite = kOpFsErrAny;
  736.     m_LastError = 0;
  737.     if (m_Fd >= 0)
  738.     {
  739. if (m_FileOffset == offset ||
  740.     //::lseek(m_Fd, offset, SEEK_SET) != -1)
  741. OpFsSeek( m_Fd, (OpFsSize)offset, SEEK_SET) != kOpFsErrAny)
  742. {
  743.     m_FileOffset = offset;
  744.     //if ((nwrite = ::write(m_Fd, buf, nbytes)) > 0)
  745. if (( nwrite = OpFsWrite( m_Fd, buf, nbytes)) != kOpFsErrAny)
  746.     {
  747. m_FileOffset += nwrite;
  748. if (m_FileOffset > m_FlushSize)
  749. m_FlushSize = m_FileOffset;
  750.     }
  751.     else
  752. m_LastError = errno;
  753. }
  754.     }
  755.     return nwrite;
  756. }
  757. /////////////////////////////////////////////////////////////////////////
  758. //
  759. // Method:
  760. //     HXBufferedDataFile::GetFileStat
  761. //  Purpose
  762. //   Get file stat. If all is of HXR_OK is returned otherwise HXR_FAIL
  763. //
  764. INT32
  765. HXBufferedDataFile::GetFileStat(struct stat* st) const
  766. {
  767.     INT32 status = HXR_FAIL;
  768.     if ((m_Fd >= 0 && ::fstat(m_Fd, st) == 0) ||
  769. (m_pFileName->GetSize() &&
  770.  ::stat((const char*) m_pFileName->GetBuffer(), st) == 0))
  771.     {
  772. status = HXR_OK;
  773.     }
  774. // cast to get around const
  775.     ((HXBufferedDataFile*) this)->m_LastError = status == HXR_OK ? 0 : errno;
  776.     return status;
  777. }
  778. /////////////////////////////////////////////////////////////////////////
  779. //
  780. // Method:
  781. //     HXBufferedDataFile::GetPageSize:
  782. // Purpose:
  783. //    Get the system page size.
  784. INT32
  785. HXBufferedDataFile::GetPageSize() const
  786. {
  787. #if defined(_FREEBSD)
  788.     return getpagesize();
  789. #else
  790.     //return ::sysconf(_SC_PAGE_SIZE);
  791. return 0;  // On Openwave platform, pages service not available
  792. #endif
  793. }