aboutsummaryrefslogtreecommitdiff
path: root/src/io_cube.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-06-09 20:06:19 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-06-09 20:06:19 +0200
commit0b1930307f41db3ea7552d6b2f4666b33c64d26a (patch)
tree6a2558e391f5cc14fa22770cb2791e4a85d84e5e /src/io_cube.h
parentb218c803ae1110b08b4896be0a59177e280c9091 (diff)
downloadnissy-core-0b1930307f41db3ea7552d6b2f4666b33c64d26a.tar.gz
nissy-core-0b1930307f41db3ea7552d6b2f4666b33c64d26a.zip
More cleanup
Diffstat (limited to 'src/io_cube.h')
-rw-r--r--src/io_cube.h359
1 files changed, 359 insertions, 0 deletions
diff --git a/src/io_cube.h b/src/io_cube.h
new file mode 100644
index 0000000..63c9f53
--- /dev/null
+++ b/src/io_cube.h
@@ -0,0 +1,359 @@
1_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
2
3_static uint8_t readco(const char *);
4_static uint8_t readcp(const char *);
5_static uint8_t readeo(const char *);
6_static uint8_t readep(const char *);
7_static cube_t readcube_B32(const char *);
8_static cube_t readcube_H48(const char *);
9_static uint8_t readpiece_LST(const char **);
10_static cube_t readcube_LST(const char *);
11
12_static int writepiece_LST(uint8_t, char *);
13_static void writecube_B32(cube_t, char *);
14_static void writecube_H48(cube_t, char *);
15_static void writecube_LST(cube_t, char *);
16
17_static uint8_t b32toedge(char);
18_static uint8_t b32tocorner(char);
19_static char edgetob32(uint8_t);
20_static char cornertob32(uint8_t);
21
22_static struct {
23 const char *name;
24 cube_t (*read)(const char *);
25 void (*write)(cube_t, char *);
26} ioformat[] =
27{
28 { .name = "B32", .read = readcube_B32, .write = writecube_B32 },
29 { .name = "LST", .read = readcube_LST, .write = writecube_LST },
30 { .name = "H48", .read = readcube_H48, .write = writecube_H48 },
31 { .name = "NONE", .read = NULL, .write = NULL },
32};
33
34_static_inline cube_t
35cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
36{
37 return static_cube(
38 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
39 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
40 e[8], e[9], e[10], e[11]);
41}
42
43cube_t
44readcube(const char *format, const char *buf)
45{
46 int i;
47
48 for (i = 0; ioformat[i].read != NULL; i++)
49 if (!strcmp(format, ioformat[i].name))
50 return ioformat[i].read(buf);
51
52 DBG_LOG("Cannot read cube in the given format\n");
53 return zero;
54}
55
56void
57writecube(const char *format, cube_t cube, char *buf)
58{
59 char *errormsg;
60 size_t len;
61
62 if (!isconsistent(cube)) {
63 errormsg = "ERROR: cannot write inconsistent cube";
64 goto writecube_error;
65 }
66
67 int i;
68
69 for (i = 0; ioformat[i].write != NULL; i++) {
70 if (!strcmp(format, ioformat[i].name)) {
71 ioformat[i].write(cube, buf);
72 return;
73 }
74 }
75
76 errormsg = "ERROR: cannot write cube in the given format";
77
78writecube_error:
79 DBG_LOG("writecube error, see stdout for details\n");
80 len = strlen(errormsg);
81 memcpy(buf, errormsg, len);
82 buf[len] = '\n';
83 buf[len+1] = '\0';
84}
85
86_static uint8_t
87readco(const char *str)
88{
89 if (*str == '0')
90 return 0;
91 if (*str == '1')
92 return _ctwist_cw;
93 if (*str == '2')
94 return _ctwist_ccw;
95
96 DBG_LOG("Error reading CO\n");
97 return _error;
98}
99
100_static uint8_t
101readcp(const char *str)
102{
103 uint8_t c;
104
105 for (c = 0; c < 8; c++)
106 if (!strncmp(str, cornerstr[c], 3) ||
107 !strncmp(str, cornerstralt[c], 3))
108 return c;
109
110 DBG_LOG("Error reading CP\n");
111 return _error;
112}
113
114_static uint8_t
115readeo(const char *str)
116{
117 if (*str == '0')
118 return 0;
119 if (*str == '1')
120 return _eflip;
121
122 DBG_LOG("Error reading EO\n");
123 return _error;
124}
125
126_static uint8_t
127readep(const char *str)
128{
129 uint8_t e;
130
131 for (e = 0; e < 12; e++)
132 if (!strncmp(str, edgestr[e], 2))
133 return e;
134
135 DBG_LOG("Error reading EP\n");
136 return _error;
137}
138
139_static cube_t
140readcube_B32(const char *buf)
141{
142 int i;
143 uint8_t c[8], e[12];
144
145 for (i = 0; i < 8; i++) {
146 c[i] = b32tocorner(buf[i]);
147 DBG_ASSERT(c[i] < 255, zero,
148 "Error reading B32 corner %d (char %d)\n", i, i);
149 }
150
151 for (i = 0; i < 12; i++) {
152 e[i] = b32toedge(buf[i+9]);
153 DBG_ASSERT(e[i] < 255, zero,
154 "Error reading B32 edge %d (char %d)\n", i, i+9);
155 }
156
157 return cubefromarray(c, e);
158}
159
160_static cube_t
161readcube_H48(const char *buf)
162{
163 int i;
164 uint8_t piece, orient, c[8], e[12];
165 const char *b;
166
167 b = buf;
168
169 for (i = 0; i < 12; i++) {
170 while (*b == ' ' || *b == '\t' || *b == '\n')
171 b++;
172 if ((piece = readep(b)) == _error)
173 return zero;
174 b += 2;
175 if ((orient = readeo(b)) == _error)
176 return zero;
177 b++;
178 e[i] = piece | orient;
179 }
180 for (i = 0; i < 8; i++) {
181 while (*b == ' ' || *b == '\t' || *b == '\n')
182 b++;
183 if ((piece = readcp(b)) == _error)
184 return zero;
185 b += 3;
186 if ((orient = readco(b)) == _error)
187 return zero;
188 b++;
189 c[i] = piece | orient;
190 }
191
192 return cubefromarray(c, e);
193}
194
195_static uint8_t
196readpiece_LST(const char **b)
197{
198 uint8_t ret;
199 bool read;
200
201 while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n')
202 (*b)++;
203
204 for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) {
205 read = true;
206 ret = ret * 10 + (**b) - '0';
207 }
208
209 return read ? ret : _error;
210}
211
212_static cube_t
213readcube_LST(const char *buf)
214{
215 int i;
216 uint8_t c[8], e[12];
217
218 for (i = 0; i < 8; i++)
219 c[i] = readpiece_LST(&buf);
220
221 for (i = 0; i < 12; i++)
222 e[i] = readpiece_LST(&buf);
223
224 return cubefromarray(c, e);
225}
226
227_static int
228writepiece_LST(uint8_t piece, char *buf)
229{
230 char digits[3];
231 int i, len;
232
233 len = 0;
234 while (piece != 0) {
235 digits[len++] = (piece % 10) + '0';
236 piece /= 10;
237 }
238
239 if (len == 0)
240 digits[len++] = '0';
241
242 for (i = 0; i < len; i++)
243 buf[i] = digits[len-i-1];
244
245 buf[len] = ',';
246 buf[len+1] = ' ';
247
248 return len+2;
249}
250
251_static void
252writecube_B32(cube_t cube, char *buf)
253{
254 int i;
255 uint8_t corner[8], edge[12];
256
257 pieces(&cube, corner, edge);
258
259 for (i = 0; i < 8; i++)
260 buf[i] = cornertob32(corner[i]);
261
262 buf[8] = '=';
263
264 for (i = 0; i < 12; i++)
265 buf[i+9] = edgetob32(edge[i]);
266
267 buf[21] = '\0';
268}
269
270_static void
271writecube_H48(cube_t cube, char *buf)
272{
273 uint8_t piece, perm, orient, corner[8], edge[12];
274 int i;
275
276 pieces(&cube, corner, edge);
277
278 for (i = 0; i < 12; i++) {
279 piece = edge[i];
280 perm = piece & _pbits;
281 orient = (piece & _eobit) >> _eoshift;
282 buf[4*i ] = edgestr[perm][0];
283 buf[4*i + 1] = edgestr[perm][1];
284 buf[4*i + 2] = orient + '0';
285 buf[4*i + 3] = ' ';
286 }
287 for (i = 0; i < 8; i++) {
288 piece = corner[i];
289 perm = piece & _pbits;
290 orient = (piece & _cobits) >> _coshift;
291 buf[48 + 5*i ] = cornerstr[perm][0];
292 buf[48 + 5*i + 1] = cornerstr[perm][1];
293 buf[48 + 5*i + 2] = cornerstr[perm][2];
294 buf[48 + 5*i + 3] = orient + '0';
295 buf[48 + 5*i + 4] = ' ';
296 }
297
298 buf[48+39] = '\0';
299}
300
301_static void
302writecube_LST(cube_t cube, char *buf)
303{
304 int i;
305 size_t ptr;
306 uint8_t piece, corner[8], edge[12];
307
308 ptr = 0;
309 pieces(&cube, corner, edge);
310
311 for (i = 0; i < 8; i++) {
312 piece = corner[i];
313 ptr += writepiece_LST(piece, buf + ptr);
314 }
315
316 for (i = 0; i < 12; i++) {
317 piece = edge[i];
318 ptr += writepiece_LST(piece, buf + ptr);
319 }
320
321 *(buf+ptr-2) = 0;
322}
323
324_static uint8_t
325b32toedge(char c)
326{
327 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
328 return 255;
329
330 return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a');
331}
332
333_static uint8_t
334b32tocorner(char c) {
335 uint8_t val;
336
337 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'g'))
338 return 255;
339
340 val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26;
341
342 return (val & 7) | ((val & 24) << 2);
343}
344
345_static char
346edgetob32(uint8_t edge)
347{
348 return edge <= 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26);
349}
350
351_static char
352cornertob32(uint8_t corner)
353{
354 uint8_t val;
355
356 val = (corner & 7) | ((corner & 96) >> 2);
357
358 return val <= 26 ? 'A' + (char)val : 'a' + (char)(val - 26);
359}

Generated with cgit - Back to sebastiano.tronto.net