2021-12-10 20:22:16 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "apfl.h"
|
|
|
|
|
|
2022-02-08 21:53:13 +00:00
|
|
|
#include "alloc.h"
|
2022-01-02 16:55:05 +00:00
|
|
|
#include "internal.h"
|
2021-12-10 20:22:16 +00:00
|
|
|
#include "resizable.h"
|
|
|
|
|
|
|
|
|
|
struct apfl_string_view
|
|
|
|
|
apfl_string_view_from_view(struct apfl_string_view view)
|
|
|
|
|
{
|
|
|
|
|
return view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct apfl_string_view
|
|
|
|
|
apfl_string_view_from_cstr(char *cstr)
|
|
|
|
|
{
|
|
|
|
|
return (struct apfl_string_view) {
|
|
|
|
|
.bytes = cstr,
|
|
|
|
|
.len = strlen(cstr),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct apfl_string_view
|
|
|
|
|
apfl_string_view_from_const_cstr(const char *cstr)
|
|
|
|
|
{
|
|
|
|
|
return (struct apfl_string_view) {
|
|
|
|
|
.bytes = cstr,
|
|
|
|
|
.len = strlen(cstr),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct apfl_string_view
|
|
|
|
|
apfl_string_view_from_string(struct apfl_string string)
|
|
|
|
|
{
|
|
|
|
|
return (struct apfl_string_view) {
|
|
|
|
|
.bytes = string.bytes,
|
|
|
|
|
.len = string.len,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
apfl_string_view_cmp(struct apfl_string_view a, struct apfl_string_view b)
|
|
|
|
|
{
|
|
|
|
|
size_t n = a.len > b.len ? b.len : a.len;
|
|
|
|
|
int cmp = memcmp(a.bytes, b.bytes, n);
|
|
|
|
|
if (cmp != 0) {
|
|
|
|
|
return cmp;
|
|
|
|
|
}
|
|
|
|
|
if (a.len == b.len) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return a.len > b.len ? 1 : -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-02 16:01:51 +00:00
|
|
|
struct apfl_string
|
|
|
|
|
apfl_string_blank(void)
|
|
|
|
|
{
|
|
|
|
|
return (struct apfl_string) {
|
|
|
|
|
.bytes = NULL,
|
|
|
|
|
.len = 0,
|
2022-02-08 21:53:13 +00:00
|
|
|
.cap = 0
|
2022-01-02 16:01:51 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
void
|
2022-02-08 21:53:13 +00:00
|
|
|
apfl_string_deinit(struct apfl_allocator allocator, struct apfl_string *string)
|
2021-12-10 20:22:16 +00:00
|
|
|
{
|
2022-02-08 21:53:13 +00:00
|
|
|
FREE_BYTES(allocator, string->bytes, string->cap);
|
2022-01-02 16:01:51 +00:00
|
|
|
*string = apfl_string_blank();
|
2021-12-10 20:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2022-02-08 21:53:13 +00:00
|
|
|
apfl_string_copy(struct apfl_allocator allocator, struct apfl_string *dst, struct apfl_string_view src)
|
2021-12-10 20:22:16 +00:00
|
|
|
{
|
2022-02-08 21:53:13 +00:00
|
|
|
apfl_string_deinit(allocator, dst);
|
|
|
|
|
if ((dst->bytes = ALLOC_BYTES(allocator, src.len)) == NULL) {
|
2021-12-10 20:22:16 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(dst->bytes, src.bytes, src.len);
|
|
|
|
|
dst->len = src.len;
|
2022-02-08 21:53:13 +00:00
|
|
|
dst->cap = src.len;
|
2021-12-10 20:22:16 +00:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct apfl_string
|
|
|
|
|
apfl_string_move(struct apfl_string *src)
|
|
|
|
|
{
|
|
|
|
|
struct apfl_string out = *src;
|
2022-01-02 16:01:51 +00:00
|
|
|
*src = apfl_string_blank();
|
2021-12-10 20:22:16 +00:00
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 21:53:13 +00:00
|
|
|
static void
|
|
|
|
|
builder_reset(struct apfl_string_builder *builder)
|
2021-12-10 20:22:16 +00:00
|
|
|
{
|
|
|
|
|
apfl_resizable_init((void **)&(builder->bytes), &(builder->len), &(builder->cap));
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 21:53:13 +00:00
|
|
|
void
|
|
|
|
|
apfl_string_builder_init(struct apfl_allocator allocator, struct apfl_string_builder *builder)
|
|
|
|
|
{
|
|
|
|
|
builder->allocator = allocator;
|
|
|
|
|
builder_reset(builder);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
void
|
|
|
|
|
apfl_string_builder_deinit(struct apfl_string_builder *builder)
|
|
|
|
|
{
|
2022-02-08 21:53:13 +00:00
|
|
|
FREE_BYTES(builder->allocator, builder->bytes, builder->cap);
|
|
|
|
|
builder_reset(builder);
|
2021-12-10 20:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
append_bytes(struct apfl_string_builder *builder, const char *bytes, size_t len)
|
|
|
|
|
{
|
|
|
|
|
return apfl_resizable_append(
|
2022-02-08 21:53:13 +00:00
|
|
|
builder->allocator,
|
2021-12-10 20:22:16 +00:00
|
|
|
sizeof(char),
|
|
|
|
|
APFL_RESIZABLE_ARGS(*builder, bytes),
|
|
|
|
|
bytes,
|
|
|
|
|
len
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
apfl_string_builder_append(struct apfl_string_builder *builder, struct apfl_string_view view)
|
|
|
|
|
{
|
|
|
|
|
return append_bytes(builder, view.bytes, view.len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
apfl_string_builder_append_byte(struct apfl_string_builder *builder, char byte)
|
|
|
|
|
{
|
|
|
|
|
return append_bytes(builder, &byte, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct apfl_string
|
|
|
|
|
apfl_string_builder_move_string(struct apfl_string_builder *builder)
|
|
|
|
|
{
|
|
|
|
|
struct apfl_string str;
|
|
|
|
|
|
|
|
|
|
str.bytes = builder->bytes;
|
|
|
|
|
str.len = builder->len;
|
2022-02-08 21:53:13 +00:00
|
|
|
str.cap = builder->cap;
|
2021-12-10 20:22:16 +00:00
|
|
|
|
2022-02-08 21:53:13 +00:00
|
|
|
builder_reset(builder);
|
2021-12-10 20:22:16 +00:00
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|