diff options
| author | 2024-06-11 23:40:34 -0400 | |
|---|---|---|
| committer | 2024-06-11 23:40:34 -0400 | |
| commit | fe131f6e4b80bad56be3e1f6e79f4defa61aa99b (patch) | |
| tree | 518f236ea2e8bbdc76021ccf3d8f509310aff4aa /examples/string/uns_string.c | |
cheney copying collector
Diffstat (limited to 'examples/string/uns_string.c')
| -rw-r--r-- | examples/string/uns_string.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/examples/string/uns_string.c b/examples/string/uns_string.c new file mode 100644 index 0000000..e510fcf --- /dev/null +++ b/examples/string/uns_string.c @@ -0,0 +1,127 @@ +/* Copyright (c) 2024, Peter McGoron + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> +#include "uns.h" +#include "uns_string.h" + +enum { + ALLEN_IND = 0, + LEN_IND = 1, + BYTES_IND = 2, + NUMBER_OF_IND = 3 +}; + +static size_t get_size_t(struct uns_gc *gc, struct uns_root_list *root, size_t i) +{ + size_t r; + + void *p = gc->record_get_ptr(root->p, i); + memcpy(&r, p, sizeof(r)); + + return r; +} + +static void set_size_t(struct uns_gc *gc, struct uns_root_list *root, size_t i, size_t val) +{ + void *p = gc->record_get_ptr(root->p, i); + memcpy(p, &val, sizeof(val)); +} + +#define set_allen(gc,root,val) set_size_t(gc, root, ALLEN_IND, val) +#define set_len(gc,root,val) set_size_t(gc, root, LEN_IND, val) + +static size_t uns_string_allen(struct uns_gc *gc, struct uns_root_list *root) +{ + return get_size_t(gc, root, ALLEN_IND); +} + +size_t uns_string_len(struct uns_gc *gc, struct uns_root_list *root) +{ + return get_size_t(gc, root, LEN_IND); +} + +char *uns_string_ptr(struct uns_gc *gc, struct uns_root_list *root) +{ + return gc->record_get_ptr(root->p, BYTES_IND); +} + +void uns_string_alloc(struct uns_gc *gc, struct uns_root_list *root, size_t start_len) +{ + root->p = gc->alloc_record(gc, NUMBER_OF_IND); + + gc->record_set_ptr(root->p, ALLEN_IND, gc->alloc(gc, sizeof(size_t))); + set_allen(gc, root, start_len); + + gc->record_set_ptr(root->p, LEN_IND, gc->alloc(gc, sizeof(size_t))); + set_len(gc, root, 0); + + gc->record_set_ptr(root->p, BYTES_IND, gc->alloc(gc, start_len)); +} + +void uns_string_resize(struct uns_gc *gc, struct uns_root_list *root, size_t newlen) +{ + char *tmp; + + tmp = gc->alloc(gc, newlen); + set_allen(gc, root, newlen); + + if (newlen <= uns_string_len(gc, root)) + set_len(gc, root, newlen); + memcpy(tmp, uns_string_ptr(gc, root), uns_string_len(gc, root)); +} + +void uns_string_ensure(struct uns_gc *gc, struct uns_root_list *root, size_t extent) +{ + size_t used = uns_string_len(gc, root); + size_t allen = uns_string_allen(gc, root); + + if (used + extent > allen) + uns_string_resize(gc, root, used + extent); +} + +void uns_string_append_bytes(struct uns_gc *gc, struct uns_root_list *to, + const void *from, size_t bytes) +{ + size_t len = uns_string_len(gc, to); + uns_string_ensure(gc, to, bytes); + memcpy(uns_string_ptr(gc, to) + len, from, bytes); + set_len(gc, to, len + bytes); +} + +void uns_string_append_char(struct uns_gc *gc, struct uns_root_list *root, char c) +{ + uns_string_append_bytes(gc, root, &c, 1); +} + +char *uns_string_cstring(struct uns_gc *gc, struct uns_root_list *root) +{ + char *p; + uns_string_ensure(gc, root, 1); + + p = uns_string_ptr(gc, root); + p[uns_string_len(gc, root)] = 0; + return p; +} |
