56static inline size_t next_power_of_2(
size_t x)
64#if SIZE_MAX == UINT64_MAX
71static inline size_t clamp(
size_t num,
size_t min_val,
size_t max_val) {
72 return num < min_val ? min_val : (num > max_val ? max_val : num);
78 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: bufsz > LITE3_BUF_SIZE_MAX\n");
86 ctx->underlying_buf = malloc(bufsz);
87 if (!ctx->underlying_buf) {
91 ctx->buf = (u8 *)(((uintptr_t)ctx->underlying_buf + LITE3_NODE_ALIGNMENT_MASK) & ~LITE3_NODE_ALIGNMENT_MASK);
93 ctx->bufsz = (size_t)((uintptr_t)ctx->underlying_buf + (uintptr_t)bufsz - (uintptr_t)ctx->buf);
99 if (LITE3_UNLIKELY(!(buf && buflen))) {
100 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: buffer cannot be empty or NULL\n");
105 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: bufsz > LITE3_BUF_SIZE_MAX\n");
109 size_t new_size = next_power_of_2(buflen + LITE3_NODE_ALIGNMENT_MASK);
113 if (LITE3_UNLIKELY(buflen > new_size - LITE3_NODE_ALIGNMENT_MASK)) {
114 LITE3_PRINT_ERROR(
"NEW SIZE OVERFLOW\n");
120 memcpy(ret->buf, buf, buflen);
121 ret->buflen = buflen;
128 if (LITE3_UNLIKELY(!(buf && bufsz))) {
129 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: buffer cannot be NULL or zero size\n");
134 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: bufsz > LITE3_BUF_SIZE_MAX\n");
138 if (LITE3_UNLIKELY(buflen > bufsz)) {
139 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: buflen > bufsz\n");
144 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: bufsz < LITE3_CONTEXT_BUF_SIZE_MIN\n");
148 if (LITE3_UNLIKELY(((uintptr_t)buf & LITE3_NODE_ALIGNMENT_MASK) != 0)) {
149 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: *buf not aligned to LITE3_NODE_ALIGNMENT\n");
157 ret->buflen = buflen;
159 ret->underlying_buf = buf;
167 LITE3_PRINT_ERROR(
"MESSAGE SIZE: bufsz >= LITE3_BUF_SIZE_MAX\n");
171 size_t current_size = (size_t)((uintptr_t)ctx->buf - (uintptr_t)ctx->underlying_buf) + ctx->bufsz;
175 if (LITE3_UNLIKELY(current_size > new_size - LITE3_NODE_ALIGNMENT_MASK)) {
176 LITE3_PRINT_ERROR(
"NEW SIZE OVERFLOW\n");
180 void *
new = malloc(new_size);
183 u8 *new_buf = (u8 *)(((uintptr_t)
new + LITE3_NODE_ALIGNMENT_MASK) & ~LITE3_NODE_ALIGNMENT_MASK);
184 memcpy(new_buf, ctx->buf, ctx->buflen);
186 ctx->bufsz = (size_t)((uintptr_t)
new + (uintptr_t)new_size - (uintptr_t)new_buf);
187 free(ctx->underlying_buf);
188 ctx->underlying_buf =
new;
195 if (LITE3_UNLIKELY(!(buf && buflen))) {
196 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: buffer cannot be empty or NULL\n");
201 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: bufsz > LITE3_BUF_SIZE_MAX\n");
205 if (buflen > ctx->bufsz) {
206 size_t new_size = next_power_of_2(buflen + LITE3_NODE_ALIGNMENT_MASK);
210 if (LITE3_UNLIKELY(buflen > new_size - LITE3_NODE_ALIGNMENT_MASK)) {
211 LITE3_PRINT_ERROR(
"NEW SIZE OVERFLOW\n");
215 free(ctx->underlying_buf);
216 void *
new = malloc(new_size);
219 ctx->underlying_buf =
new;
220 u8 *new_buf = (u8 *)(((uintptr_t)
new + LITE3_NODE_ALIGNMENT_MASK) & ~LITE3_NODE_ALIGNMENT_MASK);
222 ctx->bufsz = (size_t)((uintptr_t)
new + (uintptr_t)new_size - (uintptr_t)new_buf);
224 ctx->buflen = buflen;
225 memcpy(ctx->buf, buf, buflen);
231 free(ctx->underlying_buf);
233 ctx->underlying_buf = NULL;
#define LITE3_BUF_SIZE_MAX
Maximum Lite³ buffer size.
#define LITE3_CONTEXT_BUF_SIZE_MIN
The minimum buffer size for a Lite³ context.
lite3_ctx * lite3_ctx_create_with_size(size_t bufsz)
Create context with custom size.
void lite3_ctx_destroy(lite3_ctx *ctx)
Destroy context.
lite3_ctx * lite3_ctx_create_take_ownership(unsigned char *buf, size_t buflen, size_t bufsz)
Create context by taking ownership of a buffer.
lite3_ctx * lite3_ctx_create_from_buf(const unsigned char *buf, size_t buflen)
Create context by copying from a buffer.
int lite3_ctx_import_from_buf(lite3_ctx *ctx, const unsigned char *buf, size_t buflen)
Copy data into existing context.
Lite³ Context API Header.