📄 metadata_manip.cpp
字号:
i = 0; do { FLAC::Metadata::Prototype *block; printf("%u... ", i); fflush(stdout); if(0 == (block = iterator.get_block())) return die_("getting block from iterator"); if(*block != *our_metadata_.blocks[i]) return die_("metadata block mismatch"); delete block; i++; next_ok = iterator.next(); } while(i < our_metadata_.num_blocks && next_ok); if(next_ok) return die_("chain has more blocks than expected"); if(i < our_metadata_.num_blocks) return die_("short block count in chain"); if(0 != current_block) { printf("CURRENT_POSITION... "); fflush(stdout); if(*current_block != *our_metadata_.blocks[current_position]) return die_("metadata block mismatch"); } printf("PASSED\n"); return true;}::FLAC__StreamDecoderWriteStatus OurFileDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]){ (void)buffer; if( (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) || (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0) ) { printf("content... "); fflush(stdout); } return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;}void OurFileDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata){ /* don't bother checking if we've already hit an error */ if(error_occurred_) return; printf("%d... ", mc_our_block_number_); fflush(stdout); if(!ignore_metadata_) { if(mc_our_block_number_ >= our_metadata_.num_blocks) { (void)die_("got more metadata blocks than expected"); error_occurred_ = true; } else { if(*our_metadata_.blocks[mc_our_block_number_] != metadata) { (void)die_("metadata block mismatch"); error_occurred_ = true; } } } mc_our_block_number_++;}void OurFileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status){ error_occurred_ = true; printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);}static bool generate_file_(){ ::FLAC__StreamMetadata streaminfo, vorbiscomment, padding; ::FLAC__StreamMetadata *metadata[1]; printf("generating FLAC file for test\n"); while(our_metadata_.num_blocks > 0) delete_from_our_metadata_(0); streaminfo.is_last = false; streaminfo.type = ::FLAC__METADATA_TYPE_STREAMINFO; streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; streaminfo.data.stream_info.min_blocksize = 576; streaminfo.data.stream_info.max_blocksize = 576; streaminfo.data.stream_info.min_framesize = 0; streaminfo.data.stream_info.max_framesize = 0; streaminfo.data.stream_info.sample_rate = 44100; streaminfo.data.stream_info.channels = 1; streaminfo.data.stream_info.bits_per_sample = 8; streaminfo.data.stream_info.total_samples = 0; memset(streaminfo.data.stream_info.md5sum, 0, 16); { const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING); vorbiscomment.is_last = false; vorbiscomment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT; vorbiscomment.length = (4 + vendor_string_length) + 4; vorbiscomment.data.vorbis_comment.vendor_string.length = vendor_string_length; vorbiscomment.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1); memcpy(vorbiscomment.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1); vorbiscomment.data.vorbis_comment.num_comments = 0; vorbiscomment.data.vorbis_comment.comments = 0; } padding.is_last = true; padding.type = ::FLAC__METADATA_TYPE_PADDING; padding.length = 1234; metadata[0] = &padding; FLAC::Metadata::StreamInfo s(&streaminfo); FLAC::Metadata::VorbisComment v(&vorbiscomment); FLAC::Metadata::Padding p(&padding); if( !insert_to_our_metadata_(&s, 0, /*copy=*/true) || !insert_to_our_metadata_(&v, 1, /*copy=*/true) || !insert_to_our_metadata_(&p, 2, /*copy=*/true) ) return die_("priming our metadata"); if(!file_utils__generate_flacfile(flacfile_, 0, 512 * 1024, &streaminfo, metadata, 1)) return die_("creating the encoded file"); free(vorbiscomment.data.vorbis_comment.vendor_string.entry); return true;}static bool test_file_(const char *filename, bool ignore_metadata){ OurFileDecoder decoder(ignore_metadata); FLAC__ASSERT(0 != filename); mc_our_block_number_ = 0; decoder.error_occurred_ = false; printf("\ttesting '%s'... ", filename); fflush(stdout); if(!decoder.is_valid()) return die_("couldn't allocate decoder instance"); decoder.set_md5_checking(true); decoder.set_filename(filename); decoder.set_metadata_respond_all(); if(decoder.init() != ::FLAC__FILE_DECODER_OK) { decoder.finish(); return die_("initializing decoder\n"); } if(!decoder.process_until_end_of_file()) { decoder.finish(); return die_("decoding file\n"); } decoder.finish(); if(decoder.error_occurred_) return false; if(mc_our_block_number_ != our_metadata_.num_blocks) return die_("short metadata block count"); printf("PASSED\n"); return true;}static bool change_stats_(const char *filename, bool read_only){ if(!grabbag__file_change_stats(filename, read_only)) return die_("during grabbag__file_change_stats()"); return true;}static bool remove_file_(const char *filename){ while(our_metadata_.num_blocks > 0) delete_from_our_metadata_(0); if(!grabbag__file_remove_file(filename)) return die_("removing file"); return true;}static bool test_level_0_(){ FLAC::Metadata::StreamInfo streaminfo; printf("\n\n++++++ testing level 0 interface\n"); if(!generate_file_()) return false; if(!test_file_(flacfile_, /*ignore_metadata=*/true)) return false; printf("testing FLAC::Metadata::get_streaminfo()... "); if(!FLAC::Metadata::get_streaminfo(flacfile_, streaminfo)) return die_("during FLAC::Metadata::get_streaminfo()"); /* check to see if some basic data matches (c.f. generate_file_()) */ if(streaminfo.get_channels() != 1) return die_("mismatch in streaminfo.get_channels()"); if(streaminfo.get_bits_per_sample() != 8) return die_("mismatch in streaminfo.get_bits_per_sample()"); if(streaminfo.get_sample_rate() != 44100) return die_("mismatch in streaminfo.get_sample_rate()"); if(streaminfo.get_min_blocksize() != 576) return die_("mismatch in streaminfo.get_min_blocksize()"); if(streaminfo.get_max_blocksize() != 576) return die_("mismatch in streaminfo.get_max_blocksize()"); printf("OK\n"); { printf("testing FLAC::Metadata::get_tags(VorbisComment *&)... "); FLAC::Metadata::VorbisComment *tags = 0; if(!FLAC::Metadata::get_tags(flacfile_, tags)) return die_("during FLAC::Metadata::get_tags()"); /* check to see if some basic data matches (c.f. generate_file_()) */ if(tags->get_num_comments() != 0) return die_("mismatch in tags->get_num_comments()"); printf("OK\n"); delete tags; } { printf("testing FLAC::Metadata::get_tags(VorbisComment &)... "); FLAC::Metadata::VorbisComment tags; if(!FLAC::Metadata::get_tags(flacfile_, tags)) return die_("during FLAC::Metadata::get_tags()"); /* check to see if some basic data matches (c.f. generate_file_()) */ if(tags.get_num_comments() != 0) return die_("mismatch in tags.get_num_comments()"); printf("OK\n"); } if(!remove_file_(flacfile_)) return false; return true;}static bool test_level_1_(){ FLAC::Metadata::Prototype *block; FLAC::Metadata::StreamInfo *streaminfo; FLAC::Metadata::Padding *padding; FLAC::Metadata::Application *app; FLAC__byte data[1000]; unsigned our_current_position = 0; // initialize 'data' to avoid Valgrind errors memset(data, 0, sizeof(data)); printf("\n\n++++++ testing level 1 interface\n"); /************************************************************/ { printf("simple iterator on read-only file\n"); if(!generate_file_()) return false; if(!change_stats_(flacfile_, /*read_only=*/true)) return false; if(!test_file_(flacfile_, /*ignore_metadata=*/true)) return false; FLAC::Metadata::SimpleIterator iterator; if(!iterator.is_valid()) return die_("iterator.is_valid() returned false"); if(!iterator.init(flacfile_, /*read_only=*/false, /*preserve_file_stats=*/false)) return die_("iterator.init() returned false"); printf("is writable = %u\n", (unsigned)iterator.is_writable()); if(iterator.is_writable()) return die_("iterator claims file is writable when tester thinks it should not be; are you running as root?\n"); printf("iterate forwards\n"); if(iterator.get_block_type() != ::FLAC__METADATA_TYPE_STREAMINFO) return die_("expected STREAMINFO type from iterator.get_block_type()"); if(0 == (block = iterator.get_block())) return die_("getting block 0"); if(block->get_type() != ::FLAC__METADATA_TYPE_STREAMINFO) return die_("expected STREAMINFO type"); if(block->get_is_last()) return die_("expected is_last to be false"); if(block->get_length() != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) return die_("bad STREAMINFO length"); /* check to see if some basic data matches (c.f. generate_file_()) */ streaminfo = dynamic_cast<FLAC::Metadata::StreamInfo *>(block); FLAC__ASSERT(0 != streaminfo); if(streaminfo->get_channels() != 1) return die_("mismatch in channels"); if(streaminfo->get_bits_per_sample() != 8) return die_("mismatch in bits_per_sample"); if(streaminfo->get_sample_rate() != 44100) return die_("mismatch in sample_rate"); if(streaminfo->get_min_blocksize() != 576) return die_("mismatch in min_blocksize"); if(streaminfo->get_max_blocksize() != 576) return die_("mismatch in max_blocksize"); // we will delete streaminfo a little later when we're really done with it... if(!iterator.next()) return die_("forward iterator ended early"); our_current_position++; if(!iterator.next()) return die_("forward iterator ended early"); our_current_position++; if(iterator.get_block_type() != ::FLAC__METADATA_TYPE_PADDING) return die_("expected PADDING type from iterator.get_block_type()"); if(0 == (block = iterator.get_block())) return die_("getting block 1"); if(block->get_type() != ::FLAC__METADATA_TYPE_PADDING) return die_("expected PADDING type"); if(!block->get_is_last()) return die_("expected is_last to be true"); /* check to see if some basic data matches (c.f. generate_file_()) */ if(block->get_length() != 1234) return die_("bad PADDING length"); delete block; if(iterator.next()) return die_("forward iterator returned true but should have returned false"); printf("iterate backwards\n"); if(!iterator.prev()) return die_("reverse iterator ended early"); if(!iterator.prev()) return die_("reverse iterator ended early"); if(iterator.prev()) return die_("reverse iterator returned true but should have returned false"); printf("testing iterator.set_block() on read-only file...\n"); if(!iterator.set_block(streaminfo, false)) printf("PASSED. iterator.set_block() returned false like it should\n"); else return die_("iterator.set_block() returned true but shouldn't have"); delete streaminfo; } /************************************************************/ { printf("simple iterator on writable file\n"); if(!change_stats_(flacfile_, /*read-only=*/false)) return false; printf("creating APPLICATION block\n"); if(0 == (app = new FLAC::Metadata::Application())) return die_("new FLAC::Metadata::Application()"); app->set_id((const unsigned char *)"duh"); printf("creating PADDING block\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -