File: cstring.c

package info (click to toggle)
libqb 2.0.8-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 4,044 kB
  • sloc: ansic: 22,157; sh: 4,728; makefile: 607
file content (131 lines) | stat: -rw-r--r-- 2,572 bytes parent folder | download | duplicates (6)
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
/* A really basic expanding/appendable string type */

#include <stdlib.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include "cstring.h"

#define INITIAL_SIZE 1024
#define INCREMENT    1024
#define CHECKER_WORD 0xbcd6712a

struct cstring_header
{
	size_t checker;
	size_t allocated;
	size_t used;
	char the_string[];
};

cstring_t cstring_alloc(void)
{
	char *cstring = malloc(INITIAL_SIZE);
	if (cstring) {
		struct cstring_header *h = (struct cstring_header *)cstring;
		h->checker = CHECKER_WORD;
		h->allocated = INITIAL_SIZE;
		h->used = 0;
		h->the_string[0] = '\0';
		return cstring;
	} else {
		return NULL;
	}
}

char *cstring_to_chars(cstring_t cstring)
{
	struct cstring_header *h = (struct cstring_header *)cstring;

	if (!h) {
		return NULL;
	}

	assert(h->checker == CHECKER_WORD);
	return strdup(h->the_string);
}

size_t cstring_len(cstring_t cstring)
{
	struct cstring_header *h = (struct cstring_header *)cstring;

	if (!h) {
		return 0;
	}

	assert(h->checker == CHECKER_WORD);
	return h->used;
}


cstring_t cstring_append_chars(cstring_t cstring, const char *newstring)
{
	struct cstring_header *h = (struct cstring_header *)cstring;
	size_t newlen;

	if (!h) {
		return NULL;
	}

	assert(h->checker == CHECKER_WORD);
	if (!newstring) {
		return NULL;
	}

	newlen = h->used + strlen(newstring)+1 + sizeof(struct cstring_header);
	if (newlen > h->allocated) {
		size_t new_allocsize = (newlen + 2048) & 0xFFFFFC00;
		char *tmp = realloc(cstring, new_allocsize);
		if (!tmp) {
			return cstring;
		}

		cstring = tmp;
		h = (struct cstring_header *)cstring;
		h->allocated = new_allocsize;
	}
	strncat(h->the_string, newstring, h->allocated - h->used -1);
	h->used += strlen(newstring);
	return cstring;
}

cstring_t cstring_append_cstring(cstring_t cstring, cstring_t newstring)
{
	/* Just check the newstring - cstring_append_chars() will check the target */
	struct cstring_header *h = (struct cstring_header *)newstring;

	if (!h) {
		return NULL;
	}

	assert(h->checker == CHECKER_WORD);
	return cstring_append_chars(cstring, h->the_string);
}

cstring_t cstring_from_chars(const char* chars)
{
	cstring_t new_string = cstring_alloc();
	if (!new_string) {
		return NULL;
	}
	return cstring_append_chars(new_string, chars);
}

void cstring_free(cstring_t cstring)
{
	struct cstring_header *h = (struct cstring_header *)cstring;

	if (!h) {
		return;
	}
	assert(h->checker == CHECKER_WORD);
	free(cstring);
}