Browse code

Store read buffer on choices structure

This would allow reading from multiple files (which we don't need) as
well as allowing us to free the buffer with the rest of the choices
structure (which is nice).

John Hawthorn authored on 01/05/2016 00:28:55
Showing 2 changed files

... ...
@@ -6,7 +6,7 @@
6 6
 #include "match.h"
7 7
 
8 8
 /* Initial size of buffer for storing input in memory */
9
-#define INITIAL_BUFFER_SIZE     4096
9
+#define INITIAL_BUFFER_CAPACITY 4096
10 10
 
11 11
 /* Initial size of choices array */
12 12
 #define INITIAL_CHOICE_CAPACITY 128
... ...
@@ -34,23 +34,32 @@ static void *safe_realloc(void *buffer, size_t size) {
34 34
 }
35 35
 
36 36
 void choices_fread(choices_t *c, FILE *file) {
37
-	size_t bufsize = INITIAL_BUFFER_SIZE, pos = 0;
38
-	char *buf = safe_realloc(NULL, bufsize);
37
+	/* Save current position for parsing later */
38
+	size_t buffer_start = c->buffer_size;
39
+
40
+	/* Resize buffer to at least one byte more capacity than our current
41
+	 * size. This uses a power of two of INITIAL_BUFFER_CAPACITY.
42
+	 * This must work even when c->buffer is NULL and c->buffer_size is 0
43
+	 */
44
+	size_t capacity = INITIAL_BUFFER_CAPACITY;
45
+	while (capacity <= c->buffer_size)
46
+		capacity *= 2;
47
+	c->buffer = safe_realloc(c->buffer, capacity);
39 48
 
40 49
 	/* Continue reading until we get a "short" read, indicating EOF */
41
-	while ((pos += fread(buf + pos, 1, bufsize - pos, file)) == bufsize) {
42
-		bufsize *= 2;
43
-		buf = safe_realloc(buf, bufsize);
50
+	while ((c->buffer_size += fread(c->buffer + c->buffer_size, 1, capacity - c->buffer_size, file)) == capacity) {
51
+		capacity *= 2;
52
+		c->buffer = safe_realloc(c->buffer, capacity);
44 53
 	}
45
-	buf[pos] = 0;
54
+	c->buffer = safe_realloc(c->buffer, c->buffer_size + 1);
55
+	c->buffer[c->buffer_size++] = 0;
46 56
 
47 57
 	/* Truncate buffer to used size, (maybe) freeing some memory for
48 58
 	 * future allocations.
49 59
 	 */
50
-	buf = safe_realloc(buf, pos + 1);
51 60
 
52 61
 	/* Tokenize input and add to choices */
53
-	char *line = buf;
62
+	char *line = c->buffer + buffer_start;
54 63
 	do {
55 64
 		char *nl = strchr(line, '\n');
56 65
 		if (nl)
... ...
@@ -78,14 +87,28 @@ static void choices_reset_search(choices_t *c) {
78 87
 void choices_init(choices_t *c) {
79 88
 	c->strings = NULL;
80 89
 	c->results = NULL;
90
+
91
+	c->buffer_size = 0;
92
+	c->buffer = NULL;
93
+
81 94
 	c->capacity = c->size = 0;
82
-	choices_reset_search(c);
83 95
 	choices_resize(c, INITIAL_CHOICE_CAPACITY);
96
+
97
+	choices_reset_search(c);
84 98
 }
85 99
 
86 100
 void choices_free(choices_t *c) {
101
+	free(c->buffer);
102
+	c->buffer = NULL;
103
+	c->buffer_size = 0;
104
+
87 105
 	free(c->strings);
106
+	c->strings = NULL;
107
+	c->capacity = c->size = 0;
108
+
88 109
 	free(c->results);
110
+	c->results = NULL;
111
+	c->available = c->selection = 0;
89 112
 }
90 113
 
91 114
 void choices_add(choices_t *c, const char *choice) {
... ...
@@ -9,6 +9,9 @@ struct scored_result {
9 9
 };
10 10
 
11 11
 typedef struct {
12
+	char *buffer;
13
+	size_t buffer_size;
14
+
12 15
 	size_t capacity;
13 16
 	size_t size;
14 17