📄 hxbufdataf.cpp
字号:
// written are return. If errors occur, -1 is returned. The// LastError() member function returns the value of errno from// the last system request.//STDMETHODIMP_(ULONG32)HXBufferedDataFile::Write(REF(IHXBuffer *) pBuf){ if (m_Fd >= 0) { pBuf->AddRef(); ULONG32 count = pBuf->GetSize(); ULONG32 nleft = count; INT32 rval = 0; const unsigned char* buf = pBuf->GetBuffer(); while (nleft > 0) { // If we enter this block, m_Offset // lies within the current buffer. if (m_Begin <= m_Offset && m_Offset < m_Begin + m_BufSize || (rval = NewBuf()) >= 0) { UINT32 off = m_Offset - m_Begin; // offset within buffer // and how much to copy UINT32 ncopy = m_Begin + m_BufSize - m_Offset; if (nleft < ncopy) ncopy = nleft; ::memcpy((void*) (m_pBuf+off), (const void*) buf, ncopy); /* Flawfinder: ignore */ m_Dirty = 1; nleft -= ncopy; m_Offset += ncopy; buf += ncopy; // data extend beyond what was read in if (m_Offset-m_Begin > m_BufFill) m_BufFill = m_Offset-m_Begin; } // NewBuf() could not make the above // assertion, true because an error occured. else break; } pBuf->Release(); return rval >= 0 ? count - nleft : HXR_FAIL; } return HXR_FAIL;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::Flush()// Purpose:// Flush out the data in case of buffered I/O// STDMETHODIMPHXBufferedDataFile::Flush(){ if (m_Flags & HX_FILEFLAG_WRITE) return FlushBuf() > 0 ? HXR_OK : HXR_FAIL; return HXR_OK;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::Stat// Purpose:// Return info about the data file such as permissions, time of// creation size in bytes, etc. Note that if this method is// called with unflushed extensions to the file, the st_size field// will not be correct. We could Flush before filling in the stat// data, but this is a const function. The other alternative is// to set the st.st_size field to the value returned by// LogicalSize() (which includes unflushed extensions to the// file).//STDMETHODIMPHXBufferedDataFile::Stat(struct stat* buf){ return GetFileStat(buf);}STDMETHODIMP_(INT16)HXBufferedDataFile::GetFd(){ return m_Fd;} ///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::GetLastError:// Purpose:// Returns the value of errno from the last system request.//STDMETHODIMPHXBufferedDataFile::GetLastError(){ return m_LastError;}STDMETHODIMP_(void) HXBufferedDataFile::GetLastError(REF(IHXBuffer*) err){ char* str = ::strerror(m_LastError); err = new CHXBuffer; err->Set((BYTE*) str, ::strlen(str)+1); err->AddRef();}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::FlushSize():// Purpose:// Return flushed file size. We assume that only this object// has changed the size of the file. The size returned does NOT// include bytes in the buffer not yet flushed to the file.//ULONG32HXBufferedDataFile::FlushSize(){ if (m_FlushSize == 0) { struct stat st; if (GetFileStat(&st) == HXR_OK) m_FlushSize = st.st_size; } return m_FlushSize;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::LogicalSize():// Purpose:// Return logical file size. We assume that only this object// has changed the size of the file. The size returned includes// bytes in the buffer not yet flushed to the file.//ULONG32HXBufferedDataFile::LogicalSize(){ // If the flushed size is <= the // beginning of the current buffer, // we have extended the file, but // have not flushed it. ULONG32 size = FlushSize(); if (size <= m_Begin) { size = m_Begin + m_BufFill; } return size;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::NewBuf:// Purpose:// Utility method.// Request an new i/o buffer. If the file is open for writing,// the buffer is flushed if marked dirty. If the file is open// for reading a new buffer containing the current seek offset is// read in from the file. Note for files open for writing, the// current buffer is flushed, before the new buffer is read in.// Returns vales://// 1 Buffer was successfully refreshed.// 0 If file is open for reading, cureent seek offset// is at or beyond EOF.// -1 Error occured during flushing or filling.//INT32 HXBufferedDataFile::NewBuf(){ int status = 1; // if writing flush the current buffer if (m_Flags & HX_FILEFLAG_WRITE) { status = FlushBuf(); } // fill buffer from file if (status > 0) { status = FillBuf(); } return status;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::FillBuf://// Purpose // Utility method:// Fill buffer with file contents at current offset.// Returns:// 1 Buffer filled. If End of Buffer is beyond EOF,// buffer is partially filled. m_BufFill is set// to how much of buffer is filled.// 0 End of File// -1 Read or seek error, or file not open//INT32HXBufferedDataFile::FillBuf(){ int status = -1; m_LastError = 0; if (m_Fd >= 0) { // Get beginning of buffer on a // m_BufSize boundry. If the beginning // of the buffer is less then the current // flushed file size, seek and read it in. m_Begin = (m_Offset/m_BufSize)*m_BufSize; m_BufFill = 0; if (m_Begin < FlushSize()) { INT32 rval = -1; m_BufFill = 0; if ((rval = Pread((void*) m_pBuf, m_BufSize, m_Begin)) > 0) { m_BufFill = rval; status = 1; } else if (rval < 0) // lseek or read error { m_LastError = errno; status = -1; } else // EOF: zero buffer { ::memset((void*) m_pBuf, 0, m_BufSize); status = 0; } } else // m_Begin is beyond EOF: zero buffer { ::memset((void*) m_pBuf, 0, m_BufSize); status = 0; } } return status;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::FlushBuf:// Purpose:// Utility method:// If file is open for writing and the current i/o buffer is dirty,// write the contents to the file.// Returns:// 1 Buffer Flushed.// -1 Read or seek error, or file not open or read only.//INT32HXBufferedDataFile::FlushBuf(){ int status = -1; m_LastError = 0; if (m_Fd >= 0 && (m_Flags & HX_FILEFLAG_WRITE)) { // buffer has been scribbled on. if (m_Dirty && m_BufFill > 0) { int rval = -1; if ((rval = Pwrite((const void*) m_pBuf, m_BufFill, m_Begin)) > 0) { status = 1; m_Dirty = 0; } else { status = -1; m_LastError = errno; } } else // already flushed. status = 1; } return status;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::AllocBuf:// Purpose:// Allocate the i/o buffer off of heap.//voidHXBufferedDataFile::AllocBuf(){ if (m_pBuf == 0) { m_pBuf = new char[m_BufSize]; }}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::FreeBuf:// Purpose:// Free the i/o buffer.//voidHXBufferedDataFile::FreeBuf(){ delete [] m_pBuf; m_pBuf = 0; m_BufFill = 0; m_Begin = 0;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::Pread:// Purpose:// Read data at requrested position.// Number of bytes read is returned 0 if at EOF, or -1 on error//INT32HXBufferedDataFile::Pread(void* buf, INT32 nbytes, ULONG32 offset){ //INT32 nread = -1; OpFsSize nread = kOpFsErrAny; m_LastError = 0; if (m_Fd >= 0) { if (m_FileOffset == offset || // ::lseek(m_Fd, offset, SEEK_SET) != -1) OpFsSeek( m_Fd, (OpFsSize)offset, SEEK_SET) != kOpFsErrAny) { m_FileOffset = offset; //if ((nread = ::read(m_Fd, buf, nbytes)) > 0) if ((nread = OpFsRead( m_Fd, buf, nbytes)) != kOpFsErrAny) m_FileOffset += nread; else if (nread < 0) m_LastError = errno; } } return nread;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::Pwrite:// Purpose:// Write data at requrested position.// Number of bytes read is returned, or -1 on error//INT32HXBufferedDataFile::Pwrite(const void* buf, INT32 nbytes, ULONG32 offset){ //INT32 nwrite = -1; OpFsSize nwrite = kOpFsErrAny; m_LastError = 0; if (m_Fd >= 0) { if (m_FileOffset == offset || //::lseek(m_Fd, offset, SEEK_SET) != -1) OpFsSeek( m_Fd, (OpFsSize)offset, SEEK_SET) != kOpFsErrAny) { m_FileOffset = offset; //if ((nwrite = ::write(m_Fd, buf, nbytes)) > 0) if (( nwrite = OpFsWrite( m_Fd, buf, nbytes)) != kOpFsErrAny) { m_FileOffset += nwrite; if (m_FileOffset > m_FlushSize) m_FlushSize = m_FileOffset; } else m_LastError = errno; } } return nwrite;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::GetFileStat// Purpose// Get file stat. If all is of HXR_OK is returned otherwise HXR_FAIL//INT32HXBufferedDataFile::GetFileStat(struct stat* st) const{ INT32 status = HXR_FAIL; if ((m_Fd >= 0 && ::fstat(m_Fd, st) == 0) || (m_pFileName->GetSize() && ::stat((const char*) m_pFileName->GetBuffer(), st) == 0)) { status = HXR_OK; } // cast to get around const ((HXBufferedDataFile*) this)->m_LastError = status == HXR_OK ? 0 : errno; return status;}///////////////////////////////////////////////////////////////////////////// Method:// HXBufferedDataFile::GetPageSize:// Purpose:// Get the system page size.INT32HXBufferedDataFile::GetPageSize() const{#if defined(_FREEBSD) return getpagesize();#else //return ::sysconf(_SC_PAGE_SIZE); return 0; // On Openwave platform, pages service not available#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -