From affc723f54b1f7470696d63fff5e5749981ddbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:26:21 +0900 Subject: [PATCH] chore: tidy documents & add test --- CMakeLists.txt | 26 +++++-- base16384.c | 43 +++++++----- base16384.h | 166 ++++++++++++++++++++++++-------------------- file.c | 4 +- test/CMakeLists.txt | 15 ++++ test/coder_test.c | 64 +++++++++++++++++ 6 files changed, 219 insertions(+), 99 deletions(-) create mode 100644 test/CMakeLists.txt create mode 100644 test/coder_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index edafedc..9fd796a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,32 +1,46 @@ cmake_minimum_required(VERSION 2.8.12) if (POLICY CMP0048) - cmake_policy(SET CMP0048 NEW) + cmake_policy(SET CMP0048 NEW) endif (POLICY CMP0048) project(base16384 VERSION 2.3.0) -add_executable(base16384_b base16384.c) +add_definitions(-DBASE16384_VERSION="${PROJECT_VERSION}") +add_definitions(-DBASE16384_VERSION_DATE="April 4th 2024") +message(STATUS "Testing endian...") include(TestBigEndian) test_big_endian(isBigEndian) +message(STATUS "Is big endian: ${isBigEndian}.") if (${isBigEndian}) add_definitions(-DWORDS_BIGENDIAN) -endif() +endif () -IF(CMAKE_SIZEOF_VOID_P EQUAL 8) +add_executable(base16384_b base16384.c) + +IF (CMAKE_SIZEOF_VOID_P EQUAL 8) + message(STATUS "Adding 64bit libraries...") add_definitions(-DIS_64BIT_PROCESSOR) add_library(base16384 SHARED file.c base1464.c) add_library(base16384_s STATIC file.c base1464.c) -ELSE() +ELSE () + message(STATUS "Adding 32bit libraries...") add_library(base16384 SHARED file.c base1432.c) add_library(base16384_s STATIC file.c base1432.c) -ENDIF() +ENDIF () set_target_properties(base16384_b PROPERTIES OUTPUT_NAME base16384) set_target_properties(base16384_s PROPERTIES OUTPUT_NAME base16384) set_target_properties(base16384 PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) +message(STATUS "Linking libraries...") target_link_libraries(base16384_b base16384_s) +if (BUILD STREQUAL "test") + message(STATUS "Building test...") + enable_testing() + add_subdirectory(test) +endif () + INSTALL(TARGETS base16384_b RUNTIME DESTINATION bin) INSTALL(TARGETS base16384 LIBRARY DESTINATION lib) INSTALL(TARGETS base16384_s ARCHIVE DESTINATION lib) diff --git a/base16384.c b/base16384.c index dffafaa..b5e9e24 100644 --- a/base16384.c +++ b/base16384.c @@ -39,7 +39,13 @@ unsigned long get_start_ms() { #endif static base16384_err_t print_usage() { - fputs("Copyright (c) 2022-2024 Fumiama Minamoto.\nBase16384 2.3.0 (April 4th 2024). Usage:\n", stderr); + #ifndef BASE16384_VERSION + #define BASE16384_VERSION "dev" + #endif + #ifndef BASE16384_VERSION_DATE + #define BASE16384_VERSION_DATE "unknown date" + #endif + fputs("Copyright (c) 2022-2024 Fumiama Minamoto.\nBase16384 "BASE16384_VERSION" ("BASE16384_VERSION_DATE"). Usage:\n", stderr); fputs("base16384 [-edtn] [inputfile] [outputfile]\n", stderr); fputs(" -e\t\tencode (default)\n", stderr); fputs(" -d\t\tdecode\n", stderr); @@ -102,12 +108,13 @@ int main(int argc, char** argv) { } base16384_err_t exitstat = base16384_err_ok; + #define do_coding(method) base16384_##method##_file_detailed( \ argv[2], argv[3], encbuf, decbuf, \ (no_header?BASE16384_FLAG_NOHEADER:0) | (use_checksum?BASE16384_FLAG_SUM_CHECK_ON_REMAIN:0) \ ) - exitstat = is_encode?do_coding(encode):do_coding(decode); - + exitstat = is_encode?do_coding(encode):do_coding(decode); + #undef do_coding if(t) { #ifdef _WIN32 fprintf(stderr, "spend time: %lums\n", clock() - t); @@ -116,20 +123,22 @@ int main(int argc, char** argv) { #endif } - #define print_base16384_err(n) case base16384_err_##n: perror("base16384_err_"#n) - if(exitstat) switch(exitstat) { - print_base16384_err(get_file_size); break; - print_base16384_err(fopen_output_file); break; - print_base16384_err(fopen_input_file); break; - print_base16384_err(write_file); break; - print_base16384_err(open_input_file); break; - print_base16384_err(map_input_file); break; - print_base16384_err(read_file); break; - print_base16384_err(invalid_file_name); break; - print_base16384_err(invalid_commandline_parameter); break; - print_base16384_err(invalid_decoding_checksum); break; - default: perror("base16384"); break; - } + #define base16384_perror_case(n) case base16384_err_##n: perror("base16384_err_"#n) + if(exitstat) switch(exitstat) { + base16384_perror_case(get_file_size); break; + base16384_perror_case(fopen_output_file); break; + base16384_perror_case(fopen_input_file); break; + base16384_perror_case(write_file); break; + base16384_perror_case(open_input_file); break; + base16384_perror_case(map_input_file); break; + base16384_perror_case(read_file); break; + base16384_perror_case(invalid_file_name); break; + base16384_perror_case(invalid_commandline_parameter); break; + base16384_perror_case(invalid_decoding_checksum); break; + default: perror("base16384"); break; + } + #undef base16384_perror_case + return exitstat; } diff --git a/base16384.h b/base16384.h index 6bf9e74..609503a 100644 --- a/base16384.h +++ b/base16384.h @@ -24,28 +24,23 @@ #include #endif -#define define_base16384_err_t(n) base16384_err_##n - - enum base16384_err_t { - define_base16384_err_t(ok), - define_base16384_err_t(get_file_size), - define_base16384_err_t(fopen_output_file), - define_base16384_err_t(fopen_input_file), - define_base16384_err_t(write_file), - define_base16384_err_t(open_input_file), - define_base16384_err_t(map_input_file), - define_base16384_err_t(read_file), - define_base16384_err_t(invalid_file_name), - define_base16384_err_t(invalid_commandline_parameter), - define_base16384_err_t(invalid_decoding_checksum), - }; - - /** - * @brief return value of base16384_en/decode_file - */ - typedef enum base16384_err_t base16384_err_t; - -#undef define_base16384_err_t +enum base16384_err_t { + base16384_err_ok, + base16384_err_get_file_size, + base16384_err_fopen_output_file, + base16384_err_fopen_input_file, + base16384_err_write_file, + base16384_err_open_input_file, + base16384_err_map_input_file, + base16384_err_read_file, + base16384_err_invalid_file_name, + base16384_err_invalid_commandline_parameter, + base16384_err_invalid_decoding_checksum, +}; +/** + * @brief return value of base16384_en/decode_file +*/ +typedef enum base16384_err_t base16384_err_t; #define _BASE16384_ENCBUFSZ (BUFSIZ*1024/7*7) #define _BASE16384_DECBUFSZ (BUFSIZ*1024/8*8) @@ -157,68 +152,91 @@ int base16384_decode(const char* data, int dlen, char* buf); */ int base16384_decode_unsafe(const char* data, int dlen, char* buf); -// base16384_encode_file_detailed encodes input file to output file. -// use `-` to specify stdin/stdout -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -base16384_err_t base16384_encode_file_detailed(const char* input, const char* output, char* encbuf, char* decbuf, int flag); +#define base16384_typed_params(type) type input, type output, char* encbuf, char* decbuf +#define base16384_typed_flag_params(type) base16384_typed_params(type), int flag -// base16384_encode_fp_detailed encodes input file to output file. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -base16384_err_t base16384_encode_fp_detailed(FILE* input, FILE* output, char* encbuf, char* decbuf, int flag); +/** + * @brief encode input file to output file + * @param input filename or `-` to specify stdin + * @param output filename or `-` to specify stdout + * @param encbuf must be no less than BASE16384_ENCBUFSZ + * @param decbuf must be no less than BASE16384_DECBUFSZ + * @param flag BASE16384_FLAG_xxx value, add multiple flags by `|` + * @return the error code +*/ +base16384_err_t base16384_encode_file_detailed(base16384_typed_flag_params(const char*)); -// base16384_encode_fd_detailed encodes input fd to output fd. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -base16384_err_t base16384_encode_fd_detailed(int input, int output, char* encbuf, char* decbuf, int flag); +/** + * @brief encode input `FILE*` to output `FILE*` + * @param input `FILE*` pointer + * @param output `FILE*` pointer + * @param encbuf must be no less than BASE16384_ENCBUFSZ + * @param decbuf must be no less than BASE16384_DECBUFSZ + * @param flag BASE16384_FLAG_xxx value, add multiple flags by `|` + * @return the error code +*/ +base16384_err_t base16384_encode_fp_detailed(base16384_typed_flag_params(FILE*)); -// base16384_decode_file_detailed decodes input file to output file. -// use `-` to specify stdin/stdout -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -base16384_err_t base16384_decode_file_detailed(const char* input, const char* output, char* encbuf, char* decbuf, int flag); +/** + * @brief encode input stream to output stream + * @param input file descripter + * @param output file descripter + * @param encbuf must be no less than BASE16384_ENCBUFSZ + * @param decbuf must be no less than BASE16384_DECBUFSZ + * @param flag BASE16384_FLAG_xxx value, add multiple flags by `|` + * @return the error code +*/ +base16384_err_t base16384_encode_fd_detailed(base16384_typed_flag_params(int)); -// base16384_decode_fp_detailed decodes input file to output file. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* encbuf, char* decbuf, int flag); +/** + * @brief decode input file to output file + * @param input filename or `-` to specify stdin + * @param output filename or `-` to specify stdout + * @param encbuf must be no less than BASE16384_ENCBUFSZ + * @param decbuf must be no less than BASE16384_DECBUFSZ + * @param flag BASE16384_FLAG_xxx value, add multiple flags by `|` + * @return the error code +*/ +base16384_err_t base16384_decode_file_detailed(base16384_typed_flag_params(const char*)); -// base16384_decode_fd_detailed decodes input fd to output fd. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -base16384_err_t base16384_decode_fd_detailed(int input, int output, char* encbuf, char* decbuf, int flag); +/** + * @brief decode input `FILE*` to output `FILE*` + * @param input `FILE*` pointer + * @param output `FILE*` pointer + * @param encbuf must be no less than BASE16384_ENCBUFSZ + * @param decbuf must be no less than BASE16384_DECBUFSZ + * @param flag BASE16384_FLAG_xxx value, add multiple flags by `|` + * @return the error code +*/ +base16384_err_t base16384_decode_fp_detailed(base16384_typed_flag_params(FILE*)); -// base16384_encode_file encodes input file to output file. -// use `-` to specify stdin/stdout -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -static inline base16384_err_t base16384_encode_file(const char* input, const char* output, char* encbuf, char* decbuf) { - return base16384_encode_file_detailed(input, output, encbuf, decbuf, 0); -} +/** + * @brief decode input stream to output stream + * @param input file descripter + * @param output file descripter + * @param encbuf must be no less than BASE16384_ENCBUFSZ + * @param decbuf must be no less than BASE16384_DECBUFSZ + * @param flag BASE16384_FLAG_xxx value, add multiple flags by `|` + * @return the error code +*/ +base16384_err_t base16384_decode_fd_detailed(base16384_typed_flag_params(int)); -// base16384_encode_fp encodes input file to output file. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -static inline base16384_err_t base16384_encode_fp(FILE* input, FILE* output, char* encbuf, char* decbuf) { - return base16384_encode_fp_detailed(input, output, encbuf, decbuf, 0); -} +#define BASE16384_DEFINE_DEATILED_WRAP(method, name, type) \ + static inline base16384_err_t base16384_##method##_##name##(base16384_typed_params(type)) { \ + return base16384_##method##_##name##_detailed(input, output, encbuf, decbuf, 0); \ + } -// base16384_encode_fd encodes input fd to output fd. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -static inline base16384_err_t base16384_encode_fd(int input, int output, char* encbuf, char* decbuf) { - return base16384_encode_fd_detailed(input, output, encbuf, decbuf, 0); -} + BASE16384_DEFINE_DEATILED_WRAP(encode, file, const char*); + BASE16384_DEFINE_DEATILED_WRAP(encode, fp, FILE*); + BASE16384_DEFINE_DEATILED_WRAP(encode, fd, int); -// base16384_decode_file decodes input file to output file. -// use `-` to specify stdin/stdout -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -static inline base16384_err_t base16384_decode_file(const char* input, const char* output, char* encbuf, char* decbuf) { - return base16384_decode_file_detailed(input, output, encbuf, decbuf, 0); -} + BASE16384_DEFINE_DEATILED_WRAP(decode, file, const char*); + BASE16384_DEFINE_DEATILED_WRAP(decode, fp, FILE*); + BASE16384_DEFINE_DEATILED_WRAP(decode, fd, int); -// base16384_decode_fp decodes input file to output file. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -static inline base16384_err_t base16384_decode_fp(FILE* input, FILE* output, char* encbuf, char* decbuf) { - return base16384_decode_fp_detailed(input, output, encbuf, decbuf, 0); -} +#undef BASE16384_DEFINE_DEATILED_WRAP -// base16384_decode_fd decodes input fd to output fd. -// encbuf & decbuf must be no less than BASE16384_ENCBUFSZ & BASE16384_DECBUFSZ -static inline base16384_err_t base16384_decode_fd(int input, int output, char* encbuf, char* decbuf) { - return base16384_decode_fd_detailed(input, output, encbuf, decbuf, 0); -} +#undef base16384_typed_flag_params +#undef base16384_typed_params #endif diff --git a/file.c b/file.c index 35ff956..80bdd09 100644 --- a/file.c +++ b/file.c @@ -58,7 +58,7 @@ static inline uint32_t calc_sum(uint32_t sum, size_t cnt, char* encbuf) { fprintf(stderr, "firstval: %08x, ", htobe32(((uint32_t*)encbuf)[i])); } #endif - sum += LEFTROTATE(htobe32(((uint32_t*)encbuf)[i]), encbuf[i*sizeof(sum)]%(8*sizeof(sum))); + sum += ~LEFTROTATE(htobe32(((uint32_t*)encbuf)[i]), encbuf[i*sizeof(sum)]%(8*sizeof(sum))); } #ifdef DEBUG fprintf(stderr, "roundmid: %08x", sum); @@ -66,7 +66,7 @@ static inline uint32_t calc_sum(uint32_t sum, size_t cnt, char* encbuf) { size_t rem = cnt % sizeof(sum); if(rem) { uint32_t x = htobe32(((uint32_t*)encbuf)[i]) & (0xffffffff << (8*(sizeof(sum)-rem))); - sum += LEFTROTATE(x, encbuf[i*sizeof(sum)]%(8*sizeof(sum))); + sum += ~LEFTROTATE(x, encbuf[i*sizeof(sum)]%(8*sizeof(sum))); #ifdef DEBUG fprintf(stderr, ", roundrem:%08x\n", sum); #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..48a9ab2 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.8.12) +if (POLICY CMP0048) + cmake_policy(SET CMP0048 NEW) +endif (POLICY CMP0048) +project(base16384_test VERSION 1.0.0) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) + +file (GLOB_RECURSE C_FILES "*.c") +foreach (C_FILE ${C_FILES}) + get_filename_component(FILE_NAME ${C_FILE} NAME_WE) + add_executable(${FILE_NAME} ${C_FILE}) + target_link_libraries(${FILE_NAME} base16384_s) + add_test(NAME do_${FILE_NAME} COMMAND ${FILE_NAME}) +endforeach () diff --git a/test/coder_test.c b/test/coder_test.c new file mode 100644 index 0000000..fb5f06f --- /dev/null +++ b/test/coder_test.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include + +#include "base16384.h" + +char encbuf[4096+16]; +char decbuf[4096/7*8+16]; +char tstbuf[4096+16]; + +#define loop_diff(target) \ + for(i = start; i < end; i++) { \ + if (encbuf[i] != tstbuf[i]) { \ + if(n) { \ + fprintf(stderr, " @%d", i); \ + n = 0; \ + } \ + fprintf(stderr, " %02x", (uint8_t)(target[i])); \ + } else if(!n) { \ + n = 1; \ + fprintf(stderr, " ..."); \ + } \ + } + +#define return_error(i, n) { \ + int end = i; \ + int start; \ + for(start = 0; start < end; start++) { \ + if(encbuf[start] != tstbuf[start]) break; \ + } \ + fprintf(stderr, "result mismatch @ loop %d, decsz: %d, first diff @ %d\n", i, n, start); \ + fprintf(stderr, "expect"); \ + n = 1; \ + loop_diff(encbuf); \ + fprintf(stderr, "\ngot "); \ + n = 1; \ + loop_diff(tstbuf); \ + fputc('\n', stderr); \ + return 1; \ +} + +int main() { + srand(time(NULL)); + int i, n; + for(i = 0; i < 4096; i += sizeof(int)) { + *(int*)(&encbuf[i]) = rand(); + } + fputs("testing base16384_encode/base16384_decode...\n", stderr); + for(i = 0; i < 4096; i++) { + n = base16384_encode(encbuf, i, decbuf); + n = base16384_decode(decbuf, n, tstbuf); + int decn = n; + if (memcmp(encbuf, tstbuf, n)) return_error(i, n); + } + fputs("testing base16384_encode_unsafe/base16384_decode_unsafe...\n", stderr); + for(i = 0; i < 4096; i++) { + n = base16384_encode_unsafe(encbuf, i, decbuf); + n = base16384_decode_unsafe(decbuf, n, tstbuf); + if ((n = memcmp(encbuf, tstbuf, n))) return_error(i, n); + } + return 0; +}