#include typedef struct { c_OutStream_t base; char* data; c_size_t capacity; c_size_t size; c_Allocator_t allocator; } c_BufferOutImpl_t; static c_err_t _BufferOut_Write(c_OutStream_t* self, const void* buf, c_size_t len, c_size_t* written) { c_BufferOutImpl_t* impl = (c_BufferOutImpl_t*)self; if (impl->size + len > impl->capacity) { c_size_t new_cap = impl->capacity == 0 ? 16 : impl->capacity * 2; while (impl->size + len > new_cap) new_cap *= 2; char* new_data = (char*)c_Allocator_Realloc(&impl->allocator, impl->data, impl->capacity, new_cap); if (!new_data) return C_ERR_NOMEM; impl->data = new_data; impl->capacity = new_cap; } memcpy(impl->data + impl->size, buf, len); impl->size += len; if (written) *written = len; return C_SUCCESS; } static c_err_t _BufferOut_Flush(c_OutStream_t* self) { (void)self; return C_SUCCESS; } static void _BufferOut_Destroy(c_OutStream_t* self) { c_BufferOutImpl_t* impl = (c_BufferOutImpl_t*)self; c_Allocator_t alloc = impl->allocator; if (impl->data) c_Allocator_Free(&alloc, impl->data); c_Allocator_Free(&alloc, impl); } static const c_OutStreamVtbl_t g_BufferOutVtbl = { _BufferOut_Write, _BufferOut_Flush, _BufferOut_Destroy }; c_err_t c_BufferOutputStream_Create(c_OutStream_t** out_stream, c_size_t initial_capacity, c_Allocator_t* allocator) { if (!out_stream) return C_ERR_PARAM; c_Allocator_t alloc = allocator ? *allocator : c_DefaultAllocator; c_BufferOutImpl_t* impl = (c_BufferOutImpl_t*)c_Allocator_Calloc(&alloc, 1, sizeof(c_BufferOutImpl_t)); if (!impl) return C_ERR_NOMEM; impl->base.vtbl = &g_BufferOutVtbl; impl->allocator = alloc; if (initial_capacity > 0) { impl->data = (char*)c_Allocator_Calloc(&impl->allocator, initial_capacity, sizeof(char)); if (!impl->data) { c_Allocator_Free(&alloc, impl); return C_ERR_NOMEM; } impl->capacity = initial_capacity; } *out_stream = &impl->base; return C_SUCCESS; } c_err_t c_BufferOutputStream_GetBuffer(c_OutStream_t* self, const void** out_ptr, c_size_t* out_len) { if (!self || self->vtbl != &g_BufferOutVtbl || !out_ptr || !out_len) return C_ERR_PARAM; c_BufferOutImpl_t* impl = (c_BufferOutImpl_t*)self; *out_ptr = impl->data; *out_len = impl->size; return C_SUCCESS; }