summaryrefslogtreecommitdiff
path: root/generic/Buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'generic/Buffer.cpp')
-rw-r--r--generic/Buffer.cpp106
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];
+ }
+}