#include #include #include #include #include void b_stringstream_begin(b_stringstream *ss, char *buf, size_t max) { ss->ss_buf = buf; ss->ss_max = max; ss->ss_len = 0; ss->ss_alloc = 0; } void b_stringstream_begin_dynamic(b_stringstream *ss) { ss->ss_buf = NULL; ss->ss_max = 0; ss->ss_len = 0; ss->ss_alloc = 1; } static b_status ss_builder_push_string(b_stringstream *ss, const char *s, size_t len) { if (ss->ss_len + len >= ss->ss_max && ss->ss_alloc == 1) { char *new_buf = realloc(ss->ss_buf, ss->ss_len + len + 1); if (!new_buf) { return B_ERR_NO_MEMORY; } ss->ss_buf = new_buf; ss->ss_max = ss->ss_len + len + 1; } for (size_t i = 0; i < len; i++) { if (ss->ss_len < ss->ss_max) { ss->ss_buf[ss->ss_len++] = s[i]; ss->ss_buf[ss->ss_len] = 0; } } return B_SUCCESS; } b_status b_stringstream_add(struct b_stringstream *ss, const char *str) { return ss_builder_push_string(ss, str, strlen(str)); } b_status b_stringstream_addf(struct b_stringstream *ss, const char *format, ...) { char str[1024]; va_list arg; va_start(arg, format); size_t len = vsnprintf(str, sizeof str, format, arg); va_end(arg); return ss_builder_push_string(ss, str, len); } b_status b_stringstream_addv(b_stringstream *ss, const char **strs) { for (size_t i = 0; strs[i]; i++) { size_t len = strlen(strs[i]); b_status status = ss_builder_push_string(ss, strs[i], len); if (B_ERR(status)) { return status; } } return B_SUCCESS; } b_status b_stringstream_addvl(b_stringstream *ss, const char **strs, size_t count) { for (size_t i = 0; i < count; i++) { if (!strs[i]) { continue; } size_t len = strlen(strs[i]); b_status status = ss_builder_push_string(ss, strs[i], len); if (B_ERR(status)) { return status; } } return B_SUCCESS; } b_status b_stringstream_add_many(b_stringstream *ss, ...) { va_list arg; va_start(arg, ss); const char *s = NULL; while ((s = va_arg(arg, const char *))) { size_t len = strlen(s); b_status status = ss_builder_push_string(ss, s, len); if (B_ERR(status)) { return status; } } return B_SUCCESS; } char *b_stringstream_end(b_stringstream *ss) { char *out = ss->ss_buf; ss->ss_alloc = 0; ss->ss_len = 0; ss->ss_max = 0; ss->ss_buf = NULL; return out; }