#include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "Buffer.h" #include "generic.h" #include "gettext.h" 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() const { return true; } bool Buffer::CanWrite() const { return true; } String Buffer::GetName() const { 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() const { return false; } ssize_t Buffer::GetSize() const { 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]; } }