alloc_buffer: Return unqualified pointer type in alloc_buffer_next

alloc_buffer_next is useful for peeking to the remaining part of the
buffer and update it, with subsequent allocation (once the length
is known) using alloc_buffer_alloc_bytes.  This is not as robust
as the other interfaces, but it allows using alloc_buffer with
string-writing interfaces such as snprintf and ns_name_ntop.
This commit is contained in:
Florian Weimer 2019-04-11 09:43:16 +02:00
parent 221710af7e
commit 32d85c116d
2 changed files with 33 additions and 5 deletions

View File

@ -1,3 +1,10 @@
2019-04-11 Florian Weimer <fweimer@redhat.com>
* include/alloc_buffer.h (alloc_buffer_alloc_bytes): Update
comment.
(alloc_buffer_next): Change return type to non-const. Update
comment.
2019-04-10 TAMUKI Shoichi <tamuki@linet.gr.jp>
* manual/time.texi (Formatting Calendar Time): Add missing percent

View File

@ -183,7 +183,7 @@ alloc_buffer_add_byte (struct alloc_buffer *buf, unsigned char b)
NULL is returned if there is not enough room, and the buffer is
marked as failed, or if the buffer has already failed.
(Zero-length allocations from an empty buffer which has not yet
failed succeed.) */
failed succeed.) The buffer contents is not modified. */
static inline __attribute__ ((nonnull (1))) void *
alloc_buffer_alloc_bytes (struct alloc_buffer *buf, size_t length)
{
@ -300,11 +300,32 @@ __alloc_buffer_next (struct alloc_buffer *buf, size_t align)
/* Like alloc_buffer_alloc, but do not advance the pointer beyond the
object (so a subseqent call to alloc_buffer_next or
alloc_buffer_alloc returns the same pointer). Note that the buffer
is still aligned according to the requirements of TYPE. The effect
of this function is similar to allocating a zero-length array from
the buffer. */
is still aligned according to the requirements of TYPE, potentially
consuming buffer space. The effect of this function is similar to
allocating a zero-length array from the buffer.
It is possible to use the return pointer to write to the buffer and
consume the written bytes using alloc_buffer_alloc_bytes (which
does not change the buffer contents), but the calling code needs to
perform manual length checks using alloc_buffer_size. For example,
to read as many int32_t values that are available in the input file
and can fit into the remaining buffer space, you can use this:
int32_t array = alloc_buffer_next (buf, int32_t);
size_t ret = fread (array, sizeof (int32_t),
alloc_buffer_size (buf) / sizeof (int32_t), fp);
if (ferror (fp))
handle_error ();
alloc_buffer_alloc_array (buf, int32_t, ret);
The alloc_buffer_alloc_array call makes the actually-used part of
the buffer permanent. The remaining part of the buffer (not filled
with data from the file) can be used for something else.
This manual length checking can easily introduce errors, so this
coding style is not recommended. */
#define alloc_buffer_next(buf, type) \
((const type *) __alloc_buffer_next \
((type *) __alloc_buffer_next \
(buf, __alloc_buffer_assert_align (__alignof__ (type))))
/* Internal function. Allocate an array. */