core: rope: add bstr support

This commit is contained in:
2026-02-03 14:39:33 +00:00
parent c13b7a7e3a
commit 5889426478
2 changed files with 78 additions and 33 deletions

View File

@@ -3,10 +3,12 @@
#include <blue/core/hash.h>
#include <blue/core/misc.h>
#include <blue/core/stream.h>
#include <stdint.h>
#include <string.h>
struct b_string;
struct b_bstr;
#define B_ROPE_TYPE(f) ((f) & 0xFF)
@@ -94,10 +96,14 @@ BLUE_API void b_rope_init_uint(b_rope *rope, uintptr_t v);
BLUE_API void b_rope_destroy(b_rope *rope);
BLUE_API void b_rope_iterate(
const b_rope *rope, void (*func)(const b_rope *, void *), void *arg);
BLUE_API size_t b_rope_get_size(const b_rope *rope);
BLUE_API void b_rope_concat(b_rope *result, const b_rope *left, const b_rope *right);
BLUE_API void b_rope_join(b_rope *result, const b_rope **ropes, size_t nr_ropes);
BLUE_API void b_rope_to_cstr(const b_rope *rope, char *out, size_t max);
BLUE_API b_status b_rope_to_cstr(const b_rope *rope, char *out, size_t max);
BLUE_API b_status b_rope_to_bstr(const b_rope *rope, struct b_bstr *str);
BLUE_API b_status b_rope_to_string(const b_rope *rope, b_stream *out);
#endif

View File

@@ -1,3 +1,4 @@
#include <blue/core/bstr.h>
#include <blue/core/rope.h>
#include <inttypes.h>
#include <stdio.h>
@@ -86,6 +87,23 @@ void b_rope_destroy(struct b_rope *rope)
}
}
void b_rope_iterate(
const struct b_rope *rope, void (*func)(const b_rope *, void *), void *arg)
{
if (B_ROPE_TYPE(rope->r_flags) != B_ROPE_F_COMPOSITE) {
func(rope, arg);
return;
}
if (rope->r_v.v_composite.r_left) {
b_rope_iterate(rope->r_v.v_composite.r_left, func, arg);
}
if (rope->r_v.v_composite.r_right) {
b_rope_iterate(rope->r_v.v_composite.r_right, func, arg);
}
}
size_t b_rope_get_size(const struct b_rope *rope)
{
return rope->r_len_total;
@@ -181,56 +199,77 @@ static void rope_iterate(
}
}
struct to_cstr_args {
char *str;
size_t max;
size_t ptr;
};
static void to_cstr(const struct b_rope *rope, void *arg)
static void to_bstr(const struct b_rope *rope, void *arg)
{
struct to_cstr_args *str = arg;
if (str->ptr >= str->max) {
return;
}
b_bstr *str = arg;
unsigned int type = B_ROPE_TYPE(rope->r_flags);
char *dest = str->str + str->ptr;
size_t capacity = str->max - str->ptr;
size_t nr_written = 0;
switch (type) {
case B_ROPE_F_CHAR:
nr_written = snprintf(dest, capacity, "%c", rope->r_v.v_char);
b_bstr_write_char(str, rope->r_v.v_char);
break;
case B_ROPE_F_CSTR:
case B_ROPE_F_CSTR_BORROWED:
case B_ROPE_F_CSTR_STATIC:
nr_written = snprintf(dest, capacity, "%s", rope->r_v.v_cstr.s);
b_bstr_write_cstr(str, rope->r_v.v_cstr.s, NULL);
break;
case B_ROPE_F_INT:
nr_written
= snprintf(dest, capacity, "%" PRIdPTR, rope->r_v.v_int);
b_bstr_write_fmt(str, NULL, "%" PRIdPTR, rope->r_v.v_int);
break;
case B_ROPE_F_UINT:
nr_written
= snprintf(dest, capacity, "%" PRIuPTR, rope->r_v.v_uint);
b_bstr_write_fmt(str, NULL, "%" PRIuPTR, rope->r_v.v_uint);
break;
default:
break;
}
str->ptr += nr_written;
}
void b_rope_to_cstr(const struct b_rope *rope, char *out, size_t max)
static void to_stream(const struct b_rope *rope, void *arg)
{
struct to_cstr_args args = {
.str = out,
.max = max,
.ptr = 0,
};
b_stream *out = arg;
rope_iterate(rope, to_cstr, &args);
unsigned int type = B_ROPE_TYPE(rope->r_flags);
switch (type) {
case B_ROPE_F_CHAR:
b_stream_write_char(out, rope->r_v.v_char);
break;
case B_ROPE_F_CSTR:
case B_ROPE_F_CSTR_BORROWED:
case B_ROPE_F_CSTR_STATIC:
b_stream_write_string(out, rope->r_v.v_cstr.s, NULL);
break;
case B_ROPE_F_INT:
b_stream_write_fmt(out, NULL, "%" PRIdPTR, rope->r_v.v_int);
break;
case B_ROPE_F_UINT:
b_stream_write_fmt(out, NULL, "%" PRIuPTR, rope->r_v.v_uint);
break;
default:
break;
}
}
b_status b_rope_to_cstr(const struct b_rope *rope, char *out, size_t max)
{
b_bstr str;
b_bstr_begin(&str, out, max);
rope_iterate(rope, to_bstr, &str);
return B_SUCCESS;
}
b_status b_rope_to_bstr(const struct b_rope *rope, b_bstr *str)
{
rope_iterate(rope, to_bstr, str);
return B_SUCCESS;
}
b_status b_rope_to_string(const struct b_rope *rope, b_stream *out)
{
rope_iterate(rope, to_stream, out);
return B_SUCCESS;
}