summaryrefslogtreecommitdiff
path: root/lib/Buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Buffer.cc')
-rw-r--r--lib/Buffer.cc78
1 files changed, 61 insertions, 17 deletions
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;
+}