Hello,
I have some C++ code which context I want to re-create in Nim. Briefly, there is buffer of bytes. As it's just a pointer, I can easily designate an offset (current). Do not care about unpack_int, it's just a function combining some bytes from the buffer into an integer.
The questions is how to make this buffer concept in Nim to be safe and efficient?
I wanted to use slices, but they hold an immutuable sequence.
const unsigned char* current, start, end;
void reset(const void* data, int size) {
start = (const unsigned char*) data;
end = start + size;
current = start;
}
int get_int() {
if (current >= end) return 0; // update
int i;
current = unpack_int(current, &i);
return i;
if (current > end) return 0; // update
}
int unpack_int(const unsigned char *src, int *out) {
int sign = (*src >> 6) & 1;
*out = *src & 0x3F;
do {
if(!(*src & 0x80)) break;
src++;
*out |= (*src & (0x7F)) << (6);
if(!(*src & 0x80)) break;
src++;
*out |= (*src & (0x7F)) << (6+7);
if(!(*src & 0x80)) break;
src++;
*out |= (*src & (0x7F)) << (6+7+7);
if(!(*src & 0x80)) break;
src++;
*out |= (*src & (0x7F)) << (6+7+7+7);
} while(0);
src++;
*out ^= -sign; // if (sign) *i = ~(*i)
return src;
}
The use of ptr in Nim is always not safe.
For pointer math operation, check this post: https://forum.nim-lang.org/t/1188#7366
If it's sequence of bytes, you can use seq[Byte] or simply use cstring together with cast
I think you could find inspiration in the implementation of BitSets and IntSets since they both do low-level bit manipulation and operate on arrays of bytes. BitSets have a fixed memory size while IntSets are dynamically allocated/resized and use refs (GC'ed memory).
https://github.com/nim-lang/Nim/blob/5f685bb0e6b2d68b9796e6a7d29469ce3f3b38ec/compiler/bitsets.nim https://github.com/nim-lang/Nim/blob/df4f707743879a0ea4363fcef446d89d8b421513/lib/pure/collections/intsets.nim