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
|
/* 9p/internal.h - TODO
*
* Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-Licence-Identifier: AGPL-3.0-or-later
*/
#ifndef _9P_INTERNAL_H_
#define _9P_INTERNAL_H_
#include <stdint.h>
#include <stdbool.h>
#include "9p/defs.h"
/* C language *****************************************************************/
#define UNUSED(name) /* name __attribute__ ((unused)) */
/* vtables ********************************************************************/
typedef bool (*_checksize_fn_t)(uint32_t net_len, uint8_t *net_bytes, uint32_t *mut_net_offset, size_t *mut_host_extra);
typedef bool (*_unmarshal_fn_t)(uint8_t *net_bytes, uint32_t *mut_net_offset, void **mut_host_extra, void *out);
typedef bool (*_marshal_fn_t)(struct p9_ctx *ctx, void *val, uint8_t *out_net_bytes, uint32_t *mut_net_offset);
struct msg_vtable {
size_t unmarshal_basesize;
_checksize_fn_t unmarshal_extrasize;
_unmarshal_fn_t unmarshal;
_marshal_fn_t marshal;
};
struct version {
struct msg_vtable msgs[0xFF];
};
extern struct version version_9P2000;
/*extern struct version version_9P2000u; */
/* unmarshal utilities ********************************************************/
static inline uint8_t decode_u8le(uint8_t *in) {
return in[0];
}
static inline uint16_t decode_u16le(uint8_t *in) {
return (((uint16_t)(in[0])) << 0)
| (((uint16_t)(in[1])) << 8)
;
}
static inline uint32_t decode_u32le(uint8_t *in) {
return (((uint32_t)(in[0])) << 0)
| (((uint32_t)(in[1])) << 8)
| (((uint32_t)(in[2])) << 16)
| (((uint32_t)(in[3])) << 24)
;
}
static inline uint64_t decode_u64le(uint8_t *in) {
return (((uint64_t)(in[0])) << 0)
| (((uint64_t)(in[1])) << 8)
| (((uint64_t)(in[2])) << 16)
| (((uint64_t)(in[3])) << 24)
| (((uint64_t)(in[4])) << 32)
| (((uint64_t)(in[5])) << 40)
| (((uint64_t)(in[6])) << 48)
| (((uint64_t)(in[7])) << 56)
;
}
static inline bool is_valid_utf8_without_nul(uint8_t *str, size_t len) {
uint8_t mask;
uint8_t chlen;
for (size_t pos = 0; pos < len;) {
if ((str[pos] & 0b10000000) == 0b00000000) { mask = 0b01111111; chlen = 1; }
else if ((str[pos] & 0b11100000) == 0b11000000) { mask = 0b00011111; chlen = 2; }
else if ((str[pos] & 0b11110000) == 0b11100000) { mask = 0b00001111; chlen = 3; }
else if ((str[pos] & 0b11111000) == 0b11110000) { mask = 0b00000111; chlen = 4; }
else return false;
if (pos + chlen > len || (str[pos] & mask) == 0) return false;
switch (chlen) {
case 4: if ((str[pos+3] & 0b11000000) != 0b10000000) return false; /* fallthrough */
case 3: if ((str[pos+2] & 0b11000000) != 0b10000000) return false; /* fallthrough */
case 2: if ((str[pos+1] & 0b11000000) != 0b10000000) return false; /* fallthrough */
}
pos += chlen;
}
return true;
}
/* marshal utilities **********************************************************/
static inline void encode_u8le(uint8_t in, uint8_t *out) {
out[0] = in;
}
static inline void encode_u16le(uint16_t in, uint8_t *out) {
out[0] = (uint8_t)((in >> 0) & 0xFF);
out[1] = (uint8_t)((in >> 8) & 0xFF);
}
static inline void encode_u32le(uint32_t in, uint8_t *out) {
out[0] = (uint8_t)((in >> 0) & 0xFF);
out[1] = (uint8_t)((in >> 8) & 0xFF);
out[2] = (uint8_t)((in >> 16) & 0xFF);
out[3] = (uint8_t)((in >> 24) & 0xFF);
}
static inline void encode_u64le(uint64_t in, uint8_t *out) {
out[0] = (uint8_t)((in >> 0) & 0xFF);
out[1] = (uint8_t)((in >> 8) & 0xFF);
out[2] = (uint8_t)((in >> 16) & 0xFF);
out[3] = (uint8_t)((in >> 24) & 0xFF);
out[4] = (uint8_t)((in >> 32) & 0xFF);
out[5] = (uint8_t)((in >> 40) & 0xFF);
out[6] = (uint8_t)((in >> 48) & 0xFF);
out[7] = (uint8_t)((in >> 56) & 0xFF);
}
#endif /* _9P_INTERNAL_H_ */
|