libclod
C library for interacting with NBTs, region files, LOD data and other things.
Loading...
Searching...
No Matches
string.c
1#include "config.h"
2#include "debug.h"
3#include <clod/string.h>
4
5struct clod_string clod_string_from_cstr(const char *cstr) {
6 if (!cstr) return CLOD_STRING_NULL;
7
8 struct clod_string str = {
9 .ptr = (char*)cstr,
10 .len = 0,
11 .cap = 0
12 };
13
14 while (cstr[str.len] != '\0') str.len++;
15 return str;
16}
17size_t clod_string_cat(struct clod_string *dst, const struct clod_string src) {
18 if (dst->ptr == nullptr || dst->cap == 0 || src.ptr == nullptr) {
19 return 0;
20 }
21
22 ptrdiff_t size = dst->cap - dst->len;
23 if (size > src.len) {
24 size = src.len;
25 }
26
27 if (size < 0) {
28 return 0;
29 }
30
31 if (src.ptr > dst->ptr && src.ptr < dst->ptr + size) {
32 for (ptrdiff_t i = size - 1; i >= 0; i--) {
33 dst->ptr[i + dst->len] = src.ptr[i];
34 }
35 } else {
36 for (ptrdiff_t i = 0; i < size; i++) {
37 dst->ptr[i + dst->len] = src.ptr[i];
38 }
39 }
40
41 dst->len += size;
42 return (size_t)size;
43}
44size_t clod_string_insert(struct clod_string *dst, struct clod_string src) {
45 if (dst->ptr == nullptr || dst->cap == 0 || src.ptr == nullptr) {
46 return 0;
47 }
48
49 ptrdiff_t size = src.len < dst->cap ? src.len : dst->cap;
50
51 if (size < 0) {
52 return 0;
53 }
54
56 &(struct clod_string){
57 .ptr = dst->ptr,
58 .len = size,
59 .cap = dst->cap
60 },
61 *dst
62 );
63
64 dst->len += (ptrdiff_t)clod_string_cat(
65 &(struct clod_string){
66 .ptr = dst->ptr,
67 .len = 0,
68 .cap = size
69 },
70 src
71 );
72
73 return (size_t)size;
74}
75int clod_string_cmp(const struct clod_string str1, const struct clod_string str2) {
76 if (str1.len > str2.len) return 1;
77 if (str2.len > str1.len) return -1;
78 if (str1.ptr == str2.ptr) return 0;
79
80 for (ptrdiff_t i = 0; i < str1.len; i++) {
81 if (str1.ptr[i] > str2.ptr[i]) return 1;
82 if (str2.ptr[i] > str1.ptr[i]) return -1;
83 }
84
85 return 0;
86}
87void clod_string_put_char(struct clod_string *str, const char c) {
88 if (str->ptr && str->cap > str->len) {
89 str->ptr[str->len] = c;
90 str->len++;
91 }
92}
94 if (str->ptr && str->len > 0) {
95 char c = str->ptr[0];
96 str->ptr++;
97 str->len--;
98 if (str->cap > 0) str->cap--;
99 return c;
100 }
101 return 0;
102}
103char clod_string_peek_char(const struct clod_string str) {
104 if (str.ptr && str.len > 0) {
105 return str.ptr[0];
106 }
107 return 0;
108}
109bool clod_string_remove_prefix(struct clod_string *str, const struct clod_string prefix) {
110 if (!str->ptr) return false;
111 if (!prefix.ptr) return true;
112
113 if (str->len < prefix.len) return false;
114 for (ptrdiff_t i = 0; i < prefix.len; i++)
115 if (str->ptr[i] != prefix.ptr[i])
116 return false;
117
118 str->ptr += prefix.len;
119 str->len -= prefix.len;
120 str->cap -= prefix.len;
121 return true;
122}
123struct clod_string clod_string_contains(struct clod_string str, const struct clod_string elem) {
124 if (str.ptr == nullptr) return CLOD_STRING_NULL;
125 if (elem.len == 0) {
126 return (struct clod_string){
127 .ptr = str.ptr,
128 .len = 0,
129 .cap = str.cap
130 };
131 }
132
133 while (str.len >= elem.len) {
134 ptrdiff_t i = 0;
135 while (i < elem.len && str.ptr[i] == elem.ptr[i]) i++;
136 if (i == elem.len) {
137 return str;
138 }
139
140 str.ptr++;
141 str.len--;
142 str.cap--;
143 }
144
145 return CLOD_STRING_NULL;
146}
147struct clod_string clod_string_find(const struct clod_string str, const char elem, int occurrence) {
148 if (occurrence > 0) {
149 for (ptrdiff_t i = 0; i < str.len; i++) {
150 if (str.ptr[i] == elem) occurrence--;
151 if (occurrence == 0) return (struct clod_string){str.ptr + i, str.len - i, str.cap - i};
152 }
153 return CLOD_STRING_NULL;
154 }
155
156 if (occurrence < 0) {
157 for (ptrdiff_t i = str.len; i > 0; i--) {
158 if (str.ptr[i - 1] == elem) occurrence++;
159 if (occurrence == 0) return (struct clod_string){str.ptr + i - 1, str.len - i + 1, str.cap - i + 1};
160 }
161 return CLOD_STRING_NULL;
162 }
163
164 // occurrence == 0
165 return str;
166}
167
168size_t clod_string_put_double(struct clod_string *, double,
169 struct clod_string, unsigned char, unsigned char, unsigned char) {
170 debug(CLOD_TEST, "Not Implemented");
171 return 0;
172}
173
175 struct clod_string, unsigned char) {
176 debug(CLOD_TEST, "Not Implemented");
177 return 0;
178}
Sized string helpers.
CLOD_API bool clod_string_remove_prefix(struct clod_string *str, struct clod_string prefix)
Definition string.c:109
#define CLOD_STRING_NULL
Null string.
Definition string.h:40
size_t clod_string_cat(struct clod_string *dst, struct clod_string src)
Definition string.c:17
CLOD_API struct clod_string clod_string_find(struct clod_string str, char elem, int occurrence)
Definition string.c:147
CLOD_API struct clod_string clod_string_contains(struct clod_string str, struct clod_string elem)
Definition string.c:123
CLOD_API size_t clod_string_put_double(struct clod_string *dst, double val, struct clod_string alphabet, unsigned char base, unsigned char min_digits, unsigned char max_digits)
Definition string.c:168
struct clod_string clod_string_from_cstr(const char *cstr)
Make a string from a C string.
Definition string.c:5
char clod_string_get_char(struct clod_string *str)
Remove a single char from the start of the string.
Definition string.c:93
CLOD_API double clod_string_get_double(struct clod_string *str, struct clod_string alphabet, unsigned char base)
Definition string.c:174
int clod_string_cmp(struct clod_string str1, struct clod_string str2)
Definition string.c:75
char clod_string_peek_char(struct clod_string str)
Get the first char in the string.
Definition string.c:103
void clod_string_put_char(struct clod_string *str, char c)
Append a single char to the end of the string.
Definition string.c:87
size_t clod_string_insert(struct clod_string *dst, struct clod_string src)
Definition string.c:44
char * ptr
Definition string.h:28
ptrdiff_t len
Definition string.h:32
ptrdiff_t cap
Definition string.h:36