int hashify_process_files(string_t* files, bool check_only) { int result = HASHIFY_RESULT_OK; hashify_string_t* history = 0; size_t ifile, files_size; for (ifile = 0, files_size = array_size(files); (result == HASHIFY_RESULT_OK) && (ifile < files_size); ++ifile) { string_t input_filename; string_t output_filename; string_const_t base_filename; stream_t* input_file; stream_t* output_file; input_filename = string_allocate(0, BUILD_MAX_PATHLEN); input_filename = string_copy(input_filename.str, BUILD_MAX_PATHLEN, STRING_ARGS(files[ifile])); input_filename = path_clean(STRING_ARGS(input_filename), BUILD_MAX_PATHLEN); error_context_push(STRING_CONST("parsing file"), STRING_ARGS(input_filename)); base_filename = path_base_file_name_with_directory(STRING_ARGS(input_filename)); output_filename = string_allocate_format(STRING_CONST("%.*s.h"), STRING_FORMAT(base_filename)); log_infof(0, STRING_CONST("Hashifying %.*s -> %.*s"), STRING_FORMAT(input_filename), STRING_FORMAT(output_filename)); input_file = stream_open(STRING_ARGS(input_filename), STREAM_IN); //If only validating, open the final output file. If generating, make a memory buffer as intermediate storage if (check_only) output_file = stream_open(STRING_ARGS(output_filename), STREAM_IN); else output_file = buffer_stream_allocate(memory_allocate(0, 65536, 0, MEMORY_PERSISTENT), STREAM_IN | STREAM_OUT, 0, 65536, true, true); if (!input_file) { log_warnf(0, WARNING_INVALID_VALUE, STRING_CONST("Unable to open input file: %.*s"), STRING_FORMAT(input_filename)); result = HASHIFY_RESULT_MISSING_INPUT_FILE; } else if (!output_file) { log_warnf(0, WARNING_INVALID_VALUE, STRING_CONST("Unable to open output file: %.*s"), STRING_FORMAT(output_filename)); result = HASHIFY_RESULT_MISSING_OUTPUT_FILE; } if (input_file && output_file) { result = hashify_process_file(input_file, output_file, output_filename, check_only, &history); if ((result == HASHIFY_RESULT_OK) && !check_only) result = hashify_write_file(output_file, output_filename); } stream_deallocate(input_file); stream_deallocate(output_file); error_context_pop(); string_deallocate(input_filename.str); string_deallocate(output_filename.str); } if ((result == HASHIFY_RESULT_OK) && (files_size > 0)) { if (check_only) log_info(0, STRING_CONST("All hashes validated")); else log_info(0, STRING_CONST("All hashes generated")); } array_deallocate(history); return result; }
DECLARE_TEST(md5, streams) { stream_t* test_stream; stream_t* unix_stream; stream_t* windows_stream; uint128_t digest, unix_digest, windows_digest; size_t ichunks; char unix_buffer[] = "tvqy0C9TO2MI7uyUqr\n\n" "QVcrmjDKDEcB3e7dpM\n\n" "bMpRv6uH0LWPjvNcNp\n" "jpkje9KYXhJjSA2TBy\n" "bTqnOPhOOZ5aWnUdgO\n" "fLapbWSZInasn1SJlk\n" "ytNFKkASDln05zw39X\n" "L8McmojqPmn41Y6CRN\n\n" "wZbKo0PZofDpbAMr1u\n" "u8GJIocbEBFzsyKo62\n" "FlQh1pjm9jBeoEJIHL\n" "v4ixQn77l4M7zbRHgJ\n" "DIVy0vvpNEzxFRyD3Z\n" "5OrJvr\n"; char windows_buffer[] = "tvqy0C9TO2MI7uyUqr\r\n\r\n" "QVcrmjDKDEcB3e7dpM\r\n\r\n" "bMpRv6uH0LWPjvNcNp\r\n" "jpkje9KYXhJjSA2TBy\r\n" "bTqnOPhOOZ5aWnUdgO\r\n" "fLapbWSZInasn1SJlk\r\n" "ytNFKkASDln05zw39X\r\n" "L8McmojqPmn41Y6CRN\r\n\r\n" "wZbKo0PZofDpbAMr1u\r\n" "u8GJIocbEBFzsyKo62\r\n" "FlQh1pjm9jBeoEJIHL\r\n" "v4ixQn77l4M7zbRHgJ\r\n" "DIVy0vvpNEzxFRyD3Z\r\n" "5OrJvr\r\n"; test_stream = buffer_stream_allocate(0, STREAM_IN | STREAM_OUT | STREAM_BINARY, 0, 0, true, true); stream_write(test_stream, digest_test_string, 2000); stream_seek(test_stream, 0, STREAM_SEEK_BEGIN); digest = stream_md5(test_stream); stream_deallocate(test_stream); EXPECT_TRUE(uint128_equal(digest, uint128_make(0x230e0a23943c7d13ULL, 0xd2ccac7ec9df4d0cULL))); unix_stream = buffer_stream_allocate((void*)unix_buffer, STREAM_IN, string_length(unix_buffer), string_length(unix_buffer), false, false); windows_stream = buffer_stream_allocate((void*)windows_buffer, STREAM_IN, string_length(windows_buffer), string_length(windows_buffer), false, false); stream_set_binary(unix_stream, false); stream_set_binary(windows_stream, false); unix_digest = stream_md5(unix_stream); windows_digest = stream_md5(windows_stream); EXPECT_TRUE(uint128_equal(unix_digest, uint128_make(0xcf32b789c7e77197ULL, 0x2bff28c36c601093ULL))); EXPECT_TRUE(uint128_equal(unix_digest, windows_digest)); stream_set_binary(unix_stream, true); stream_set_binary(windows_stream, true); stream_seek(unix_stream, 0, STREAM_SEEK_BEGIN); stream_seek(windows_stream, 0, STREAM_SEEK_BEGIN); unix_digest = stream_md5(unix_stream); windows_digest = stream_md5(windows_stream); stream_deallocate(unix_stream); stream_deallocate(windows_stream); EXPECT_TRUE(uint128_equal(unix_digest, uint128_make(0xcf32b789c7e77197ULL, 0x2bff28c36c601093ULL))); EXPECT_TRUE(uint128_equal(windows_digest, uint128_make(0xf77d63bbe1df9334ULL, 0x24d5cb05cd503e44ULL))); EXPECT_TRUE(!uint128_equal(unix_digest, windows_digest)); unix_stream = buffer_stream_allocate(nullptr, STREAM_IN | STREAM_OUT, 128 * 1024, 128 * 1024, true, true); windows_stream = buffer_stream_allocate(nullptr, STREAM_IN | STREAM_OUT, 128 * 1024, 128 * 1024, true, true); ichunks = 0; while ((ichunks+1) * 3 < 128 * 1024) { stream_write(unix_stream, STRING_CONST("a\n")); stream_write(windows_stream, STRING_CONST("a\r\n")); ++ichunks; } stream_seek(unix_stream, 0, STREAM_SEEK_BEGIN); stream_seek(windows_stream, 0, STREAM_SEEK_BEGIN); unix_digest = stream_md5(unix_stream); windows_digest = stream_md5(windows_stream); stream_deallocate(unix_stream); stream_deallocate(windows_stream); EXPECT_TRUE(uint128_equal(unix_digest, windows_digest)); return 0; }
int hashify_process_files( const char* const* files, bool check_only ) { int result = HASHIFY_RESULT_OK; hashify_string_t* history = 0; unsigned int ifile, files_size; for( ifile = 0, files_size = array_size( files ); ( result == HASHIFY_RESULT_OK ) && ( ifile < files_size ); ++ifile ) { char* input_filename; char* output_filename; stream_t* input_file; stream_t* output_file; input_filename = path_clean( string_clone( files[ifile] ), path_is_absolute( files[ifile] ) ); error_context_push( "parsing file", input_filename ); output_filename = string_append( path_base_file_name_with_path( input_filename ), ".h" ); log_infof( "Hashifying %s -> %s", input_filename, output_filename ); input_file = stream_open( input_filename, STREAM_IN ); //If only validating, open the final output file. If generating, make a memory buffer as intermediate storage if( check_only ) output_file = stream_open( output_filename, STREAM_IN ); else output_file = buffer_stream_allocate( memory_allocate( 65536, 0, MEMORY_PERSISTENT ), STREAM_IN | STREAM_OUT, 0, 65536, true, true ); if( !input_file ) { log_warnf( WARNING_BAD_DATA, "Unable to open input file: %s", input_filename ); result = HASHIFY_RESULT_MISSING_INPUT_FILE; } else if( !output_file ) { log_warnf( WARNING_BAD_DATA, "Unable to open output file: %s", output_filename ); result = HASHIFY_RESULT_MISSING_OUTPUT_FILE; } if( input_file && output_file ) { result = hashify_process_file( input_file, output_file, check_only, &history ); if( ( result == HASHIFY_RESULT_OK ) && !check_only ) result = hashify_write_file( output_file, output_filename ); } stream_deallocate( input_file ); stream_deallocate( output_file ); error_context_pop(); string_deallocate( input_filename ); string_deallocate( output_filename ); } if( ( result == HASHIFY_RESULT_OK ) && ( files_size > 0 ) ) { if( check_only ) log_infof( "All hashes validated" ); else log_infof( "All hashes generated" ); } array_deallocate( history ); return result; }