h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

tables.h (4228B)


      1 /* Type definitions and macros are in a separate file for easier testing */
      2 #include "tables_types_macros.h"
      3 
      4 STATIC uint64_t read_unaligned_u64(const char *);
      5 STATIC void write_unaligned_u64(char *, uint64_t);
      6 STATIC int64_t readtableinfo(uint64_t, const char *, tableinfo_t *);
      7 STATIC int64_t readtableinfo_n(uint64_t, const char *, uint8_t, tableinfo_t *);
      8 STATIC int64_t writetableinfo(const tableinfo_t *, uint64_t, char *);
      9 
     10 STATIC uint64_t
     11 read_unaligned_u64(const char *buf)
     12 {
     13 	uint64_t ret;
     14 
     15 	memcpy(&ret, buf, sizeof(uint64_t));
     16 
     17 	return ret;
     18 }
     19 
     20 STATIC void
     21 write_unaligned_u64(char *buf, uint64_t x)
     22 {
     23 	memcpy(buf, &x, sizeof(uint64_t));
     24 }
     25 
     26 STATIC int64_t
     27 readtableinfo(uint64_t buf_size, const char *buf, tableinfo_t *info)
     28 {
     29 	size_t i;
     30 
     31 	if (buf == NULL) {
     32 		LOG("Error reading table: buffer is NULL\n");
     33 		return NISSY_ERROR_NULL_POINTER;
     34 	}
     35 
     36 	if (buf_size < INFOSIZE) {
     37 		LOG("Error reading table: buffer size is too small "
     38 		    "(given size %" PRIu64 " is smaller than INFOSIZE = %"
     39 		    PRId64 ")\n", buf_size, INFOSIZE);
     40 		return NISSY_ERROR_BUFFER_SIZE;
     41 	}
     42 
     43 	if (info == NULL) {
     44 		LOG("Error reading table info: info struct is NULL\n");
     45 		return NISSY_ERROR_UNKNOWN;
     46 	}
     47 
     48 	for (i = 0; i < INFO_DISTRIBUTION_LEN; i++)
     49 		info->distribution[i] = read_unaligned_u64(OFFSET(buf,
     50 		    INFO_OFFSET_DISTRIBUTION + i * sizeof(uint64_t)));
     51 
     52 	info->type = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_TYPE));
     53 	info->infosize = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_INFOSIZE));
     54 	info->fullsize = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_FULLSIZE));
     55 	info->hash = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_HASH));
     56 	info->entries = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_ENTRIES));
     57 	info->classes = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_CLASSES));
     58 	info->next = read_unaligned_u64(OFFSET(buf, INFO_OFFSET_NEXT));
     59 
     60 	memcpy(info->solver, OFFSET(buf, INFO_OFFSET_SOLVER),
     61 	    INFO_SOLVER_STRLEN);
     62 
     63 	info->h48h = *(uint8_t *)OFFSET(buf, INFO_OFFSET_H48H);
     64 	info->bits = *(uint8_t *)OFFSET(buf, INFO_OFFSET_BITS);
     65 	info->base = *(uint8_t *)OFFSET(buf, INFO_OFFSET_BASE);
     66 	info->maxvalue = *(uint8_t *)OFFSET(buf, INFO_OFFSET_MAXVALUE);
     67 
     68 	return NISSY_OK;
     69 }
     70 
     71 STATIC int64_t
     72 readtableinfo_n(
     73 	uint64_t buf_size,
     74 	const char *buf,
     75 	uint8_t n,
     76 	tableinfo_t *info
     77 )
     78 {
     79 	int64_t ret;
     80 
     81 	for (; n > 0; n--, buf = buf + info->next, buf_size -= info->next)
     82 		if ((ret = readtableinfo(buf_size, buf, info)) != 0)
     83 			return ret;
     84 
     85 	return NISSY_OK;
     86 }
     87 
     88 STATIC int64_t
     89 writetableinfo(const tableinfo_t *info, uint64_t data_size, char *buf)
     90 {
     91 	size_t i;
     92 	bool end;
     93 	char *c;
     94 
     95 	if (buf == NULL) {
     96 		LOG("Error writing table: buffer is NULL\n");
     97 		return NISSY_ERROR_NULL_POINTER;
     98 	}
     99 
    100 	if (info == NULL) {
    101 		LOG("Error writing table info: provided info is NULL\n");
    102 		return NISSY_ERROR_UNKNOWN;
    103 	}
    104 
    105 	if (data_size < info->fullsize) {
    106 		LOG("Error writing table: buffer size is too small "
    107 		    "(given %" PRId64 " but table requires %" PRId64 ")\n",
    108 		    data_size, info->fullsize);
    109 		return NISSY_ERROR_BUFFER_SIZE;
    110 	}
    111 
    112 	for (i = 0; i < INFO_DISTRIBUTION_LEN; i++)
    113 		write_unaligned_u64(OFFSET(buf, INFO_OFFSET_DISTRIBUTION +
    114 		    i * sizeof(uint64_t)), info->distribution[i]);
    115 
    116 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_TYPE), info->type);
    117 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_INFOSIZE), info->infosize);
    118 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_FULLSIZE), info->fullsize);
    119 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_HASH), info->hash);
    120 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_ENTRIES), info->entries);
    121 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_CLASSES), info->classes);
    122 	write_unaligned_u64(OFFSET(buf, INFO_OFFSET_NEXT), info->next);
    123 
    124 	memcpy(OFFSET(buf, INFO_OFFSET_SOLVER), info->solver,
    125 	    INFO_SOLVER_STRLEN);
    126 
    127 	/* Zeroing all chars after the end of the string, for consistency */
    128 	end = false;
    129 	for (i = 0; i < INFO_SOLVER_STRLEN; i++) {
    130 		c = OFFSET(buf, INFO_OFFSET_SOLVER + i);
    131 		end = end || *c == 0;
    132 		if (end)
    133 			*c = 0;
    134 	}
    135 
    136 	*(uint8_t *)OFFSET(buf, INFO_OFFSET_H48H) = info->h48h;
    137 	*(uint8_t *)OFFSET(buf, INFO_OFFSET_BITS) = info->bits;
    138 	*(uint8_t *)OFFSET(buf, INFO_OFFSET_BASE) = info->base;
    139 	*(uint8_t *)OFFSET(buf, INFO_OFFSET_MAXVALUE) = info->maxvalue;
    140 
    141 	return NISSY_OK;
    142 }