56 lines
1.8 KiB
C
56 lines
1.8 KiB
C
#include <c_BufferInputStream.h>
|
|||
|
|
|
||
|
|
|
||
|
|
typedef struct {
|
||
|
|
c_InStream_t base;
|
||
|
|
const char* data;
|
||
|
|
c_size_t size;
|
||
|
|
c_size_t ptr;
|
||
|
|
c_Allocator_t allocator;
|
||
|
|
} c_BufferInImpl_t;
|
||
|
|
|
||
|
|
static c_err_t _BufferIn_Read(c_InStream_t* self, void* buf, c_size_t len, c_size_t* bytes_read) {
|
||
|
|
c_BufferInImpl_t* impl = (c_BufferInImpl_t*)self;
|
||
|
|
if (!buf || len == 0) return C_ERR_PARAM;
|
||
|
|
|
||
|
|
if (impl->ptr >= impl->size) {
|
||
|
|
if (bytes_read) *bytes_read = 0;
|
||
|
|
return C_ERR_OUTOFBOUND;
|
||
|
|
}
|
||
|
|
|
||
|
|
c_size_t available = impl->size - impl->ptr;
|
||
|
|
c_size_t to_copy = (len < available) ? len : available;
|
||
|
|
|
||
|
|
memcpy(buf, impl->data + impl->ptr, to_copy);
|
||
|
|
impl->ptr += to_copy;
|
||
|
|
if (bytes_read) *bytes_read = to_copy;
|
||
|
|
|
||
|
|
return (to_copy == len) ? C_SUCCESS : C_ERR_OUTOFBOUND;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void _BufferIn_Destroy(c_InStream_t* self) {
|
||
|
|
c_BufferInImpl_t* impl = (c_BufferInImpl_t*)self;
|
||
|
|
c_Allocator_t alloc = impl->allocator;
|
||
|
|
c_Allocator_Free(&alloc, impl);
|
||
|
|
}
|
||
|
|
|
||
|
|
static const c_InStreamVtbl_t g_BufferInVtbl = { _BufferIn_Read, _BufferIn_Destroy };
|
||
|
|
|
||
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||
|
|
/* */
|
||
|
|
|
||
|
|
c_err_t c_BufferInputStream_Create(c_InStream_t** out_stream, const void* buffer_ptr, c_size_t buffer_len, c_Allocator_t* allocator) {
|
||
|
|
if (!out_stream || !buffer_ptr || buffer_len == 0) return C_ERR_PARAM;
|
||
|
|
c_Allocator_t alloc = allocator ? *allocator : c_DefaultAllocator;
|
||
|
|
c_BufferInImpl_t* impl = (c_BufferInImpl_t*)c_Allocator_Calloc(&alloc, 1, sizeof(c_BufferInImpl_t));
|
||
|
|
if (!impl) return C_ERR_NOMEM;
|
||
|
|
|
||
|
|
impl->base.vtbl = &g_BufferInVtbl;
|
||
|
|
impl->data = (const char*)buffer_ptr;
|
||
|
|
impl->size = buffer_len;
|
||
|
|
impl->ptr = 0;
|
||
|
|
impl->allocator = alloc;
|
||
|
|
*out_stream = &impl->base;
|
||
|
|
return C_SUCCESS;
|
||
|
|
}
|