diff options
Diffstat (limited to 'lib/Buffer.cc')
-rw-r--r-- | lib/Buffer.cc | 78 |
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; +} |