📄 opwavehxdataf.cpp
字号:
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:
// OpenwaveHXDataFile::Flush()
// Purpose:
// Flush out the data in case of buffered I/O
//
STDMETHODIMP
OpenwaveHXDataFile::Flush()
{
if (m_Flags & HX_FILEFLAG_WRITE)
return FlushBuf() > 0 ? HXR_OK : HXR_FAIL;
return HXR_OK;
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::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).
//
STDMETHODIMP
OpenwaveHXDataFile::Stat(struct stat* buf)
{
return GetFileStat(buf);
}
STDMETHODIMP
OpenwaveHXDataFile::Delete()
{
return HXR_OK;
}
STDMETHODIMP_(INT16)
OpenwaveHXDataFile::GetFd()
{
return m_Fd;
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::GetLastError:
// Purpose:
// Returns the value of errno from the last system request.
//
STDMETHODIMP
OpenwaveHXDataFile::GetLastError()
{
return m_LastError;
}
STDMETHODIMP_(void)
OpenwaveHXDataFile::GetLastError(REF(IHXBuffer*) err)
{
char* str = ::strerror(m_LastError);
err = new CHXBuffer;
err->Set((BYTE*) str, ::strlen(str)+1);
err->AddRef();
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::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.
//
ULONG32
OpenwaveHXDataFile::FlushSize()
{
if (m_FlushSize == 0)
{
struct stat st;
if (GetFileStat(&st) == HXR_OK)
m_FlushSize = st.st_size;
}
return m_FlushSize;
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::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.
//
ULONG32
OpenwaveHXDataFile::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:
// OpenwaveHXDataFile::NewBuf:
// Purpose:
// Utility method.
// Request an new i/o buffer. If the file is en 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 OpenwaveHXDataFile::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:
// OpenwaveHXDataFile::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
//
INT32
OpenwaveHXDataFile::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:
// OpenwaveHXDataFile::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.
//
INT32
OpenwaveHXDataFile::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:
// OpenwaveHXDataFile::AllocBuf:
// Purpose:
// Allocate the i/o buffer off of heap.
//
void
OpenwaveHXDataFile::AllocBuf()
{
if (m_BufSize > 0)
{
m_pBuf = new char[m_BufSize];
}
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::FreeBuf:
// Purpose:
// Free the i/o buffer.
//
void
OpenwaveHXDataFile::FreeBuf()
{
if (m_pBuf)
{
delete [] m_pBuf;
m_pBuf = 0;
}
m_BufFill = 0;
m_Begin = 0;
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::Pread:
// Purpose:
// Read data at requrested position.
// Number of bytes read is returned 0 if at EOF, or -1 on error
//
INT32
OpenwaveHXDataFile::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, kOpFsSeekCur) != 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:
// OpenwaveHXDataFile::Pwrite:
// Purpose:
// Write data at requrested position.
// Number of bytes read is returned, or -1 on error
//
INT32
OpenwaveHXDataFile::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, kOpFsSeekCur) != 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:
// OpenwaveHXDataFile::GetFileStat
// Purpose
// Get file stat. If all is of HXR_OK is returned otherwise HXR_FAIL
//
INT32
OpenwaveHXDataFile::GetFileStat(struct stat* st) const
{
INT32 status = HXR_FAIL;
OpFsStatStruct filestats;
if (m_Fd >= 0)
{
if (OpFsStat((const char*) m_pFileName->GetBuffer(), &filestats) == kOpFsErrOk)
{
st->st_size = filestats.size;
status = HXR_OK;
}
}
// cast to get around const
((OpenwaveHXDataFile*) this)->m_LastError = status == HXR_OK ? 0 : errno;
return status;
}
/////////////////////////////////////////////////////////////////////////
//
// Method:
// OpenwaveHXDataFile::GetPageSize:
// Purpose:
// Get the system page size.
INT32
OpenwaveHXDataFile::GetPageSize() const
{
//return ::sysconf(_SC_PAGE_SIZE);
return 0; // On Openwave platform, pages service not available
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -