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