object: update to_string callback to use b_stream instead of b_stringstream

This commit is contained in:
2025-06-27 21:47:55 +01:00
parent 579a9e8505
commit c54d51d381
9 changed files with 237 additions and 51 deletions

View File

@@ -1,5 +1,6 @@
#include "string.h"
#include <blue/core/stream.h>
#include <blue/core/stringstream.h>
#include <blue/object/string.h>
#include <blue/object/type.h>
@@ -11,7 +12,7 @@
#include <string.h>
static void string_release(struct b_object *obj);
static void string_to_string(struct b_object *obj, struct b_stringstream *out);
static void string_to_string(struct b_object *obj, struct b_stream *out);
static struct b_object_type string_type = {
.t_name = "corelib::string",
@@ -176,6 +177,7 @@ char *b_string_steal(struct b_string *str)
if (string_is_inline(str)) {
dest = b_strdup(src);
src[0] = 0;
} else {
dest = src;
str->s_data.d_external = NULL;
@@ -209,6 +211,132 @@ b_status b_string_replace_all(b_string *str, const char *new_data)
return B_SUCCESS;
}
enum b_status stream_close(struct b_stream *stream)
{
struct b_string *str = stream->s_ptr;
b_string_release(str);
return B_SUCCESS;
}
enum b_status stream_getc(struct b_stream *stream, int *out)
{
struct b_string *str = stream->s_ptr;
if (stream->s_cursor >= str->s_len) {
return B_ERR_NO_DATA;
}
char *s = string_ptr(str);
*out = s[stream->s_cursor];
stream->s_cursor++;
return B_SUCCESS;
}
enum b_status stream_read(
struct b_stream *stream, unsigned char *buf, size_t count, size_t *nr_read)
{
struct b_string *str = stream->s_ptr;
if (stream->s_cursor >= str->s_len) {
*nr_read = 0;
return B_SUCCESS;
}
size_t available = str->s_len - stream->s_cursor;
size_t to_read = b_min(size_t, count, available);
char *s = string_ptr(str) + stream->s_cursor;
memcpy(buf, s, to_read);
*nr_read = to_read;
return B_SUCCESS;
}
enum b_status stream_write(
struct b_stream *stream, const unsigned char *buf, size_t count,
size_t *nr_written)
{
struct b_string *str = stream->s_ptr;
enum b_status status = B_SUCCESS;
if (stream->s_cursor + count > str->s_max) {
status = b_string_reserve(str, stream->s_cursor + count);
}
if (!B_OK(status)) {
return status;
}
char *s = string_ptr(str) + stream->s_cursor;
memcpy(s, buf, count);
s[str->s_max] = '\0';
stream->s_cursor += count;
str->s_len = b_max(size_t, str->s_len, stream->s_cursor + count);
*nr_written = count;
return B_SUCCESS;
}
enum b_status stream_seek(
struct b_stream *stream, long long offset, b_stream_seek_origin origin)
{
struct b_string *str = stream->s_ptr;
size_t abs_offset;
switch (origin) {
case B_STREAM_SEEK_START:
abs_offset = offset;
break;
case B_STREAM_SEEK_CURRENT:
abs_offset = stream->s_cursor + offset;
break;
case B_STREAM_SEEK_END:
abs_offset = str->s_len + offset;
break;
default:
return B_ERR_INVALID_ARGUMENT;
}
stream->s_cursor = abs_offset;
return B_SUCCESS;
}
enum b_status stream_reserve(struct b_stream *stream, size_t len)
{
struct b_string *str = stream->s_ptr;
size_t new_capacity = str->s_len + len;
return b_string_reserve(str, new_capacity);
}
enum b_status b_string_open_stream(struct b_string *str, struct b_stream **out)
{
struct b_stream *stream = malloc(sizeof *stream);
if (!stream) {
return B_ERR_NO_MEMORY;
}
memset(stream, 0x0, sizeof *stream);
stream->s_mode |= B_STREAM_READ | B_STREAM_WRITE;
stream->s_ptr = b_string_retain(str);
stream->s_close = stream_close;
stream->s_getc = stream_getc;
stream->s_read = stream_read;
stream->s_write = stream_write;
stream->s_seek = stream_seek;
stream->s_reserve = stream_reserve;
*out = stream;
return B_SUCCESS;
}
static void string_insert(
struct b_string *dest, const char *src, size_t len, size_t at)
{
@@ -395,10 +523,10 @@ static void string_release(struct b_object *obj)
}
}
static void string_to_string(struct b_object *obj, struct b_stringstream *out)
static void string_to_string(struct b_object *obj, struct b_stream *out)
{
b_string *str = B_STRING(obj);
b_stringstream_add(out, b_string_ptr(str));
b_stream_write_fmt(out, NULL, "%s", b_string_ptr(str));
}
char *b_strdup(const char *s)