summaryrefslogtreecommitdiff
path: root/lib/common/BufferedStream.cpp
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2007-01-17 20:41:24 +0000
committerChris Wilson <chris+github@qwirx.com>2007-01-17 20:41:24 +0000
commit83c3656651028ab8854dcc95ecc6a49e5ad71a08 (patch)
tree832eb824e8561f9c6d4d7f8f2a88b0eaacc3867b /lib/common/BufferedStream.cpp
parentaa42fa6e400d0f682e7dc9b1cd78e6575457f2d7 (diff)
Added a BufferedStream class that can be wrapped around an IOStream to
improve read performance when many small reads will be performed, e.g. while reading directories and during housekeeping. (refs #3)
Diffstat (limited to 'lib/common/BufferedStream.cpp')
-rw-r--r--lib/common/BufferedStream.cpp207
1 files changed, 207 insertions, 0 deletions
diff --git a/lib/common/BufferedStream.cpp b/lib/common/BufferedStream.cpp
new file mode 100644
index 00000000..288e1ed1
--- /dev/null
+++ b/lib/common/BufferedStream.cpp
@@ -0,0 +1,207 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: BufferedStream.cpp
+// Purpose: Buffering wrapper around IOStreams
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+#include "BufferedStream.h"
+#include "CommonException.h"
+
+#include <string.h>
+
+#include "MemLeakFindOn.h"
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::BufferedStream(const char *, int, int)
+// Purpose: Constructor, set up buffer
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+BufferedStream::BufferedStream(IOStream& rSource)
+: mrSource(rSource), mBufferSize(0), mBufferPosition(0)
+{ }
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::Read(void *, int)
+// Purpose: Reads bytes from the file
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+int BufferedStream::Read(void *pBuffer, int NBytes, int Timeout)
+{
+ if (mBufferSize == mBufferPosition)
+ {
+ // buffer is empty, fill it.
+
+ int numBytesRead = mrSource.Read(mBuffer, sizeof(mBuffer),
+ Timeout);
+
+ if (numBytesRead < 0)
+ {
+ return numBytesRead;
+ }
+
+ mBufferSize = numBytesRead;
+ }
+
+ int sizeToReturn = mBufferSize - mBufferPosition;
+
+ if (sizeToReturn > NBytes)
+ {
+ sizeToReturn = NBytes;
+ }
+
+ memcpy(pBuffer, mBuffer + mBufferPosition, sizeToReturn);
+ mBufferPosition += sizeToReturn;
+
+ if (mBufferPosition == mBufferSize)
+ {
+ // clear out the buffer
+ mBufferSize = 0;
+ mBufferPosition = 0;
+ }
+
+ return sizeToReturn;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::BytesLeftToRead()
+// Purpose: Returns number of bytes to read (may not be most efficient function ever)
+// Created: 2007/01/16
+//
+// --------------------------------------------------------------------------
+IOStream::pos_type BufferedStream::BytesLeftToRead()
+{
+ return mrSource.BytesLeftToRead() + mBufferSize - mBufferPosition;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::Write(void *, int)
+// Purpose: Writes bytes to the underlying stream (not supported)
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void BufferedStream::Write(const void *pBuffer, int NBytes)
+{
+ THROW_EXCEPTION(CommonException, NotSupported);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::GetPosition()
+// Purpose: Get position in stream
+// Created: 2003/08/21
+//
+// --------------------------------------------------------------------------
+IOStream::pos_type BufferedStream::GetPosition() const
+{
+ return mrSource.GetPosition() - mBufferSize + mBufferPosition;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::Seek(pos_type, int)
+// Purpose: Seeks within file, as lseek, invalidate buffer
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void BufferedStream::Seek(IOStream::pos_type Offset, int SeekType)
+{
+ switch (SeekType)
+ {
+ case SeekType_Absolute:
+ {
+ // just go there
+ mrSource.Seek(Offset, SeekType);
+ }
+ break;
+
+ case SeekType_Relative:
+ {
+ // Actual underlying file position is
+ // (mBufferSize - mBufferPosition) ahead of us.
+ // Need to subtract that amount from the seek
+ // to seek forward that much less, putting the
+ // real pointer in the right place.
+ mrSource.Seek(Offset - mBufferSize + mBufferPosition,
+ SeekType);
+ }
+ break;
+
+ case SeekType_End:
+ {
+ // Actual underlying file position is
+ // (mBufferSize - mBufferPosition) ahead of us.
+ // Need to add that amount to the seek
+ // to seek backwards that much more, putting the
+ // real pointer in the right place.
+ mrSource.Seek(Offset + mBufferSize - mBufferPosition,
+ SeekType);
+ }
+ }
+
+ // always clear the buffer for now (may be slightly wasteful)
+ mBufferSize = 0;
+ mBufferPosition = 0;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::Close()
+// Purpose: Closes the underlying stream (not needed)
+// Created: 2003/07/31
+//
+// --------------------------------------------------------------------------
+void BufferedStream::Close()
+{
+ THROW_EXCEPTION(CommonException, NotSupported);
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::StreamDataLeft()
+// Purpose: Any data left to write?
+// Created: 2003/08/02
+//
+// --------------------------------------------------------------------------
+bool BufferedStream::StreamDataLeft()
+{
+ return mrSource.StreamDataLeft();
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+// Name: BufferedStream::StreamClosed()
+// Purpose: Is the stream closed?
+// Created: 2003/08/02
+//
+// --------------------------------------------------------------------------
+bool BufferedStream::StreamClosed()
+{
+ return mrSource.StreamClosed();
+}
+