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
|
#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;
};
GU_API_DECL GuIn*
gu_new_in(GuInStream* stream, GuPool* pool);
GU_API_DECL const uint8_t*
gu_in_begin_span(GuIn* in, size_t *sz_out, GuExn* err);
GU_API_DECL void
gu_in_end_span(GuIn* in, size_t consumed);
GU_API_DECL 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)) {
GU_API_DECL 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)) {
GU_API_DECL uint8_t gu_in_u8_(GuIn* restrict in, GuExn* err);
return gu_in_u8_(in, err);
}
return in->buf_end[in->buf_curr++];
}
GU_API_DECL int8_t
gu_in_s8(GuIn* in, GuExn* err);
GU_API_DECL uint16_t
gu_in_u16le(GuIn* in, GuExn* err);
GU_API_DECL uint16_t
gu_in_u16be(GuIn* in, GuExn* err);
GU_API_DECL int16_t
gu_in_s16le(GuIn* in, GuExn* err);
GU_API_DECL int16_t
gu_in_s16be(GuIn* in, GuExn* err);
GU_API_DECL uint32_t
gu_in_u32le(GuIn* in, GuExn* err);
GU_API_DECL uint32_t
gu_in_u32be(GuIn* in, GuExn* err);
GU_API_DECL int32_t
gu_in_s32le(GuIn* in, GuExn* err);
GU_API_DECL int32_t
gu_in_s32be(GuIn* in, GuExn* err);
GU_API_DECL uint64_t
gu_in_u64le(GuIn* in, GuExn* err);
GU_API_DECL uint64_t
gu_in_u64be(GuIn* in, GuExn* err);
GU_API_DECL int64_t
gu_in_s64le(GuIn* in, GuExn* err);
GU_API_DECL int64_t
gu_in_s64be(GuIn* in, GuExn* err);
GU_API_DECL double
gu_in_f64le(GuIn* in, GuExn* err);
GU_API_DECL double
gu_in_f64be(GuIn* in, GuExn* err);
GU_API_DECL GuIn*
gu_buffered_in(GuIn* in, size_t sz, GuPool* pool);
GU_API_DECL GuIn*
gu_data_in(const uint8_t* buf, size_t size, GuPool* pool);
#endif // GU_IN_H_
|