summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Buffer.h12
-rw-r--r--lib/Buffer.cc78
2 files changed, 69 insertions, 21 deletions
diff --git a/include/Buffer.h b/include/Buffer.h
index 316af13..8996b2d 100644
--- a/include/Buffer.h
+++ b/include/Buffer.h
@@ -11,7 +11,7 @@
class Buffer : public Handle {
public:
- Buffer();
+ Buffer(bool seekable = false);
Buffer(const Buffer &);
virtual ~Buffer();
virtual ssize_t write(const void *buf, size_t count) throw(GeneralException);
@@ -22,12 +22,16 @@ class Buffer : public Handle {
virtual Buffer operator=(const Buffer &);
virtual bool CanWatch() const;
virtual ssize_t GetSize() const;
- char operator[](size_t) const;
- char & operator[](size_t);
+ virtual bool CanSeek() const;
+ virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
+ virtual off_t tell() const;
+ Byte operator[](size_t) const;
+ Byte & operator[](size_t);
private:
- char * buffer, zero;
+ Byte * buffer, zero;
size_t realsiz, bufsiz, ptr;
+ bool seekable;
};
#endif
diff --git a/lib/Buffer.cc b/lib/Buffer.cc
index db8b3ee..d0e5af2 100644
--- a/lib/Buffer.cc
+++ b/lib/Buffer.cc
@@ -5,14 +5,14 @@
#include "Buffer.h"
#include "generic.h"
-Buffer::Buffer() : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0) { }
+Buffer::Buffer(bool _seekable) : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0), seekable(_seekable) { }
Buffer::~Buffer() {
free(buffer);
}
-Buffer::Buffer(const Buffer & b) : Handle(-1), buffer(0), zero(b.zero), realsiz(b.realsiz), bufsiz(b.bufsiz), ptr(b.ptr) {
- buffer = (char *) malloc(bufsiz);
+Buffer::Buffer(const Buffer & b) : Handle(-1), buffer(0), zero(b.zero), realsiz(b.realsiz), bufsiz(b.bufsiz), ptr(b.ptr), seekable(b.seekable) {
+ buffer = (Byte *) malloc(bufsiz);
memcpy(buffer, b.buffer, bufsiz);
}
@@ -23,7 +23,7 @@ ssize_t Buffer::write(const void *buf, size_t count) throw (GeneralException) {
if (count + realsiz > bufsiz) {
int numblocks = (count + realsiz) / realloc_threshold;
int remains = (count + realsiz) % realloc_threshold;
- buffer = (char *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
+ buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
}
memcpy(buffer + realsiz, buf, count);
realsiz += count;
@@ -40,13 +40,15 @@ ssize_t Buffer::read(void *buf, size_t count) throw (GeneralException) {
memcpy(buf, buffer + ptr, count);
ptr += count;
-
- if (ptr >= realloc_threshold) {
- int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold);
- memmove(buffer, buffer + (bufsiz - numblocks * realloc_threshold), numblocks * realloc_threshold);
- ptr -= (bufsiz - numblocks * realloc_threshold);
- realsiz -= (bufsiz - numblocks * realloc_threshold);
- buffer = (char *) realloc(buffer, bufsiz = (numblocks * realloc_threshold));
+
+ if (!seekable) {
+ if (ptr >= realloc_threshold) {
+ int numblocks = (bufsiz / realloc_threshold) - (ptr / realloc_threshold);
+ memmove(buffer, buffer + (bufsiz - numblocks * realloc_threshold), numblocks * realloc_threshold);
+ ptr -= (bufsiz - numblocks * realloc_threshold);
+ realsiz -= (bufsiz - numblocks * realloc_threshold);
+ buffer = (Byte *) realloc(buffer, bufsiz = (numblocks * realloc_threshold));
+ }
}
return count;
@@ -69,8 +71,9 @@ Buffer Buffer::operator=(const Buffer & b) {
free(buffer);
realsiz = b.realsiz;
ptr = b.ptr;
+ seekable = b.seekable;
if ((bufsiz = b.bufsiz)) {
- buffer = (char *) malloc(bufsiz);
+ buffer = (Byte *) malloc(bufsiz);
memcpy(buffer, b.buffer, realsiz);
} else {
buffer = 0;
@@ -87,18 +90,59 @@ ssize_t Buffer::GetSize() const {
return realsiz;
}
-char Buffer::operator[](size_t p) const {
+Byte Buffer::operator[](size_t p) const {
if (p >= realsiz) {
return 0;
} else {
- return buffer[ptr + p];
+ if (seekable) {
+ return buffer[p];
+ } else {
+ return buffer[ptr + p];
+ }
}
}
-char & Buffer::operator[](size_t p) {
+Byte & Buffer::operator[](size_t p) {
+ if (p > bufsiz) {
+ int numblocks = p / realloc_threshold;
+ int remains = p % realloc_threshold;
+ buffer = (Byte *) realloc(buffer, bufsiz = ((numblocks + (remains ? 1 : 0)) * realloc_threshold));
+ }
if (p >= realsiz) {
- return zero;
+ memset(buffer + realsiz, 0, p - realsiz);
+ realsiz = p;
+ }
+
+ if (seekable) {
+ return buffer[p];
} else {
- return buffer[ptr + p];
+ return buffer[ptr + p];
}
}
+
+bool Buffer::CanSeek() const {
+ return seekable;
+}
+
+off_t Buffer::seek(off_t off, int wheel) throw (GeneralException) {
+ if (!seekable) {
+ throw GeneralException("This buffer is a fifo, thus is not seekable");
+ }
+ switch (wheel) {
+ case SEEK_SET:
+ ptr = off;
+ break;
+ case SEEK_CUR:
+ ptr += off;
+ break;
+ case SEEK_END:
+ ptr = realsiz + off;
+ break;
+ }
+ operator[](ptr) = operator[](ptr);
+ return ptr;
+}
+
+off_t Buffer::tell() const {
+ return ptr;
+}