initial commit
This commit is contained in:
118
core/stringstream.c
Normal file
118
core/stringstream.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user