kiba-engine
buffer.c
1 #include <kiba/format/buffer.h>
2 
3 #include <kiba/core/memory.h>
4 
5 b8 format_buffer_create_static(format_buffer *buf, format_buffer_mode mode, char *buffer, usize length) {
6  KB_ASSERT(buffer != KB_NULL, "provided pointer to buffer must be valid");
7  buf->data = buffer;
8  buf->length = length;
9  buf->head = 0;
10  buf->alloc = KB_NULL;
11  buf->mode = mode;
12  return true;
13 }
14 
15 b8 format_buffer_create_dynamic(format_buffer *buf, usize initial_length, allocator *alloc) {
16  KB_ASSERT(alloc != KB_NULL, "must receive valid allocator pointer");
17  char *data = allocator_allocate(alloc, sizeof(char) * initial_length);
18  if (data == KB_NULL) {
19  KB_ERROR("can not allocate initial memory for the format buf");
20  return false;
21  }
22  if (!format_buffer_create_static(buf, FORMAT_BUFFER_WRITE, data, initial_length)) {
23  return false;
24  }
25  buf->alloc = alloc;
26  return true;
27 }
28 
29 void format_buffer_destroy(format_buffer *buf) {
30  if (buf->alloc != KB_NULL) {
31  allocator_free(buf->alloc, buf->data);
32  }
33  memory_zero(buf, sizeof(format_buffer));
34 }
35 
36 static b8 format_buffer_resize(format_buffer *buf, usize min_new_size) {
37  KB_ASSERT_DEBUG(buf->mode == FORMAT_BUFFER_WRITE, "only writing format_buffer may call resize");
38  if (buf->alloc == KB_NULL) {
39  KB_WARN("static format_buffer will not be resized");
40  return false;
41  }
42  const usize new_length = (min_new_size / buf->length + 1) * buf->length;
43  char *new_data = allocator_reallocate(buf->alloc, buf->data, sizeof(char) * new_length);
44  if (new_data == KB_NULL) {
45  KB_WARN("could not resize dynamic format_buffer");
46  return false;
47  }
48  buf->data = new_data;
49  buf->length = new_length;
50  return true;
51 }
52 
53 b8 format_buffer_advance(format_buffer *buf) { return buf->head++ < buf->length; }
54 
55 void format_buffer_reset(format_buffer *buf) { buf->head = 0; }
56 
57 b8 format_buffer_add_char(format_buffer *buf, char c) {
58  KB_ASSERT_DEBUG(buf->mode == FORMAT_BUFFER_WRITE, "only writing format_buffer may add content to the buffer");
59  if (buf->head == buf->length && !format_buffer_resize(buf, buf->length + 1)) {
60  return false;
61  }
62  buf->data[buf->head++] = c;
63  return true;
64 }
65 
66 b8 format_buffer_add_char_n(format_buffer *buf, char c, usize n) {
67  KB_ASSERT_DEBUG(buf->mode == FORMAT_BUFFER_WRITE, "only writing format_buffer may add content to the buffer");
68  usize remaining_length = buf->length - buf->head;
69  if (remaining_length < n && !format_buffer_resize(buf, buf->length + n - remaining_length)) {
70  return false;
71  }
72  memory_set(buf->data + buf->head, (u8) c, n);
73  buf->head += n;
74  return true;
75 }
76 
77 b8 format_buffer_add_chars(format_buffer *buf, const char *chars, usize length) {
78  KB_ASSERT_DEBUG(buf->mode == FORMAT_BUFFER_WRITE, "only writing format_buffer may add content to the buffer");
79  usize remaining_length = buf->length - buf->head;
80  if (remaining_length < length && !format_buffer_resize(buf, buf->length + length - remaining_length)) {
81  return false;
82  }
83  memory_copy(buf->data + buf->head, chars, sizeof(char) * length);
84  buf->head += length;
85  return true;
86 }
87 
88 b8 format_buffer_add_string_view(format_buffer *buf, string_view view) {
89  if (!view.is_valid) {
90  return false;
91  }
92  return format_buffer_add_chars(buf, string_view_data(view), view.length);
93 }
94 
95 // TODO rethink how to export buffer data (e.g. proccessed, all, remaining?)
96 string_view string_view_from_format_buffer(const format_buffer *buf) {
97  // TODO allow creation of string from char ptr with length
98  return string_view_from_string((string){
99  .data = buf->data,
100  .length = buf->head,
101  .alloc = KB_NULL,
102  });
103 }
104 
105 b8 format_buffer_peak_char(const format_buffer *buf, char *c) {
106  KB_ASSERT_DEBUG(buf->mode == FORMAT_BUFFER_READ, "only reading format_buffer may read content from the buffer");
107  if (buf->head < buf->length) {
108  *c = buf->data[buf->head];
109  return true;
110  }
111  return false;
112 }
113 
114 b8 format_buffer_read_char(format_buffer *buf, char *c) {
115  return format_buffer_peak_char(buf, c) && format_buffer_advance(buf);
116 }
117 
118 b8 format_buffer_match_char(format_buffer *buf, char c) {
119  char actual;
120  return format_buffer_peak_char(buf, &actual) && c == actual && format_buffer_advance(buf);
121 }
122 
123 b8 format_buffer_match_chars(format_buffer *buf, const char *c, usize length) {
124  for (usize i = 0; i < length; ++i) {
125  if (!format_buffer_match_char(buf, c[i])) {
126  buf->head -= i; // reset the head to avoid indeterministic position of head
127  return false;
128  }
129  }
130  return true;
131 }
132 
133 b8 format_buffer_match_string_view(format_buffer *buf, string_view view) {
134  if (!view.is_valid) {
135  return false;
136  }
137  return format_buffer_match_chars(buf, string_view_data(view), view.length);
138 }
void * allocator_allocate(allocator *alloc, usize size)
Allocate unaligned memory.
Definition: allocator.c:92
void * allocator_reallocate(allocator *alloc, void *original, usize new_size)
Reallocate memory to unaligned block.
Definition: allocator.c:107
void allocator_free(allocator *alloc, void *mem)
Give back memory to the allocator.
Definition: allocator.c:134
void * memory_copy(void *dst, const void *src, usize size)
Copy memory.
Definition: memory.c:83
void * memory_zero(void *mem, usize size)
Zero out memory.
Definition: memory.c:79
void * memory_set(void *mem, u8 byte, usize size)
Set content of memory block.
Definition: memory.c:81
Lightweight layer between platform and other engine components to enable tracing/monitoring.
const char * string_view_data(const string_view view)
Get raw pointer to beginning of the string_view data.
Definition: string.c:135
string_view string_view_from_string(const string str)
Create a new string view of a whole string.
Definition: string.c:126
#define KB_NULL
Value of an invalid ptr (nullptr).
Definition: defines.h:18
#define KB_ASSERT(expr,...)
Perform runtime assertion and log failures.
Definition: log.h:133
#define KB_WARN(...)
Log entry with warn log level.
Definition: log.h:161
#define KB_ERROR(...)
Log entry with error log level.
Definition: log.h:142
#define KB_ASSERT_DEBUG(expr,...)
Perform runtime debug assertion and log failures.
Definition: log.h:165
Central allocator structure.
Definition: allocator.h:87
Non owning views on actual strings.
Definition: string.h:31
b8 is_valid
Indicates if the view is valid and can be used/accessed.
Definition: string.h:39
usize length
The length of the view.
Definition: string.h:35