diff --git a/CHANGELOG.md b/CHANGELOG.md index 573c49d7ede1783da6ae593e7962f16f4366f376..e3707ef4c3be22719d2a64f00e5703b86c8e446b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added +- add --binary option for read and write files in binary format - add cross compile file for sparc - add tests for the compression entity - add test for cmp_rdcu_cfg.c diff --git a/README.md b/README.md index 48c0fd9937a76c428535cf8503d5f41d0c86bc94..e4d48879bfca88ad5bf17165259a7d8e4e240c6a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Compiled executables can be found [here](https://gitlab.phaidra.org/loidoltd15/c | `-o <prefix>` | Use the `<prefix>` for output files<sup>[1](#fnote1)</sup> | | `-n, --model_cfg` | Print a default model configuration and exit<sup>[2](#fnote2)</sup> | | `--diff_cfg` | Print a default 1d-differencing configuration and exit<sup>[2](#fnote2)</sup> | +| `--binary` | Read and write files in binary format | | `--no_header` | Do not add a compression entity header in front of the compressed data | | `-a, --rdcu_par` | Add additional RDCU control parameters | | `-V, --version` | Print program version and exit | diff --git a/cmp_tool.c b/cmp_tool.c index e9cd735ab2a4ad7b0cd580d120e133a977b258af..f30969929bed398958a45ad5339c87ea6181e83b 100644 --- a/cmp_tool.c +++ b/cmp_tool.c @@ -73,6 +73,7 @@ enum { NO_HEADER, MODEL_ID, MODEL_COUTER, + BINARY_IO, }; static const struct option long_options[] = { @@ -89,6 +90,7 @@ static const struct option long_options[] = { {"no_header", no_argument, NULL, NO_HEADER}, {"model_id", required_argument, NULL, MODEL_ID}, {"model_counter", required_argument, NULL, MODEL_COUTER}, + {"binary", no_argument, NULL, BINARY_IO}, {NULL, 0, NULL, 0} }; @@ -106,8 +108,8 @@ static int rdcu_pkt_mode; * setup packets */ static const char *last_info_file_name; -/* if non zero print additional verbose output */ -static int verbose_en; +/* option flags for file IO */ +static int io_flags; /* if non zero add a compression entity header in front of the compressed data */ static int include_cmp_header = 1; @@ -197,7 +199,7 @@ int main(int argc, char **argv) output_prefix = optarg; break; case 'v': /* --verbose */ - verbose_en = 1; + io_flags |= CMP_IO_VERBOSE; break; case 'V': /* --version */ printf("%s version %s\n", PROGRAM_NAME, CMP_TOOL_VERSION); @@ -231,6 +233,9 @@ int main(int argc, char **argv) case MODEL_COUTER: model_counter_str = optarg; break; + case BINARY_IO: + io_flags |= CMP_IO_BINARY; + break; default: print_help(program_name); exit(EXIT_FAILURE); @@ -317,7 +322,7 @@ int main(int argc, char **argv) if (cmp_operation) { printf("## Starting the compression ##\n"); printf("Importing configuration file %s ... ", cfg_file_name); - error = cmp_cfg_read(cfg_file_name, &cfg, verbose_en); + error = cmp_cfg_read(cfg_file_name, &cfg, io_flags & CMP_IO_VERBOSE); if (error) goto fail; printf("DONE\n"); @@ -330,7 +335,7 @@ int main(int argc, char **argv) if (cfg.samples == 0) { int32_t samples; - size = read_file_data(data_file_name, cfg.data_type, NULL, 0, 0); + size = read_file_data(data_file_name, cfg.data_type, NULL, 0, io_flags); if (size <= 0 || size > UINT32_MAX) /* empty file is treated as an error */ goto fail; samples = cmp_input_size_to_samples((uint32_t)size, cfg.data_type); @@ -348,7 +353,7 @@ int main(int argc, char **argv) } size = read_file_data(data_file_name, cfg.data_type, cfg.input_buf, - input_size, verbose_en); + input_size, io_flags); if (size < 0) goto fail; printf("DONE\n"); @@ -361,7 +366,7 @@ int main(int argc, char **argv) uint32_t cmp_size_byte; printf("Importing decompression information file %s ... ", info_file_name); - error = cmp_info_read(info_file_name, &info, verbose_en); + error = cmp_info_read(info_file_name, &info, io_flags & CMP_IO_VERBOSE); if (error) goto fail; printf("DONE\n"); @@ -384,7 +389,7 @@ int main(int argc, char **argv) cmp_size_byte = (info.cmp_size+7)/CHAR_BIT; f_size = read_file8(data_file_name, cmp_ent_get_data_buf(decomp_entity), - cmp_size_byte, verbose_en); + cmp_size_byte, io_flags); if (f_size < 0) goto fail; @@ -396,11 +401,11 @@ int main(int argc, char **argv) size_t buf_size; printf("Importing compressed data file %s ... ", data_file_name); - buf_size = size = read_file_cmp_entity(data_file_name, - NULL, 0, 0); + size = read_file_cmp_entity(data_file_name, NULL, 0, io_flags); if (size < 0 || size > UINT32_MAX) goto fail; /* to be save allocate at least the size of the cmp_entity struct */ + buf_size = (size_t)size; if (buf_size < sizeof(struct cmp_entity)) buf_size = sizeof(struct cmp_entity); /* The compressed data is read in 4-byte words, so our @@ -414,7 +419,7 @@ int main(int argc, char **argv) goto fail; } size = read_file_cmp_entity(data_file_name, decomp_entity, - (uint32_t)size, verbose_en); + (uint32_t)size, io_flags); if (size < 0) goto fail; @@ -423,7 +428,7 @@ int main(int argc, char **argv) cmp_ent_set_size(decomp_entity, (uint32_t)buf_size); } - if (verbose_en) { + if (io_flags & CMP_IO_VERBOSE) { cmp_ent_print(decomp_entity); printf("\n"); } @@ -465,7 +470,7 @@ int main(int argc, char **argv) } size = read_file_data(model_file_name, data_type, input_model_buf, - model_size, verbose_en); + model_size, io_flags); if (size < 0) goto fail; printf("DONE\n"); @@ -505,7 +510,7 @@ int main(int argc, char **argv) } error = write_input_data_to_file(input_model_buf, model_size, data_type, - output_prefix, "_upmodel.dat", verbose_en); + output_prefix, "_upmodel.dat", io_flags); if (error) goto fail; printf("DONE\n"); @@ -592,7 +597,7 @@ static int guess_cmp_pars(struct cmp_cfg *cfg, const char *guess_cmp_mode, printf("DONE\n"); printf("Write the guessed compression configuration to file %s.cfg ... ", output_prefix); - error = cmp_cfg_fo_file(cfg, output_prefix, verbose_en); + error = cmp_cfg_fo_file(cfg, output_prefix, io_flags & CMP_IO_VERBOSE); if (error) return -1; printf("DONE\n"); @@ -623,7 +628,7 @@ static int gen_rdcu_write_pkts(struct cmp_cfg *cfg) /* generation of packets for parallel read/write RDCU setup */ struct cmp_info last_info = {0}; - error = cmp_info_read(last_info_file_name, &last_info, verbose_en); + error = cmp_info_read(last_info_file_name, &last_info, io_flags & CMP_IO_VERBOSE); if (error) { fprintf(stderr, "%s: %s: Importing last decompression information file failed.\n", PROGRAM_NAME, last_info_file_name); @@ -703,13 +708,13 @@ static int cmp_gernate_rdcu_info(const struct cmp_cfg *cfg, int cmp_size_bit, cfg_cpy.golomb_par = cfg_cpy.ap1_golomb_par; cfg_cpy.spill = cfg_cpy.ap1_spill; - info->ap1_cmp_size = icu_compress_data(&cfg_cpy); + info->ap1_cmp_size = (uint32_t)icu_compress_data(&cfg_cpy); if ((int)info->ap1_cmp_size < 0) info->ap1_cmp_size = 0; cfg_cpy.golomb_par = cfg_cpy.ap2_golomb_par; cfg_cpy.spill = cfg_cpy.ap2_spill; - info->ap2_cmp_size = icu_compress_data(&cfg_cpy); + info->ap2_cmp_size = (uint32_t)icu_compress_data(&cfg_cpy); if ((int)info->ap2_cmp_size < 0) info->ap2_cmp_size = 0; } @@ -819,8 +824,8 @@ static int compression(struct cmp_cfg *cfg, struct cmp_info *info) } printf("Write compressed data to file %s.cmp ... ", output_prefix); - error = write_cmp_data_file(data_to_write_to_file, cmp_size_byte, - output_prefix, ".cmp", verbose_en); + error = write_data_to_file(data_to_write_to_file, cmp_size_byte, + output_prefix, ".cmp", io_flags); if (error) goto error_cleanup; printf("DONE\n"); @@ -833,7 +838,7 @@ static int compression(struct cmp_cfg *cfg, struct cmp_info *info) goto error_cleanup; printf("DONE\n"); - if (verbose_en) { + if (io_flags & CMP_IO_VERBOSE) { printf("\n"); print_cmp_info(info); printf("\n"); @@ -891,7 +896,7 @@ static int decompression(struct cmp_entity *ent, uint16_t *input_model_buf) printf("Write decompressed data to file %s.dat ... ", output_prefix); error = write_input_data_to_file(decomp_output, (uint32_t)decomp_size, cmp_ent_get_data_type(ent), - output_prefix, ".dat", verbose_en); + output_prefix, ".dat", io_flags); free(decomp_output); if (error) diff --git a/include/cmp_io.h b/include/cmp_io.h index ec5a77af818683fc4b7d5871e0924a8b86d50983..c9bc953d8f172858c328b7b2ef43699203d42296 100644 --- a/include/cmp_io.h +++ b/include/cmp_io.h @@ -28,26 +28,29 @@ #define BUFFER_LENGTH_DEF_FAKTOR 2 +/* flags argument options (can be combined) */ +#define CMP_IO_VERBOSE 1 +#define CMP_IO_BINARY 2 + void print_help(const char *program_name); int cmp_cfg_read(const char *file_name, struct cmp_cfg *cfg, int verbose_en); int cmp_info_read(const char *file_name, struct cmp_info *info, int verbose_en); -ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, - int verbose_en); +ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, int flags); ssize_t read_file_data(const char *file_name, enum cmp_data_type data_type, - void *buf, uint32_t buf_size, int verbose_en); + void *buf, uint32_t buf_size, int flags); ssize_t read_file_cmp_entity(const char *file_name, struct cmp_entity *ent, - uint32_t ent_size, int verbose_en); + uint32_t ent_size, int flags); ssize_t read_file32(const char *file_name, uint32_t *buf, uint32_t buf_size, int verbose_en); uint32_t cmp_tool_gen_version_id(const char *version); -int write_cmp_data_file(const void *buf, uint32_t buf_size, const char - *output_prefix, const char *name_extension, int verbose); +int write_data_to_file(const void *buf, uint32_t buf_size, const char *output_prefix, + const char *name_extension, int flags); int write_input_data_to_file(void *data, uint32_t data_size, enum cmp_data_type data_type, - const char *output_prefix, const char *name_extension, int verbose); + const char *output_prefix, const char *name_extension, int flags); int cmp_info_to_file(const struct cmp_info *info, const char *output_prefix, int rdcu_cfg); int cmp_cfg_fo_file(const struct cmp_cfg *cfg, const char *output_prefix, int verbose); void cmp_cfg_print(const struct cmp_cfg *cfg); diff --git a/lib/cmp_io.c b/lib/cmp_io.c index 9cf36eac9f5c1224aedd275cd3548e5b575feacc..df96e7009c56eedea053ed6418be3ba92c66e3b3 100644 --- a/lib/cmp_io.c +++ b/lib/cmp_io.c @@ -32,6 +32,7 @@ #include <byteorder.h> #include <cmp_data_types.h> #include <my_inttypes.h> +#include <cmp_io.h> /* directory to convert from data_type to string */ @@ -80,6 +81,7 @@ void print_help(const char *program_name) printf(" -o <prefix> Use the <prefix> for output files\n"); printf(" -n, --model_cfg Print a default model configuration and exit\n"); printf(" --diff_cfg Print a default 1d-differencing configuration and exit\n"); + printf(" --binary Read and write files in binary format\n"); printf(" --no_header Do not add a compression entity header in front of the compressed data\n"); printf(" -a, --rdcu_par Add additional RDCU control parameters\n"); printf(" -V, --version Print program version and exit\n"); @@ -134,7 +136,7 @@ static FILE *open_file(const char *dirname, const char *filename) } errno = 0; - pathname = (char *) alloca((size_t)n + 1); + pathname = (char *)alloca((size_t)n + 1); errno = 0; n = snprintf(pathname, (size_t)n + 1, "%s%s", dirname, filename); @@ -148,25 +150,25 @@ static FILE *open_file(const char *dirname, const char *filename) /** - * @brief write uncompressed input data to an output file + * @brief write uncompressed input data in big-endian to an output file * * @param data the data to write a file * @param data_size size of the data in bytes * @param data_type compression data type of the data * @param output_prefix file name without file extension * @param name_extension extension (with leading point character) - * @param verbose print verbose output if not zero + * @param flags CMP_IO_VERBOSE print verbose output if set + * CMP_IO_BINARY write file in binary format if set * * @returns 0 on success, error otherwise */ int write_input_data_to_file(void *data, uint32_t data_size, enum cmp_data_type data_type, - const char *output_prefix, const char *name_extension, int verbose) + const char *output_prefix, const char *name_extension, int flags) { - uint32_t i = 0; - FILE *fp; - uint8_t *tmp_buf; size_t sample_size = size_of_a_sample(data_type); + uint8_t *tmp_buf; + int return_value; if (!data) abort(); @@ -177,43 +179,18 @@ int write_input_data_to_file(void *data, uint32_t data_size, enum cmp_data_type if (!sample_size) return -1; - fp = open_file(output_prefix, name_extension); - if (fp == NULL) { - fprintf(stderr, "%s: %s%s: %s\n", PROGRAM_NAME, output_prefix, - name_extension, strerror(errno)); - return -1; - } - tmp_buf = malloc(data_size); + if (!tmp_buf) + return -1; memcpy(tmp_buf, data, data_size); cmp_input_big_to_cpu_endianness(tmp_buf, data_size, data_type); - for (i = 0 ; i < data_size; i++) { - fprintf(fp, "%02X", tmp_buf[i]); - if ((i + 1) % 16 == 0) - fprintf(fp, "\n"); - else - fprintf(fp, " "); - } - fprintf(fp, "\n"); - - fclose(fp); - - if (verbose) { - printf("\n\n"); - for (i = 0; i < data_size; i++) { - printf("%02X", tmp_buf[i]); - if ((i + 1) % 16 == 0) - printf("\n"); - else - printf(" "); - } - - printf("\n\n"); - } + return_value = write_data_to_file(tmp_buf, data_size, output_prefix, + name_extension, flags); free(tmp_buf); - return 0; + + return return_value; } @@ -226,17 +203,20 @@ int write_input_data_to_file(void *data, uint32_t data_size, enum cmp_data_type * @param output_prefix file name without file extension * @param name_extension file extension (with leading point character) * - * @param verbose print verbose output if not zero + * @param flags CMP_IO_VERBOSE print verbose output if set + * CMP_IO_BINARY write file in binary format if set * * @returns 0 on success, error otherwise */ -int write_cmp_data_file(const void *buf, uint32_t buf_size, const char *output_prefix, - const char *name_extension, int verbose) +int write_data_to_file(const void *buf, uint32_t buf_size, const char *output_prefix, + const char *name_extension, int flags) { - unsigned int i; FILE *fp; const uint8_t *p = (const uint8_t *)buf; + const uint8_t *output_file_data; + uint8_t *tmp_buf = NULL; + size_t output_file_size; if (!buf) abort(); @@ -251,28 +231,49 @@ int write_cmp_data_file(const void *buf, uint32_t buf_size, const char *output_p return -1; } - for (i = 0; i < buf_size; i++) { - fprintf(fp, "%02X", p[i]); - if ((i + 1) % 32 == 0) - fprintf(fp, "\n"); - else - fprintf(fp, " "); - } - fprintf(fp, "\n"); + if (flags & CMP_IO_BINARY) { + output_file_size = buf_size; + output_file_data = buf; + } else { + size_t i, j; + const uint8_t lut[0x10] = "0123456789abcdef"; + + /* convert data to ASCII */ + output_file_size = buf_size*3 + 1; + tmp_buf = malloc(output_file_size); + if (!tmp_buf){ + fclose(fp); + return -1; + } - fclose(fp); + for (i = 0, j = 0; i < buf_size; i++) { + tmp_buf[j++] = lut[(p[i] >> 4)]; + tmp_buf[j++] = lut[(p[i] & 0xF)]; - if (verbose) { - printf("\n\n"); - for (i = 0; i < buf_size; i++) { - printf("%02X", p[i]); - if ((i + 1) % 32 == 0) - printf("\n"); + if ((i + 1) % 16 == 0) + tmp_buf[j++] = '\n'; else - printf(" "); + tmp_buf[j++] = ' '; + } + tmp_buf[j] = '\n'; + output_file_data = tmp_buf; + } + { + size_t const size_check = fwrite(output_file_data, sizeof(uint8_t), + output_file_size, fp); + fclose(fp); + if (size_check != output_file_size) { + free(tmp_buf); + return -1; } + } + + if (flags & CMP_IO_VERBOSE && !(flags & CMP_IO_BINARY)) { + fwrite(output_file_data, 1, output_file_size, stdout); printf("\n\n"); } + + free(tmp_buf); return 0; } @@ -1094,7 +1095,7 @@ int cmp_info_read(const char *file_name, struct cmp_info *info, int verbose_en) * @returns a pointer to the character after the spaces */ -static const char *skip_space(const char *str) +static __inline const char *skip_space(const char *str) { while (isspace(*str)) str++; @@ -1110,7 +1111,7 @@ static const char *skip_space(const char *str) * @returns a pointer to the character after the comment */ -static const char *skip_comment(const char *str) +static __inline const char *skip_comment(const char *str) { char c = *str; @@ -1143,7 +1144,7 @@ static const char *skip_comment(const char *str) * conversion can be performed, 0 is returned (errno is set to EINVAL)). */ -static uint8_t str_to_uint8(const char *str, char **str_end) +static __inline uint8_t str_to_uint8(const char *str, char const **str_end) { const int BASE = 16; int i; @@ -1155,7 +1156,7 @@ static uint8_t str_to_uint8(const char *str, char **str_end) orig = str; for (i = 0; i < 2; i++) { - unsigned char c = *str; + unsigned char c = (unsigned char)*str; if (c >= 'a') c = c - 'a' + 10; @@ -1166,7 +1167,7 @@ static uint8_t str_to_uint8(const char *str, char **str_end) else c = 0xff; - if (c >= BASE) + if (unlikely(c >= BASE)) break; res = res * BASE + c; @@ -1175,9 +1176,9 @@ static uint8_t str_to_uint8(const char *str, char **str_end) } if (str_end) - *str_end = (char *)str; + *str_end = str; - if (str == orig) { /* no value read in */ + if (unlikely(str == orig)) { /* no value read in */ errno = EINVAL; res = 0; } @@ -1207,24 +1208,24 @@ static uint8_t str_to_uint8(const char *str, char **str_end) * @returns the size in bytes to store the string content; negative on error */ -static ssize_t str2uint8_arr(const char *str, uint8_t *data, uint32_t buf_size, - const char *file_name, int verbose_en) +static ssize_t __inline str2uint8_arr(const char *str, uint8_t *data, uint32_t buf_size, + const char *file_name, int verbose_en) { const char *nptr = str; - char *eptr = NULL; + const char *eptr = NULL; size_t i = 0; errno = 0; if (!data) - buf_size = ~0; + buf_size = ~0U; if (!file_name) file_name = "unknown file name"; for (i = 0; i < buf_size; ) { uint8_t read_val; - unsigned char c = *nptr; + char c = *nptr; if (c == '\0') { if (!data) /* finished counting the sample */ @@ -1249,8 +1250,12 @@ static ssize_t str2uint8_arr(const char *str, uint8_t *data, uint32_t buf_size, abort(); c = *eptr; if (c != '\0' && !isxdigit(c) && !isspace(c) && c != '#') { - fprintf(stderr, "%s: %s: Error read in '%.*s'. The data are not correct formatted.\n", - PROGRAM_NAME, file_name, (int)(eptr-nptr+1), nptr); + if (isprint(c)) + fprintf(stderr, "%s: %s: Error read in '%.*s'. The data are not correct formatted.\n", + PROGRAM_NAME, file_name, (int)(eptr-nptr+1), nptr); + else + fprintf(stderr, "%s: %s: Error: Non printable character found. If you want to read binary files, use the --binary option.\n", + PROGRAM_NAME, file_name); return -1; } if (errno == EINVAL) { @@ -1287,7 +1292,7 @@ static ssize_t str2uint8_arr(const char *str, uint8_t *data, uint32_t buf_size, PROGRAM_NAME, file_name); } - return i; + return (ssize_t)i; } @@ -1306,12 +1311,13 @@ static ssize_t str2uint8_arr(const char *str, uint8_t *data, uint32_t buf_size, * @param file_name data/model file name * @param buf buffer to write the file content (can be NULL) * @param buf_size number of uint8_t data words to read in - * @param verbose_en print verbose output if not zero + * @param flags CMP_IO_VERBOSE print verbose output if set + * CMP_IO_BINARY read in file in binary format if set * * @returns the size in bytes to store the file content; negative on error */ -ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, int verbose_en) +ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, int flags) { FILE *fp; char *file_cpy = NULL; @@ -1346,14 +1352,27 @@ ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, int v if (fseek(fp, 0L, SEEK_SET) != 0) goto fail; - file_cpy = (char *)calloc(file_size+1, sizeof(char)); + if (flags & CMP_IO_BINARY) { + if (buf) { + ret_code = fread(buf, sizeof(uint8_t), buf_size, fp); + if (ret_code != (size_t)file_size) { + if (feof(fp)) + printf("%s: %s: Error: unexpected end of file.\n", PROGRAM_NAME, file_name); + goto fail; + } + } + fclose(fp); + return file_size; + } + + file_cpy = calloc((size_t)file_size+1, sizeof(char)); if (file_cpy == NULL) { fprintf(stderr, "%s: %s: Error: allocating memory!\n", PROGRAM_NAME, file_name); goto fail; } /* copy all the text into the file_cpy buffer */ - ret_code = fread(file_cpy, sizeof(char), file_size, fp); + ret_code = fread(file_cpy, sizeof(uint8_t), (unsigned long)file_size, fp); if (ret_code != (size_t)file_size) { if (feof(fp)) printf("%s: %s: Error: unexpected end of file.\n", PROGRAM_NAME, file_name); @@ -1365,7 +1384,7 @@ ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, int v fclose(fp); fp = NULL; - size = str2uint8_arr(file_cpy, buf, buf_size, file_name, verbose_en); + size = str2uint8_arr(file_cpy, buf, buf_size, file_name, flags & CMP_IO_VERBOSE); free(file_cpy); file_cpy = NULL; @@ -1389,31 +1408,34 @@ fail: * @param data_type compression data type used for the data * @param buf buffer to write the file content (can be NULL) * @param buf_size size in bytes of the buffer - * @param verbose_en print verbose output if not zero + * @param flags CMP_IO_VERBOSE print verbose output if set + * CMP_IO_BINARY read in file in binary format if set * * @returns the size in bytes to store the file content; negative on error */ ssize_t read_file_data(const char *file_name, enum cmp_data_type data_type, - void *buf, uint32_t buf_size, int verbose_en) + void *buf, uint32_t buf_size, int flags) { ssize_t size; int32_t samples; int err; - size = read_file8(file_name, (uint8_t *)buf, buf_size, verbose_en); + size = read_file8(file_name, (uint8_t *)buf, buf_size, flags); + if (size > UINT32_MAX) + return -1; if (size < 0) return size; - samples = cmp_input_size_to_samples(size, data_type); + samples = cmp_input_size_to_samples((uint32_t)size, data_type); if (samples < 0) { fprintf(stderr, "%s: %s: Error: The data are not correct formatted for the used compression data type.\n", PROGRAM_NAME, file_name); return -1; } - err = cmp_input_big_to_cpu_endianness(buf, size, data_type); + err = cmp_input_big_to_cpu_endianness(buf, (uint32_t)size, data_type); if (err) return -1; @@ -1427,17 +1449,18 @@ ssize_t read_file_data(const char *file_name, enum cmp_data_type data_type, * @param file_name file name of the file containing the compression entity * @param ent pointer to the buffer where the content of the file is written (can be NULL) * @param ent_size size in bytes of the compression entity to read in - * @param verbose_en print verbose output if not zero + * @param flags CMP_IO_VERBOSE print verbose output if set + * CMP_IO_BINARY read in file in binary format if set * * @returns the size in bytes to store the file content; negative on error */ ssize_t read_file_cmp_entity(const char *file_name, struct cmp_entity *ent, - uint32_t ent_size, int verbose_en) + uint32_t ent_size, int flags) { ssize_t size; - size = read_file8(file_name, (uint8_t *)ent, ent_size, 0); + size = read_file8(file_name, (uint8_t *)ent, ent_size, flags); if (size < 0) return size; @@ -1457,11 +1480,11 @@ ssize_t read_file_cmp_entity(const char *file_name, struct cmp_entity *ent, } if (size != (ssize_t)cmp_ent_get_size(ent)) { fprintf(stderr, "%s: %s: The size of the compression entity set in the header of the compression entity is not the same size as the read-in file has. Expected: 0x%x, has 0x%zx.\n", - PROGRAM_NAME, file_name, cmp_ent_get_size(ent), size); + PROGRAM_NAME, file_name, cmp_ent_get_size(ent), (size_t)size); return -1; } - if (verbose_en) + if (flags & CMP_IO_VERBOSE) cmp_ent_parse(ent); } @@ -1528,7 +1551,7 @@ uint32_t cmp_tool_gen_version_id(const char *version) */ copy = strdup(version); token = strtok(copy, "."); - n = atoi(token); + n = (unsigned int)atoi(token); if (n > UINT16_MAX) { free(copy); return 0; @@ -1540,7 +1563,7 @@ uint32_t cmp_tool_gen_version_id(const char *version) } token = strtok(NULL, "."); - n = atoi(token); + n = (unsigned int)atoi(token); free(copy); if (n > UINT16_MAX) return 0; diff --git a/meson.build b/meson.build index 5f282685062ecf880cd5317d705516848d10c2c9..1548ca2b3a60e5a7129809e78bddef02c565c00e 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cmp_tool', 'c', - version : '0.10', + version : '0.10-b.2', meson_version : '>= 0.56', license : 'GPL-2.0', default_options : ['warning_level=3', 'c_std=gnu99'] diff --git a/test/cmp_tool/cmp_tool_integration_test.py b/test/cmp_tool/cmp_tool_integration_test.py index c5e489861be23a0dc8b4a26087f06383b1256418..6f16ae8b368e7fd29c08d58a47e07498308b3529 100755 --- a/test/cmp_tool/cmp_tool_integration_test.py +++ b/test/cmp_tool/cmp_tool_integration_test.py @@ -191,6 +191,7 @@ General Options: -o <prefix> Use the <prefix> for output files -n, --model_cfg Print a default model configuration and exit --diff_cfg Print a default 1d-differencing configuration and exit + --binary Read and write files in binary format --no_header Do not add a compression entity header in front of the compressed data -a, --rdcu_par Add additional RDCU control parameters -V, --version Print program version and exit @@ -412,7 +413,7 @@ def test_compression_diff(): assert(info['cmp_err'] == '0') else: header = read_in_cmp_header(f.read()) - assert(header['asw_version_id']['value'] == VERSION) + assert(header['asw_version_id']['value'] == VERSION.split('-')[0]) assert(header['cmp_ent_size']['value'] == IMAGETTE_HEADER_SIZE+4) assert(header['original_size']['value'] == 10) # todo @@ -464,6 +465,8 @@ def test_model_compression(): # generate test data data = '00 01 00 02 00 03 00 04 00 05 \n' model = '00 00 00 01 00 02 00 03 00 04 \n' + data_byte = bytearray.fromhex(data) + model_byte = bytearray.fromhex(model) data_file_name = 'data.dat' model_file_name = 'model.dat' cfg_file_name = 'model.cfg' @@ -488,12 +491,17 @@ def test_model_compression(): for key, value in cfg.items(): f.write(key + ' = ' + str(value) + '\n') - add_args = [" --no_header", ""] + add_args = [" --no_header", "", " --binary"] + add_args = [" --no_header", "", " --binary"] for add_arg in add_args: - print("Remove this", add_arg) + if "--binary" in add_arg: + with open(data_file_name, 'wb') as f: + f.write(data_byte) + with open(model_file_name, 'wb') as f: + f.write(model_byte) # compression returncode, stdout, stderr = call_cmp_tool( - " -c "+cfg_file_name+" -d "+data_file_name + " -m "+model_file_name+" -o "+output_prefix1+ add_arg) + " -c "+cfg_file_name+" -d "+data_file_name+" -m "+model_file_name+" -o " +output_prefix1+add_arg) # check compression results assert(stderr == "") @@ -509,7 +517,7 @@ def test_model_compression(): ) assert(returncode == EXIT_SUCCESS) - if add_arg == " --no_header": + if "--no_header" in add_arg: # check compressed data with open(output_prefix1+".cmp", encoding='utf-8') as f: assert(f.read() == "49 24 00 00 \n") @@ -525,9 +533,14 @@ def test_model_compression(): assert(info['cmp_size'] == '15') assert(info['cmp_err'] == '0') else: - with open(output_prefix1+".cmp", encoding='utf-8') as f: - header = read_in_cmp_header(f.read()) - assert(header['asw_version_id']['value'] == VERSION) + if not "--binary" in add_arg: + with open(output_prefix1+".cmp", encoding='utf-8') as f: + header = read_in_cmp_header(f.read()) + else: + with open(output_prefix1+".cmp", 'rb') as f: + header = read_in_cmp_header(bytearray(f.read()).hex()) + + assert(header['asw_version_id']['value'] == VERSION.split('-')[0]) assert(header['cmp_ent_size']['value'] == IMAGETTE_HEADER_SIZE+4) assert(header['original_size']['value'] == 10) # todo @@ -545,9 +558,11 @@ def test_model_compression(): assert(header['compressed_data']['value'] == "49240000") # decompression - if add_arg == " --no_header": + if "--no_header" in add_arg: returncode, stdout, stderr = call_cmp_tool( " -i "+output_prefix1+".info -d "+output_prefix1+".cmp -m "+model_file_name+" -o "+output_prefix2) + elif "--binary" in add_arg: + returncode, stdout, stderr = call_cmp_tool("-d "+output_prefix1+".cmp -m "+model_file_name+" -o "+output_prefix2+" --binary") else: returncode, stdout, stderr = call_cmp_tool("-d "+output_prefix1+".cmp -m "+model_file_name+" -o "+output_prefix2) assert(stderr == "") @@ -562,13 +577,19 @@ def test_model_compression(): assert(returncode == EXIT_SUCCESS) # check compressed data - with open(output_prefix2+".dat", encoding='utf-8') as f: - assert(f.read() == data) - - with open(output_prefix1+"_upmodel.dat", encoding='utf-8') as f1: - with open(output_prefix2+"_upmodel.dat", encoding='utf-8') as f2: - assert(f1.read() == f2.read() == data) # upmodel == data -> model_value = 0 - # '00 00 00 01 00 02 00 03 00 04 \n') + if not "--binary" in add_arg: + with open(output_prefix2+".dat", encoding='utf-8') as f: + assert(f.read() == data) + with open(output_prefix1+"_upmodel.dat", encoding='utf-8') as f1: + with open(output_prefix2+"_upmodel.dat", encoding='utf-8') as f2: + assert(f1.read() == f2.read() == data) # upmodel == data -> model_value = 0 + # '00 00 00 01 00 02 00 03 00 04 \n') + else: + with open(output_prefix2+".dat", 'rb') as f: + assert(f.read() == data_byte) + with open(output_prefix1+"_upmodel.dat", 'rb') as f1: + with open(output_prefix2+"_upmodel.dat", 'rb') as f2: + assert(f1.read() == f2.read() == data_byte) # clean up finally: del_file(data_file_name) @@ -628,7 +649,7 @@ def test_raw_mode_compression(): assert(info['cmp_err'] == '0') else: header = read_in_cmp_header(f.read()) - assert(header['asw_version_id']['value'] == VERSION) + assert(header['asw_version_id']['value'] == VERSION.split('-')[0]) assert(header['cmp_ent_size']['value'] == GENERIC_HEADER_SIZE+12) assert(header['original_size']['value'] == 10) # todo