forked from GitHub/gf-core
140 lines
2.5 KiB
C
140 lines
2.5 KiB
C
#ifndef GU_IN_H_
|
|
#define GU_IN_H_
|
|
|
|
#include <gu/defs.h>
|
|
#include <gu/exn.h>
|
|
#include <gu/assert.h>
|
|
|
|
typedef struct GuInStream GuInStream;
|
|
|
|
struct GuInStream {
|
|
const uint8_t* (*begin_buffer)(GuInStream* self, size_t* sz_out,
|
|
GuExn* err);
|
|
void (*end_buffer)(GuInStream* self, size_t consumed, GuExn* err);
|
|
size_t (*input)(GuInStream* self, uint8_t* buf, size_t max_sz,
|
|
GuExn* err);
|
|
};
|
|
|
|
typedef struct GuIn GuIn;
|
|
|
|
struct GuIn {
|
|
const uint8_t* restrict buf_end;
|
|
ptrdiff_t buf_curr;
|
|
size_t buf_size;
|
|
GuInStream* stream;
|
|
GuFinalizer fini;
|
|
};
|
|
|
|
GuIn*
|
|
gu_new_in(GuInStream* stream, GuPool* pool);
|
|
|
|
const uint8_t*
|
|
gu_in_begin_span(GuIn* in, size_t *sz_out, GuExn* err);
|
|
|
|
void
|
|
gu_in_end_span(GuIn* in, size_t consumed);
|
|
|
|
size_t
|
|
gu_in_some(GuIn* in, uint8_t* buf, size_t max_len, GuExn* err);
|
|
|
|
inline void
|
|
gu_in_bytes(GuIn* in, uint8_t* buf, size_t sz, GuExn* err)
|
|
{
|
|
gu_require(sz < PTRDIFF_MAX);
|
|
ptrdiff_t curr = in->buf_curr;
|
|
ptrdiff_t new_curr = curr + (ptrdiff_t) sz;
|
|
if (GU_UNLIKELY(new_curr > 0)) {
|
|
extern void gu_in_bytes_(GuIn* in, uint8_t* buf, size_t sz,
|
|
GuExn* err);
|
|
gu_in_bytes_(in, buf, sz, err);
|
|
return;
|
|
}
|
|
memcpy(buf, &in->buf_end[curr], sz);
|
|
in->buf_curr = new_curr;
|
|
}
|
|
|
|
inline int
|
|
gu_in_peek_u8(GuIn* restrict in)
|
|
{
|
|
if (GU_UNLIKELY(in->buf_curr == 0)) {
|
|
return -1;
|
|
}
|
|
return in->buf_end[in->buf_curr];
|
|
}
|
|
|
|
inline void
|
|
gu_in_consume(GuIn* restrict in, size_t sz)
|
|
{
|
|
gu_require((ptrdiff_t) sz + in->buf_curr <= 0);
|
|
in->buf_curr += sz;
|
|
}
|
|
|
|
|
|
inline uint8_t
|
|
gu_in_u8(GuIn* restrict in, GuExn* err)
|
|
{
|
|
if (GU_UNLIKELY(in->buf_curr == 0)) {
|
|
extern uint8_t gu_in_u8_(GuIn* restrict in, GuExn* err);
|
|
return gu_in_u8_(in, err);
|
|
}
|
|
return in->buf_end[in->buf_curr++];
|
|
}
|
|
|
|
int8_t
|
|
gu_in_s8(GuIn* in, GuExn* err);
|
|
|
|
uint16_t
|
|
gu_in_u16le(GuIn* in, GuExn* err);
|
|
|
|
uint16_t
|
|
gu_in_u16be(GuIn* in, GuExn* err);
|
|
|
|
int16_t
|
|
gu_in_s16le(GuIn* in, GuExn* err);
|
|
|
|
int16_t
|
|
gu_in_s16be(GuIn* in, GuExn* err);
|
|
|
|
uint32_t
|
|
gu_in_u32le(GuIn* in, GuExn* err);
|
|
|
|
uint32_t
|
|
gu_in_u32be(GuIn* in, GuExn* err);
|
|
|
|
int32_t
|
|
gu_in_s32le(GuIn* in, GuExn* err);
|
|
|
|
int32_t
|
|
gu_in_s32be(GuIn* in, GuExn* err);
|
|
|
|
uint64_t
|
|
gu_in_u64le(GuIn* in, GuExn* err);
|
|
|
|
uint64_t
|
|
gu_in_u64be(GuIn* in, GuExn* err);
|
|
|
|
int64_t
|
|
gu_in_s64le(GuIn* in, GuExn* err);
|
|
|
|
int64_t
|
|
gu_in_s64be(GuIn* in, GuExn* err);
|
|
|
|
double
|
|
gu_in_f64le(GuIn* in, GuExn* err);
|
|
|
|
double
|
|
gu_in_f64be(GuIn* in, GuExn* err);
|
|
|
|
GuIn*
|
|
gu_buffered_in(GuIn* in, size_t sz, GuPool* pool);
|
|
|
|
GuIn*
|
|
gu_data_in(const uint8_t* buf, size_t size, GuPool* pool);
|
|
|
|
|
|
extern GU_DECLARE_TYPE(GuEOF, abstract);
|
|
|
|
#include <gu/type.h>
|
|
|
|
#endif // GU_IN_H_
|