1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-18 11:19:56 +00:00

Add buffer/push-at for easier manipulation of buffers

buffer/blit is difficult to use, and while buffer/push is the easiet
buffer manipulation function to use it only appends to the buffer.
buffer/push-at lets users manipulate buffers at any index - useful
for buffers used as an in-memory databases, for example.
This commit is contained in:
Calvin Rose 2023-02-12 11:19:09 -06:00
parent 2e38f9ba61
commit c55d93512b
4 changed files with 40 additions and 13 deletions

View File

@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file.
## ??? - Unreleased
- Add `buffer/push-at`
- Add `ffi/pointer-buffer` to convert pointers to buffers the cannot be reallocated. This
allows easier manipulation of FFI memory, memory mapped files, and buffer memory shared between threads.
- Calling `ev/cancel` on a fiber waiting on `ev/gather` will correctly

View File

@ -307,17 +307,8 @@ JANET_CORE_FN(cfun_buffer_chars,
return argv[0];
}
JANET_CORE_FN(cfun_buffer_push,
"(buffer/push buffer & xs)",
"Push both individual bytes and byte sequences to a buffer. For each x in xs, "
"push the byte if x is an integer, otherwise push the bytesequence to the buffer. "
"Thus, this function behaves like both `buffer/push-string` and `buffer/push-byte`. "
"Returns the modified buffer. "
"Will throw an error if the buffer overflows.") {
int32_t i;
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
for (i = 1; i < argc; i++) {
static void buffer_push_impl(JanetBuffer *buffer, Janet *argv, int32_t argc_offset, int32_t argc) {
for (int32_t i = argc_offset; i < argc; i++) {
if (janet_checktype(argv[i], JANET_NUMBER)) {
janet_buffer_push_u8(buffer, (uint8_t)(janet_getinteger(argv, i) & 0xFF));
} else {
@ -329,6 +320,36 @@ JANET_CORE_FN(cfun_buffer_push,
janet_buffer_push_bytes(buffer, view.bytes, view.len);
}
}
}
JANET_CORE_FN(cfun_buffer_push_at,
"(buffer/push-at buffer index & xs)",
"Same as buffer/push, but inserts new data at index `index`.") {
janet_arity(argc, 2, -1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
int32_t index = janet_getinteger(argv, 1);
int32_t old_count = buffer->count;
if (index < 0 || index > old_count) {
janet_panicf("index out of range [0, %d)", old_count);
}
buffer->count = index;
buffer_push_impl(buffer, argv, 2, argc);
if (buffer->count < old_count) {
buffer->count = old_count;
}
return argv[0];
}
JANET_CORE_FN(cfun_buffer_push,
"(buffer/push buffer & xs)",
"Push both individual bytes and byte sequences to a buffer. For each x in xs, "
"push the byte if x is an integer, otherwise push the bytesequence to the buffer. "
"Thus, this function behaves like both `buffer/push-string` and `buffer/push-byte`. "
"Returns the modified buffer. "
"Will throw an error if the buffer overflows.") {
janet_arity(argc, 1, -1);
JanetBuffer *buffer = janet_getbuffer(argv, 0);
buffer_push_impl(buffer, argv, 1, argc);
return argv[0];
}
@ -492,6 +513,7 @@ void janet_lib_buffer(JanetTable *env) {
JANET_CORE_REG("buffer/push-word", cfun_buffer_word),
JANET_CORE_REG("buffer/push-string", cfun_buffer_chars),
JANET_CORE_REG("buffer/push", cfun_buffer_push),
JANET_CORE_REG("buffer/push-at", cfun_buffer_push_at),
JANET_CORE_REG("buffer/popn", cfun_buffer_popn),
JANET_CORE_REG("buffer/clear", cfun_buffer_clear),
JANET_CORE_REG("buffer/slice", cfun_buffer_slice),

View File

@ -1374,7 +1374,7 @@ JANET_CORE_FN(cfun_ffi_call,
JANET_CORE_FN(cfun_ffi_buffer_write,
"(ffi/write ffi-type data &opt buffer)",
"Append a native tyep to a buffer such as it would appear in memory. This can be used "
"Append a native type to a buffer such as it would appear in memory. This can be used "
"to pass pointers to structs in the ffi, or send C/C++/native structs over the network "
"or to files. Returns a modifed buffer or a new buffer if one is not supplied.") {
janet_sandbox_assert(JANET_SANDBOX_FFI);

View File

@ -19,7 +19,6 @@
symbolslots)
"symbolslots survive disasm/asm")
# need to fix upvalues
(comment
(setdyn *debug* true)
(setdyn :pretty-format "%.40M")
@ -41,4 +40,9 @@
[3 7 4 'z]])
"arg & inner symbolslots")
# buffer/push-at
(assert (deep= @"abc456" (buffer/push-at @"abc123" 3 "456")) "buffer/push-at 1")
(assert (deep= @"abc456789" (buffer/push-at @"abc123" 3 "456789")) "buffer/push-at 2")
(assert (deep= @"abc423" (buffer/push-at @"abc123" 3 "4")) "buffer/push-at 3")
(end-suite)