nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

tables.h (4323B)


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