#ifndef UC_DSTR_H_ #define UC_DSTR_H_ #include #include #ifdef __cplusplus extern "C" { #endif /** A managed C-string, using dynalically 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); /** Destroy/free the string. * (Frees str->str, not str itself) */ void uc_dstr_destroy(struct DStr *str); /** * @return the available/unused tail bytes in the string. */ size_t uc_dstr_available(const struct DStr *str); /** Ensure the DStr is of at least 'len' bytes, * allocating room if needed. * * @return 0 on success (!= 0 if an allocation fail) */ int uc_dstr_ensure(struct DStr *str, size_t len); /** 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_put_str_filter(struct DStr *str, const char *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_put_str_sz(struct DStr *str, const char *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_put_str(struct DStr *str, const char *s); /* Append a single char. * * @return 0 on success (!= 0 if an allocation fail) */ int uc_dstr_put_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 *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 *a, struct DStr *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 *fmt, ...) __attribute__((format(printf,2,3))); /** va_list variant */ int uc_dstr_vsprintf(struct DStr *str, const char *fmt, va_list ap_)__attribute__((format(printf,2,0))); #ifdef __cplusplus } #endif #endif