esc

Externally Scriptable Editor

git clone git://mccd.space/esc

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 }