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,12 +1,14 @@
#include "array.h"
#include <blue/core/iterator.h>
#include <blue/core/stream.h>
#include <blue/object/array.h>
#include <blue/object/type.h>
#include <stdlib.h>
#include <string.h>
static void array_release(struct b_object *obj);
static void array_to_string(struct b_object *obj, struct b_stream *out);
static struct b_object_type array_type = {
.t_flags = B_OBJECT_FUNDAMENTAL,
@@ -14,6 +16,7 @@ static struct b_object_type array_type = {
.t_name = "corelib::array",
.t_instance_size = sizeof(struct b_array),
.t_release = array_release,
.t_to_string = array_to_string,
};
struct b_array *b_array_create(void)
@@ -218,7 +221,47 @@ size_t b_array_capacity(const struct b_array *array)
return array->ar_cap;
}
void array_release(struct b_object *obj)
static void array_to_string(struct b_object *obj, struct b_stream *out)
{
struct b_array *array = B_ARRAY(obj);
if (!array->ar_len) {
b_stream_write_string(out, "[]", NULL);
return;
}
b_stream_write_string(out, "[\n", NULL);
b_stream_push_indent(out, 1);
size_t len = b_array_size(array);
b_array_iterator it;
b_array_foreach(&it, array)
{
bool is_string = b_typeid(it.value) == B_OBJECT_TYPE_STRING;
if (is_string) {
b_stream_write_char(out, '"');
}
b_to_string(it.value, out);
if (is_string) {
b_stream_write_char(out, '"');
}
if (it.i < len - 1) {
b_stream_write_string(out, ",", NULL);
}
b_stream_write_char(out, '\n');
}
b_stream_pop_indent(out);
b_stream_write_char(out, ']');
}
static void array_release(struct b_object *obj)
{
struct b_array *array = B_ARRAY(obj);

View File

@@ -1,7 +1,7 @@
#include "dict.h"
#include <blue/core/status.h>
#include <blue/core/stringstream.h>
#include <blue/core/stream.h>
#include <blue/object/dict.h>
#include <blue/object/string.h>
#include <blue/object/type.h>
@@ -24,7 +24,7 @@ uint64_t b_cstr_hash(const char *s)
}
static void dict_release(struct b_object *obj);
static void dict_to_string(struct b_object *obj, struct b_stringstream *out);
static void dict_to_string(struct b_object *obj, struct b_stream *out);
static struct b_object_type dict_type = {
.t_name = "corelib::dict",
@@ -186,35 +186,46 @@ bool b_dict_is_empty(const b_dict *dict)
return false;
}
static void dict_to_string(struct b_object *obj, struct b_stringstream *out)
static void dict_to_string(struct b_object *obj, struct b_stream *out)
{
struct b_dict *dict = B_DICT(obj);
if (b_dict_is_empty(dict)) {
b_stringstream_add(out, "{}");
b_stream_write_string(out, "{}", NULL);
return;
}
b_stringstream_add(out, "{\n");
b_stream_write_string(out, "{\n", NULL);
b_stringstream_push_indent(out, 1);
b_stream_push_indent(out, 1);
size_t len = b_dict_get_size(dict);
b_dict_iterator it;
b_dict_foreach(&it, dict)
{
b_stringstream_addf(out, "%s: ", it.key);
b_stream_write_fmt(out, NULL, "%s: ", it.key);
bool is_string = b_typeid(it.value) == B_OBJECT_TYPE_STRING;
if (is_string) {
b_stream_write_char(out, '"');
}
b_to_string(it.value, out);
if (is_string) {
b_stream_write_char(out, '"');
}
if (it.i < len - 1) {
b_stringstream_add(out, ",");
b_stream_write_string(out, ",", NULL);
}
b_stringstream_add(out, "\n");
b_stream_write_char(out, '\n');
}
b_stringstream_pop_indent(out);
b_stringstream_add(out, "}");
b_stream_pop_indent(out);
b_stream_write_char(out, '}');
}
static bool dict_iterator_next(struct b_iterator *it)

View File

@@ -12,7 +12,7 @@
#define B_RVT(t, p) ((t *)(b_make_rvalue(B_OBJECT(p))))
struct b_string;
struct b_stringstream;
struct b_stream;
typedef enum b_comparison_result {
B_LESS = -1,
@@ -30,7 +30,7 @@ BLUE_API b_object *b_make_rvalue(b_object *obj);
BLUE_API b_object *b_retain(b_object *obj);
BLUE_API void b_release(b_object *obj);
BLUE_API void b_to_string(b_object *obj, struct b_stringstream *out);
BLUE_API void b_to_string(b_object *obj, struct b_stream *out);
BLUE_API b_object_type_id b_typeid(const b_object *obj);
BLUE_API b_comparison_result_t b_compare(const b_object *a, const b_object *b);

View File

@@ -5,6 +5,8 @@
#include <blue/object/object.h>
#include <blue/object/type.h>
struct b_stream;
#define B_STRING(p) ((b_string *)(p))
#define B_CSTR(s) (b_string_create_from_cstr(s))
@@ -33,6 +35,7 @@ static inline void b_string_release(b_string *str)
BLUE_API char *b_string_steal(b_string *str);
BLUE_API b_status b_string_reserve(b_string *str, size_t capacity);
BLUE_API b_status b_string_replace_all(b_string *str, const char *new_data);
BLUE_API b_status b_string_open_stream(b_string *str, struct b_stream **out);
BLUE_API void b_string_append_s(b_string *dest, const b_string *src);
BLUE_API void b_string_append_cstr(b_string *dest, const char *src);

View File

@@ -10,7 +10,7 @@
#define B_NPOS ((size_t)INTPTR_MAX)
struct b_object;
struct b_stringstream;
struct b_stream;
typedef uintptr_t b_object_type_id;
@@ -44,7 +44,7 @@ typedef struct b_object_type {
b_queue_entry t_entry;
void (*t_init)(struct b_object *);
void (*t_release)(struct b_object *);
void (*t_to_string)(struct b_object *, struct b_stringstream *);
void (*t_to_string)(struct b_object *, struct b_stream *);
} b_object_type;
BLUE_API b_status b_object_type_register(b_object_type *type);

View File

@@ -1,6 +1,6 @@
#include "number.h"
#include <blue/core/stringstream.h>
#include <blue/core/stream.h>
#include <blue/object/type.h>
#include <inttypes.h>
#include <stdlib.h>
@@ -10,7 +10,7 @@ typedef int (*number_converter_t)(const struct b_number *, void *);
static number_converter_t converters[B_NUMBER_TYPE_COUNT][B_NUMBER_TYPE_COUNT];
static void number_to_string(struct b_object *obj, struct b_stringstream *out);
static void number_to_string(struct b_object *obj, struct b_stream *out);
static struct b_object_type number_type = {
.t_name = "corelib::number",
@@ -175,55 +175,55 @@ size_t b_number_data_size(const struct b_number *number)
}
}
static void number_to_string(struct b_object *obj, struct b_stringstream *out)
static void number_to_string(struct b_object *obj, struct b_stream *out)
{
struct b_number *number = B_NUMBER(obj);
switch (number->n_type) {
case B_NUMBER_INT8:
b_stringstream_addf(out, "%" PRIu8, number->n_value.v_int8);
b_stream_write_fmt(out, NULL, "%" PRIu8, number->n_value.v_int8);
break;
case B_NUMBER_INT16:
b_stringstream_addf(out, "%" PRIu16, number->n_value.v_int16);
b_stream_write_fmt(out, NULL, "%" PRIu16, number->n_value.v_int16);
break;
case B_NUMBER_INT32:
b_stringstream_addf(out, "%" PRIu32, number->n_value.v_int32);
b_stream_write_fmt(out, NULL, "%" PRIu32, number->n_value.v_int32);
break;
case B_NUMBER_INT64:
b_stringstream_addf(out, "%" PRIu64, number->n_value.v_int64);
b_stream_write_fmt(out, NULL, "%" PRIu64, number->n_value.v_int64);
break;
case B_NUMBER_FLOAT32:
b_stringstream_addf(out, "%f", number->n_value.v_float32);
b_stream_write_fmt(out, NULL, "%f", number->n_value.v_float32);
break;
case B_NUMBER_FLOAT64:
b_stringstream_addf(out, "%lf", number->n_value.v_float64);
b_stream_write_fmt(out, NULL, "%lf", number->n_value.v_float64);
break;
case B_NUMBER_CHAR:
b_stringstream_addf(out, "%d", number->n_value.v_char);
b_stream_write_fmt(out, NULL, "%d", number->n_value.v_char);
break;
case B_NUMBER_SHORT:
b_stringstream_addf(out, "%d", number->n_value.v_short);
b_stream_write_fmt(out, NULL, "%d", number->n_value.v_short);
break;
case B_NUMBER_INT:
b_stringstream_addf(out, "%d", number->n_value.v_int);
b_stream_write_fmt(out, NULL, "%d", number->n_value.v_int);
break;
case B_NUMBER_LONG:
b_stringstream_addf(out, "%ld", number->n_value.v_long);
b_stream_write_fmt(out, NULL, "%ld", number->n_value.v_long);
break;
case B_NUMBER_LONGLONG:
b_stringstream_addf(out, "%lld", number->n_value.v_longlong);
b_stream_write_fmt(out, NULL, "%lld", number->n_value.v_longlong);
break;
case B_NUMBER_FLOAT:
b_stringstream_addf(out, "%f", number->n_value.v_float);
b_stream_write_fmt(out, NULL, "%f", number->n_value.v_float);
break;
case B_NUMBER_DOUBLE:
b_stringstream_addf(out, "%lf", number->n_value.v_double);
b_stream_write_fmt(out, NULL, "%lf", number->n_value.v_double);
break;
case B_NUMBER_SIZE_T:
b_stringstream_addf(out, "%zu", number->n_value.v_size_t);
b_stream_write_fmt(out, NULL, "%zu", number->n_value.v_size_t);
break;
case B_NUMBER_HANDLE:
b_stringstream_addf(
out, "%016" PRIx64, number->n_value.v_size_t);
b_stream_write_fmt(
out, NULL, "%016" PRIx64, number->n_value.v_size_t);
break;
default:
break;

View File

@@ -1,10 +1,11 @@
#include "object.h"
#include <blue/core/stream.h>
#include <blue/object/object.h>
#include <blue/object/type.h>
#include <blue/object/string.h>
#include <blue/core/stringstream.h>
#include <stdlib.h>
#include <blue/object/type.h>
#include <stdio.h>
#include <stdlib.h>
void b_object_init(struct b_object *obj, struct b_object_type *type)
{
@@ -40,7 +41,7 @@ void b_release(struct b_object *obj)
free(obj);
}
void b_to_string(struct b_object *obj, struct b_stringstream *out)
void b_to_string(struct b_object *obj, struct b_stream *out)
{
if (obj->ob_type->t_to_string) {
obj->ob_type->t_to_string(obj, out);
@@ -52,7 +53,7 @@ void b_to_string(struct b_object *obj, struct b_stringstream *out)
name = obj->ob_type->t_name;
}
b_stringstream_addf(out, "<%s@%p>", name, obj);
b_stream_write_fmt(out, NULL, "<%s@%p>", name, obj);
}
b_object_type_id b_typeid(const struct b_object *obj)

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)