core: rope: add bstr support
This commit is contained in:
99
core/rope.c
99
core/rope.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user