forked from ashishzero/Kano
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStringBuilder.cpp
146 lines (116 loc) · 3.92 KB
/
StringBuilder.cpp
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
141
142
143
144
145
146
#include "StringBuilder.h"
#include <string.h>
#include <stdio.h>
static String_Builder::Bucket *StringBuilderNewBucket(String_Builder *builder) {
if (builder->free_list == nullptr) {
builder->free_list = new(builder->allocator) String_Builder::Bucket;
}
auto buk = builder->free_list;
builder->free_list = buk->next;
*buk = String_Builder::Bucket{};
return buk;
}
int WriteBuffer(String_Builder *builder, void *buffer, int64_t size) {
auto data = (uint8_t *)buffer;
int written = 0;
while (size > 0) {
if (builder->current->written == STRING_BUILDER_BUCKET_SIZE) {
auto new_bucket = StringBuilderNewBucket(builder);
builder->current->next = new_bucket;
builder->current = new_bucket;
}
int64_t write_size = Minimum(size, STRING_BUILDER_BUCKET_SIZE - builder->current->written);
memcpy(builder->current->data + builder->current->written, data, write_size);
builder->current->written += (int32_t)write_size;
size -= write_size;
data += write_size;
written += (int)write_size;
}
builder->written += written;
return written;
}
int Write(String_Builder *builder, bool value) {
return Write(builder, value ? String("true") : String("false"));
}
int Write(String_Builder *builder, char value) {
return WriteBuffer(builder, &value, 1);
}
int Write(String_Builder *builder, uint8_t value) {
return WriteBuffer(builder, &value, 1);
}
int Write(String_Builder *builder, int32_t value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%d", value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, uint32_t value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%u", value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, int64_t value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%zd", value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, uint64_t value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%zu", value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, float value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%.2f", value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, double value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%.2f", value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, void *value) {
char buffer[128];
int written = snprintf(buffer, sizeof(buffer), "%08llx", (size_t)value);
return WriteBuffer(builder, &buffer, written);
}
int Write(String_Builder *builder, const char *value) {
return WriteBuffer(builder, (void *)value, strlen(value));
}
int Write(String_Builder *builder, String value) {
return WriteBuffer(builder, value.data, value.length);
}
int WriteFormatted(String_Builder *builder, const char *format) {
return WriteBuffer(builder, (void *)format, strlen(format));
}
//
//
//
String BuildString(String_Builder *builder, Memory_Allocator &allocator) {
String string;
string.data = (uint8_t *)MemoryAllocate(builder->written + 1, allocator);
string.length = 0;
for (auto bucket = &builder->head; bucket; bucket = bucket->next) {
int64_t copy_size = bucket->written;
memcpy(string.data + string.length, bucket->data, copy_size);
string.length += copy_size;
}
string.data[string.length] = 0;
return string;
}
void ResetBuilder(String_Builder *builder) {
if (builder->current != &builder->head) {
Assert(builder->current->next == nullptr && builder->head.next);
builder->current->next = builder->free_list;
builder->free_list = builder->head.next;
}
builder->head = String_Builder::Bucket{};
}
void FreeBuilder(String_Builder *builder) {
ResetBuilder(builder);
auto root = builder->free_list;
while (root) {
auto ptr = root;
root = root->next;
MemoryFree(ptr, sizeof(*ptr), builder->allocator);
}
}