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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#include "prism/util/pm_buffer.h"
/**
* Return the size of the pm_buffer_t struct.
*/
size_t
pm_buffer_sizeof(void) {
return sizeof(pm_buffer_t);
}
/**
* Initialize a pm_buffer_t with the given capacity.
*/
bool
pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
buffer->length = 0;
buffer->capacity = capacity;
buffer->value = (char *) malloc(capacity);
return buffer->value != NULL;
}
/**
* Initialize a pm_buffer_t with its default values.
*/
bool
pm_buffer_init(pm_buffer_t *buffer) {
return pm_buffer_init_capacity(buffer, 1024);
}
/**
* Return the value of the buffer.
*/
char *
pm_buffer_value(pm_buffer_t *buffer) {
return buffer->value;
}
/**
* Return the length of the buffer.
*/
size_t
pm_buffer_length(pm_buffer_t *buffer) {
return buffer->length;
}
/**
* Append the given amount of space to the buffer.
*/
static inline void
pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
size_t next_length = buffer->length + length;
if (next_length > buffer->capacity) {
if (buffer->capacity == 0) {
buffer->capacity = 1;
}
while (next_length > buffer->capacity) {
buffer->capacity *= 2;
}
buffer->value = realloc(buffer->value, buffer->capacity);
}
buffer->length = next_length;
}
/**
* Append a generic pointer to memory to the buffer.
*/
static inline void
pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
size_t cursor = buffer->length;
pm_buffer_append_length(buffer, length);
memcpy(buffer->value + cursor, source, length);
}
/**
* Append the given amount of space as zeroes to the buffer.
*/
void
pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) {
size_t cursor = buffer->length;
pm_buffer_append_length(buffer, length);
memset(buffer->value + cursor, 0, length);
}
/**
* Append a formatted string to the buffer.
*/
void
pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) {
va_list arguments;
va_start(arguments, format);
int result = vsnprintf(NULL, 0, format, arguments);
va_end(arguments);
if (result < 0) return;
size_t length = (size_t) (result + 1);
size_t cursor = buffer->length;
pm_buffer_append_length(buffer, length);
va_start(arguments, format);
vsnprintf(buffer->value + cursor, length, format, arguments);
va_end(arguments);
buffer->length--;
}
/**
* Append a string to the buffer.
*/
void
pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) {
pm_buffer_append(buffer, value, length);
}
/**
* Append a list of bytes to the buffer.
*/
void
pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length) {
pm_buffer_append(buffer, (const char *) value, length);
}
/**
* Append a single byte to the buffer.
*/
void
pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) {
const void *source = &value;
pm_buffer_append(buffer, source, sizeof(uint8_t));
}
/**
* Append a 32-bit unsigned integer to the buffer as a variable-length integer.
*/
void
pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value) {
if (value < 128) {
pm_buffer_append_byte(buffer, (uint8_t) value);
} else {
uint32_t n = value;
while (n >= 128) {
pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
n >>= 7;
}
pm_buffer_append_byte(buffer, (uint8_t) n);
}
}
/**
* Append a 32-bit signed integer to the buffer as a variable-length integer.
*/
void
pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value) {
uint32_t unsigned_int = ((uint32_t)(value) << 1) ^ ((uint32_t)(value >> 31));
pm_buffer_append_varuint(buffer, unsigned_int);
}
/**
* Concatenate one buffer onto another.
*/
void
pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) {
if (source->length > 0) {
pm_buffer_append(destination, source->value, source->length);
}
}
/**
* Free the memory associated with the buffer.
*/
void
pm_buffer_free(pm_buffer_t *buffer) {
free(buffer->value);
}
|