FLAC__bool grabbag__file_change_stats(const char *filename, FLAC__bool read_only) { struct flac_stat_s stats; if(0 == flac_stat(filename, &stats)) { #if !defined _MSC_VER && !defined __MINGW32__ if(read_only) { stats.st_mode &= ~S_IWUSR; stats.st_mode &= ~S_IWGRP; stats.st_mode &= ~S_IWOTH; } else { stats.st_mode |= S_IWUSR; } #else if(read_only) stats.st_mode &= ~S_IWRITE; else stats.st_mode |= S_IWRITE; #endif if(0 != flac_chmod(filename, stats.st_mode)) return false; } else return false; return true; }
FLAC__off_t grabbag__file_get_filesize(const char *srcpath) { struct flac_stat_s srcstat; if(0 == flac_stat(srcpath, &srcstat)) return srcstat.st_size; else return -1; }
void grabbag__file_copy_metadata(const char *srcpath, const char *destpath) { struct flac_stat_s srcstat; struct utimbuf srctime; if(0 == flac_stat(srcpath, &srcstat)) { srctime.actime = srcstat.st_atime; srctime.modtime = srcstat.st_mtime; (void)flac_chmod(destpath, srcstat.st_mode); (void)flac_utime(destpath, &srctime); } }
FLAC__bool grabbag__file_are_same(const char *f1, const char *f2) { #if defined _MSC_VER || defined __MINGW32__ /* see * http://www.hydrogenaudio.org/forums/index.php?showtopic=49439&pid=444300&st=0 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileinformationbyhandle.asp * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/by_handle_file_information_str.asp * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp * apparently both the files have to be open at the same time for the comparison to work */ FLAC__bool same = false; BY_HANDLE_FILE_INFORMATION info1, info2; HANDLE h1, h2; BOOL ok = 1; h1 = CreateFile_utf8(f1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); h2 = CreateFile_utf8(f2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE) ok = 0; ok &= GetFileInformationByHandle(h1, &info1); ok &= GetFileInformationByHandle(h2, &info2); if(ok) same = info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber && info1.nFileIndexHigh == info2.nFileIndexHigh && info1.nFileIndexLow == info2.nFileIndexLow ; if(h1 != INVALID_HANDLE_VALUE) CloseHandle(h1); if(h2 != INVALID_HANDLE_VALUE) CloseHandle(h2); return same; #else struct flac_stat_s s1, s2; return f1 && f2 && flac_stat(f1, &s1) == 0 && flac_stat(f2, &s2) == 0 && s1.st_ino == s2.st_ino && s1.st_dev == s2.st_dev; #endif }
FLAC__bool file_utils__generate_flacfile(FLAC__bool is_ogg, const char *output_filename, FLAC__off_t *output_filesize, unsigned length, const FLAC__StreamMetadata *streaminfo, FLAC__StreamMetadata **metadata, unsigned num_metadata) { FLAC__int32 samples[1024]; FLAC__StreamEncoder *encoder; FLAC__StreamEncoderInitStatus init_status; encoder_client_struct encoder_client_data; unsigned i, n; FLAC__ASSERT(0 != output_filename); FLAC__ASSERT(0 != streaminfo); FLAC__ASSERT(streaminfo->type == FLAC__METADATA_TYPE_STREAMINFO); FLAC__ASSERT((streaminfo->is_last && num_metadata == 0) || (!streaminfo->is_last && num_metadata > 0)); if(0 == (encoder_client_data.file = flac_fopen(output_filename, "wb"))) return false; encoder = FLAC__stream_encoder_new(); if(0 == encoder) { fclose(encoder_client_data.file); return false; } FLAC__stream_encoder_set_ogg_serial_number(encoder, file_utils__ogg_serial_number); FLAC__stream_encoder_set_verify(encoder, true); FLAC__stream_encoder_set_streamable_subset(encoder, true); FLAC__stream_encoder_set_do_mid_side_stereo(encoder, false); FLAC__stream_encoder_set_loose_mid_side_stereo(encoder, false); FLAC__stream_encoder_set_channels(encoder, streaminfo->data.stream_info.channels); FLAC__stream_encoder_set_bits_per_sample(encoder, streaminfo->data.stream_info.bits_per_sample); FLAC__stream_encoder_set_sample_rate(encoder, streaminfo->data.stream_info.sample_rate); FLAC__stream_encoder_set_blocksize(encoder, streaminfo->data.stream_info.min_blocksize); FLAC__stream_encoder_set_max_lpc_order(encoder, 0); FLAC__stream_encoder_set_qlp_coeff_precision(encoder, 0); FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder, false); FLAC__stream_encoder_set_do_escape_coding(encoder, false); FLAC__stream_encoder_set_do_exhaustive_model_search(encoder, false); FLAC__stream_encoder_set_min_residual_partition_order(encoder, 0); FLAC__stream_encoder_set_max_residual_partition_order(encoder, 0); FLAC__stream_encoder_set_rice_parameter_search_dist(encoder, 0); FLAC__stream_encoder_set_total_samples_estimate(encoder, streaminfo->data.stream_info.total_samples); FLAC__stream_encoder_set_metadata(encoder, metadata, num_metadata); if(is_ogg) init_status = FLAC__stream_encoder_init_ogg_stream(encoder, /*read_callback=*/0, encoder_write_callback_, /*seek_callback=*/0, /*tell_callback=*/0, encoder_metadata_callback_, &encoder_client_data); else init_status = FLAC__stream_encoder_init_stream(encoder, encoder_write_callback_, /*seek_callback=*/0, /*tell_callback=*/0, encoder_metadata_callback_, &encoder_client_data); if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { fclose(encoder_client_data.file); return false; } /* init the dummy sample buffer */ for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++) samples[i] = i & 7; while(length > 0) { n = min(length, sizeof(samples) / sizeof(FLAC__int32)); if(!FLAC__stream_encoder_process_interleaved(encoder, samples, n)) { fclose(encoder_client_data.file); return false; } length -= n; } (void)FLAC__stream_encoder_finish(encoder); fclose(encoder_client_data.file); FLAC__stream_encoder_delete(encoder); if(0 != output_filesize) { struct flac_stat_s filestats; if(flac_stat(output_filename, &filestats) != 0) return false; else *output_filesize = filestats.st_size; } return true; }