mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +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:
parent
2e38f9ba61
commit
c55d93512b
@ -2,6 +2,7 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## ??? - Unreleased
|
## ??? - Unreleased
|
||||||
|
- Add `buffer/push-at`
|
||||||
- Add `ffi/pointer-buffer` to convert pointers to buffers the cannot be reallocated. This
|
- 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.
|
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
|
- Calling `ev/cancel` on a fiber waiting on `ev/gather` will correctly
|
||||||
|
@ -307,17 +307,8 @@ JANET_CORE_FN(cfun_buffer_chars,
|
|||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_buffer_push,
|
static void buffer_push_impl(JanetBuffer *buffer, Janet *argv, int32_t argc_offset, int32_t argc) {
|
||||||
"(buffer/push buffer & xs)",
|
for (int32_t i = argc_offset; i < argc; i++) {
|
||||||
"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++) {
|
|
||||||
if (janet_checktype(argv[i], JANET_NUMBER)) {
|
if (janet_checktype(argv[i], JANET_NUMBER)) {
|
||||||
janet_buffer_push_u8(buffer, (uint8_t)(janet_getinteger(argv, i) & 0xFF));
|
janet_buffer_push_u8(buffer, (uint8_t)(janet_getinteger(argv, i) & 0xFF));
|
||||||
} else {
|
} else {
|
||||||
@ -329,6 +320,36 @@ JANET_CORE_FN(cfun_buffer_push,
|
|||||||
janet_buffer_push_bytes(buffer, view.bytes, view.len);
|
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];
|
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-word", cfun_buffer_word),
|
||||||
JANET_CORE_REG("buffer/push-string", cfun_buffer_chars),
|
JANET_CORE_REG("buffer/push-string", cfun_buffer_chars),
|
||||||
JANET_CORE_REG("buffer/push", cfun_buffer_push),
|
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/popn", cfun_buffer_popn),
|
||||||
JANET_CORE_REG("buffer/clear", cfun_buffer_clear),
|
JANET_CORE_REG("buffer/clear", cfun_buffer_clear),
|
||||||
JANET_CORE_REG("buffer/slice", cfun_buffer_slice),
|
JANET_CORE_REG("buffer/slice", cfun_buffer_slice),
|
||||||
|
@ -1374,7 +1374,7 @@ JANET_CORE_FN(cfun_ffi_call,
|
|||||||
|
|
||||||
JANET_CORE_FN(cfun_ffi_buffer_write,
|
JANET_CORE_FN(cfun_ffi_buffer_write,
|
||||||
"(ffi/write ffi-type data &opt buffer)",
|
"(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 "
|
"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.") {
|
"or to files. Returns a modifed buffer or a new buffer if one is not supplied.") {
|
||||||
janet_sandbox_assert(JANET_SANDBOX_FFI);
|
janet_sandbox_assert(JANET_SANDBOX_FFI);
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
symbolslots)
|
symbolslots)
|
||||||
"symbolslots survive disasm/asm")
|
"symbolslots survive disasm/asm")
|
||||||
|
|
||||||
# need to fix upvalues
|
|
||||||
(comment
|
(comment
|
||||||
(setdyn *debug* true)
|
(setdyn *debug* true)
|
||||||
(setdyn :pretty-format "%.40M")
|
(setdyn :pretty-format "%.40M")
|
||||||
@ -41,4 +40,9 @@
|
|||||||
[3 7 4 'z]])
|
[3 7 4 'z]])
|
||||||
"arg & inner symbolslots")
|
"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)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user