core: rope: add bstr support
This commit is contained in:
@@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
#include <blue/core/hash.h>
|
#include <blue/core/hash.h>
|
||||||
#include <blue/core/misc.h>
|
#include <blue/core/misc.h>
|
||||||
|
#include <blue/core/stream.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct b_string;
|
struct b_string;
|
||||||
|
struct b_bstr;
|
||||||
|
|
||||||
#define B_ROPE_TYPE(f) ((f) & 0xFF)
|
#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_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 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_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_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
|
#endif
|
||||||
|
|||||||
99
core/rope.c
99
core/rope.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <blue/core/bstr.h>
|
||||||
#include <blue/core/rope.h>
|
#include <blue/core/rope.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.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)
|
size_t b_rope_get_size(const struct b_rope *rope)
|
||||||
{
|
{
|
||||||
return rope->r_len_total;
|
return rope->r_len_total;
|
||||||
@@ -181,56 +199,77 @@ static void rope_iterate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct to_cstr_args {
|
static void to_bstr(const struct b_rope *rope, void *arg)
|
||||||
char *str;
|
|
||||||
size_t max;
|
|
||||||
size_t ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void to_cstr(const struct b_rope *rope, void *arg)
|
|
||||||
{
|
{
|
||||||
struct to_cstr_args *str = arg;
|
b_bstr *str = arg;
|
||||||
if (str->ptr >= str->max) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int type = B_ROPE_TYPE(rope->r_flags);
|
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) {
|
switch (type) {
|
||||||
case B_ROPE_F_CHAR:
|
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;
|
break;
|
||||||
case B_ROPE_F_CSTR:
|
case B_ROPE_F_CSTR:
|
||||||
case B_ROPE_F_CSTR_BORROWED:
|
case B_ROPE_F_CSTR_BORROWED:
|
||||||
case B_ROPE_F_CSTR_STATIC:
|
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;
|
break;
|
||||||
case B_ROPE_F_INT:
|
case B_ROPE_F_INT:
|
||||||
nr_written
|
b_bstr_write_fmt(str, NULL, "%" PRIdPTR, rope->r_v.v_int);
|
||||||
= snprintf(dest, capacity, "%" PRIdPTR, rope->r_v.v_int);
|
|
||||||
break;
|
break;
|
||||||
case B_ROPE_F_UINT:
|
case B_ROPE_F_UINT:
|
||||||
nr_written
|
b_bstr_write_fmt(str, NULL, "%" PRIuPTR, rope->r_v.v_uint);
|
||||||
= snprintf(dest, capacity, "%" PRIuPTR, rope->r_v.v_uint);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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 = {
|
b_stream *out = arg;
|
||||||
.str = out,
|
|
||||||
.max = max,
|
|
||||||
.ptr = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
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