* Rewrote headers as necessary; only Errors.h and Debug.h still originate from a Be header now;
feel free to change that ;-) * Cleaned up existing headers. * Coding style guide update to BBufferIO (renamed m_* members to f*). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19972 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+109
-102
@@ -1,17 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005, Haiku
|
||||
* Copyright (c) 2001-2007, Haiku
|
||||
* Distributed under the terms of the MIT license
|
||||
*
|
||||
* Authors:
|
||||
Stefano Ceccherini ([email protected])
|
||||
* Stefano Ceccherini ([email protected])
|
||||
*/
|
||||
|
||||
// A buffered adapter for BPositionIO objects.
|
||||
|
||||
//! A buffered adapter for BPositionIO objects.
|
||||
|
||||
|
||||
#include <BufferIO.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <BufferIO.h>
|
||||
|
||||
/*! \class BBufferIO
|
||||
\brief A buffered adapter for BPositionIO objects.
|
||||
@@ -28,43 +31,46 @@
|
||||
\param buf_size The size of the buffer that the object will allocate and use.
|
||||
\param owns_stream Specifies if the object will delete the stream on destruction.
|
||||
*/
|
||||
BBufferIO::BBufferIO(BPositionIO *stream, size_t buf_size, bool owns_stream)
|
||||
:m_buffer_start(0),
|
||||
m_stream(stream),
|
||||
m_buffer(NULL),
|
||||
m_buffer_used(0),
|
||||
m_buffer_dirty(false),
|
||||
m_owns_stream(owns_stream)
|
||||
BBufferIO::BBufferIO(BPositionIO *stream, size_t bufferSize, bool ownsStream)
|
||||
:
|
||||
fBufferStart(0),
|
||||
fStream(stream),
|
||||
fBuffer(NULL),
|
||||
fBufferUsed(0),
|
||||
fBufferIsDirty(false),
|
||||
fOwnsStream(ownsStream)
|
||||
|
||||
{
|
||||
if (buf_size < 512)
|
||||
buf_size = 512;
|
||||
if (bufferSize < 512)
|
||||
bufferSize = 512;
|
||||
|
||||
m_buffer_phys = buf_size;
|
||||
fBufferSize = bufferSize;
|
||||
|
||||
// What can we do if this malloc fails ?
|
||||
// I think R5 uses new, but doesn't catch the thrown exception
|
||||
// (if you specify a very big buffer, the application just
|
||||
// terminates with abort).
|
||||
m_buffer = (char *)malloc(m_buffer_phys * sizeof(char));
|
||||
// terminates with abort).
|
||||
fBuffer = (char *)malloc(fBufferSize);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Frees the resources allocated by the object
|
||||
|
||||
|
||||
Flushes pending changes to the stream and frees the allocated memory.
|
||||
If the owns_stream property is true, the destructor also
|
||||
deletes the stream associated with the BBufferIO object.
|
||||
*/
|
||||
BBufferIO::~BBufferIO()
|
||||
{
|
||||
if (m_buffer_dirty)
|
||||
Flush(); // Writes pending changes to the stream
|
||||
if (fBufferIsDirty) {
|
||||
// Write pending changes to the stream
|
||||
Flush();
|
||||
}
|
||||
|
||||
free(m_buffer);
|
||||
|
||||
if (m_owns_stream)
|
||||
delete m_stream;
|
||||
free(fBuffer);
|
||||
|
||||
if (fOwnsStream)
|
||||
delete fStream;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,41 +86,40 @@ BBufferIO::ReadAt(off_t pos, void *buffer, size_t size)
|
||||
// We refuse to crash, even if
|
||||
// you were lazy and didn't give a valid
|
||||
// stream on construction.
|
||||
if (m_stream == NULL)
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
|
||||
if (buffer == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
||||
// If the amount of data we want doesn't fit in the buffer, just
|
||||
// read it directly from the disk (and don't touch the buffer).
|
||||
if (size > m_buffer_phys) {
|
||||
if (m_buffer_dirty)
|
||||
if (size > fBufferSize) {
|
||||
if (fBufferIsDirty)
|
||||
Flush();
|
||||
return m_stream->ReadAt(pos, buffer, size);
|
||||
return fStream->ReadAt(pos, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
// If the data we are looking for is not in the buffer...
|
||||
if (size > m_buffer_used
|
||||
|| pos < m_buffer_start
|
||||
|| pos > m_buffer_start + m_buffer_used
|
||||
|| pos + size > m_buffer_start + m_buffer_used) {
|
||||
|
||||
if (m_buffer_dirty)
|
||||
if (size > fBufferUsed
|
||||
|| pos < fBufferStart
|
||||
|| pos > fBufferStart + fBufferUsed
|
||||
|| pos + size > fBufferStart + fBufferUsed) {
|
||||
if (fBufferIsDirty)
|
||||
Flush(); // If there are pending writes, do them.
|
||||
|
||||
|
||||
// ...cache as much as we can from the stream
|
||||
m_buffer_used = m_stream->ReadAt(pos, m_buffer, m_buffer_phys);
|
||||
|
||||
if (m_buffer_used > 0)
|
||||
m_buffer_start = pos; // The data is buffered starting from this offset
|
||||
fBufferUsed = fStream->ReadAt(pos, fBuffer, fBufferSize);
|
||||
|
||||
if (fBufferUsed > 0)
|
||||
fBufferStart = pos; // The data is buffered starting from this offset
|
||||
}
|
||||
|
||||
size = min_c(size, m_buffer_used);
|
||||
|
||||
|
||||
size = min_c(size, fBufferUsed);
|
||||
|
||||
// copy data from the cache to the given buffer
|
||||
memcpy(buffer, m_buffer + pos - m_buffer_start, size);
|
||||
|
||||
memcpy(buffer, fBuffer + pos - fBufferStart, size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -128,45 +133,45 @@ BBufferIO::ReadAt(off_t pos, void *buffer, size_t size)
|
||||
ssize_t
|
||||
BBufferIO::WriteAt(off_t pos, const void *buffer, size_t size)
|
||||
{
|
||||
if (m_stream == NULL)
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
|
||||
if (buffer == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
||||
// If data doesn't fit into the buffer, write it directly to the stream
|
||||
if (size > m_buffer_phys)
|
||||
return m_stream->WriteAt(pos, buffer, size);
|
||||
|
||||
if (size > fBufferSize)
|
||||
return fStream->WriteAt(pos, buffer, size);
|
||||
|
||||
// If we have cached data in the buffer, whose offset into the stream
|
||||
// is > 0, and the buffer isn't dirty, drop the data.
|
||||
if (!m_buffer_dirty && m_buffer_start > pos) {
|
||||
m_buffer_start = 0;
|
||||
m_buffer_used = 0;
|
||||
if (!fBufferIsDirty && fBufferStart > pos) {
|
||||
fBufferStart = 0;
|
||||
fBufferUsed = 0;
|
||||
}
|
||||
|
||||
|
||||
// If we want to write beyond the cached data...
|
||||
if (pos > m_buffer_start + m_buffer_used
|
||||
|| pos < m_buffer_start) {
|
||||
if (pos > fBufferStart + fBufferUsed
|
||||
|| pos < fBufferStart) {
|
||||
ssize_t read;
|
||||
off_t where = pos;
|
||||
|
||||
if (pos + size <= m_buffer_phys) // Can we just cache from the beginning ?
|
||||
|
||||
if (pos + size <= fBufferSize) // Can we just cache from the beginning ?
|
||||
where = 0;
|
||||
|
||||
|
||||
// ...cache more.
|
||||
read = m_stream->ReadAt(where, m_buffer, m_buffer_phys);
|
||||
read = fStream->ReadAt(where, fBuffer, fBufferSize);
|
||||
if (read > 0) {
|
||||
m_buffer_used = read;
|
||||
m_buffer_start = where;
|
||||
fBufferUsed = read;
|
||||
fBufferStart = where;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(m_buffer + pos - m_buffer_start, buffer, size);
|
||||
|
||||
m_buffer_dirty = true;
|
||||
m_buffer_used = max_c((size + pos), m_buffer_used);
|
||||
|
||||
|
||||
memcpy(fBuffer + pos - fBufferStart, buffer, size);
|
||||
|
||||
fBufferIsDirty = true;
|
||||
fBufferUsed = max_c((size + pos), fBufferUsed);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -194,12 +199,12 @@ BBufferIO::WriteAt(off_t pos, const void *buffer, size_t size)
|
||||
from the beginning of the stream.
|
||||
*/
|
||||
off_t
|
||||
BBufferIO::Seek(off_t position, uint32 seek_mode)
|
||||
BBufferIO::Seek(off_t position, uint32 seekMode)
|
||||
{
|
||||
if (m_stream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return m_stream->Seek(position, seek_mode);
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fStream->Seek(position, seekMode);
|
||||
}
|
||||
|
||||
|
||||
@@ -210,10 +215,10 @@ BBufferIO::Seek(off_t position, uint32 seek_mode)
|
||||
off_t
|
||||
BBufferIO::Position() const
|
||||
{
|
||||
if (m_stream == NULL)
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return m_stream->Position();
|
||||
|
||||
return fStream->Position();
|
||||
}
|
||||
|
||||
|
||||
@@ -224,10 +229,10 @@ BBufferIO::Position() const
|
||||
status_t
|
||||
BBufferIO::SetSize(off_t size)
|
||||
{
|
||||
if (m_stream == NULL)
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return m_stream->SetSize(size);
|
||||
return fStream->SetSize(size);
|
||||
}
|
||||
|
||||
|
||||
@@ -237,16 +242,15 @@ BBufferIO::SetSize(off_t size)
|
||||
status_t
|
||||
BBufferIO::Flush()
|
||||
{
|
||||
if (!m_buffer_dirty)
|
||||
if (!fBufferIsDirty)
|
||||
return B_OK;
|
||||
|
||||
|
||||
// Write the cached data to the stream
|
||||
status_t err = m_stream->WriteAt(m_buffer_start, m_buffer, m_buffer_used);
|
||||
|
||||
if (err > 0)
|
||||
m_buffer_dirty = false;
|
||||
|
||||
return (err < 0) ? err : B_OK;
|
||||
ssize_t bytesWritten = fStream->WriteAt(fBufferStart, fBuffer, fBufferUsed);
|
||||
if (bytesWritten > 0)
|
||||
fBufferIsDirty = false;
|
||||
|
||||
return (bytesWritten < 0) ? bytesWritten : B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,7 +260,7 @@ BBufferIO::Flush()
|
||||
BPositionIO *
|
||||
BBufferIO::Stream() const
|
||||
{
|
||||
return m_stream;
|
||||
return fStream;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,7 +270,7 @@ BBufferIO::Stream() const
|
||||
size_t
|
||||
BBufferIO::BufferSize() const
|
||||
{
|
||||
return m_buffer_phys;
|
||||
return fBufferSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +281,7 @@ BBufferIO::BufferSize() const
|
||||
bool
|
||||
BBufferIO::OwnsStream() const
|
||||
{
|
||||
return m_owns_stream;
|
||||
return fOwnsStream;
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +292,7 @@ BBufferIO::OwnsStream() const
|
||||
void
|
||||
BBufferIO::SetOwnsStream(bool owns_stream)
|
||||
{
|
||||
m_owns_stream = owns_stream;
|
||||
fOwnsStream = owns_stream;
|
||||
}
|
||||
|
||||
|
||||
@@ -297,18 +301,21 @@ BBufferIO::SetOwnsStream(bool owns_stream)
|
||||
void
|
||||
BBufferIO::PrintToStream() const
|
||||
{
|
||||
printf("stream %p\n", m_stream);
|
||||
printf("buffer %p\n", m_buffer);
|
||||
printf("start %lld\n", m_buffer_start);
|
||||
printf("used %ld\n", m_buffer_used);
|
||||
printf("phys %ld\n", m_buffer_phys);
|
||||
printf("dirty %s\n", (m_buffer_dirty) ? "true" : "false");
|
||||
printf("owns %s\n", (m_owns_stream) ? "true" : "false");
|
||||
printf("stream %p\n", fStream);
|
||||
printf("buffer %p\n", fBuffer);
|
||||
printf("start %lld\n", fBufferStart);
|
||||
printf("used %ld\n", fBufferUsed);
|
||||
printf("phys %ld\n", fBufferSize);
|
||||
printf("dirty %s\n", (fBufferIsDirty) ? "true" : "false");
|
||||
printf("owns %s\n", (fOwnsStream) ? "true" : "false");
|
||||
}
|
||||
|
||||
|
||||
// These functions are here to maintain future binary
|
||||
// compatibility.
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
// These functions are here to maintain future binary
|
||||
// compatibility.
|
||||
status_t BBufferIO::_Reserved_BufferIO_0(void *) { return B_ERROR; }
|
||||
status_t BBufferIO::_Reserved_BufferIO_1(void *) { return B_ERROR; }
|
||||
status_t BBufferIO::_Reserved_BufferIO_2(void *) { return B_ERROR; }
|
||||
|
||||
Reference in New Issue
Block a user