esc
Externally Scriptable Editor
git clone git://mccd.space/esc
| Log | Files | Refs | README |
strbuf.c (1771B)
1 #include "strbuf.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 void strbuf_init(StrBuf *sb, size_t init_cap) {
7 sb->cap = init_cap > 0 ? init_cap : 1024;
8 sb->data = malloc(sb->cap);
9 if (sb->data) sb->data[0] = '\0';
10 sb->len = 0;
11 }
12
13 void strbuf_free(StrBuf *sb) {
14 free(sb->data);
15 sb->data = NULL;
16 sb->len = 0;
17 sb->cap = 0;
18 }
19
20 static bool strbuf_ensure_cap(StrBuf *sb, size_t req_cap) {
21 if (req_cap <= sb->cap) return true;
22 size_t new_cap = sb->cap * 2;
23 while (new_cap < req_cap) new_cap *= 2;
24
25 char *new_data = realloc(sb->data, new_cap);
26 if (!new_data) return false;
27
28 sb->data = new_data;
29 sb->cap = new_cap;
30 return true;
31 }
32
33 bool strbuf_insert(StrBuf *sb, size_t pos, const char *text, size_t text_len) {
34 if (pos > sb->len) pos = sb->len;
35 if (!strbuf_ensure_cap(sb, sb->len + text_len + 1)) return false;
36
37 memmove(sb->data + pos + text_len, sb->data + pos, sb->len - pos + 1);
38 memcpy(sb->data + pos, text, text_len);
39 sb->len += text_len;
40 return true;
41 }
42
43 void strbuf_delete(StrBuf *sb, size_t pos, size_t len) {
44 if (pos >= sb->len) return;
45 if (pos + len > sb->len) len = sb->len - pos;
46
47 memmove(sb->data + pos, sb->data + pos + len, sb->len - pos - len + 1);
48 sb->len -= len;
49 }
50
51 bool strbuf_read_file(StrBuf *sb, const char *filename) {
52 FILE *f = fopen(filename, "rb");
53 if (!f) return false;
54
55 fseek(f, 0, SEEK_END);
56 size_t size = ftell(f);
57 fseek(f, 0, SEEK_SET);
58
59 if (!strbuf_ensure_cap(sb, size + 1)) {
60 fclose(f);
61 return false;
62 }
63 fread(sb->data, 1, size, f);
64 sb->data[size] = '\0';
65 sb->len = size;
66 fclose(f);
67 return true;
68 }
69
70 bool strbuf_write_file(const StrBuf *sb, const char *filename) {
71 FILE *f = fopen(filename, "wb");
72 if (!f) return false;
73 fwrite(sb->data, 1, sb->len, f);
74 fclose(f);
75 return true;
76 }