File: strbuild.c

package info (click to toggle)
libsfdo 0.1.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 740 kB
  • sloc: ansic: 6,491; python: 111; makefile: 4
file content (55 lines) | stat: -rw-r--r-- 1,308 bytes parent folder | download
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
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "common/strbuild.h"

void sfdo_strbuild_init(struct sfdo_strbuild *strbuild) {
	strbuild->data = NULL;
	strbuild->len = strbuild->cap = 0;
}

void sfdo_strbuild_finish(struct sfdo_strbuild *strbuild) {
	free(strbuild->data);
}

void sfdo_strbuild_reset(struct sfdo_strbuild *strbuild) {
	strbuild->len = 0;
}

bool sfdo_strbuild_add(
		struct sfdo_strbuild *strbuild, const struct sfdo_string *items, size_t n_items) {
	size_t total_len = 0;
	for (size_t i = 0; i < n_items; i++) {
		const struct sfdo_string *item = &items[i];
		total_len += item->len;
	}

	size_t cap = strbuild->cap == 0 ? 4096 : strbuild->cap;
	// end must be strictly bigger than cap to have space for a null terminator
	size_t end = strbuild->len + total_len;
	while (end >= cap) {
		if (cap > SIZE_MAX / 2) {
			return false;
		}
		cap *= 2;
	}
	if (strbuild->cap != cap) {
		char *pb_data = realloc(strbuild->data, cap);
		if (pb_data == NULL) {
			return false;
		}
		strbuild->data = pb_data;
		strbuild->cap = cap;
	}

	for (size_t i = 0; i < n_items; i++) {
		const struct sfdo_string *item = &items[i];
		memcpy(&strbuild->data[strbuild->len], item->data, item->len);
		strbuild->len += item->len;
	}

	strbuild->data[strbuild->len] = '\0';

	return true;
}