GSK Reference Manual | ||||
---|---|---|---|---|
GskBuffer; GskBufferFragment; void gsk_buffer_construct (GskBuffer *buffer); guint gsk_buffer_read (GskBuffer *buffer, gpointer data, guint max_length); guint gsk_buffer_peek (const GskBuffer *buffer, gpointer data, guint max_length); int gsk_buffer_discard (GskBuffer *buffer, guint max_discard); char* gsk_buffer_read_line (GskBuffer *buffer); char* gsk_buffer_parse_string0 (GskBuffer *buffer); int gsk_buffer_peek_char (const GskBuffer *buffer); int gsk_buffer_read_char (GskBuffer *buffer); void gsk_buffer_append (GskBuffer *buffer, gconstpointer data, guint length); void gsk_buffer_append_string (GskBuffer *buffer, const char *string); void gsk_buffer_append_char (GskBuffer *buffer, char character); void gsk_buffer_append_string0 (GskBuffer *buffer, const char *string); void gsk_buffer_append_foreign (GskBuffer *buffer, gconstpointer data, int length, GDestroyNotify destroy, gpointer destroy_data); void gsk_buffer_printf (GskBuffer *buffer, const char *format, ...); void gsk_buffer_vprintf (GskBuffer *buffer, const char *format, va_list args); guint gsk_buffer_drain (GskBuffer *dst, GskBuffer *src); guint gsk_buffer_transfer (GskBuffer *dst, GskBuffer *src, guint max_transfer); int gsk_buffer_writev (GskBuffer *read_from, int fd); int gsk_buffer_read_in_fd (GskBuffer *write_to, int read_from); int gsk_buffer_index_of (GskBuffer *buffer, char char_to_find); int gsk_buffer_polystr_index_of (GskBuffer *buffer, char **strings); void gsk_buffer_destruct (GskBuffer *to_destroy); void gsk_buffer_cleanup_recycling_bin (); GskBufferIterator; #define gsk_buffer_iterator_offset (iterator) void gsk_buffer_iterator_construct (GskBufferIterator *iterator, GskBuffer *to_iterate); guint gsk_buffer_iterator_peek (GskBufferIterator *iterator, gpointer out, guint max_length); guint gsk_buffer_iterator_read (GskBufferIterator *iterator, gpointer out, guint max_length); guint gsk_buffer_iterator_skip (GskBufferIterator *iterator, guint max_length); gboolean gsk_buffer_iterator_find_char (GskBufferIterator *iterator, char c); #define GSK_BUFFER_STATIC_INIT
This code manages a binary data buffer.
Data is maintained first-in first-out; so
gsk_buffer_append()
writes to the end of the buffer,
and gsk_buffer_read()
reads from the beginning.
typedef struct { guint size; GskBufferFragment *first_frag; GskBufferFragment *last_frag; } GskBuffer;
A buffer is just a list of fragments and a size counter.
guint size ; |
the number of bytes in the buffer total. |
GskBufferFragment *first_frag ; |
the first fragment in the buffer (read end) |
GskBufferFragment *last_frag ; |
the last fragment in the buffer (write end) |
typedef struct { GskBufferFragment *next; char *buf; guint buf_max_size; /* allocation size of buf */ guint buf_start; /* offset in buf of valid data */ guint buf_length; /* length of valid data in buf */ gboolean is_foreign; GDestroyNotify destroy; gpointer destroy_data; } GskBufferFragment;
This structure should rarely be accessed directly, instead you should use the GskBuffer methods. They are exposed for optimization and debugging convenience.
A single contiguous chunk of memory in the buffer. Each GskBufferFragment is managed by a single buffer, but internally fragments are sometimes transferred whole between buffers.
A foreign fragment is one which created with
gsk_buffer_append_foreign()
. It means that gsk
will use the destroy method rather than the normal
buffer pool, where data and the GskBufferFragment
are allocated continguously.
The headers of foreign fragments are pooled in a separate pool.
GskBufferFragment *next ; |
next fragment in the buffer. |
char *buf ; |
raw data in the buffer |
guint buf_max_size ; |
maximum size of buffer, assuming buf_start==0. |
guint buf_start ; |
offset in buf of first readable data.
|
guint buf_length ; |
number of bytes currently in the buffer. |
gboolean is_foreign ; |
is this fragment foreign? |
GDestroyNotify destroy ; |
function to free foreign data. |
gpointer destroy_data ; |
data to destroy to free buf, if foreign. |
void gsk_buffer_construct (GskBuffer *buffer);
Construct an empty buffer out of raw memory. (This is equivalent to filling the buffer with 0s)
buffer : |
buffer to initialize (as empty). |
guint gsk_buffer_read (GskBuffer *buffer, gpointer data, guint max_length);
Removes up to max_length
data from the beginning of the buffer,
and writes it to data
. The number of bytes actually read
is returned.
buffer : |
the buffer to read data from. |
data : |
buffer to fill with up to max_length bytes of data.
|
max_length : |
maximum number of bytes to read. |
Returns : | number of bytes transferred. |
guint gsk_buffer_peek (const GskBuffer *buffer, gpointer data, guint max_length);
Copies up to max_length
data from the beginning of the buffer,
and writes it to data
. The number of bytes actually copied
is returned.
This function is just like gsk_buffer_read()
except that the
data is not removed from the buffer.
buffer : |
the buffer to peek data from the front of. This buffer is unchanged by the operation. |
data : |
buffer to fill with up to max_length bytes of data.
|
max_length : |
maximum number of bytes to peek. |
Returns : | number of bytes copied into data. |
int gsk_buffer_discard (GskBuffer *buffer, guint max_discard);
Removes up to max_discard
data from the beginning of the buffer,
and returns the number of bytes actually discarded.
buffer : |
the buffer to discard data from. |
max_discard : |
maximum number of bytes to discard. |
Returns : | number of bytes discarded. |
char* gsk_buffer_read_line (GskBuffer *buffer);
Parse a newline (\n) terminated line from buffer and return it as a newly allocated string. The newline is changed to a NUL character.
If the buffer does not contain a newline, then NULL is returned.
buffer : |
buffer to read a line from. |
Returns : | a newly allocated NUL-terminated string, or NULL. |
char* gsk_buffer_parse_string0 (GskBuffer *buffer);
Parse a NUL-terminated line from buffer and return it as a newly allocated string.
If the buffer does not contain a newline, then NULL is returned.
buffer : |
buffer to read a line from. |
Returns : | a newly allocated NUL-terminated string, or NULL. |
int gsk_buffer_peek_char (const GskBuffer *buffer);
Get the first byte in the buffer as a positive or 0 number. If the buffer is empty, -1 is returned. The buffer is unchanged.
buffer : |
buffer to peek a single byte from. |
Returns : | an unsigned character or -1. |
int gsk_buffer_read_char (GskBuffer *buffer);
Get the first byte in the buffer as a positive or 0 number, and remove the character from the buffer. If the buffer is empty, -1 is returned.
buffer : |
buffer to read a single byte from. |
Returns : | an unsigned character or -1. |
void gsk_buffer_append (GskBuffer *buffer, gconstpointer data, guint length);
Append data into the buffer.
buffer : |
the buffer to add data to. Data is put at the end of the buffer. |
data : |
binary data to add to the buffer. |
length : |
length of data to add to the buffer.
|
void gsk_buffer_append_string (GskBuffer *buffer, const char *string);
Append a string to the buffer.
buffer : |
the buffer to add data to. Data is put at the end of the buffer. |
string : |
NUL-terminated string to append to the buffer. The NUL is not appended. |
void gsk_buffer_append_char (GskBuffer *buffer, char character);
Append a byte to a buffer.
buffer : |
the buffer to add the byte to. |
character : |
the byte to add to the buffer. |
void gsk_buffer_append_string0 (GskBuffer *buffer, const char *string);
Append a NUL-terminated string to the buffer. The NUL is appended.
buffer : |
the buffer to add data to. Data is put at the end of the buffer. |
string : |
NUL-terminated string to append to the buffer; NUL is appended. |
void gsk_buffer_append_foreign (GskBuffer *buffer, gconstpointer data, int length, GDestroyNotify destroy, gpointer destroy_data);
This function allows data to be placed in a buffer without
copying. It is the callers' responsibility to ensure that
data
will remain valid until the destroy method is called.
destroy
may be omitted if data
is permanent, for example,
if appended a static string into a buffer.
buffer : |
the buffer to append into. |
data : |
the data to append. |
length : |
length of data .
|
destroy : |
optional method to call when the data is no longer needed. |
destroy_data : |
the argument to the destroy method. |
void gsk_buffer_printf (GskBuffer *buffer, const char *format, ...);
Append printf-style content to a buffer.
buffer : |
the buffer to append to. |
format : |
printf-style format string describing what to append to buffer. |
... : |
values referenced by format string.
|
void gsk_buffer_vprintf (GskBuffer *buffer, const char *format, va_list args);
Append printf-style content to a buffer, given a va_list.
buffer : |
the buffer to append to. |
format : |
printf-style format string describing what to append to buffer. |
args : |
values referenced by format string.
|
guint gsk_buffer_drain (GskBuffer *dst, GskBuffer *src);
Transfer all data from src
to dst
,
leaving src
empty.
dst : |
buffer to add to. |
src : |
buffer to remove from. |
Returns : | the number of bytes transferred. |
guint gsk_buffer_transfer (GskBuffer *dst, GskBuffer *src, guint max_transfer);
Transfer data out of src
and into dst
.
Data is removed from src
. The number of bytes
transferred is returned.
dst : |
place to copy data into. |
src : |
place to read data from. |
max_transfer : |
maximum number of bytes to transfer. |
Returns : | the number of bytes transferred. |
int gsk_buffer_writev (GskBuffer *read_from, int fd);
Writes as much data as possible to the given file-descriptor using the writev(2) function to deal with multiple fragments efficiently, where available.
read_from : |
buffer to take data from. |
fd : |
file-descriptor to write data to. |
Returns : | the number of bytes transferred, or -1 on a write error (consult errno). |
int gsk_buffer_read_in_fd (GskBuffer *write_to, int read_from);
Append data into the buffer directly from the given file-descriptor.
write_to : |
buffer to append data to. |
read_from : |
file-descriptor to read data from. |
Returns : | the number of bytes transferred, or -1 on a read error (consult errno). |
int gsk_buffer_index_of (GskBuffer *buffer, char char_to_find);
Scans for the first instance of the given character.
buffer : |
buffer to scan. |
char_to_find : |
a byte to look for. |
Returns : | its index in the buffer, or -1 if the character is not in the buffer. |
int gsk_buffer_polystr_index_of (GskBuffer *buffer, char **strings);
Scans for the first instance of any of the strings in the buffer.
buffer : |
buffer to scan. |
strings : |
NULL-terminated set of string. |
Returns : | the index of that instance, or -1 if not found. |
void gsk_buffer_destruct (GskBuffer *to_destroy);
Remove all fragments from a buffer, leaving it empty. The buffer is guaranteed to not to be consuming any resources, but it also is allowed to start using it again.
to_destroy : |
the buffer to empty. |
void gsk_buffer_cleanup_recycling_bin ();
Free unused buffer fragments. (Normally some are kept around to reduce strain on the global allocator.)
typedef struct { GskBufferFragment *fragment; guint in_cur; guint cur_length; const guint8 *cur_data; guint offset; } GskBufferIterator;
An iterator which can be used to walk through a buffer.
You MUST not modify the buffer that you are editing in any way.
TODO: exceptions to the above may be feasible, but we have to see what the demands are...
GskBufferFragment *fragment ; |
which fragment we are currently in. |
guint in_cur ; |
the offset in bytes into fragment .
|
guint cur_length ; |
the length of fragment. |
const guint8 *cur_data ; |
the data of fragment. |
guint offset ; |
the offset in bytes into the whole buffer. |
#define gsk_buffer_iterator_offset(iterator) ((iterator)->offset)
Get the offset in bytes into GskBuffer that we are into the whole buffer.
iterator : |
the iterator to examine. |
void gsk_buffer_iterator_construct (GskBufferIterator *iterator, GskBuffer *to_iterate);
Initialize a new GskBufferIterator.
iterator : |
to initialize. |
to_iterate : |
the buffer to walk through. |
guint gsk_buffer_iterator_peek (GskBufferIterator *iterator, gpointer out, guint max_length);
Peek data from the current position of an iterator. The iterator's position is not changed.
iterator : |
to peek data from. |
out : |
to copy data into. |
max_length : |
maximum number of bytes to write to out .
|
Returns : | number of bytes peeked into out .
|
guint gsk_buffer_iterator_read (GskBufferIterator *iterator, gpointer out, guint max_length);
Peek data from the current position of an iterator. The iterator's position is updated to be at the end of the data read.
iterator : |
to read data from. |
out : |
to copy data into. |
max_length : |
maximum number of bytes to write to out .
|
Returns : | number of bytes read into out .
|
guint gsk_buffer_iterator_skip (GskBufferIterator *iterator, guint max_length);
Advance an iterator forward in the buffer, returning the number of bytes skipped.
iterator : |
to advance. |
max_length : |
maximum number of bytes to skip forward. |
Returns : | number of bytes skipped forward. |
gboolean gsk_buffer_iterator_find_char (GskBufferIterator *iterator, char c);
If it exists,
skip forward to the next instance of c
and return TRUE.
Otherwise, do nothing and return FALSE.
iterator : |
to advance. |
c : |
the character to look for. |
Returns : | whether the character was found. |