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