summaryrefslogtreecommitdiffstats
path: root/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_ops.c')
-rw-r--r--src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_ops.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_ops.c b/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_ops.c
new file mode 100644
index 000000000..4cdf598e3
--- /dev/null
+++ b/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_ops.c
@@ -0,0 +1,82 @@
+/*
+ * duk_hbuffer operations such as resizing and inserting/appending data to
+ * a dynamic buffer.
+ *
+ * Append operations append to the end of the buffer and they are relatively
+ * efficient: the buffer is grown with a "spare" part relative to the buffer
+ * size to minimize reallocations. Insert operations need to move existing
+ * data forward in the buffer with memmove() and are not very efficient.
+ * They are used e.g. by the regexp compiler to "backpatch" regexp bytecode.
+ */
+
+#include "duk_internal.h"
+
+/*
+ * Resizing
+ */
+
+DUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) {
+ void *res;
+ duk_size_t prev_size;
+
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(buf != NULL);
+ DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));
+ DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));
+
+ /*
+ * Maximum size check
+ */
+
+ if (new_size > DUK_HBUFFER_MAX_BYTELEN) {
+ DUK_ERROR_RANGE(thr, "buffer too long");
+ }
+
+ /*
+ * Note: use indirect realloc variant just in case mark-and-sweep
+ * (finalizers) might resize this same buffer during garbage
+ * collection.
+ */
+
+ res = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size);
+ if (res != NULL || new_size == 0) {
+ /* 'res' may be NULL if new allocation size is 0. */
+
+ DUK_DDD(DUK_DDDPRINT("resized dynamic buffer %p:%ld -> %p:%ld",
+ (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf),
+ (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),
+ (void *) res,
+ (long) new_size));
+
+ /*
+ * The entire allocated buffer area, regardless of actual used
+ * size, is kept zeroed in resizes for simplicity. If the buffer
+ * is grown, zero the new part.
+ */
+
+ prev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);
+ if (new_size > prev_size) {
+ DUK_ASSERT(new_size - prev_size > 0);
+#ifdef DUK_USE_ZERO_BUFFER_DATA
+ DUK_MEMZERO((void *) ((char *) res + prev_size),
+ (duk_size_t) (new_size - prev_size));
+#endif
+ }
+
+ DUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size);
+ DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);
+ } else {
+ DUK_ERROR_ALLOC_DEFMSG(thr);
+ }
+
+ DUK_ASSERT(res != NULL || new_size == 0);
+}
+
+DUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) {
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(buf != NULL);
+ DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));
+ DUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));
+
+ duk_hbuffer_resize(thr, buf, 0);
+}