15pm_buffer_init_capacity(
pm_buffer_t *buffer,
size_t capacity) {
20 return buffer->
value != NULL;
51pm_buffer_append_length(
pm_buffer_t *buffer,
size_t length) {
52 size_t next_length = buffer->
length + length;
54 if (next_length > buffer->
capacity) {
59 while (next_length > buffer->
capacity) {
64 if (buffer->
value == NULL)
return false;
67 buffer->
length = next_length;
75pm_buffer_append(
pm_buffer_t *buffer,
const void *source,
size_t length) {
76 size_t cursor = buffer->
length;
77 if (pm_buffer_append_length(buffer, length)) {
78 memcpy(buffer->
value + cursor, source, length);
87 size_t cursor = buffer->
length;
88 if (pm_buffer_append_length(buffer, length)) {
89 memset(buffer->
value + cursor, 0, length);
97pm_buffer_append_format(
pm_buffer_t *buffer,
const char *format, ...) {
99 va_start(arguments, format);
100 int result = vsnprintf(NULL, 0, format, arguments);
103 if (result < 0)
return;
104 size_t length = (size_t) (result + 1);
106 size_t cursor = buffer->
length;
107 if (pm_buffer_append_length(buffer, length)) {
108 va_start(arguments, format);
109 vsnprintf(buffer->
value + cursor, length, format, arguments);
119pm_buffer_append_string(
pm_buffer_t *buffer,
const char *value,
size_t length) {
120 pm_buffer_append(buffer, value, length);
127pm_buffer_append_bytes(
pm_buffer_t *buffer,
const uint8_t *value,
size_t length) {
128 pm_buffer_append(buffer, (
const char *) value, length);
136 const void *source = &value;
137 pm_buffer_append(buffer, source,
sizeof(uint8_t));
146 pm_buffer_append_byte(buffer, (uint8_t) value);
150 pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
153 pm_buffer_append_byte(buffer, (uint8_t) n);
162 uint32_t unsigned_int = ((uint32_t)(value) << 1) ^ ((uint32_t)(value >> 31));
163 pm_buffer_append_varuint(buffer, unsigned_int);
171 const void *source = &value;
172 pm_buffer_append(buffer, source,
sizeof(
double));
179pm_buffer_append_unicode_codepoint(
pm_buffer_t *buffer, uint32_t value) {
181 pm_buffer_append_byte(buffer, (uint8_t) value);
183 }
else if (value <= 0x7FF) {
185 (uint8_t) (0xC0 | ((value >> 6) & 0x3F)),
186 (uint8_t) (0x80 | (value & 0x3F))
189 pm_buffer_append_bytes(buffer, bytes, 2);
191 }
else if (value <= 0xFFFF) {
193 (uint8_t) (0xE0 | ((value >> 12) & 0x3F)),
194 (uint8_t) (0x80 | ((value >> 6) & 0x3F)),
195 (uint8_t) (0x80 | (value & 0x3F))
198 pm_buffer_append_bytes(buffer, bytes, 3);
200 }
else if (value <= 0x10FFFF) {
202 (uint8_t) (0xF0 | ((value >> 18) & 0x3F)),
203 (uint8_t) (0x80 | ((value >> 12) & 0x3F)),
204 (uint8_t) (0x80 | ((value >> 6) & 0x3F)),
205 (uint8_t) (0x80 | (value & 0x3F))
208 pm_buffer_append_bytes(buffer, bytes, 4);
220 for (
size_t index = 0; index < length; index++) {
221 const uint8_t
byte = source[index];
223 if ((
byte <= 0x06) || (
byte >= 0x0E &&
byte <= 0x1F) || (
byte >= 0x7F)) {
224 if (escaping == PM_BUFFER_ESCAPING_RUBY) {
225 pm_buffer_append_format(buffer,
"\\x%02X",
byte);
227 pm_buffer_append_format(buffer,
"\\u%04X",
byte);
232 if (escaping == PM_BUFFER_ESCAPING_RUBY) {
233 pm_buffer_append_string(buffer,
"\\a", 2);
235 pm_buffer_append_format(buffer,
"\\u%04X",
byte);
239 pm_buffer_append_string(buffer,
"\\b", 2);
242 pm_buffer_append_string(buffer,
"\\t", 2);
245 pm_buffer_append_string(buffer,
"\\n", 2);
248 if (escaping == PM_BUFFER_ESCAPING_RUBY) {
249 pm_buffer_append_string(buffer,
"\\v", 2);
251 pm_buffer_append_format(buffer,
"\\u%04X",
byte);
255 pm_buffer_append_string(buffer,
"\\f", 2);
258 pm_buffer_append_string(buffer,
"\\r", 2);
261 pm_buffer_append_string(buffer,
"\\\"", 2);
264 if (escaping == PM_BUFFER_ESCAPING_RUBY && index + 1 < length) {
265 const uint8_t next_byte = source[index + 1];
266 if (next_byte ==
'{' || next_byte ==
'@' || next_byte ==
'$') {
267 pm_buffer_append_byte(buffer,
'\\');
271 pm_buffer_append_byte(buffer,
'#');
275 pm_buffer_append_string(buffer,
"\\\\", 2);
278 pm_buffer_append_byte(buffer,
byte);
289pm_buffer_prepend_string(
pm_buffer_t *buffer,
const char *value,
size_t length) {
290 size_t cursor = buffer->
length;
291 if (pm_buffer_append_length(buffer, length)) {
292 memmove(buffer->
value + length, buffer->
value, cursor);
293 memcpy(buffer->
value, value, length);
303 pm_buffer_append(destination, source->
value, source->
length);
321 while (buffer->
length > 0 && pm_char_is_whitespace((uint8_t) buffer->
value[buffer->
length - 1])) {
331 const char *first = memchr(buffer->
value, value, buffer->
length);
332 return (first == NULL) ? SIZE_MAX : (size_t) (first - buffer->
value);
339pm_buffer_insert(
pm_buffer_t *buffer,
size_t index,
const char *value,
size_t length) {
340 assert(index <= buffer->length);
342 if (index == buffer->
length) {
343 pm_buffer_append_string(buffer, value, length);
345 pm_buffer_append_zeroes(buffer, length);
346 memmove(buffer->
value + index + length, buffer->
value + index, buffer->
length - length - index);
347 memcpy(buffer->
value + index, value, length);
#define xfree
Old name of ruby_xfree.
#define xrealloc
Old name of ruby_xrealloc.
#define xmalloc
Old name of ruby_xmalloc.
A wrapper around a contiguous block of allocated memory.
bool pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity)
Initialize a pm_buffer_t with the given capacity.
PRISM_EXPORTED_FUNCTION size_t pm_buffer_sizeof(void)
Return the size of the pm_buffer_t struct.
pm_buffer_escaping_t
The different types of escaping that can be performed by the buffer when appending a slice of Ruby so...
A pm_buffer_t is a simple memory buffer that stores data in a contiguous block of memory.
PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(const pm_buffer_t *buffer)
Return the length of the buffer.
size_t capacity
The capacity of the buffer in bytes that has been allocated.
PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer)
Initialize a pm_buffer_t with its default values.
size_t length
The length of the buffer in bytes.
PRISM_EXPORTED_FUNCTION void pm_buffer_free(pm_buffer_t *buffer)
Free the memory associated with the buffer.
PRISM_EXPORTED_FUNCTION char * pm_buffer_value(const pm_buffer_t *buffer)
Return the value of the buffer.
char * value
A pointer to the start of the buffer.