Files
libucore/include/ucore/dstr.h
T
2014-08-26 21:39:08 +02:00

178 lines
5.0 KiB
C

#ifndef UC_DSTR_H_
#define UC_DSTR_H_
#include <stddef.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/** A managed C-string, using dynamically allocated memory for the string.
*
* The .str member might not always be nul terminated,
* Normally, use uc_dstr_str() to retreive the managed string
* instead of accessing ->str directly.
*
* Normally, let the DSTR manage the nul terminator as manually adding
* a nul byte and potintially adding more data to the DStr would append
* it after that nul terminator.
*/
struct DStr {
/** Length of the managed string.*/
size_t len;
//internal fields:
size_t allocated;
char *str;
};
#define UC_DSTR_STATIC_INIT {0, 0, NULL}
/** Initialize a DStr.
* Note that str->str will be NULL after initialization.
*
*/
void uc_dstr_init(struct DStr *str);
/** Initialize a DStr from an existing string
*
* @return 0 on success (!= 0 if an allocation fail)
*/
int uc_dstr_init_str(struct DStr *str, const char *init);
/** Initialize a DStr from an existing string with a given length
*
* @return 0 on success (!= 0 if an allocation fail)
*/
int uc_dstr_init_str_sz(struct DStr *str, const char *init, size_t len);
/** Destroy/free the string.
* (Frees str->str, not str itself)
*/
void uc_dstr_destroy(struct DStr *str);
/** Copy a DStr.
* The @dest string should not be an initialized string since it will be
* initialized by uc_dstr_copy, and would cause a memory leak if it's already
* initialized.
*
* @param dest destination string to copy to, must not contain an existing string
* @param src DStr to copy
*
* @return 0 if success, != 0 if allocation fails
*/
int uc_dstr_copy(struct DStr *restrict dest, const struct DStr *restrict src);
/**
* @return the available/unused tail bytes in the string.
*/
size_t uc_dstr_available(const struct DStr *str);
/** Ensure the DStr have room for least 'len' bytes,
* allocating room if needed.
*
* This includes the length of the existing string,
* to ensure e.g an additional 10 bytes can be appended,
* one would do uc_dstr_ensure(str, str->len + 10)
*
* @return 0 on success (!= 0 if an allocation fail)
*/
int uc_dstr_ensure(struct DStr *str, size_t total);
/** Reset the DStr, setting its length to 0
*/
void uc_dstr_reset(struct DStr *str);
/** nul terminate the DStr */
void uc_dstr_terminate(struct DStr *str);
/** Retreive the managed string, the returned string
* is always nul terminated. The DStr will still be managing
* the returned char *.
*/
char *uc_dstr_str(struct DStr *str);
/** Reserve len bytes for appending to the dstr
* you must fill in a string in the 0-len range of
* the returned pointer.
*
* @param len bytes to reseve
* @return poiinter to the start of the data to append
*/
char *uc_dstr_put(struct DStr *str, size_t len);
/** Append a string, filtering out characters.
* e.g. pass in the ctype.h isdigit as the is_x function
* to append only the digits in the supplied string.
*
* @param s string to append
* @param is_x ctype.h compatible function to use as a filter.
* @return number of chars appended
*/
size_t uc_dstr_append_str_filter(struct DStr *str, const char *restrict s, int (*is_x)(int c));
/* Append a string of the give size.
* (The nul terminator is not appended)
*
* @param s string to append
* @param len bytes to append (not including the nul terminator)
* @return 0 on success (!= 0 if an allocation fail)
*/
int uc_dstr_append_str_sz(struct DStr *str, const char *restrict s, size_t len);
/* Append a string.
* (The nul terminator is not appended)
*
* @return 0 on success (!= 0 if an allocation fail)
*/
int uc_dstr_append_str(struct DStr *str, const char *restrict s);
/* Append a single char.
*
* @return 0 on success (!= 0 if an allocation fail)
*/
int uc_dstr_append_char(struct DStr *str, char c);
/* Make the DStr take ownership of the given dynamically allocated string.
* Any existing string in the DStr is freed.
*/
void uc_dstr_own(struct DStr *str, char *restrict s);
/** Release the managed string.
* The caller is now responsible for managing/free'ing the returned string.
* The DStr is considered empty afterwards.
*
* @return The dynamically allocated string that was managed.
*/
char *uc_dstr_steal(struct DStr *str);
/** Swap the A and B DStr */
void uc_str_swap(struct DStr *restrict a, struct DStr *restrict b);
/** Replace all occurences in the DStr
* (This may be used to replace any embedded nul bytes too)
*
* @param f char to find
* @param r char to replace with
*/
size_t uc_dstr_replace(struct DStr *str, char f, char r);
/** Remove leading and trailing spaces in the DStr
* Spaces are the ascii ones: " \t\r\v\t\n"
*/
void uc_dstr_trim(struct DStr *str);
/** Append formatted string (just as sprintf)*/
int uc_dstr_sprintf(struct DStr *str, const char *restrict fmt, ...) __attribute__((format(printf,2,3)));
/** va_list variant */
int uc_dstr_vsprintf(struct DStr *str, const char *restrict fmt, va_list ap_)__attribute__((format(printf,2,0)));
#ifdef __cplusplus
}
#endif
#endif