-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBuffer.C
134 lines (102 loc) · 3.69 KB
/
Buffer.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* File generated by the BNF Converter (bnfc 2.9.4). */
/* A dynamically allocated character buffer that grows as it is appended. */
#include <assert.h> /* assert */
#include <stdlib.h> /* free, malloc */
#include <stdio.h> /* fprintf */
#include <string.h> /* size_t, strncpy */
#include "Buffer.H"
/* Internal functions. */
/************************************************************************/
/* Make sure the buffer can hold `n` more characters. */
static void bufferAllocateChars (Buffer buffer, const unsigned int n);
/* Increase the buffer size to the new `buffer->size`. */
static void resizeBuffer(Buffer buffer);
/* External interface. */
/************************************************************************/
/* Create a new buffer of the given size. */
Buffer newBuffer (const unsigned int size) {
/* The buffer cannot be of size 0. */
assert (size >= 1);
/* Allocate and initialize a new Buffer structure. */
Buffer buffer = (Buffer) malloc(sizeof(struct buffer));
buffer->size = size;
buffer->current = 0;
buffer->chars = NULL;
resizeBuffer(buffer);
buffer->chars[0] = 0;
return buffer;
}
/* Deallocate the buffer and its content. */
void freeBuffer (Buffer buffer) {
free(buffer->chars);
free(buffer);
}
/* Deallocate the buffer, but return its content as string. */
char* releaseBuffer (Buffer buffer) {
char* content = (char*) realloc (buffer->chars, buffer->current + 1);
free(buffer);
return content;
}
/* Clear contents of buffer. */
void resetBuffer (Buffer buffer) {
buffer->current = 0;
buffer->chars[buffer->current] = 0;
}
/* Append string at the end of the buffer. */
void bufferAppendString (Buffer buffer, const char *s)
{
/* Nothing to do if s is the empty string. */
size_t len = strlen(s);
if (len) {
/* Make sure the buffer can hold all of s. */
bufferAllocateChars(buffer, len);
/* Append s at the end of the buffer, including terminating 0. */
strncpy(buffer->chars + buffer->current, s, len + 1);
buffer->current += len;
}
}
/* Append single character at the end of the buffer. */
void bufferAppendChar (Buffer buffer, const char c)
{
/* Make sure the buffer can hold one more character and append it. */
bufferAllocateChars(buffer, 1);
buffer->chars[buffer->current] = c;
/* Terminate with 0. */
buffer->current++;
buffer->chars[buffer->current] = 0;
}
/* Give read-only access to the buffer content.
Does not survive the destruction of the buffer object. */
const char* bufferContent (Buffer buffer) {
return buffer->chars;
}
/* Internal functions. */
/************************************************************************/
/* Make sure the buffer can hold `n` more characters. */
static void bufferAllocateChars (Buffer buffer, const unsigned int n) {
/* 1 extra char for terminating 0. */
unsigned int requiredSize = buffer->current + 1 + n;
if (buffer->size < requiredSize)
{
do buffer->size *= 2; /* Double the buffer size */
while (buffer->size < requiredSize);
resizeBuffer(buffer);
}
}
/* Increase the buffer size to the new `size`. */
static void resizeBuffer(Buffer buffer)
{
/* The new size needs to be strictly greater than the currently
* used part, otherwise writing to position buffer->current will
* be out of bounds.
*/
assert(buffer->size > buffer->current);
/* Resize (or, the first time allocate) the buffer. */
buffer->chars = (char*) realloc(buffer->chars, buffer->size);
/* Crash if out-of-memory. */
if (! buffer->chars)
{
fprintf(stderr, "Buffer.c: Error: Out of memory while attempting to grow buffer!\n");
exit(1); /* This seems to be the right exit code for out-of-memory. 137 is only when the OS kills us. */
}
}