![]() |
wget2
2.0.0
|
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)
Example with wget_buffer on the stack and 16 bytes initial stack buffer (no heap allocation is needed)
Example on how to check for memory failure and how to transfer buffer data
int wget_buffer_init | ( | wget_buffer * | buf, |
char * | data, | ||
size_t | size | ||
) |
[in] | buf | Pointer to the buffer that should become initialized. |
[in] | data | Initial contents of the buffer. Might be NULL. |
[in] | size | Initial length of the buffer. Might be zero (will default to 128 bytes). |
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:
data
pointer, you must free it yourself before your program ends.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* wget_buffer_alloc | ( | size_t | size | ) |
[in] | size | Initial length of the 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).
int wget_buffer_ensure_capacity | ( | wget_buffer * | buf, |
size_t | size | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | size | Total size (in bytes) required in the buffer |
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.
void wget_buffer_deinit | ( | wget_buffer * | buf | ) |
[in] | buf | A 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.
void wget_buffer_free | ( | wget_buffer ** | buf | ) |
[in] | buf | A 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;
void wget_buffer_free_data | ( | wget_buffer * | buf | ) |
[in] | buf | A 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.
void wget_buffer_reset | ( | wget_buffer * | buf | ) |
[in] | buf | A 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;
size_t wget_buffer_memcpy | ( | wget_buffer * | buf, |
const void * | data, | ||
size_t | length | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | data | A pointer to the data to be copied |
[in] | length | How many bytes from data (starting at the beginning) should be copied |
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()).
size_t wget_buffer_memcat | ( | wget_buffer * | buf, |
const void * | data, | ||
size_t | length | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | data | A pointer to the data to be appended |
[in] | length | How many bytes of data should be written to buf |
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.
size_t wget_buffer_strcpy | ( | wget_buffer * | buf, |
const char * | s | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | s | A NULL-terminated 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));
size_t wget_buffer_strcat | ( | wget_buffer * | buf, |
const char * | s | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | s | A NULL-terminated 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));
size_t wget_buffer_bufcpy | ( | wget_buffer * | buf, |
wget_buffer * | src | ||
) |
[in] | buf | The destination buffer |
[in] | src | The source 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);
size_t wget_buffer_bufcat | ( | wget_buffer * | buf, |
wget_buffer * | src | ||
) |
[in] | buf | The destination buffer |
[in] | src | The source 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);
size_t wget_buffer_memset | ( | wget_buffer * | buf, |
char | c, | ||
size_t | length | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | c | The byte to be copied at the end of the buffer |
[in] | length | How many times will the byte c be copied. |
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.
size_t wget_buffer_memset_append | ( | wget_buffer * | buf, |
char | c, | ||
size_t | length | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | c | The byte to be copied at the end of the buffer |
[in] | length | How many times will the byte c be copied. |
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.
char* wget_buffer_trim | ( | wget_buffer * | buf | ) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
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.
size_t wget_buffer_vprintf_append | ( | wget_buffer * | buf, |
const char * | fmt, | ||
va_list | args | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | fmt | A printf(3) -like format string |
[in] | args | A va_list with the format string placeholders' values |
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)
.
size_t wget_buffer_vprintf | ( | wget_buffer * | buf, |
const char * | fmt, | ||
va_list | args | ||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | fmt | A printf(3) -like format string |
[in] | args | A va_list with the format string placeholders' values |
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)
.
size_t wget_buffer_printf_append | ( | wget_buffer * | buf, |
const char * | fmt, | ||
... | |||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | fmt | A printf(3) -like format string |
[in] | ... | Variable arguments |
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)
.
size_t wget_buffer_printf | ( | wget_buffer * | buf, |
const char * | fmt, | ||
... | |||
) |
[in] | buf | A buffer, created with wget_buffer_init() or wget_buffer_alloc() |
[in] | fmt | A printf(3) -like format string |
[in] | ... | Variable arguments |
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)
.