aboutsummaryrefslogtreecommitdiff
path: root/src/un_strings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/un_strings.c')
-rw-r--r--src/un_strings.c381
1 files changed, 381 insertions, 0 deletions
diff --git a/src/un_strings.c b/src/un_strings.c
new file mode 100644
index 0000000..1499726
--- /dev/null
+++ b/src/un_strings.c
@@ -0,0 +1,381 @@
+u64 un_string_get_length(u8 *cstring) {
+ u8* start = cstring;
+
+ while (*start != '\0') {
+ start++;
+ }
+
+ return start - cstring;
+}
+
+String un_string_from_cstring(u8* cstring) {
+ String result;
+ u64 length = un_string_get_length(cstring);
+ assert(length < LLONG_MAX);
+ result.size = length;
+ result.data = cstring;
+ return result;
+}
+
+u8* un_string_to_cstring(String string, Allocator alloc) {
+ u8 *mem;
+
+ assert(string.size > 0);
+
+ mem = (u8*)un_memory_alloc(string.size + 1, alloc);
+ un_memory_copy(mem, string.data, (u64)string.size);
+
+ return mem;
+}
+
+String un_string_copy(String source, Allocator alloc) {
+ u8 *mem;
+ String result;
+
+ assert(source.size >= 0);
+
+ mem = (u8*)un_memory_alloc(source.size, alloc);
+ un_memory_copy(mem, source.data, (u64)source.size);
+
+ result.size = source.size;
+ result.data = mem;
+
+ return result;
+}
+
+s32 un_string_compare(String left, String right) {
+ s32 result;
+
+ if (left.size == right.size && left.size == 0) return 0;
+ if (left.size == 0) return -1;
+ if (right.size == 0) return 1;
+
+ result = un_memory_compare(left.data, right.data, left.size);
+
+ if (result == 0) {
+ if (left.size > right.size) return 1;
+ if (left.size < right.size) return -1;
+ return 0;
+ } else {
+ return result;
+ }
+}
+
+String un_string_concat(String left, String right, Allocator alloc) {
+ String result = { 0 };
+
+ assert(left.size >= 0 && right.size >= 0);
+
+ if (left.size == right.size && left.size == 0) {
+ return result;
+ }
+
+ u8* data = (u8*)un_memory_alloc(left.size + right.size, alloc);
+
+ if (left.size > 0) {
+ assert(left.data != NULL);
+ un_memory_copy(data, left.data, left.size);
+ }
+
+ if (right.size > 0) {
+ assert(right.data != NULL);
+ un_memory_copy((data + left.size), right.data, right.size);
+ }
+
+ result.size = left.size + right.size;
+ result.data = data;
+
+ return result;
+}
+
+String un_string_swap(String input, u8 from, u8 to, Allocator alloc) {
+ s64 i;
+ String output;
+
+ output = un_string_copy(input, alloc);
+
+ for (i = 0; i < input.size; i++) {
+ if (output.data[i] != from)
+ continue;
+
+ output.data[i] = to;
+ }
+
+ return output;
+}
+
+List un_string_split(String input, String pattern, Allocator alloc) {
+ List splits;
+ String string;
+ s64 i, start;
+ u64 matches, size;
+ u8 *buffer;
+
+ UN_CLEAR(splits);
+
+ if (input.size <= pattern.size) {
+ return splits;
+ }
+
+ if (pattern.size == 0) {
+ return splits;
+ }
+
+ for (i = 0, matches = 1; i < (input.size - (pattern.size - 1)); i++) {
+ if (un_memory_compare(input.data + i, pattern.data, pattern.size) != 0) {
+ continue;
+ }
+
+ matches++;
+ }
+
+ splits = un_list_create(matches, sizeof(String), alloc);
+
+ start = 0;
+
+ for (i = 0; i < (input.size - (pattern.size - 1)); i++) {
+ if (un_memory_compare(input.data + i, pattern.data, pattern.size) != 0) {
+ continue;
+ }
+
+ size = i - start;
+
+ if (size == 0) {
+ start = i + pattern.size;
+ continue;
+ }
+
+ buffer = (u8*)un_memory_alloc(size, alloc);
+ un_memory_copy(buffer, input.data + start, size);
+ string = CLITERAL(String) { .size = size, .data = buffer };
+ un_list_append(&splits, &string);
+ start = i + pattern.size;
+ }
+
+ if (start != input.size - pattern.size) {
+ if (un_memory_compare(input.data + start, pattern.data, pattern.size) == 0) {
+ return splits;
+ }
+
+ size = input.size - start;
+ if (size == 0) {
+ return splits;
+ }
+
+ buffer = (u8*)un_memory_alloc(size, alloc);
+ un_memory_copy(buffer, input.data + start, size);
+ string = CLITERAL(String) { .size = size, .data = buffer };
+ un_list_append(&splits, &string);
+ }
+
+ return splits;
+}
+
+String un_string_join(List string_list, String separator, Allocator alloc) {
+ String cont, temp;
+ u64 i;
+ Allocator talloc;
+
+ UN_CLEAR(cont);
+
+ talloc = un_allocator_get_temporary();
+
+ assert(string_list.element_size == sizeof(String));
+
+
+ for (i = 0; i < string_list.count; i++) {
+ temp = *(String *)un_list_get(&string_list, i);
+
+ cont = un_string_concat(cont, temp, talloc);
+
+ if (i != (string_list.count - 1)) {
+ cont = un_string_concat(cont, separator, talloc);
+ }
+ }
+
+ return un_string_copy(cont, alloc);
+}
+
+String un_string_substring(String input, s64 start, s64 max_size) {
+ String slice;
+
+ assert(start >= 0);
+ assert(max_size > 0);
+
+ slice.size = UN_MIN(max_size, (input.size - (s64)max_size));
+ slice.data = input.data + start;
+
+
+ if (start > (input.size - max_size)) {
+ slice.size = UN_MIN(max_size, (input.size - (s64)max_size));
+ } else {
+ slice.size = max_size;
+ }
+
+ slice.data = input.data + start;
+ return slice;
+}
+
+s64 un_string_index_of(String input, u8 value, u64 skip_count) {
+ s64 i;
+
+ for (i = 0; i < input.size; i++) {
+ if (input.data[i] != value) {
+ continue;
+ }
+
+ if (skip_count) {
+ skip_count--;
+ } else {
+ return i;
+ }
+ }
+
+ return -1;
+}
+extern s64 un_string_index_of_last(String input, u8 value) {
+ s64 i, index;
+
+ index = -1;
+
+ for (i = 0; i < input.size; i++) {
+ if (input.data[i] == value) index = i;
+ }
+
+ return index;
+}
+
+static String format_u64(u64 value) {
+ String output;
+ u64 l, r, size;
+ u8 t;
+ u8 buffer[32];
+
+ size = 0;
+
+ if (value == 0) {
+ return UN_STR("0");
+ }
+
+ while (value) {
+ buffer[size++] = '0' + (value % 10);
+ value /= 10;
+ }
+
+ assert(size <= 20);
+
+ for (l = 0, r = size - 1; l < r; l++, r--) {
+ t = buffer[l];
+ buffer[l] = buffer[r];
+ buffer[r] = t;
+ }
+
+ output.size = size;
+ output.data = buffer;
+ return un_string_copy(output, un_allocator_get_temporary());
+}
+
+static String format_s64(s64 value) {
+ String output;
+ u64 l, r, size;
+ b32 negative;
+ u8 t;
+ u8 buffer[32];
+
+ size = 0;
+
+ if (value == 0) {
+ return UN_STR("0");
+ }
+
+ negative = false;
+
+ if (value < 0) {
+ value = -value;
+ negative = true;
+ }
+
+ while (value) {
+ buffer[size++] = '0' + (value % 10);
+ value /= 10;
+ }
+
+ if (negative) {
+ buffer[size++] = '-';
+ }
+
+ assert(size <= 20);
+
+ for (l = 0, r = size - 1; l < r; l++, r--) {
+ t = buffer[l];
+ buffer[l] = buffer[r];
+ buffer[r] = t;
+ }
+
+ output.size = size;
+ output.data = buffer;
+ return un_string_copy(output, un_allocator_get_temporary());
+}
+
+String un_string_format(Allocator alloc, String buffer, ...) {
+ va_list args;
+ String s;
+ List output;
+ s64 i, j;
+
+ Allocator talloc = un_allocator_get_temporary();
+ output = un_list_create(UN_KB(1), sizeof(u8), talloc);
+
+ va_start(args, buffer);
+
+ for (i = 0; i < buffer.size; i++) {
+ if (buffer.data[i] != '%') {
+ un_list_append(&output, buffer.data + i);
+ continue;
+ }
+
+ switch (buffer.data[++i]) {
+ case '%':
+ {
+ un_list_append(&output, buffer.data + i);
+ } break;
+ case 'c':
+ {
+ u32 b = va_arg(args, u32);
+ un_list_append(&output, &b);
+ } break;
+
+ case 'u':
+ {
+ s = format_u64(va_arg(args, u64));
+ for (j = 0; j < s.size; j++) {
+ un_list_append(&output, s.data + j);
+ }
+ } break;
+
+ case 'd':
+ {
+ s = format_s64(va_arg(args, u64));
+ for (j = 0; j < s.size; j++) {
+ un_list_append(&output, s.data + j);
+ }
+ } break;
+
+ case 's':
+ {
+ s = va_arg(args, String);
+ for (j = 0; j < s.size; j++) {
+ un_list_append(&output, s.data + j);
+ }
+ } break;
+ default: break;
+ }
+ }
+
+ va_end(args);
+
+ s.size = (s64)output.count;
+ s.data = output.data;
+
+ return un_string_copy(s, alloc);
+}