1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
/*
* Buffer
*/
#include "duk_internal.h"
DUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) {
duk_hbuffer_dynamic *h;
DUK_ASSERT_API_ENTRY(thr);
h = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);
DUK_ASSERT(h != NULL);
if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);
DUK_WO_NORETURN(return NULL;);
}
/* Maximum size check is handled by callee. */
duk_hbuffer_resize(thr, h, new_size);
return DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);
}
DUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {
duk_hbuffer_dynamic *h;
void *ptr;
duk_size_t sz;
DUK_ASSERT_API_ENTRY(thr);
h = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);
DUK_ASSERT(h != NULL);
if (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {
DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);
DUK_WO_NORETURN(return NULL;);
}
/* Forget the previous allocation, setting size to 0 and alloc to
* NULL. Caller is responsible for freeing the previous allocation.
* Getting the allocation and clearing it is done in the same API
* call to avoid any chance of a realloc.
*/
ptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);
sz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h);
if (out_size) {
*out_size = sz;
}
DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h);
DUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0);
return ptr;
}
DUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) {
duk_hbuffer_external *h;
DUK_ASSERT_API_ENTRY(thr);
h = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx);
DUK_ASSERT(h != NULL);
if (!DUK_HBUFFER_HAS_EXTERNAL(h)) {
DUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);
DUK_WO_NORETURN(return;);
}
DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));
DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr);
DUK_HBUFFER_EXTERNAL_SET_SIZE(h, len);
}
|