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 (4101B)


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