diff options
Diffstat (limited to 'generic/Buffer.cpp')
-rw-r--r-- | generic/Buffer.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/generic/Buffer.cpp b/generic/Buffer.cpp new file mode 100644 index 0000000..edd70bc --- /dev/null +++ b/generic/Buffer.cpp @@ -0,0 +1,106 @@ +#include <string.h> +#include "Buffer.h" +#include "General.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +#endif + +Buffer::Buffer() : Handle(-1), buffer(0), zero(0), realsiz(0), bufsiz(0), ptr(0) { } + +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); + memcpy(buffer, b.buffer, bufsiz); +} + +ssize_t Buffer::write(const void *buf, size_t count) throw (GeneralException) { + if (!count) { + return 0; + } + 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)); + } + memcpy(buffer + realsiz, buf, count); + realsiz += count; + + return count; +} + +ssize_t Buffer::read(void *buf, size_t count) throw (GeneralException) { + count = MIN(count, realsiz - ptr); + + if (!count) { + return 0; + } + + 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)); + } + + return count; +} + +bool Buffer::CanRead() { + return true; +} + +bool Buffer::CanWrite() { + return true; +} + +String Buffer::GetName() { + return "Buffer"; +} + +Buffer Buffer::operator=(const Buffer & b) { + if (b.buffer != buffer) { + free(buffer); + realsiz = b.realsiz; + ptr = b.ptr; + if ((bufsiz = b.bufsiz)) { + buffer = (char *) malloc(bufsiz); + memcpy(buffer, b.buffer, realsiz); + } else { + buffer = 0; + } + } + return *this; +} + +bool Buffer::CanWatch() { + return false; +} + +ssize_t Buffer::GetSize() { + return realsiz; +} + +char Buffer::operator[](size_t p) const { + if (p >= realsiz) { + return 0; + } else { + return buffer[ptr + p]; + } +} + +char & Buffer::operator[](size_t p) { + if (p >= realsiz) { + return zero; + } else { + return buffer[ptr + p]; + } +} |