this repo has no description
1#include "string.h"
2#include "lock.h"
3
4#include <assert.h>
5#include <cstring>
6
7#include <darling/emulation/common/simple.h>
8
9//
10// Helper Functions
11//
12
13int vsnprintf_wrapper(char* buffer, size_t len, const char* format, va_list args) {
14 va_list string_size_args;
15 va_copy(string_size_args, args);
16 int size = __simple_vsnprintf(buffer, len, format, string_size_args);
17 va_end(string_size_args);
18
19 return size;
20}
21
22//
23// C++ Implementation
24//
25
26namespace xtrace {
27 // Static Implementation
28
29 String* String::new_ptr() {
30 void* buffer = xtrace_malloc(sizeof(String));
31 return new (buffer) String();
32 }
33
34 void String::free_ptr(String* obj) {
35 obj->~String();
36 xtrace_free(obj);
37 }
38
39 String* String::to_cxx_ptr(xtrace_string_t obj) {
40 return (xtrace::String*)obj;
41 }
42
43 xtrace_string_t String::to_c_ptr(String* obj) {
44 return (xtrace_string_t)obj;
45 }
46
47 // Constructor and Destructor
48
49 String::String() {
50 constructor_internal();
51 }
52
53 String::String(const char* other) {
54 constructor_internal();
55 append(other);
56
57 }
58
59 String::String(const String* other_obj) {
60 buffer_capacity = other_obj->buffer_capacity;
61 buffer = (char*)xtrace_malloc(buffer_capacity);
62
63 buffer_size = 0;
64 append(other_obj->buffer);
65 }
66
67 String::~String() {
68 destructor_internal();
69 }
70
71 // Methods
72
73 void String::append(const char* other) {
74 // If other is nullptr, use empty string
75 other = (other == nullptr) ? "" : other;
76 append_format("%s", other);
77 }
78
79 void String::append(const String* other) {
80 append(other->c_str());
81 }
82
83 void print_array_debug(char* value, size_t size);
84
85 void String::append_format(const char* format, va_list args) {
86 // Calculate size
87 int other_buffer_size = vsnprintf_wrapper(nullptr, 0, format, args)+1; // vsnprintf length + NULL Terminator
88 size_t new_buffer_size = increase_capacity_internal(other_buffer_size-1); // We will replace the current NULL Terminator
89
90 // Point to the NULL Terminator
91 char *buffer_append_string = buffer+size();
92 vsnprintf_wrapper(buffer_append_string, other_buffer_size, format, args);
93
94 buffer_size = new_buffer_size;
95 }
96
97 void String::append_format(const char* format, ...) {
98 va_list args;
99 va_start(args, format);
100 append_format(format,args);
101 va_end(args);
102 }
103
104 const char* String::c_str() const {
105 return buffer;
106 }
107
108 void String::clear() {
109 destructor_internal();
110 constructor_internal();
111 }
112
113 size_t String::size() {
114 // Ignore the null terminator
115 return buffer_size-1;
116 }
117
118 size_t String::capacity() {
119 return buffer_capacity;
120 }
121
122 // Internal Methods
123
124 void String::constructor_internal() {
125 buffer_capacity = 1024;
126 buffer = (char*)xtrace_malloc(buffer_capacity*sizeof(char));
127
128 buffer_size = 1;
129 buffer[0] = '\0';
130 }
131
132 void String::destructor_internal() {
133 xtrace_free(buffer);
134 buffer = nullptr;
135 }
136
137 size_t String::increase_capacity_internal(size_t other_buffer_size) {
138 size_t new_buffer_size = buffer_size+other_buffer_size;
139 if (new_buffer_size > buffer_capacity) {
140 size_t new_buffer_capacity = buffer_capacity + ((new_buffer_size)/1024)*1024 + 1024;
141 assert(new_buffer_capacity > buffer_capacity);
142
143 void *new_buffer = xtrace_realloc(buffer,new_buffer_capacity);
144 if (new_buffer != nullptr) {
145 buffer_capacity = new_buffer_capacity;
146 buffer = (char*)new_buffer;
147 }
148 }
149
150 return new_buffer_size;
151 }
152}
153
154//
155// C Implementation
156//
157
158extern "C"
159xtrace_string_t xtrace_string_construct() {
160 return xtrace::String::to_c_ptr(xtrace::String::new_ptr());
161}
162
163extern "C"
164void xtrace_string_destruct(xtrace_string_t obj) {
165 xtrace::String::free_ptr(xtrace::String::to_cxx_ptr(obj));
166}
167
168extern "C"
169void xtrace_string_append_c_string(xtrace_string_t obj, const char* other) {
170 xtrace::String::to_cxx_ptr(obj)->append(other);
171}
172
173extern "C"
174void xtrace_string_append_xtrace_string(xtrace_string_t obj, xtrace_string_t other) {
175 xtrace::String::to_cxx_ptr(obj)->append(xtrace::String::to_cxx_ptr(other));
176}
177
178extern "C"
179void xtrace_string_append_format_valist(xtrace_string_t obj, const char* format, va_list args) {
180 xtrace::String::to_cxx_ptr(obj)->append_format(format,args);
181}
182
183extern "C"
184void xtrace_string_append_format(xtrace_string_t obj, const char* format, ...) {
185 va_list args;
186 va_start(args,format);
187 xtrace_string_append_format_valist(obj,format,args);
188 va_end(args);
189}
190
191extern "C"
192void xtrace_string_clear(xtrace_string_t obj) {
193 xtrace::String::to_cxx_ptr(obj)->clear();
194}
195
196extern "C"
197const char* xtrace_string_c_str(xtrace_string_t obj) {
198 return xtrace::String::to_cxx_ptr(obj)->c_str();
199}
200
201extern "C"
202size_t xtrace_string_size(xtrace_string_t obj) {
203 return xtrace::String::to_cxx_ptr(obj)->size();
204}
205
206extern "C"
207size_t xtrace_string_capacity(xtrace_string_t obj) {
208 return xtrace::String::to_cxx_ptr(obj)->capacity();
209}