]> git.lizzy.rs Git - dragonstd.git/blob - number.c
Portable endian.h header
[dragonstd.git] / number.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #ifdef DRAGONTYPE_ENDIAN_HEADER
4 #include DRAGONTYPE_ENDIAN_HEADER
5 #else
6 #include <endian.h>
7 #endif
8 #include <poll.h>
9 #include "number.h"
10
11 bool read_full(int fd, char *buffer, size_t size)
12 {
13         size_t n_read_total = 0;
14         int n_read;
15         while (n_read_total < size) {
16                 if ((n_read = read(fd, buffer + n_read_total, size - n_read_total)) == -1) {
17                         perror("read");
18                         return false;
19                 }
20                 n_read_total += n_read;
21         }
22         return true;
23 }
24
25 #define htobe8(x) x
26 #define be8toh(x) x
27
28 #define READVEC(type, n) \
29         type buf[n]; \
30         for (int i = 0; i < n; i++) { \
31                 if (! read_ ## type(fd, &buf[i])) \
32                         return false; \
33         }
34
35 #define WRITEVEC(type, n) \
36         for (int i = 0; i < n; i++) { \
37                 if (! write_ ## type(fd, vec[i])) \
38                         return false; \
39         } \
40         return true;
41
42 #define DEFVEC(type) \
43         bool read_v2 ## type(int fd, v2 ## type *ptr) \
44         { \
45                 READVEC(type, 2) \
46                 ptr->x = buf[0]; \
47                 ptr->y = buf[1]; \
48                 return true; \
49         } \
50         bool write_v2 ## type(int fd, v2 ## type val) \
51         { \
52                 type vec[2] = {val.x, val.y}; \
53                 WRITEVEC(type, 2) \
54         } \
55         bool v2 ## type ## _equals(v2 ## type a, v2 ## type b) \
56         { \
57                 return a.x == b.x && a.y == b.y; \
58         } \
59         v2 ## type v2 ## type ## _add(v2 ## type a, v2 ## type b) \
60         { \
61                 return (v2 ## type) {a.x + b.x, a.y + b.y}; \
62         } \
63         bool read_v3 ## type(int fd, v3 ## type *ptr) \
64         { \
65                 READVEC(type, 3) \
66                 ptr->x = buf[0]; \
67                 ptr->y = buf[1]; \
68                 ptr->z = buf[2]; \
69                 return true; \
70         } \
71         bool write_v3 ## type(int fd, v3 ## type val) \
72         { \
73                 type vec[3] = {val.x, val.y, val.z}; \
74                 WRITEVEC(type, 3) \
75         } \
76         bool v3 ## type ## _equals(v3 ## type a, v3 ## type b) \
77         { \
78                 return a.x == b.x && a.y == b.y && a.z == b.z; \
79         } \
80         v3 ## type v3 ## type ## _add(v3 ## type a, v3 ## type b) \
81         { \
82                 return (v3 ## type) {a.x + b.x, a.y + b.y, a.z + b.z}; \
83         } \
84         bool read_v4 ## type(int fd, v4 ## type *ptr) \
85         { \
86                 READVEC(type, 4) \
87                 ptr->x = buf[0]; \
88                 ptr->y = buf[1]; \
89                 ptr->z = buf[2]; \
90                 ptr->w = buf[3]; \
91                 return true; \
92         } \
93         bool write_v4 ## type(int fd, v4 ## type val) \
94         { \
95                 type vec[4] = {val.x, val.y, val.z, val.w}; \
96                 WRITEVEC(type, 4) \
97         } \
98         bool v4 ## type ## _equals(v4 ## type a, v4 ## type b) \
99         { \
100                 return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; \
101         } \
102         v4 ## type v4 ## type ## _add(v4 ## type a, v4 ## type b) \
103         { \
104                 return (v4 ## type) {a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w}; \
105         }
106
107 #define DEFTYP(type, bits) \
108         bool read_ ## type(int fd, type *buf) \
109         { \
110                 u ## bits encoded; \
111                 if (! read_full(fd, (char *) &encoded, sizeof(type))) \
112                         return false; \
113                 *buf = be ## bits ## toh(encoded); \
114                 return true; \
115         } \
116         bool write_ ## type(int fd, type val) \
117         { \
118                 u ## bits encoded = htobe ## bits(val); \
119                 if (write(fd, &encoded, sizeof(encoded)) == -1) { \
120                         perror("write"); \
121                         return false; \
122                 } \
123                 return true; \
124         } \
125         DEFVEC(type)
126
127 #define DEFTYPES(bits) \
128         DEFTYP(s ## bits, bits) \
129         DEFTYP(u ## bits, bits)
130
131 DEFTYPES(8)
132 DEFTYPES(16)
133 DEFTYPES(32)
134 DEFTYPES(64)
135
136 #define DEFFLOAT(type) \
137         bool read_ ## type(int fd, type *buf) \
138         { \
139                 if (! read_full(fd, (char *) buf, sizeof(type))) \
140                         return false; \
141                 return true; \
142         } \
143         bool write_ ## type(int fd, type val) \
144         { \
145                 if (write(fd, &val, sizeof(val)) == -1) { \
146                         perror("write"); \
147                         return false; \
148                 } \
149                 return true; \
150         } \
151         DEFVEC(type)
152
153 DEFFLOAT(f32)
154 DEFFLOAT(f64)