Ruby: prism/util/pm_buffer.c Source File

Ruby 3.3.7p123 (2025-01-15 revision be31f993d7fa0219d85f7b3c694d454da4ecc10b)

pm_buffer.c
1#include "prism/util/pm_buffer.h"
2
6size_t
7pm_buffer_sizeof(void) {
8 return sizeof(pm_buffer_t);
9}
10
14bool
15pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
16 buffer->length = 0;
17 buffer->capacity = capacity;
18
19 buffer->value = (char *) malloc(capacity);
20 return buffer->value != NULL;
21}
22
26bool
27pm_buffer_init(pm_buffer_t *buffer) {
28 return pm_buffer_init_capacity(buffer, 1024);
29}
30
34char *
35pm_buffer_value(pm_buffer_t *buffer) {
36 return buffer->value;
37}
38
42size_t
43pm_buffer_length(pm_buffer_t *buffer) {
44 return buffer->length;
45}
46
50static inline void
51pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
52 size_t next_length = buffer->length + length;
53
54 if (next_length > buffer->capacity) {
55 if (buffer->capacity == 0) {
56 buffer->capacity = 1;
57 }
58
59 while (next_length > buffer->capacity) {
60 buffer->capacity *= 2;
61 }
62
63 buffer->value = realloc(buffer->value, buffer->capacity);
64 }
65
66 buffer->length = next_length;
67}
68
72static inline void
73pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
74 size_t cursor = buffer->length;
75 pm_buffer_append_length(buffer, length);
76 memcpy(buffer->value + cursor, source, length);
77}
78
82void
83pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) {
84 size_t cursor = buffer->length;
85 pm_buffer_append_length(buffer, length);
86 memset(buffer->value + cursor, 0, length);
87}
88
92void
93pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) {
94 va_list arguments;
95 va_start(arguments, format);
96 int result = vsnprintf(NULL, 0, format, arguments);
97 va_end(arguments);
98
99 if (result < 0) return;
100 size_t length = (size_t) (result + 1);
101
102 size_t cursor = buffer->length;
103 pm_buffer_append_length(buffer, length);
104
105 va_start(arguments, format);
106 vsnprintf(buffer->value + cursor, length, format, arguments);
107 va_end(arguments);
108
109 buffer->length--;
110}
111
115void
116pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) {
117 pm_buffer_append(buffer, value, length);
118}
119
123void
124pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length) {
125 pm_buffer_append(buffer, (const char *) value, length);
126}
127
131void
132pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) {
133 const void *source = &value;
134 pm_buffer_append(buffer, source, sizeof(uint8_t));
135}
136
140void
141pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value) {
142 if (value < 128) {
143 pm_buffer_append_byte(buffer, (uint8_t) value);
144 } else {
145 uint32_t n = value;
146 while (n >= 128) {
147 pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
148 n >>= 7;
149 }
150 pm_buffer_append_byte(buffer, (uint8_t) n);
151 }
152}
153
157void
158pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value) {
159 uint32_t unsigned_int = ((uint32_t)(value) << 1) ^ ((uint32_t)(value >> 31));
160 pm_buffer_append_varuint(buffer, unsigned_int);
161}
162
166void
167pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) {
168 if (source->length > 0) {
169 pm_buffer_append(destination, source->value, source->length);
170 }
171}
172
176void
177pm_buffer_free(pm_buffer_t *buffer) {
178 free(buffer->value);
179}
pm_buffer.h
A wrapper around a contiguous block of allocated memory.
pm_buffer_t
A pm_buffer_t is a simple memory buffer that stores data in a contiguous block of memory.
Definition pm_buffer.h:21
pm_buffer_t::capacity
size_t capacity
The capacity of the buffer in bytes that has been allocated.
Definition pm_buffer.h:26
pm_buffer_t::length
size_t length
The length of the buffer in bytes.
Definition pm_buffer.h:23
pm_buffer_t::value
char * value
A pointer to the start of the buffer.
Definition pm_buffer.h:29