append data at limit, not at position
[ecparse.git] / GrowingBuffer.cpp
1 /**
2  * © 2008 by David ‘Bombe’ Roden <bombe@pterodactylus.net>
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stddef.h>
8 #include "GrowingBuffer.h"
9
10 GrowingBuffer::GrowingBuffer(size_t initialSize) {
11         this->data = malloc(1024);
12         this->size = 1024;
13         this->limit = 0;
14         this->position = 0;
15 }
16
17 GrowingBuffer::~GrowingBuffer() {
18         if (this->data) {
19                 free(this->data);
20         }
21 }
22
23 size_t GrowingBuffer::getPosition() {
24         return position;
25 }
26
27 size_t GrowingBuffer::getLimit() {
28         return limit;
29 }
30
31 size_t GrowingBuffer::getSize() {
32         return size;
33 }
34
35 void GrowingBuffer::seek(size_t position) {
36         this->position = (position > limit) ? limit : position;
37 }
38
39 void* GrowingBuffer::read(void* buffer, size_t length) {
40         size_t bytesToCopy = (length > (limit - position)) ? (limit - position) : length;
41         memcpy(buffer, (ptrdiff_t*) data + position, bytesToCopy);
42         position += bytesToCopy;
43         return buffer;
44 }
45
46 void GrowingBuffer::write(const void* buffer, size_t length) {
47         if (length > (size - limit)) {
48                 int newSize = size;
49                 do {
50                         newSize *= 2;
51                 } while (length > (newSize - limit));
52                 void* newData = malloc(newSize);
53                 memcpy(newData, data, position);
54                 free(data);
55                 data = newData;
56         }
57         memcpy((ptrdiff_t*) data + limit, buffer, length);
58         limit += length;
59 }
60
61 void GrowingBuffer::cut() {
62         memcpy(data, (ptrdiff_t*) data + position, position);
63         limit = position;
64         position = 0;
65 }
66
67 void GrowingBuffer::truncate() {
68         limit = position;
69 }
70
71 void GrowingBuffer::clear() {
72         position = 0;
73         limit = 0;
74 }
75
76 void GrowingBuffer::resize(double factor) {
77         if (factor < 1.0) {
78                 factor = 1.0;
79         }
80         if (size != (limit * factor)) {
81                 void* newData = malloc((size_t) (limit * factor));
82                 memcpy(newData, data, limit);
83                 free(data);
84                 data = newData;
85         }
86 }
87