diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/io_cube.h | 103 |
1 files changed, 61 insertions, 42 deletions
diff --git a/src/core/io_cube.h b/src/core/io_cube.h index 1ac8ec7..0c18f34 100644 --- a/src/core/io_cube.h +++ b/src/core/io_cube.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | STATIC cube_t readcube(const char *, const char *); | 1 | STATIC cube_t readcube(const char *, const char *); |
| 2 | STATIC int writecube(const char *, cube_t, char *); | 2 | STATIC int64_t writecube(const char *, cube_t, uint64_t, char *); |
| 3 | STATIC void log_available_formats(void); | 3 | STATIC void log_available_formats(void); |
| 4 | STATIC uint8_t readco(const char *); | 4 | STATIC uint8_t readco(const char *); |
| 5 | STATIC uint8_t readcp(const char *); | 5 | STATIC uint8_t readcp(const char *); |
| @@ -10,10 +10,10 @@ STATIC cube_t readcube_H48(const char *); | |||
| 10 | STATIC uint8_t readpiece_LST(const char **); | 10 | STATIC uint8_t readpiece_LST(const char **); |
| 11 | STATIC cube_t readcube_LST(const char *); | 11 | STATIC cube_t readcube_LST(const char *); |
| 12 | 12 | ||
| 13 | STATIC int writepiece_LST(uint8_t, char *); | 13 | STATIC int64_t writepiece_LST(uint8_t, uint64_t, char *); |
| 14 | STATIC void writecube_B32(cube_t, char *); | 14 | STATIC int64_t writecube_B32(cube_t, uint64_t, char *); |
| 15 | STATIC void writecube_H48(cube_t, char *); | 15 | STATIC int64_t writecube_H48(cube_t, uint64_t, char *); |
| 16 | STATIC void writecube_LST(cube_t, char *); | 16 | STATIC int64_t writecube_LST(cube_t, uint64_t, char *); |
| 17 | 17 | ||
| 18 | STATIC uint8_t b32toedge(char); | 18 | STATIC uint8_t b32toedge(char); |
| 19 | STATIC uint8_t b32tocorner(char); | 19 | STATIC uint8_t b32tocorner(char); |
| @@ -23,7 +23,7 @@ STATIC char cornertob32(uint8_t); | |||
| 23 | STATIC struct { | 23 | STATIC struct { |
| 24 | const char *name; | 24 | const char *name; |
| 25 | cube_t (*read)(const char *); | 25 | cube_t (*read)(const char *); |
| 26 | void (*write)(cube_t, char *); | 26 | int64_t (*write)(cube_t, uint64_t, char *); |
| 27 | } ioformat[] = | 27 | } ioformat[] = |
| 28 | { | 28 | { |
| 29 | { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, | 29 | { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, |
| @@ -46,35 +46,18 @@ readcube(const char *format, const char *buf) | |||
| 46 | return ZERO_CUBE; | 46 | return ZERO_CUBE; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | STATIC int | 49 | STATIC int64_t |
| 50 | writecube(const char *format, cube_t cube, char *buf) | 50 | writecube(const char *format, cube_t cube, uint64_t buf_size, char *buf) |
| 51 | { | 51 | { |
| 52 | char *errormsg; | ||
| 53 | size_t len; | ||
| 54 | |||
| 55 | if (!isconsistent(cube)) { | ||
| 56 | errormsg = "ERROR: inconsistent"; | ||
| 57 | goto writecube_error; | ||
| 58 | } | ||
| 59 | |||
| 60 | int i; | 52 | int i; |
| 61 | 53 | ||
| 62 | for (i = 0; ioformat[i].write != NULL; i++) { | 54 | for (i = 0; ioformat[i].write != NULL; i++) |
| 63 | if (!strcmp(format, ioformat[i].name)) { | 55 | if (!strcmp(format, ioformat[i].name)) |
| 64 | ioformat[i].write(cube, buf); | 56 | return ioformat[i].write(cube, buf_size, buf); |
| 65 | return 0; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | 57 | ||
| 69 | LOG("Cannot write cube: unknown format '%s'\n", format); | 58 | LOG("Cannot write cube: unknown format '%s'\n", format); |
| 70 | log_available_formats(); | 59 | log_available_formats(); |
| 71 | errormsg = "ERROR: format"; | 60 | return NISSY_ERROR_INVALID_FORMAT; |
| 72 | |||
| 73 | writecube_error: | ||
| 74 | len = strlen(errormsg); | ||
| 75 | memcpy(buf, errormsg, len); | ||
| 76 | buf[len] = '\0'; | ||
| 77 | return 1; | ||
| 78 | } | 61 | } |
| 79 | 62 | ||
| 80 | STATIC void | 63 | STATIC void |
| @@ -249,11 +232,14 @@ readcube_LST(const char *buf) | |||
| 249 | return cubefromarray(c, e); | 232 | return cubefromarray(c, e); |
| 250 | } | 233 | } |
| 251 | 234 | ||
| 252 | STATIC int | 235 | STATIC int64_t |
| 253 | writepiece_LST(uint8_t piece, char *buf) | 236 | writepiece_LST(uint8_t piece, uint64_t buf_size, char *buf) |
| 254 | { | 237 | { |
| 255 | char digits[3]; | 238 | char digits[3]; |
| 256 | int i, len; | 239 | uint64_t i, len; |
| 240 | |||
| 241 | if (piece > 99 || buf_size < 3) | ||
| 242 | return 0; | ||
| 257 | 243 | ||
| 258 | len = 0; | 244 | len = 0; |
| 259 | while (piece != 0) { | 245 | while (piece != 0) { |
| @@ -261,6 +247,9 @@ writepiece_LST(uint8_t piece, char *buf) | |||
| 261 | piece /= 10; | 247 | piece /= 10; |
| 262 | } | 248 | } |
| 263 | 249 | ||
| 250 | if (buf_size < len+2) | ||
| 251 | return 0; | ||
| 252 | |||
| 264 | if (len == 0) | 253 | if (len == 0) |
| 265 | digits[len++] = '0'; | 254 | digits[len++] = '0'; |
| 266 | 255 | ||
| @@ -273,12 +262,19 @@ writepiece_LST(uint8_t piece, char *buf) | |||
| 273 | return len+2; | 262 | return len+2; |
| 274 | } | 263 | } |
| 275 | 264 | ||
| 276 | STATIC void | 265 | STATIC int64_t |
| 277 | writecube_B32(cube_t cube, char *buf) | 266 | writecube_B32(cube_t cube, uint64_t buf_size, char *buf) |
| 278 | { | 267 | { |
| 279 | int i; | 268 | int i; |
| 280 | uint8_t corner[8], edge[12]; | 269 | uint8_t corner[8], edge[12]; |
| 281 | 270 | ||
| 271 | if (buf_size < NISSY_SIZE_B32) { | ||
| 272 | LOG("Cannot write cube in B32 format: buffer size must be " | ||
| 273 | "at least %" PRIu64 " bytes, but the provided one is %" | ||
| 274 | PRIu64 " bytes.\n", NISSY_SIZE_B32, buf_size); | ||
| 275 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 276 | } | ||
| 277 | |||
| 282 | pieces(&cube, corner, edge); | 278 | pieces(&cube, corner, edge); |
| 283 | 279 | ||
| 284 | for (i = 0; i < 8; i++) | 280 | for (i = 0; i < 8; i++) |
| @@ -290,14 +286,23 @@ writecube_B32(cube_t cube, char *buf) | |||
| 290 | buf[i+9] = edgetob32(edge[i]); | 286 | buf[i+9] = edgetob32(edge[i]); |
| 291 | 287 | ||
| 292 | buf[21] = '\0'; | 288 | buf[21] = '\0'; |
| 289 | |||
| 290 | return NISSY_OK; | ||
| 293 | } | 291 | } |
| 294 | 292 | ||
| 295 | STATIC void | 293 | STATIC int64_t |
| 296 | writecube_H48(cube_t cube, char *buf) | 294 | writecube_H48(cube_t cube, uint64_t buf_size, char *buf) |
| 297 | { | 295 | { |
| 298 | uint8_t piece, perm, orient, corner[8], edge[12]; | 296 | uint8_t piece, perm, orient, corner[8], edge[12]; |
| 299 | int i; | 297 | int i; |
| 300 | 298 | ||
| 299 | if (buf_size < NISSY_SIZE_H48) { | ||
| 300 | LOG("Cannot write cube in H48 format: buffer size must be " | ||
| 301 | "at least %" PRIu64 " bytes, but the provided one is %" | ||
| 302 | PRIu64 " bytes.\n", NISSY_SIZE_H48, buf_size); | ||
| 303 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 304 | } | ||
| 305 | |||
| 301 | pieces(&cube, corner, edge); | 306 | pieces(&cube, corner, edge); |
| 302 | 307 | ||
| 303 | for (i = 0; i < 12; i++) { | 308 | for (i = 0; i < 12; i++) { |
| @@ -321,13 +326,15 @@ writecube_H48(cube_t cube, char *buf) | |||
| 321 | } | 326 | } |
| 322 | 327 | ||
| 323 | buf[48+39] = '\0'; | 328 | buf[48+39] = '\0'; |
| 329 | |||
| 330 | return NISSY_OK; | ||
| 324 | } | 331 | } |
| 325 | 332 | ||
| 326 | STATIC void | 333 | STATIC int64_t |
| 327 | writecube_LST(cube_t cube, char *buf) | 334 | writecube_LST(cube_t cube, uint64_t buf_size, char *buf) |
| 328 | { | 335 | { |
| 329 | int i; | 336 | int i; |
| 330 | size_t ptr; | 337 | uint64_t ptr; |
| 331 | uint8_t piece, corner[8], edge[12]; | 338 | uint8_t piece, corner[8], edge[12]; |
| 332 | 339 | ||
| 333 | ptr = 0; | 340 | ptr = 0; |
| @@ -335,15 +342,27 @@ writecube_LST(cube_t cube, char *buf) | |||
| 335 | 342 | ||
| 336 | for (i = 0; i < 8; i++) { | 343 | for (i = 0; i < 8; i++) { |
| 337 | piece = corner[i]; | 344 | piece = corner[i]; |
| 338 | ptr += writepiece_LST(piece, buf + ptr); | 345 | ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr); |
| 346 | if (ptr == 0) | ||
| 347 | goto writecube_LST_error; | ||
| 339 | } | 348 | } |
| 340 | 349 | ||
| 341 | for (i = 0; i < 12; i++) { | 350 | for (i = 0; i < 12; i++) { |
| 342 | piece = edge[i]; | 351 | piece = edge[i]; |
| 343 | ptr += writepiece_LST(piece, buf + ptr); | 352 | ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr); |
| 353 | if (ptr == 0) | ||
| 354 | goto writecube_LST_error; | ||
| 344 | } | 355 | } |
| 345 | 356 | ||
| 346 | *(buf+ptr-2) = 0; | 357 | *(buf+ptr-2) = '\0'; |
| 358 | |||
| 359 | return NISSY_OK; | ||
| 360 | |||
| 361 | writecube_LST_error: | ||
| 362 | LOG("Cannot write cube in LST: buffer is too small (%" PRIu64 | ||
| 363 | " bytes given). The LST format has a variable size, try a " | ||
| 364 | "larger buffer.\n", buf_size); | ||
| 365 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 347 | } | 366 | } |
| 348 | 367 | ||
| 349 | STATIC uint8_t | 368 | STATIC uint8_t |
