diff options
Diffstat (limited to 'src/un_strings.c')
-rw-r--r-- | src/un_strings.c | 381 |
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); +} |