@ -11,74 +11,96 @@
# include <sys/types.h>
# include <stdio.h>
# if defined HAVE_STDINT_H
# include <stdint.h>
# elif defined HAVE_INTTYPES_H
# include <inttypes.h>
# endif
/* generic string + binary data container; contains a terminating 0 in both
* cases
*
* used = = 0 indicates a special " empty " state ( unset config values ) ; ptr
* might be NULL too then . otherwise an empty string has used = = 1 ( and ptr [ 0 ]
* = = 0 ) ;
*
* copy / append functions will ensure used > = 1 ( i . e . never leave it in the
* special empty state ) ; only buffer_copy_buffer will copy the special empty
* state .
*/
typedef struct {
char * ptr ;
/* "used" includes a terminating 0 */
size_t used ;
/* size of allocated buffer at *ptr */
size_t size ;
} buffer ;
typedef struct {
buffer * * ptr ;
size_t used ;
size_t size ;
} buffer_array ;
typedef struct {
char * ptr ;
size_t offset ; /* input-pointer */
size_t used ; /* output-pointer */
size_t size ;
} read_buffer ;
buffer_array * buffer_array_init ( void ) ;
void buffer_array_free ( buffer_array * b ) ;
void buffer_array_reset ( buffer_array * b ) ;
buffer * buffer_array_append_get_buffer ( buffer_array * b ) ;
/* create new buffer; either empty or copy given data */
buffer * buffer_init ( void ) ;
buffer * buffer_init_buffer ( buffer * b ) ;
buffer * buffer_init_string ( const char * str ) ;
void buffer_free ( buffer * b ) ;
void buffer_reset ( buffer * b ) ;
int buffer_prepare_copy ( buffer * b , size_t size ) ;
int buffer_prepare_append ( buffer * b , size_t size ) ;
int buffer_copy_string ( buffer * b , const char * s ) ;
int buffer_copy_string_len ( buffer * b , const char * s , size_t s_len ) ;
int buffer_copy_string_buffer ( buffer * b , const buffer * src ) ;
int buffer_copy_string_hex ( buffer * b , const char * in , size_t in_len ) ;
int buffer_copy_long ( buffer * b , long val ) ;
int buffer_copy_memory ( buffer * b , const char * s , size_t s_len ) ;
int buffer_append_string ( buffer * b , const char * s ) ;
int buffer_append_string_len ( buffer * b , const char * s , size_t s_len ) ;
int buffer_append_string_buffer ( buffer * b , const buffer * src ) ;
int buffer_append_string_lfill ( buffer * b , const char * s , size_t maxlen ) ;
int buffer_append_string_rfill ( buffer * b , const char * s , size_t maxlen ) ;
int buffer_append_long_hex ( buffer * b , unsigned long len ) ;
int buffer_append_long ( buffer * b , long val ) ;
# if defined(SIZEOF_LONG) && (SIZEOF_LONG == SIZEOF_OFF_T)
# define buffer_copy_off_t(x, y) buffer_copy_long(x, y)
# define buffer_append_off_t(x, y) buffer_append_long(x, y)
# else
int buffer_copy_off_t ( buffer * b , off_t val ) ;
int buffer_append_off_t ( buffer * b , off_t val ) ;
# endif
int buffer_append_memory ( buffer * b , const char * s , size_t s_len ) ;
buffer * buffer_init_buffer ( const buffer * src ) ; /* src can be NULL */
buffer * buffer_init_string ( const char * str ) ; /* str can be NULL */
void buffer_free ( buffer * b ) ; /* b can be NULL */
/* truncates to used == 0; frees large buffers, might keep smaller ones for reuse */
void buffer_reset ( buffer * b ) ; /* b can be NULL */
/* reset b. if NULL != b && NULL != src, move src content to b. reset src. */
void buffer_move ( buffer * b , buffer * src ) ;
/* prepare for size bytes in the buffer (b->size > size), destroys content
* ( sets used = 0 and ptr [ 0 ] = 0 ) . allocates storage for terminating 0.
* @ return b - > ptr
*/
char * buffer_prepare_copy ( buffer * b , size_t size ) ;
/* prepare for appending size bytes to the buffer
* allocates storage for terminating 0 ; if used > 0 assumes ptr [ used - 1 ] = = 0 ,
* i . e . doesn ' t allocate another byte for terminating 0.
* @ return ( b - > used > 0 ? b - > ptr + b - > used - 1 : b - > ptr ) - first new character
*/
char * buffer_prepare_append ( buffer * b , size_t size ) ;
/* use after prepare_(copy,append) when you have written data to the buffer
* to increase the buffer length by size . also sets the terminating zero .
* requires enough space is present for the terminating zero ( prepare with the
* same size to be sure ) .
*/
void buffer_commit ( buffer * b , size_t size ) ;
void buffer_copy_string ( buffer * b , const char * s ) ;
void buffer_copy_string_len ( buffer * b , const char * s , size_t s_len ) ;
void buffer_copy_buffer ( buffer * b , const buffer * src ) ;
/* convert input to hex and store in buffer */
void buffer_copy_string_hex ( buffer * b , const char * in , size_t in_len ) ;
void buffer_append_string ( buffer * b , const char * s ) ;
void buffer_append_string_len ( buffer * b , const char * s , size_t s_len ) ;
void buffer_append_string_buffer ( buffer * b , const buffer * src ) ;
void buffer_append_long_hex ( buffer * b , unsigned long len ) ;
void buffer_append_int ( buffer * b , intmax_t val ) ;
void buffer_copy_int ( buffer * b , intmax_t val ) ;
/* '-', log_10 (2^bits) = bits * log 2 / log 10 < bits * 0.31, terminating 0 */
# define LI_ITOSTRING_LENGTH (2 + (8 * sizeof(intmax_t) * 31 + 99) / 100)
void li_itostrn ( char * buf , size_t buf_len , intmax_t val ) ;
void li_itostr ( char * buf , intmax_t val ) ; /* buf must have at least LI_ITOSTRING_LENGTH bytes */
void li_utostrn ( char * buf , size_t buf_len , uintmax_t val ) ;
void li_utostr ( char * buf , uintmax_t val ) ; /* buf must have at least LI_ITOSTRING_LENGTH bytes */
char * buffer_search_string_len ( buffer * b , const char * needle , size_t len ) ;
/* NULL buffer or empty buffer (used == 0);
* unset " string " ( buffer ) config options are initialized to used = = 0 ,
* while setting an empty string leads to used = = 1
*/
int buffer_is_empty ( buffer * b ) ;
/* NULL buffer, empty buffer (used == 0) or empty string (used == 1) */
int buffer_string_is_empty ( buffer * b ) ;
int buffer_is_equal ( buffer * a , buffer * b ) ;
int buffer_is_equal_right_len ( buffer * a , buffer * b , size_t len ) ;
int buffer_is_equal_string ( buffer * a , const char * s , size_t b_len ) ;
@ -86,7 +108,6 @@ int buffer_is_equal_caseless_string(buffer *a, const char *s, size_t b_len);
int buffer_caseless_compare ( const char * a , size_t a_len , const char * b , size_t b_len ) ;
typedef enum {
ENCODING_UNSET ,
ENCODING_REL_URI , /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */
ENCODING_REL_URI_PART , /* same as ENC_REL_URL plus coding / too as %2F */
ENCODING_HTML , /* & becomes & and so on */
@ -95,17 +116,17 @@ typedef enum {
ENCODING_HTTP_HEADER /* encode \n with \t\n */
} buffer_encoding_t ;
int buffer_append_string_encoded ( buffer * b , const char * s , size_t s_len , buffer_encoding_t encoding ) ;
void buffer_append_string_encoded ( buffer * b , const char * s , size_t s_len , buffer_encoding_t encoding ) ;
void buffer_urldecode_path ( buffer * url ) ;
void buffer_urldecode_query ( buffer * url ) ;
void buffer_path_simplify ( buffer * dest , buffer * src ) ;
int buffer_urldecode_path ( buffer * url ) ;
int buffer_urldecode_query ( buffer * url ) ;
int buffer_path_simplify ( buffer * dest , buffer * src ) ;
void buffer_to_lower ( buffer * b ) ;
void buffer_to_upper ( buffer * b ) ;
int buffer_to_lower ( buffer * b ) ;
int buffer_to_upper ( buffer * b ) ;
/** deprecated */
int LI_ltostr ( char * buf , long val ) ;
char hex2int ( unsigned char c ) ;
char int2hex ( char i ) ;
@ -114,17 +135,17 @@ int light_isxdigit(int c);
int light_isalpha ( int c ) ;
int light_isalnum ( int c ) ;
static inline size_t buffer_string_length ( const buffer * b ) ; /* buffer string length without terminating 0 */
static inline void buffer_append_slash ( buffer * b ) ; /* append '/' no non-empty strings not ending in '/' */
# define BUFFER_APPEND_STRING_CONST(x, y) \
buffer_append_string_len ( x , y , sizeof ( y ) - 1 )
# define BUFFER_COPY_STRING_CONST(x, y) \
buffer_copy_string_len ( x , y , sizeof ( y ) - 1 )
# define BUFFER_APPEND_SLASH(x) \
if ( x - > used > 1 & & x - > ptr [ x - > used - 2 ] ! = ' / ' ) { BUFFER_APPEND_STRING_CONST ( x , " / " ) ; }
# define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0
# define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0
# define CONST_STR_LEN(x) x, (x) ? sizeof(x) - 1 : 0
# define CONST_BUF_LEN(x) (x)->ptr, buffer_string_length(x)
# define UNUSED(x) ( (void)(x) )
@ -134,4 +155,15 @@ void log_failed_assert(const char *filename, unsigned int line, const char *msg)
# define force_assert(x) do { if (!(x)) log_failed_assert(__FILE__, __LINE__, "assertion failed: " #x); } while(0)
# define SEGFAULT() log_failed_assert(__FILE__, __LINE__, "aborted");
/* inline implementations */
static inline size_t buffer_string_length ( const buffer * b ) {
return NULL ! = b & & 0 ! = b - > used ? b - > used - 1 : 0 ;
}
static inline void buffer_append_slash ( buffer * b ) {
size_t len = buffer_string_length ( b ) ;
if ( len > 0 & & ' / ' ! = b - > ptr [ len - 1 ] ) BUFFER_APPEND_STRING_CONST ( b , " / " ) ;
}
# endif