On Mon, Jun 02, 2008 at 10:59:51PM +0000, Miklos Vajna wrote:
is
I wouldn't write that part this way at all: I have a personal
implementation of things that look like strbufs that are able to use an
`alloca`-ed buffers and deals with overflows with malloc's, possibility
to stream and so on (implemented with skips, meaning that what is the
->buf member is, isn't always the real start of the allocated memory
block). And I don't think it's a good idea to carve such informations
into stone. So what I'd says in summary is:
(1) it is totally safe to touch anything in the buffer pointed by the
buf member between the index 0 and buf->len excluded.
(1b) what you write later: it's also possible to write after buf->len
if not after strbuf_avail() _BUT_ then you have when you're done
the task to reset the (2) invariant yourself, using
strbuf_setlen().
(2) ->buf[->len] =3D=3D '\0' holds _ALL TIME_.
(3) ->buf is never ever NULL so it can be used in any usual C string
ops safely.
(4) do NOT assume anything on what ->buf really is (allocated memory
or not e.g.), use strbuf_detach to unwrap a memory buffer from its
strbuf shell in a safe way. That is the sole supported way. This
will give you a malloced buffer that you can later free().
I'd add that it is _MANDATORY_ to initialize strbufs, and that a
static allocation (for global variables e.g.) can be done using
the STRBUF_INIT static initializer.
Actually this is wrong because strbuf_release performs a new init
since init allocates 0 memory and that it's idiot-proof. But it could be
changed in the future and it should not be relied upon.
Not really strbuf_detach unwraps the embedded buffer for sure, but it
doesn't "empties" the buffer, strbuf_detach is like strbuf_release:
after a release, strbuf should be init-ed again (even if for now
strbuf_release does so).
In addition to what Johannes said: size must be > len. Because the
string you pass is supposed to be a NUL-terminated string.
I'd put that this way: ensure that at least this amount of available
memory is available. This is used when you know a typical size for what
you will do and want to avoid repetitive automatic resize of the
underlying buffer. This is never a needed operation, but can be critical
for performance in some cases.
This function does NOT allocate new memory, so you should not perform
a strbuf_setlen to a length that is larger than sb->len + strbuf_avail(sb).
strbuf_setlen is just meant as a "please fix invariants from this strbuf
I just messed with)"
Please use NUL, '\0' is NUL (as in its ascii name), NULL is (void *)0.
In addition to that, I'd say that strbuf_addstr will ALWAYS be
implemented as an inline or a macro that expands to:
strbuf_add(..., s, strlen(s))
Meaning that this is efficient to write things like:
strbuf_addstr(sb, "immediate string").
This function is a pretty printer that expands magic formats string
thanks to callbacks, so that it's done in a generic way. It's what is
used to generate git-log e.g. I'm not its author, so I'm not really best
placed to describe it.
For all: the buffer is rewinded if the read fails.
If -1 is returned, errno must be consulted, like you would do for
read(3).
On Tue, Jun 03, 2008 at 12:00:33AM +0000, Johannes Schindelin wrote:
hnical/api-strbuf.txt
ry
=20
ACK. I'd add the fact that strbuf are meant to be used with all the
usual C string and memory APIs. Given that the length of the buffer is
known, it's often better to use the mem* functions than a str* one
(memchr vs. strchr e.g.). Though, one has to be careful about the fact
that str* functions often stop on NULs and that strbufs may have
embedded NULs.
y=20
Well I'd go even further like I proposed above.
h,
=20
ACK.
--=20
=C2=B7O=C2=B7 Pierre Habouzit
=C2=B7=C2=B7O madcoder@debia=
n.org
OOO http://www.madism.org