Show misc_buf.h syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* $Id: misc_buf.h,v 1.26 2005/10/29 18:35:19 girod Exp $ */
/**
* \file misc_buf.h buffer-related things
* \brief the "buf_t" utility for a growing buffer, and other
* buffer-related things
*/
#ifndef __MISC_BUF_H__
#define __MISC_BUF_H__
#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/**
* buf_t:
* @buf: A pointer to the data. A null character will always appear
* after the last byte of user data
* @len: The number of bytes in the buffer. This does not include the
* space used by the terminating null character automatically added by
* #buf_t
* @alloc_size: not user accesible
* @empty: not user accessible
*
* "buf_t" is a structure that makes it easy to construct a growing
* buffer of data, without worrying about sizing it correctly.
*
* As you add more data to a #buf_t, it automatically grows. The
* allocation is exponential, to guarantee that there won't be more
* than log_2(n) allocations for data of size n. Internally, the
* buffer is always kept in a single block of contiguous memory --
* this makes the implementation slightly less efficient, but makes
* the contents of the buffer easier to use.
*
* A #buf_t can be used for either text or binary data. The contents
* of the buffer are always guaranteed to be null-terminated, for both
* text and binary.
*
* A #buf_t is dynamically allocated, so it must be created using
* buf_new() and destroyed using buf_free().
*
* The user-visible fields of #buf_t are @buf, which is a pointer to
* the data, and @len, which is the number of bytes in @buf.
*
* Once a #buf_t is created using buf_new() it is used as the argument
* to functions such as bufprintf() and bufcpy() when adding data.
* For example, bufprintf() works just like sprintf, except that it
* prints to a #buf_t:
*
* buf_t *buf = buf_new();
*
* bufprintf(buf, "Hi there, for the %d'th time!\n", num_hellos);
* bufprintf(buf, "I hope you enjoy your stay!"); fprintf(stderr, "Message
* is: '%s'\n", buf->buf);
*
* or, alternately, bufcpy() can be used to add binary (non-null-terimnated
* data):
*
* bufcpy(buf, &my_thing, sizeof(my_thing)); bufcpy(buf, &my_other_thing,
* sizeof(my_other_thing)); write(network_file_descriptor, buf->buf,
* buf->len);
*/
typedef struct {
char *buf; /**< pointer to the start of the buffer */
unsigned int len; /**< size of the userdata in the buffer */
unsigned int alloc_size; /**< amount of memory allocated */
char *empty; /**< pointer to first empty character */
} buf_t;
/**
* buf_new:
* Creates a new buffer. It returns a pointer to the buffer on
* success, NULL on failure.
*
* Returns: creates and returns a new #buf_t
*/
buf_t *buf_new();
/**
* buf_free:
* @b: the #buf_t to destroy
*
* Destroy a #buf_t and free its contents
*/
void buf_free(buf_t *b);
/**
* buf_init:
* @b: #buf_t that is declared on the stack and needs to be initialized
*
* For buf_t's that are declared on the stack (i.e. not with buf_new),
* buf_init initializes one
*/
void buf_init(buf_t *b);
/**
* bufcpy:
* @b: #buf_t to copy into
* @src: pointer to data to copy from
* @len: amount of bytes from @src to copy into @b
*
* Add @len bytes of data to @b, starting from @src. If src is null,
* this will just allocate @len space into @b but not increase the
* public len parameter.
*/
void bufcpy(buf_t *b, const void *src, int len);
/**
* bufcat:
* @to: #buf_t to append data to
* @from: #buf_t to copy data from
*
* Copy all the data from @from and add/append it to @to. Equivalent
* to bufcpy(@to, @from->buf, @from->leb)
*/
void bufcat(buf_t *to, const buf_t *from);
/**
* buf_insert:
* @b: #buf_t to insert into
* @offset: location in @b to insert at
* @src: data to insert into @b
* @len: number of bytes to insert
*
* Insert @len bytes of data from @src into @b at location @offset in
* @b. Only works if @offset is valid.
*/
void buf_insert(buf_t *b, uint32_t offset, const void *src, uint32_t len);
/**
* buf_subsume:
* @b: #buf_t to modify
* @len: Number of bytes to subsume
*
* For performance reasons it is sometimes preferable to pre-allocate a
* buffer and write directly into the allocated space, beyond the "length"
* (but still in an allocated region). After doing so, we need to move
* the length pointer forward to subsume these allocated and written bytes.
*
* e.g.:
*
* buf_t *serial_data = buf_new(); // allocate a buffer
* buf_prealloc(serial_data, READ_LEN); // pre-alloc space
* int status = read(fd, buf_get_prealloc_buf(serial_data),
* buf_get_prealloc_len(serial_data));
* if (status > 0)
* buf_subsume(serial_data, status);
*/
int buf_subsume(buf_t *b, size_t len);
/**
* bufcpy_zeros:
* @b: #buf_t to append zeros to
* @len: number of zero bytes to append to @b
*
* Append/Add @len bytes of 0's to @b.
*/
void bufcpy_zeroes(buf_t *b, int len);
/**
* buf_prealloc
* @buf: #buf_t to allocate space in
*
* Allocates to ensures there is specified allocated space at
* the end of @buf
*
*/
void buf_prealloc(buf_t *buf, size_t space);
/**
* buf_shorten:
* @b: #buf_t to shorten
* @count: number of bytes to shorten @b by
*
* Removes bytes from the end of a @b. Does not add '\0' to new end.
*
* Returns: count if successfull, -1 if count > then actual len.
*/
int buf_shorten(buf_t *b, int count);
/**
* buf_clear:
* @b: #buf_t to clear
* @dealloc: set to 1 to free @b->buf and zero out *@b
*
* Clears @b by calling buf_shorten() for the length of @b. If
* @dealloc is set to 1, free's the bufer and zeros out *@b.
*
* Returns: 0 if @dealloc set to 1 or length of @b is zero, -1 if buf
* is invalid, otherwise returns the length of @b.
*/
int buf_clear(buf_t *b, int dealloc);
/**
* buf_remove:
* @buf: #buf_t to remove data from
* @start: location in @buf to start removing from
* @count: number of bytes to remove from @buf
*
* Removes @count bytes from the middle of @buf at @start
*
* Returns: new length of @buf, -1 if there is an error
*/
int buf_remove(buf_t *buf, int start, int count);
/**
* buf_swap:
* @a: #buf_t to swap
* @b: #buf_t to swap
*
* swap the data of two buf_t's
*/
void buf_swap(buf_t *a, buf_t *b);
/**
* steal_to_buf:
* @a: #buf_t to replace
* @mem_to_steal: memory buffer to use in the #buf_t
* @size: size of memory buffer
*
* frees any memory in the given buf and swaps the
* specified pointer into the buf
*/
void steal_to_buf(buf_t *a, char *mem_to_steal, int size);
/**
* bufcmp:
* @buf1: #buf_t to compare
* @buf2: #buf_t to compare
*
* #buf_t comparison
*
* Returns: returns an integer less than, equal to, or greater than
* zero if @buf1, respectively, to be less than, to match, or be
* greater than @buf2.
*/
int bufcmp(buf_t *buf1, buf_t *buf2);
/**
* bufprintf:
* @b: #buf_t to print string to
* @fnt: format of string to print
*
* Identical to sprintf, but output goes to a buf_t.
*/
void bufprintf(buf_t *b, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
/**
* buf_get:
* @buf: #buf_t to retrieve underlying buffer from
*
* Get the char* from @buf... same as @buf->buf
*
* Returns: the data in the @buf
*/
char *buf_get(buf_t *buf);
/**
* buf_len:
* @buf: #buf_t to get the length of
*
* Returns the amount of data in bytes in @buf
*
* Returns: The length of the buffer
*/
size_t buf_len(buf_t *buf);
/**
* buf_get_allocated_len:
* @buf: #buf_t to get the allocated region of
*
* Returns the amount of space allocated in @buf
*
* Returns: number of bytes allocated
*/
size_t buf_get_allocated_len(buf_t *buf);
/**
* buf_get_prealloc_len
* @buf: #buf_t to get the pre-allocated region of
*
* Returns the amount of pre-allocated space (unused space at end)
*
* Returns: number of bytes pre-allocated
*/
size_t buf_get_prealloc_len(buf_t *buf);
/**
* buf_get_prealloc_buf
* @buf: #buf_t to get pointer to pre-allocated region of
*
* Returns pointer to pre-allocated space (unused space at end)
*
* Returns: pointer to pre-allocated space
*/
char *buf_get_prealloc_buf(buf_t *buf);
/**
* file_to_buf:
* @buf: #buf_t to write data into
* @filename: file to open and read into @buf
*
* Opens a file and tries to read the entire file into @buf
*
* Returns: number of bytes read in, -1 if there was a problem
*/
int file_to_buf(buf_t *buf, const char *filename);
/**
* buf_to_file:
* @filename: the file to open and output to (overwrites the file)
* @buf: #buf_t that contains the data to write to the file
*
* Opens the @filename (overwrite mode), and attempts to dump the buf to the file
*
* Returns: 0 on success, non zero result on error
*/
int buf_to_file(const char *filename, buf_t *buf);
/**
* buf_print_raw:
* @buf: #buf_t to write to
* @str: string to write from
* @len: number of bytes to write to @buf from @str
*
* Write @len bytes of the string @str to @buf without converting any
* of hte formats
*/
void buf_print_raw(buf_t *buf, char *str, int len);
/**
* buf_pop_chars:
* @buf: #buf_t to pop chars from
* @count: number of chars to pop from the front of @buf
*
* Remove @count chars from the front of @buf
*
* Returns: the number of chars poped, -1 if count > @buf->len
*/
int buf_pop_chars(buf_t *buf, int count);
/*
* buf_t item iterators
* the buf_t item iterator appends and traverses a buf_t composed of a
* series of items, each of which is preceded by a length field.
*/
typedef uint16_t item_size_t;
typedef struct buf_iter buf_iter_t;
buf_iter_t *buf_item_iter_new(buf_t *buf);
void buf_item_iter_destroy(buf_iter_t *iter, int free_buf);
/* sets an iterator from another iterator */
void buf_item_iter_set(buf_iter_t *to, buf_iter_t *from);
void buf_item_iter_top(buf_iter_t *iter);
void buf_item_iter_append_buf(buf_iter_t *iter, buf_t *buf);
void buf_item_iter_append_str(buf_iter_t *iter, const char *str, int len);
buf_t *buf_item_iter_get_buf(buf_iter_t *iter, buf_t *into);
char *buf_item_iter_get_pointer(buf_iter_t *iter, int min_valid_length);
void buf_item_iter_remove(buf_iter_t *iter);
int buf_item_iter_next(buf_iter_t *iter);
item_size_t buf_item_iter_length(buf_iter_t *iter);
int buf_item_iter_valid(buf_iter_t *iter);
#endif /* __MISC_BUF_H__ */
See more files for this project here