despite not being a b_object, the b_stream interface can now detect when
a b_bstr instance has been passed as a stream parameter and use the correct
functions to handle writing to it.
this allows any function that expects a b_stream parameter to be called
with a b_bstr instance instead, allowing complex stream-based I/O operations
to be directed towards bounded character arrays with no heap allocation
required.
bstr is very similar to b_stringstream, with the key difference being it can be
stack-allocated. this allows you to write a complex formatted string to a
stack-allocated character buffer with no heap memory allocation required.
bstr also supports automatically-managed dynamic string buffers for unbounded
string construction.
any characters written to a stringstream can be optionally read back again
using the b_stream read API.
this functions similar to a ringbuffer, with two key differences:
1) the buffer is not circular, and will continuously expand to accomodate all incoming data.
2) reading data from the stringstream does not remove it from the buffer.
moving a btree node is similar to simply using memmove() or memcpy(), with the added
bonus of updating the pointers in the wider data structure to the new node memory
and zeroing the old node memory so that it isn't used accidentally after the move
is complete.
b_stream can now read/write utf-8 encoded data, and will do so unless
the stream is in binary mode.
b_stream will also report an error it encounters invalid utf-8 data
(unless binary mode is enabled).
this will allow a wider range of data structures (e.g. b_error, b_stream, b_stringstream) to make use
of the new object system, and other modules and library users can use the object system without
depending on the blue-object or blue-ds modules.
blue-ds will become a simple library of data structures (string, hashmap, etc), built on top of the
core object system.