fsl_buffer Struct Reference

A general-purpose buffer class, analog to Fossil v1's Blob class, but it is not called fsl_blob to avoid confusion with DB-side blobs. More...

#include "fossil-util.h"

Data Fields

fsl_size_t capacity
 Number of bytes allocated for this buffer. More...
fsl_size_t cursor
 Used by some routines to keep a cursor into this->mem. More...
unsigned char * mem
 The raw memory owned by this buffer. More...
fsl_size_t used
 Number of "used" bytes in the buffer. More...

Detailed Description

A general-purpose buffer class, analog to Fossil v1's Blob class, but it is not called fsl_blob to avoid confusion with DB-side blobs.

Buffers are used extensively in fossil to do everything from reading files to compressing artifacts to creating dynamically-formatted strings. Because they are such a pervasive low-level type, and have such a simple structure, their members (unlike most other structs in this API) may be considered public and used directly by client code (as long as they do not mangle their state, e.g. by setting this->capacity smaller than this->used!).

General conventions of this class:

  • ALWAYS initialize them by copying fsl_buffer_empty or (depending on the context) fsl_buffer_empty_m. Failing to initialize them properly leads to undefined behaviour.
  • ALWAYS fsl_buffer_clear() buffers when done with them. Remember that failed routines which output to buffers might partially populate the buffer, so be sure to clean up on error cases.
  • The 'capacity' member specifies how much memory the buffer current holds in its 'mem' member.
  • The 'used' member specifies how much of the memory is actually "in use" by the client.
  • As a rule, the API tries to keep (used<capacity) and always (unless documented otherwise) tries to keep the memory buffer NUL-terminated (if it has any memory at all).
  • Use fsl_buffer_reset() to keep memory around and reset the 'used' amount to 0. Most rountines which write to buffers will re-use that memory if they can.

This example demonstrates the difference between 'used' and 'capacity' (error checking reduced to assert()ions for clarity):

int rc = fsl_buffer_reserve(&b, 20);
assert(b.capacity>=20); // it may reserve more!
rc = fsl_buffer_append(&b, "abc", 3);
assert(0==b.mem[b.used]); // API always NUL-terminates
See also

Definition at line 632 of file fossil-util.h.

Field Documentation

fsl_size_t fsl_buffer::capacity

Number of bytes allocated for this buffer.

Definition at line 644 of file fossil-util.h.

fsl_size_t fsl_buffer::cursor

Used by some routines to keep a cursor into this->mem.

TODO: factor this back out and let those cases keep their own state. This is only used by fsl_input_f_buffer() (and that function cannot be implemented unless we add the cursor here or add another layer of state type specifically for it).

Definition at line 671 of file fossil-util.h.

unsigned char* fsl_buffer::mem

The raw memory owned by this buffer.

It is this->capacity bytes long, of which this->used are considered "used" by the client. The difference beween (this->capacity - this->used) represents space the buffer has available for use before it will require another expansion/reallocation.

Definition at line 640 of file fossil-util.h.

fsl_size_t fsl_buffer::used

Number of "used" bytes in the buffer.

This is generally interpreted as the string length of this->mem, and the buffer APIs which add data to a buffer always ensure that this->capacity is large enough to account for a trailing NUL byte in this->mem.

Library routines which manipulate buffers must ensure that (this->used<=this->capacity) is always true, expanding the buffer if necessary. Much of the API assumes that precondition is always met, and any violation of it opens the code to undefined behaviour (which is okay, just don't ever break that precondition). Most APIs ensure that (used<capacity) is always true (as opposed to used<=capacity) because they add a trailing NUL byte which is not counted in the "used" length.

Definition at line 661 of file fossil-util.h.

The documentation for this struct was generated from the following file: