Files
bluelib/core/stringstream.c

119 lines
2.3 KiB
C
Raw Normal View History

2024-08-03 07:54:28 +01:00
#include <blue/core/stringstream.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}