// Проверяет, можно ли считать таблицей нечто с адресом p и шириной элементов N static bool slow_check_for_data_table (int N, byte *p, uint32 &type, BYTE *&table_start, BYTE *&table_end, byte *bufstart, byte *bufend, byte *buf, uint64 &offset, Buffer &ReorderingBuffer) { // Сначала сканируем назад, начиная с p, в поисках начала таблицы int useless; table_start = search_for_table_boundary (-N, p, bufstart, bufend, useless); // Затем сканируем вперёд, начиная с table_start, в поисках конца таблицы table_end = search_for_table_boundary (N, table_start, bufstart, bufend, useless); // +разрешить таблицы с широкими столбцами и небольшим числом строк (sqrt(N)*rows >= X) // +учитывать расстояние до предыдущей таблицы для оптимизации конечного уровня сжатия // улучшать оценку для столбцов с фиксированной разницей между элементами (типа 8,16,24,32...) // считать количество байтов, энтропия которых уменьшилась от вычитания [как минимум на два бита] // Теперь выясняем, достаточно ли хороша эта таблица для того, чтобы её стоило закодировать int rows = (table_end-table_start)/N; int useful = rows - useless; // количество полезных строк таблицы double skipBits = logb(mymax(table_start-bufstart,1)); // сколько бит придётся потратить на кодирование поля skip stat ((slow_checks++, verbose>1 && printf ("Slow check %08x-%08x (%d*%d+%d)\n", int(table_start-buf+offset), int(table_end-buf+offset), N, useful, useless))); if (useful*sqrt((double)N) > 30+4*skipBits) { stat ((table_count++, table_sumlen += N*rows, table_skipBits+=skipBits)); stat (verbose>0 && printf("%08x-%08x %d*%d ", int(table_start-buf+offset), int(table_end-buf+offset), N, rows)); // Определить какие столбцы нужно вычесть, а какие являются иммутабельными. // Вычесть вычитаемое и собрать иммутабельные столбцы в начале таблицы (для удобства работы lz77) bool doDiff[MAX_ELEMENT_SIZE], immutable[MAX_ELEMENT_SIZE]; analyze_table (N, table_start, rows, doDiff, immutable); diff_table (N, table_start, rows, doDiff); reorder_table (N, table_start, rows, immutable, ReorderingBuffer); type = encode_type (N, doDiff, immutable); stat (verbose>0 && printf("\n")); return TRUE; } return FALSE; }
const char * type_get_encoding (const type_t *type) { static dstring_t *encoding; if (!encoding) encoding = dstring_newstr(); else dstring_clearstr (encoding); encode_type (encoding, type); return save_string (encoding->str); }
/** * Gets all attributes of MDS Instance as an array of AVA_Type's * * \param mds the mds. * \param count The number of attributes * \param tot_length The total length of the MDS * \return Array of AVA_Type with attributes */ AVA_Type* mds_get_attributes(MDS *mds, intu16* count, intu16 *tot_length) { int i; *count = 17; AVA_Type *ava = calloc(*count, sizeof(AVA_Type)); intu16 length; ByteStreamWriter *stream; *tot_length += 17 * sizeof(ava[0].attribute_id); *tot_length += 17 * sizeof(ava[0].attribute_value.length); length = 4; ava[0].attribute_id = MDC_ATTR_SYS_TYPE; stream = byte_stream_writer_instance(length); encode_type(stream, &mds->system_type); ava[0].attribute_value.value = stream->buffer; ava[0].attribute_value.length = length; // stream buffer lives beyond stream free(stream); *tot_length += length; length = sizeof(intu16) * 2 + mds->system_model.manufacturer.length + mds->system_model.model_number.length; ava[1].attribute_id = MDC_ATTR_ID_MODEL; stream = byte_stream_writer_instance(length); encode_systemmodel(stream, &mds->system_model); ava[1].attribute_value.value = stream->buffer; ava[1].attribute_value.length = length; free(stream); *tot_length += length; // length includes intu16 because it is variable-size length = sizeof(intu16) + mds->system_id.length; ava[2].attribute_id = MDC_ATTR_SYS_ID; stream = byte_stream_writer_instance(length); encode_octet_string(stream, &mds->system_id); ava[2].attribute_value.value = stream->buffer; ava[2].attribute_value.length = length; free(stream); *tot_length += length; length = 2; ava[3].attribute_id = MDC_ATTR_DEV_CONFIG_ID; stream = byte_stream_writer_instance(length); encode_configid(stream, &mds->dev_configuration_id); ava[3].attribute_value.value = stream->buffer; ava[3].attribute_value.length = length; free(stream); *tot_length += length; length = 2 + 2 + mds->attribute_value_map.count * (2 + 2); ava[4].attribute_id = MDC_ATTR_ATTRIBUTE_VAL_MAP; stream = byte_stream_writer_instance(length); encode_attrvalmap(stream, &mds->attribute_value_map); ava[4].attribute_value.value = stream->buffer; ava[4].attribute_value.length = length; free(stream); *tot_length += length; length = 2 + 2 + mds->production_specification.count * (2 + 2 + 2); for (i = 0; i < mds->production_specification.count; i++) { ProdSpecEntry *entry = &mds->production_specification.value[i]; length += entry->prod_spec.length; } ava[5].attribute_id = MDC_ATTR_ID_PROD_SPECN; stream = byte_stream_writer_instance(length); encode_productionspec(stream, &mds->production_specification); ava[5].attribute_value.value = stream->buffer; ava[5].attribute_value.length = length; free(stream); *tot_length += length; length = 2 + 2 + 4 + 2 + 2 + 4; ava[6].attribute_id = MDC_ATTR_MDS_TIME_INFO; stream = byte_stream_writer_instance(length); encode_mdstimeinfo(stream, &mds->mds_time_info); ava[6].attribute_value.value = stream->buffer; ava[6].attribute_value.length = length; free(stream); *tot_length += length; length = 8; ava[7].attribute_id = MDC_ATTR_TIME_ABS; stream = byte_stream_writer_instance(length); encode_absolutetime(stream, &mds->date_and_time); ava[7].attribute_value.value = stream->buffer; ava[7].attribute_value.length = length; free(stream); *tot_length += length; length = 4; ava[8].attribute_id = MDC_ATTR_TIME_REL; stream = byte_stream_writer_instance(length); write_intu32(stream, mds->relative_time); ava[8].attribute_value.value = stream->buffer; ava[8].attribute_value.length = length; free(stream); *tot_length += length; length = 8; ava[9].attribute_id = MDC_ATTR_TIME_REL_HI_RES; stream = byte_stream_writer_instance(length); encode_highresrelativetime(stream, &mds->hires_relative_time); ava[9].attribute_value.value = stream->buffer; ava[9].attribute_value.length = length; free(stream); *tot_length += length; length = 6; ava[10].attribute_id = MDC_ATTR_TIME_ABS_ADJUST; stream = byte_stream_writer_instance(length); encode_absolutetimeadjust(stream, &mds->date_and_time_adjustment); ava[10].attribute_value.value = stream->buffer; ava[10].attribute_value.length = length; free(stream); *tot_length += length; length = 2; ava[11].attribute_id = MDC_ATTR_POWER_STAT; stream = byte_stream_writer_instance(length); write_intu16(stream, mds->power_status); ava[11].attribute_value.value = stream->buffer; ava[11].attribute_value.length = length; free(stream); *tot_length += length; length = 2; ava[12].attribute_id = MDC_ATTR_VAL_BATT_CHARGE; stream = byte_stream_writer_instance(length); write_intu16(stream, mds->battery_level); ava[12].attribute_value.value = stream->buffer; ava[12].attribute_value.length = length; free(stream); *tot_length += length; length = 4 + 2; ava[13].attribute_id = MDC_ATTR_TIME_BATT_REMAIN; stream = byte_stream_writer_instance(length); encode_batmeasure(stream, &mds->remaining_battery_time); ava[13].attribute_value.value = stream->buffer; ava[13].attribute_value.length = length; free(stream); *tot_length += length; length = 2 + 2 + mds->reg_cert_data_list.count * ((1 + 1) + 2); for (i = 0; i < mds->reg_cert_data_list.count; i++) { RegCertData *entry = &mds->reg_cert_data_list.value[i]; length += entry->auth_body_data.length; } ava[14].attribute_id = MDC_ATTR_REG_CERT_DATA_LIST; stream = byte_stream_writer_instance(length); encode_regcertdatalist(stream, &mds->reg_cert_data_list); ava[14].attribute_value.value = stream->buffer; ava[14].attribute_value.length = length; free(stream); *tot_length += length; length = 2 + 2 + mds->system_type_spec_list.count * (2 + 2); ava[15].attribute_id = MDC_ATTR_SYS_TYPE_SPEC_LIST; stream = byte_stream_writer_instance(length); encode_typeverlist(stream, &mds->system_type_spec_list); ava[15].attribute_value.value = stream->buffer; ava[15].attribute_value.length = length; free(stream); *tot_length += length; length = 4; ava[16].attribute_id = MDC_ATTR_CONFIRM_TIMEOUT; stream = byte_stream_writer_instance(length); write_intu32(stream, mds->confirm_timeout); ava[16].attribute_value.value = stream->buffer; ava[16].attribute_value.length = length; free(stream); *tot_length += length; return ava; }