wget2  2.0.0
Buffer management functions

Functions

int wget_buffer_init (wget_buffer *buf, char *data, size_t size)
 
wget_bufferwget_buffer_alloc (size_t size)
 
int wget_buffer_ensure_capacity (wget_buffer *buf, size_t size)
 
void wget_buffer_deinit (wget_buffer *buf)
 
void wget_buffer_free (wget_buffer **buf)
 
void wget_buffer_free_data (wget_buffer *buf)
 
void wget_buffer_reset (wget_buffer *buf)
 
size_t wget_buffer_memcpy (wget_buffer *buf, const void *data, size_t length)
 
size_t wget_buffer_memcat (wget_buffer *buf, const void *data, size_t length)
 
size_t wget_buffer_strcpy (wget_buffer *buf, const char *s)
 
size_t wget_buffer_strcat (wget_buffer *buf, const char *s)
 
size_t wget_buffer_bufcpy (wget_buffer *buf, wget_buffer *src)
 
size_t wget_buffer_bufcat (wget_buffer *buf, wget_buffer *src)
 
size_t wget_buffer_memset (wget_buffer *buf, char c, size_t length)
 
size_t wget_buffer_memset_append (wget_buffer *buf, char c, size_t length)
 
char * wget_buffer_trim (wget_buffer *buf)
 
size_t wget_buffer_vprintf_append (wget_buffer *buf, const char *fmt, va_list args)
 
size_t wget_buffer_vprintf (wget_buffer *buf, const char *fmt, va_list args)
 
size_t wget_buffer_printf_append (wget_buffer *buf, const char *fmt,...)
 
size_t wget_buffer_printf (wget_buffer *buf, const char *fmt,...)
 

Detailed Description

A buffer (represented with an opaque wget_buffer) is a managed memory area.

Apart from a pointer to a raw chunk of memory (char *), it also has some metadata attached such as the length of the buffer and the actual occupied positions.

Actually, when we talk about the length of the buffer, we refer to the actual number of bytes stored in it by the user. On the other hand, the size is the total number of slots in the buffer, either occupied or not.

The stored data is always 0-terminated, so you safely use it with standard string functions.

The functions here allow you to easily work with buffers, providing shortcuts to commonly used memory and string management operations and avoiding usual pitfalls, such as buffer overflows. They provide a higher-level abstraction to working with memory than the memory management functions.

If your application uses memory allocation functions that may return NULL values (e.g. like the standard libc functions), you have to check the error value before using the result. If set, it indicates that a memory allocation failure occurred during internal (re-)allocation.

Example with wget_buffer on the stack (initial 16 bytes heap allocation)

wet_buffer_init(&buf, NULL, 16);
wget_buffer_strcpy(&buf, "A");
wget_buffer_strcat(&buf, "B");
wget_buffer_memcat(&buf, "C", 1);
wget_buffer_printf_append(&buf, "%s", "E");
// buf.data now contains the 0-terminated string "ABCDE"
printf("buf.data = %s\n", buf.data);
WGETAPI size_t wget_buffer_memset_append(wget_buffer *buf, char c, size_t length)
Definition: buffer.c:515
WGETAPI size_t wget_buffer_strcat(wget_buffer *buf, const char *s)
Definition: buffer.c:436
size_t wget_buffer_printf_append(wget_buffer *buf, const char *fmt,...)
Definition: buffer_printf.c:539
WGETAPI void wget_buffer_deinit(wget_buffer *buf) WGET_GCC_NONNULL((1))
Definition: buffer.c:268
WGETAPI size_t wget_buffer_memcat(wget_buffer *buf, const void *data, size_t length)
Definition: buffer.c:378
WGETAPI size_t wget_buffer_strcpy(wget_buffer *buf, const char *s)
Definition: buffer.c:414
Definition: wget.h:542
char * data
pointer to internal memory
Definition: wget.h:544

Example with wget_buffer on the stack and 16 bytes initial stack buffer (no heap allocation is needed)

char sbuf[16];
wet_buffer_init(&buf, sbuf, sizeof(sbuf));
wget_buffer_strcpy(&buf, "A");
wget_buffer_strcat(&buf, "B");
wget_buffer_memcat(&buf, "C", 1);
wget_buffer_printf_append(&buf, "%s", "E");
// buf.data now contains the 0-terminated string "ABCDE"
printf("buf.data = %s\n", buf.data);

Example on how to check for memory failure and how to transfer buffer data

wet_buffer_init(&buf, NULL, 16);
wget_buffer_strcpy(&buf, "A");
wget_buffer_strcat(&buf, "B");
wget_buffer_memcat(&buf, "C", 1);
wget_buffer_printf_append(&buf, "%s", "E");
if (buf.error)
panic("No memory !");
// transfer ownership away from wget_buffer
char *ret = buf.data;
buf.data = NULL; // avoid double frees
return ret; // the caller must free() this value after use
bool error
a memory failure occurred, the result in 'data' is likely erroneous
Definition: wget.h:552

Function Documentation

◆ wget_buffer_init()

int wget_buffer_init ( wget_buffer buf,
char *  data,
size_t  size 
)
Parameters
[in]bufPointer to the buffer that should become initialized.
[in]dataInitial contents of the buffer. Might be NULL.
[in]sizeInitial length of the buffer. Might be zero (will default to 128 bytes).
Returns
WGET_E_SUCCESS or WGET_E_MEMORY in case of a memory allocation failure.

Create a new buffer.

If data is NULL, the buffer will be empty, but it will be pre-allocated with size bytes. This will make future operations on the buffer faster since there will be less re-allocations needed.

If size is zero, the buffer will be pre-allocated with 128 bytes.

You may provide some data to fill the buffer with it. The contents of the data pointer are not copied, but rather the pointer itself is referenced directly within the buffer. If you modify the contents of data, those changes will be reflected in the buffer as they both point to the same memory area.

Apart from that, there are other concerns you should keep in mind if you provide your own data here:

  • wget_buffer_deinit() will not free that memory when you call it. So if you provide a data pointer, you must free it yourself before your program ends.
  • wget_buffer_realloc() will also not free that memory. It will allocate a new buffer and copy the contents there, but will not touch the old buffer. The new buffer will be freed by these functions since it's been allocated by libwget internally and thus it knows it can be freed without harm.

If an existing buffer is provided in buf, it will be initialized with the provided data and size according to the rules stated above.

◆ wget_buffer_alloc()

wget_buffer* wget_buffer_alloc ( size_t  size)
Parameters
[in]sizeInitial length of the buffer.
Returns
A new buffer.

Allocates a new buffer of size size bytes.

The buffer will be pre-allocated with that many bytes, all zeros.

This is equivalent to wget_buffer_init(NULL, NULL, size).

◆ wget_buffer_ensure_capacity()

int wget_buffer_ensure_capacity ( wget_buffer buf,
size_t  size 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]sizeTotal size (in bytes) required in the buffer
Returns
WGET_E_SUCCESS on success, else WGET_E_MEMORY if the memory allocation failed

Make sure the buffer buf has at least a size of size bytes.

If the buffer's size is less than that, it will automatically enlarge it (with wget_buffer_realloc()) to make it at least as long.

◆ wget_buffer_deinit()

void wget_buffer_deinit ( wget_buffer buf)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()

Free the buffer, and all its contents.

If you provided your own data when calling wget_buffer_init() (you passed a non-NULL data pointer) then that buffer will not be freed. As stated in the description of wget_buffer_init() you must free that buffer yourself: this function will only free the wget_buffer structure.

Similarly, if you provided your own buffer when calling wget_buffer_init() (buf was non-NULL) the buffer (the wget_buffer structure) will not be freed, and the data might or might not be freed depending on the above condition.

◆ wget_buffer_free()

void wget_buffer_free ( wget_buffer **  buf)
Parameters
[in]bufA double pointer to a buffer

Free the buffer, and all its contents.

It behaves like wget_buffer_deinit() but it also sets the buf pointer to NULL.

This function is equivalent to:

wget_buffer_deinit(*buf);
*buf = NULL;

◆ wget_buffer_free_data()

void wget_buffer_free_data ( wget_buffer buf)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()

Release the buffer's data, but keep the buffer itself (the wget_buffer structure).

The length of the buffer will be maintained, but after this function succeeds, the size will obviously be zero.

The same rules that apply to wget_buffer_deinit() also apply here: if you provided your own data when calling wget_buffer_init() (ie. data was non-NULL) then that data will not be freed, and this function will essentially be a no-op.

◆ wget_buffer_reset()

void wget_buffer_reset ( wget_buffer buf)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()

This function is lighter than wget_buffer_free_data(). It does not free the data buffer, it just sets its first byte to zero, as well as the length.

This function is equivalent to:

buf->length = 0;
*buf->data = 0;

◆ wget_buffer_memcpy()

size_t wget_buffer_memcpy ( wget_buffer buf,
const void *  data,
size_t  length 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]dataA pointer to the data to be copied
[in]lengthHow many bytes from data (starting at the beginning) should be copied
Returns
The new length of the buffer after copying the data

Copy the contents in the pointer data to the buffer buf, clobbering the previous contents.

The first length bytes of data are written to buf. The content of buf is overwritten with the new data.

If the buffer is not large enough to store that amount of data, it is enlarged automatically at least length bytes (with wget_buffer_realloc()).

◆ wget_buffer_memcat()

size_t wget_buffer_memcat ( wget_buffer buf,
const void *  data,
size_t  length 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]dataA pointer to the data to be appended
[in]lengthHow many bytes of data should be written to buf
Returns
The new length of the buffer after appending the data

Append the provided data to the end of the buffer buf (preserving contents).

If there's not enough space in buf, it is enlarged automatically (with wget_buffer_realloc()) at least length bytes, so that the whole data can be written.

◆ wget_buffer_strcpy()

size_t wget_buffer_strcpy ( wget_buffer buf,
const char *  s 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]sA NULL-terminated string
Returns
The new length of the buffer after copying the string

Copy the NULL-terminated string s to the buffer buf, overwriting its original contents.

If the buffer is not large enough it is enlarged automatically.

This is essentially equivalent to:

buf->length = 0;
wget_buffer_memcat(buf, s, strlen(s));

◆ wget_buffer_strcat()

size_t wget_buffer_strcat ( wget_buffer buf,
const char *  s 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]sA NULL-terminated string
Returns
The new length of the buffer after appending the string

Append the NULL-terminated string s to the end of the buffer buf (preserving its contents).

If the buffer is not large enough it is enlarged automatically.

This is essentially equivalent to calling wget_buffer_memcat() with length equal to strlen(s):

wget_buffer_memcat(buf, s, strlen(s));

◆ wget_buffer_bufcpy()

size_t wget_buffer_bufcpy ( wget_buffer buf,
wget_buffer src 
)
Parameters
[in]bufThe destination buffer
[in]srcThe source buffer
Returns
The new length of the destination buffer buf after copying the contents of src

Copy the contents of the buffer src in the buffer buf, clobbering its previous contents.

If the buffer buf is not large enough it is enlarged automatically.

This is equivalent to:

wget_buffer_memcpy(buf, src->data, src->length);

◆ wget_buffer_bufcat()

size_t wget_buffer_bufcat ( wget_buffer buf,
wget_buffer src 
)
Parameters
[in]bufThe destination buffer
[in]srcThe source buffer
Returns
The new length of the destination buffer buf after appending the contents of src

Append the contents of the buffer src to the end of the buffer buf.

If the buffer buf is not large enough it is enlarged automatically.

This is equivalent to:

wget_buffer_memcat(buf, src->data, src->length);

◆ wget_buffer_memset()

size_t wget_buffer_memset ( wget_buffer buf,
char  c,
size_t  length 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]cThe byte to be copied at the end of the buffer
[in]lengthHow many times will the byte c be copied.
Returns
The new length of the buffer buf.

Copy the byte c repeatedly length times starting at the beginning of the buffer, so the first length bytes of the buffer are overwritten.

If there's not enough space in buf, it is enlarged automatically (with wget_buffer_realloc()) at least length bytes.

◆ wget_buffer_memset_append()

size_t wget_buffer_memset_append ( wget_buffer buf,
char  c,
size_t  length 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]cThe byte to be copied at the end of the buffer
[in]lengthHow many times will the byte c be copied.
Returns
The new length of the buffer buf.

Copy the byte c at the end of the buffer buf repeatedly length times.

If there's not enough space in buf, it is enlarged automatically (with wget_buffer_realloc()) at least length bytes.

◆ wget_buffer_trim()

char* wget_buffer_trim ( wget_buffer buf)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
Returns
The buffer's new contents

Remove all leading and trailing whitespace from the buffer buf.

The transformation is done in-place, that is, the buffer's original content is overwritten with the new trimmed content.

◆ wget_buffer_vprintf_append()

size_t wget_buffer_vprintf_append ( wget_buffer buf,
const char *  fmt,
va_list  args 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]fmtA printf(3)-like format string
[in]argsA va_list with the format string placeholders' values
Returns
Length of the buffer after appending the formatted string

Formats the string fmt (with printf(3)-like args) and appends the result to the end of the buffer buf (using wget_buffer_memcat()).

For more information, see vprintf(3).

◆ wget_buffer_vprintf()

size_t wget_buffer_vprintf ( wget_buffer buf,
const char *  fmt,
va_list  args 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]fmtA printf(3)-like format string
[in]argsA va_list with the format string placeholders' values
Returns
Length of the buffer after appending the formatted string

Formats the string fmt (with printf(3)-like args) and overwrites the contents of the buffer buf with that formatted string.

This is equivalent to the following code:

buf->length = 0;
wget_buffer_vprintf_append(buf, fmt, args);

For more information, see vprintf(3).

◆ wget_buffer_printf_append()

size_t wget_buffer_printf_append ( wget_buffer buf,
const char *  fmt,
  ... 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]fmtA printf(3)-like format string
[in]...Variable arguments
Returns
Length of the buffer after appending the formatted string

Formats the string fmt (with printf(3)-like args) and appends the result to the end of the buffer buf (using wget_buffer_memcat()).

This function is equivalent to wget_buffer_vprintf_append(), except in that it uses a variable number of arguments rather than a va_list.

For more information, see printf(3).

◆ wget_buffer_printf()

size_t wget_buffer_printf ( wget_buffer buf,
const char *  fmt,
  ... 
)
Parameters
[in]bufA buffer, created with wget_buffer_init() or wget_buffer_alloc()
[in]fmtA printf(3)-like format string
[in]...Variable arguments
Returns
Length of the buffer after appending the formatted string

Formats the string fmt (with printf(3)-like args) and overwrites the contents of the buffer buf with that formatted string.

This function is equivalent to wget_buffer_vprintf(), except in that it uses a variable number of arguments rather than a va_list.

For more information, see printf(3).