4#if !defined _GNU_SOURCE
31#define INVARIANT_CHECK(self) \
33 ASSUME((self)->alloc); \
34 ASSUME(WHEN((self)->buf, (self)->stream && (self)->capacity > 0)); \
35 ASSUME(WHEN((self)->capacity == 0, !(self)->buf)); \
36 ASSUME(WHEN((self)->buf, (self)->size_without_null + 1 <= (self)->capacity));
47 PANIC(
"cookie set in write-only mode, but read was called.");
57 if (self->
buf != NULL) {
58 size_t const growth_factor = 2;
105 .size_without_null = 0,
115 if (self->stream == NULL) {
116 cookie_io_functions_t
const io = {
122 self->stream = fopencookie(self,
"w", io);
123 ASSERT(self->stream != NULL,
"Failed to open stream for string builder, with error: %s",
130 setvbuf(self->stream, NULL, _IONBF, 0);
139 self->size_without_null = 0;
145 if (self->size_without_null == 0) {
154 char* buf = self->buf;
155 self->size_without_null = 0;
164 return self->size_without_null;
170 fclose(self->stream);
177#undef INVARIANT_CHECK
static void free(SELF *self, void *ptr)
static void * realloc(SELF *self, void *ptr, size_t size)
static void * malloc(SELF *self, size_t size)
static INDEX_TYPE size(SELF const *self)
#define INVARIANT_CHECK(self)
static VALUE const * read(SELF const *self, INDEX index)
static VALUE * write(SELF *self, INDEX index)
static ITEM * data(SELF *self)
static char * release_string(SELF *self)
Disowns the current string, free/management with chosen allocator determined by user.
static size_t const additional_alloc_size
static int PRIV close(void *capture)
static size_t string_size(SELF *self)
static FILE * stream(SELF *self)
Opens a file for.
static int PRIV seek(void *capture, off_t *offset, int whence)
static void reset(SELF *self)
Resets the string, but keps the same stream pointer alive.