forked from cdacamar/fredbuf
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfred-strings.cpp
More file actions
140 lines (126 loc) · 3.94 KB
/
fred-strings.cpp
File metadata and controls
140 lines (126 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "fred-strings.h"
// Node construction.
String8Node* str8_list_push_node(String8List* lst, String8Node* node)
{
SLLQueuePush(lst->first, lst->last, node);
++lst->node_count;
lst->total_size += node->string.size;
return node;
}
String8Node* str8_list_push_node_set_string(String8List* lst, String8Node* node, String8 string)
{
SLLQueuePush(lst->first, lst->last, node);
++lst->node_count;
lst->total_size += string.size;
node->string = string;
return node;
}
// List construction.
String8Node* str8_list_push(Arena::Arena* arena, String8List* lst, String8 string)
{
String8Node* node = Arena::push_array_no_zero<String8Node>(arena, 1);
return str8_list_push_node_set_string(lst, node, string);
}
// Serializing data.
void str8_serial_begin(Arena::Arena* arena, String8List* lst)
{
String8Node* node = str8_list_push(arena, lst, str8_empty);
// Begin the string allocation site.
node->string.str = Arena::push_array_no_zero<char>(arena, 0);
}
String8 str8_serial_end(Arena::Arena* arena, const String8List& lst)
{
String8 result = str8_cstr_alloc(arena, lst.total_size);
char* out = result.str;
for EachNode(n, lst.first)
{
memcpy(out, n->string.str, n->string.size);
out += n->string.size;
}
return result;
}
void str8_serial_push_char(Arena::Arena* arena, String8List* lst, char c)
{
str8_serial_push_str8(arena, lst, str8(&c, 1));
}
void str8_serial_push_str8(Arena::Arena* arena, String8List* lst, String8 str)
{
if (str.size == 0)
return;
// Try to append allocations.
auto arena_pos = Arena::pos(arena);
char* buf = Arena::push_array_no_zero_aligned<char>(arena, str.size, Arena::Alignment{ alignof(char) });
String8* latest = &lst->last->string;
if (latest->str == nullptr && latest->size == 0)
{
latest->str = buf;
}
if (latest->str + latest->size == buf)
{
latest->size += str.size;
lst->total_size += str.size;
}
// Append a new node.
else
{
// Note: in order for this to remain efficient, we will actually discard the memory allocated above, allocate a new node and _then_
// allocate a new string buffer. This is to ensure that we can grow the buffer of the new string in the new chunk.
Arena::pop_to(arena, arena_pos);
str8_list_push(arena, lst, str);
// Now we allocate a buffer for the string, and assign it.
buf = Arena::push_array_no_zero<char>(arena, str.size);
lst->last->string.str = buf;
}
memcpy(buf, str.str, str.size);
}
// Basic string construction.
String8 str8_cstr(char* str)
{
String8 s{};
s.str = str;
s.size = str != nullptr ? strlen(str) : 0;
return s;
}
String8 str8_cppview(std::string_view str)
{
String8 s{};
// Bad, but a workaround until I get rid of string_view.
s.str = const_cast<char*>(str.data());
s.size = str.size();
return s;
}
String8 str8_mut(String8View str)
{
String8 s{};
s.str = const_cast<char*>(str.str);
s.size = str.size;
return s;
}
String8 str8_alloc(Arena::Arena* arena, uint64_t size)
{
char* str = Arena::push_array_no_zero<char>(arena, size);
return str8(str, size);
}
String8 str8_cstr_alloc(Arena::Arena* arena, uint64_t size)
{
char* str = Arena::push_array_no_zero<char>(arena, size + 1);
str[size] = 0;
return str8(str, size);
}
String8 str8_copy(Arena::Arena* arena, String8 string)
{
// +1 for null byte.
String8 cpy{};
cpy.size = string.size;
cpy.str = Arena::push_array_no_zero<char>(arena, string.size + 1);
memcpy(cpy.str, string.str, string.size);
cpy.str[cpy.size] = 0;
return cpy;
}
// String searching.
bool str8_match_exact(String8 a, String8 b)
{
if (a.size != b.size)
return false;
return memcmp(a.str, b.str, a.size) == 0;
}