|
|
|
@ -1,6 +1,6 @@ |
|
|
|
|
/*
|
|
|
|
|
* This file is part of corelibs. (https://git.redxen.eu/corelibs)
|
|
|
|
|
* Copyright (c) 2021 Alex-David Denes |
|
|
|
|
* Copyright (c) 2021-2022 Alex-David Denes |
|
|
|
|
* |
|
|
|
|
* corelibs is free software: you can redistribute it and/or modify |
|
|
|
|
* it under the terms of the GNU General Public License as published by |
|
|
|
@ -43,7 +43,7 @@ corelibs_dynarray_export_slice (const cl_dynarray_t *, uintmax_t, uintmax_t, voi |
|
|
|
|
corelibs_dynarray_bcheck (const cl_dynarray_t *, uintmax_t, uintmax_t); |
|
|
|
|
|
|
|
|
|
struct cl_dynarray_t { |
|
|
|
|
void * addr; // Location of element
|
|
|
|
|
uint8_t * addr; // Location of element
|
|
|
|
|
uintmax_t len; // Element count
|
|
|
|
|
struct { |
|
|
|
|
bool lock; // Is the capacity frozen?
|
|
|
|
@ -89,105 +89,130 @@ const struct corelibs_dynarray_interface cl_dynarray = { |
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_make_new (size_t sbyte, cl_dynarray_t **ptr) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (ptr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
cl_dynarray_t *new = malloc (sizeof (*new)); |
|
|
|
|
if (new != NULL) { |
|
|
|
|
new->addr = NULL; |
|
|
|
|
new->es = sbyte; |
|
|
|
|
new->len = 0; |
|
|
|
|
new->cap.len = 0; |
|
|
|
|
new->cap.lock = false; |
|
|
|
|
*ptr = new; |
|
|
|
|
} else { |
|
|
|
|
err = cl_error.err.mem.alloc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ptr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cl_dynarray_t *new = malloc (sizeof (*new)); |
|
|
|
|
if (new == NULL) { |
|
|
|
|
err = cl_error.err.mem.alloc; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
new->addr = NULL; |
|
|
|
|
new->es = sbyte; |
|
|
|
|
new->len = 0; |
|
|
|
|
new->cap.len = 0; |
|
|
|
|
new->cap.lock = false; |
|
|
|
|
*ptr = new; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_make_slice (const cl_dynarray_t *arr, uintmax_t pos, uintmax_t cnt, cl_dynarray_t **save) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (save == NULL || arr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
if (cnt == 0) { |
|
|
|
|
// Don't copy anything, just make new array
|
|
|
|
|
return corelibs_dynarray_make_new (arr->es, save); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Can we slice these elements?
|
|
|
|
|
if (!(err = corelibs_dynarray_bcheck (arr, pos, cnt))) { |
|
|
|
|
// Create new array
|
|
|
|
|
cl_dynarray_t *new; |
|
|
|
|
if (!(err = corelibs_dynarray_make_new (arr->es, &new))) { |
|
|
|
|
// Resize array to fit contents
|
|
|
|
|
if (!(err = corelibs_dynarray_mod_arr_cap (new, cnt))) { |
|
|
|
|
// Copy contents from old array to new one
|
|
|
|
|
if (!(err = corelibs_dynarray_export_slice (arr, pos, cnt, new->addr))) { |
|
|
|
|
new->len = cnt; |
|
|
|
|
new->cap.lock = arr->cap.lock; // Inherit capacity lock
|
|
|
|
|
*save = new; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (err) corelibs_dynarray_free (new); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (save == NULL || arr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cnt == 0) { |
|
|
|
|
// Don't copy anything, just make new array
|
|
|
|
|
err = corelibs_dynarray_make_new (arr->es, save); |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Can we slice these elements?
|
|
|
|
|
if ((err = corelibs_dynarray_bcheck (arr, pos, cnt))) goto ret; |
|
|
|
|
|
|
|
|
|
// Create new array
|
|
|
|
|
cl_dynarray_t *new; |
|
|
|
|
if ((err = corelibs_dynarray_make_new (arr->es, &new))) goto ret; |
|
|
|
|
|
|
|
|
|
// Resize array to fit contents
|
|
|
|
|
if ((err = corelibs_dynarray_mod_arr_cap (new, cnt))) { |
|
|
|
|
corelibs_dynarray_free (new); |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Copy contents from old array to new one
|
|
|
|
|
if ((err = corelibs_dynarray_export_slice (arr, pos, cnt, new->addr))) { |
|
|
|
|
corelibs_dynarray_free (new); |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
new->len = cnt; |
|
|
|
|
new->cap.lock = arr->cap.lock; // Inherit capacity lock
|
|
|
|
|
*save = new; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_free (cl_dynarray_t *arr) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
if (!(err = corelibs_dynarray_mod_arr_cap (arr, 0))) { |
|
|
|
|
free (arr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (arr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((err = corelibs_dynarray_mod_arr_cap (arr, 0))) goto ret; |
|
|
|
|
free (arr); |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_mod_arr_cap (cl_dynarray_t *arr, uintmax_t len) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
if (len == 0) { |
|
|
|
|
free (arr->addr); |
|
|
|
|
arr->cap.len = 0; |
|
|
|
|
} else if (!arr->cap.lock) { |
|
|
|
|
void * reg = NULL; |
|
|
|
|
const size_t nl = len * arr->es; |
|
|
|
|
|
|
|
|
|
if (arr->addr == NULL) { |
|
|
|
|
reg = malloc (nl); |
|
|
|
|
} else if (arr->cap.len != len) { |
|
|
|
|
reg = realloc (arr->addr, nl); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (reg != NULL) { |
|
|
|
|
arr->cap.len = len; |
|
|
|
|
arr->addr = reg; |
|
|
|
|
if (arr->cap.len < arr->len) arr->len = arr->cap.len; // Cut out discarded elements if resized to shorter size
|
|
|
|
|
} else { |
|
|
|
|
err = cl_error.err.mem.alloc; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
err = cl_error.err.data.immut; |
|
|
|
|
if (arr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (len == 0) { |
|
|
|
|
free (arr->addr); |
|
|
|
|
arr->cap.len = 0; |
|
|
|
|
} else if (!arr->cap.lock) { |
|
|
|
|
void * reg = NULL; |
|
|
|
|
const size_t nl = len * arr->es; |
|
|
|
|
|
|
|
|
|
if (arr->addr == NULL) { |
|
|
|
|
reg = malloc (nl); |
|
|
|
|
} else if (arr->cap.len != len) { |
|
|
|
|
reg = realloc (arr->addr, nl); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (reg != NULL) { |
|
|
|
|
err = cl_error.err.mem.alloc; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
arr->cap.len = len; |
|
|
|
|
arr->addr = reg; |
|
|
|
|
if (arr->cap.len < arr->len) arr->len = arr->cap.len; // Cut out discarded elements if resized to shorter size
|
|
|
|
|
} else { |
|
|
|
|
err = cl_error.err.data.immut; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_mod_arr_lock (cl_dynarray_t *arr, bool lock) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
arr->cap.lock = lock; |
|
|
|
|
if (arr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
arr->cap.lock = lock; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -199,182 +224,212 @@ corelibs_dynarray_mod_dat_app (cl_dynarray_t *arr, uintmax_t cnt, const void *el |
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_mod_dat_ins (cl_dynarray_t *arr, uintmax_t pos, uintmax_t cnt, const void *elem) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || elem == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
// Resize array to fit inserted objects
|
|
|
|
|
if (!(err = corelibs_dynarray_mod_arr_cap (arr, ((arr->cap.len < pos) ? pos : arr->cap.len) + cnt))) { |
|
|
|
|
// CHECKPOINT: From here it is safe to commit changes as required conditions are met
|
|
|
|
|
// and no errors should be possible (unless you have some special hardware)
|
|
|
|
|
|
|
|
|
|
uintmax_t clen = arr->len; // Lenght pre-resize
|
|
|
|
|
|
|
|
|
|
if (arr->len < pos) arr->len = pos; |
|
|
|
|
arr->len += cnt; |
|
|
|
|
|
|
|
|
|
uintptr_t src, // Source of copy address without pointer aritmethic
|
|
|
|
|
dest; // Destination to copy to
|
|
|
|
|
size_t bcnt; // Amount of bytes to copy
|
|
|
|
|
|
|
|
|
|
// If we are inserting and not appending
|
|
|
|
|
if (pos < clen) { |
|
|
|
|
src = (uintptr_t) arr->addr + (pos * arr->es); |
|
|
|
|
dest = src + (cnt * arr->es); |
|
|
|
|
bcnt = (clen - pos) * arr->es; |
|
|
|
|
memmove ((void *) dest, (void *) src, bcnt); // Shift bytes to after insertion region
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
src = (uintptr_t) elem; |
|
|
|
|
dest = (uintptr_t) arr->addr + (pos * arr->es); |
|
|
|
|
bcnt = cnt * arr->es; |
|
|
|
|
memcpy ((void *) dest, (void *) src, bcnt); // No overlaps possible
|
|
|
|
|
} |
|
|
|
|
if (arr == NULL || elem == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Resize array to fit inserted objects
|
|
|
|
|
if ((err = corelibs_dynarray_mod_arr_cap (arr, ((arr->cap.len < pos) ? pos : arr->cap.len) + cnt))) goto ret; |
|
|
|
|
|
|
|
|
|
// CHECKPOINT: From here it is safe to commit changes as required conditions are met
|
|
|
|
|
// and no errors should be possible (unless you have some special hardware)
|
|
|
|
|
|
|
|
|
|
uintmax_t clen = arr->len; // Lenght pre-resize
|
|
|
|
|
|
|
|
|
|
if (arr->len < pos) arr->len = pos; |
|
|
|
|
arr->len += cnt; |
|
|
|
|
|
|
|
|
|
const uint8_t *src; |
|
|
|
|
uint8_t * dest; |
|
|
|
|
size_t bcnt; |
|
|
|
|
|
|
|
|
|
// If we are inserting and not appending
|
|
|
|
|
if (pos < clen) { |
|
|
|
|
src = arr->addr + (pos * arr->es); |
|
|
|
|
dest = arr->addr + ((pos + cnt) * arr->es); |
|
|
|
|
bcnt = (clen - pos) * arr->es; |
|
|
|
|
memmove (dest, src, bcnt); // Shift bytes to after insertion region
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
src = elem; |
|
|
|
|
dest = arr->addr + (pos * arr->es); |
|
|
|
|
bcnt = cnt * arr->es; |
|
|
|
|
memcpy (dest, src, bcnt); // No overlaps possible
|
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_mod_dat_rep (cl_dynarray_t *arr, uintmax_t pos, uintmax_t cnt, const void *elem) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || elem == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
if (corelibs_dynarray_bcheck (arr, pos, cnt) == cl_error.err.mem.oob) { |
|
|
|
|
// Resize array to fit new elements
|
|
|
|
|
err = corelibs_dynarray_mod_arr_cap (arr, pos + cnt); |
|
|
|
|
} |
|
|
|
|
if (arr == NULL || elem == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!err) { |
|
|
|
|
// CHECKPOINT: From here it is safe to commit changes as required conditions are met
|
|
|
|
|
// and no errors should be possible (unless you have some special hardware)
|
|
|
|
|
if ((err = corelibs_dynarray_bcheck (arr, pos, cnt)) == cl_error.err.mem.oob) { |
|
|
|
|
// Resize array to fit new elements
|
|
|
|
|
if ((err = corelibs_dynarray_mod_arr_cap (arr, pos + cnt))) goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uintptr_t src, // Source of copy address without pointer aritmethic
|
|
|
|
|
dest; // Destination to copy to
|
|
|
|
|
size_t bcnt; // Amount of bytes to copy
|
|
|
|
|
// CHECKPOINT: From here it is safe to commit changes as required conditions are met
|
|
|
|
|
// and no errors should be possible (unless you have some special hardware)
|
|
|
|
|
|
|
|
|
|
src = (uintptr_t) elem; |
|
|
|
|
dest = (uintptr_t) arr->addr + (pos * arr->es); |
|
|
|
|
bcnt = cnt * arr->es; |
|
|
|
|
memcpy ((void *) dest, (void *) src, bcnt); |
|
|
|
|
if (arr->len < pos + cnt) arr->len = pos + cnt; // Set length at end of replacement if not already same or longer
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
const uint8_t *src; |
|
|
|
|
uint8_t * dest; |
|
|
|
|
size_t bcnt; |
|
|
|
|
|
|
|
|
|
src = elem; |
|
|
|
|
dest = arr->addr + (pos * arr->es); |
|
|
|
|
bcnt = cnt * arr->es; |
|
|
|
|
memcpy (dest, src, bcnt); |
|
|
|
|
if (arr->len < pos + cnt) arr->len = pos + cnt; // Set length at end of replacement if not already same or longer
|
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_mod_dat_rm (cl_dynarray_t *arr, uintmax_t pos, uintmax_t cnt) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
// Are we removing elements we don't have?
|
|
|
|
|
if (!(err = corelibs_dynarray_bcheck (arr, pos, cnt))) { |
|
|
|
|
// Allocate intermediate buffer
|
|
|
|
|
void *tbuf = malloc (arr->es * arr->len); |
|
|
|
|
if (tbuf != NULL) { |
|
|
|
|
// CHECKPOINT: From here it is safe to commit changes as required conditions are met
|
|
|
|
|
// and no errors should be possible (unless you have some special hardware)
|
|
|
|
|
|
|
|
|
|
arr->len -= cnt; // We remove cnt elements from array
|
|
|
|
|
|
|
|
|
|
uintptr_t src, // Source of copy address without pointer aritmethic
|
|
|
|
|
dest; // Destination to copy to
|
|
|
|
|
size_t bcnt; // Amount of bytes to copy
|
|
|
|
|
|
|
|
|
|
dest = (uintptr_t) tbuf; |
|
|
|
|
src = (uintptr_t) arr->addr; |
|
|
|
|
bcnt = arr->len * arr->es; |
|
|
|
|
memcpy ((void *) dest, (void *) src, bcnt); // Copy current contents up to arr->len to intermediate buffer
|
|
|
|
|
|
|
|
|
|
// If tail is the only thing removed, don't copy back
|
|
|
|
|
if (pos + cnt != arr->len) { |
|
|
|
|
// Copy back slice and overwrite region removed
|
|
|
|
|
dest += pos * arr->es; |
|
|
|
|
src += (pos + cnt) * arr->es; |
|
|
|
|
bcnt -= pos * arr->es; |
|
|
|
|
memcpy ((void *) dest, (void *) src, bcnt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free (arr->addr); |
|
|
|
|
arr->addr = tbuf; // Swap buffers and free previous one
|
|
|
|
|
} else { |
|
|
|
|
err = cl_error.err.mem.alloc; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (arr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
// Are we removing elements we don't have?
|
|
|
|
|
if ((err = corelibs_dynarray_bcheck (arr, pos, cnt))) goto ret; |
|
|
|
|
|
|
|
|
|
// Allocate intermediate buffer
|
|
|
|
|
void *tbuf = malloc (arr->es * arr->len); |
|
|
|
|
if (tbuf != NULL) { |
|
|
|
|
err = cl_error.err.mem.alloc; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CHECKPOINT: From here it is safe to commit changes as required conditions are met
|
|
|
|
|
// and no errors should be possible (unless you have some special hardware)
|
|
|
|
|
|
|
|
|
|
arr->len -= cnt; // We remove cnt elements from array
|
|
|
|
|
|
|
|
|
|
const uint8_t *src; |
|
|
|
|
uint8_t * dest; |
|
|
|
|
size_t bcnt; |
|
|
|
|
|
|
|
|
|
src = arr->addr; |
|
|
|
|
dest = tbuf; |
|
|
|
|
bcnt = arr->len * arr->es; |
|
|
|
|
memcpy (dest, src, bcnt); // Copy current contents up to arr->len to intermediate buffer
|
|
|
|
|
|
|
|
|
|
// If tail is the only thing removed, don't copy back
|
|
|
|
|
if (pos + cnt != arr->len) { |
|
|
|
|
// Copy back slice and overwrite region removed
|
|
|
|
|
src += (pos + cnt) * arr->es; |
|
|
|
|
dest += pos * arr->es; |
|
|
|
|
bcnt -= pos * arr->es; |
|
|
|
|
memcpy (dest, src, bcnt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free (arr->addr); |
|
|
|
|
arr->addr = tbuf; // Swap buffers and free previous one
|
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_export_slice (const cl_dynarray_t *arr, uintmax_t pos, uintmax_t cnt, void *save) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || save == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err || cnt != 0) { |
|
|
|
|
// Do we have the requested slice?
|
|
|
|
|
if (!(err = corelibs_dynarray_bcheck (arr, pos, cnt))) { |
|
|
|
|
uintptr_t src, // Source of copy address without pointer aritmethic
|
|
|
|
|
dest; // Destination to copy to
|
|
|
|
|
size_t bcnt; // Amount of bytes to copy
|
|
|
|
|
|
|
|
|
|
src = (uintptr_t) arr->addr + (arr->es * pos); |
|
|
|
|
dest = (uintptr_t) save; |
|
|
|
|
bcnt = arr->es * cnt; |
|
|
|
|
memcpy ((void *) dest, (void *) src, bcnt); |
|
|
|
|
} |
|
|
|
|
if (arr == NULL || save == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
if (cnt == 0) goto ret; // Skip exporting anything, nothing was requested
|
|
|
|
|
|
|
|
|
|
// Do we have the requested slice?
|
|
|
|
|
if ((err = corelibs_dynarray_bcheck (arr, pos, cnt))) goto ret; |
|
|
|
|
|
|
|
|
|
const uint8_t *src; |
|
|
|
|
uint8_t * dest; |
|
|
|
|
size_t bcnt; |
|
|
|
|
|
|
|
|
|
src = arr->addr + (pos * arr->es); |
|
|
|
|
dest = save; |
|
|
|
|
bcnt = arr->es * cnt; |
|
|
|
|
memcpy (dest, src, bcnt); |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_get_len (const cl_dynarray_t *arr, uintmax_t *save) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || save == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
*save = arr->len; |
|
|
|
|
|
|
|
|
|
if (arr == NULL || save == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
*save = arr->len; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_get_cap_len (const cl_dynarray_t *arr, uintmax_t *save) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || save == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
*save = arr->cap.len; |
|
|
|
|
|
|
|
|
|
if (arr == NULL || save == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
*save = arr->cap.len; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_get_cap_lock (const cl_dynarray_t *arr, bool *save) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || save == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
*save = arr->cap.lock; |
|
|
|
|
|
|
|
|
|
if (arr == NULL || save == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
*save = arr->cap.lock; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_get_size (const cl_dynarray_t *arr, size_t *save) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL || save == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (!err) { |
|
|
|
|
*save = arr->es; |
|
|
|
|
|
|
|
|
|
if (arr == NULL || save == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
*save = arr->es; |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_cmp_data (const cl_dynarray_t *a, const cl_dynarray_t *b, bool *eq) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (a == NULL || b == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (a->es != b->es) err = cl_error.err.data.incompat; |
|
|
|
|
if (!err) { |
|
|
|
|
if (a->len != b->len) { |
|
|
|
|
*eq = false; |
|
|
|
|
} else { |
|
|
|
|
*eq = (memcmp (a->addr, b->addr, a->len) != 0) ? false : true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (a == NULL || b == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
if (a->es != b->es) { |
|
|
|
|
err = cl_error.err.data.incompat; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (a->len != b->len) { |
|
|
|
|
*eq = false; |
|
|
|
|
} else { |
|
|
|
|
*eq = (memcmp (a->addr, b->addr, a->len) != 0) ? false : true; |
|
|
|
|
} |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -382,7 +437,14 @@ corelibs_dynarray_cmp_data (const cl_dynarray_t *a, const cl_dynarray_t *b, bool |
|
|
|
|
static cl_error_t |
|
|
|
|
corelibs_dynarray_bcheck (const cl_dynarray_t *arr, uintmax_t pos, uintmax_t len) { |
|
|
|
|
cl_error_t err = cl_error.err.ok; |
|
|
|
|
if (arr == NULL) err = cl_error.err.mem.null; |
|
|
|
|
if (arr->cap.len < pos + len) err = cl_error.err.mem.oob; |
|
|
|
|
if (arr == NULL) { |
|
|
|
|
err = cl_error.err.mem.null; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
if (arr->cap.len < pos + len) { |
|
|
|
|
err = cl_error.err.mem.oob; |
|
|
|
|
goto ret; |
|
|
|
|
} |
|
|
|
|
ret: |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|