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
135
136
137
138
139
140
141
142
143
144
145
146
|
#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_init_in(GuInStream* stream);
GuIn*
gu_new_in(GuInStream* stream, GuPool* pool);
GuInStream*
gu_in_proxy_stream(GuIn* in, 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_
|