From 57ba6f4eb7f2bb0b1bda14fec70e1dac64106770 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Fri, 7 Jun 2002 05:27:37 +0000 Subject: [PATCH] massive glob of checkins: improved tests, more tests, bugfixes --- Makefile.lite | 14 +- configure.in | 17 +- flac.pbproj/project.pbxproj | 10 +- include/FLAC++/decoder.h | 12 +- include/FLAC++/encoder.h | 8 +- include/FLAC++/metadata.h | 74 +- include/FLAC/file_decoder.h | 4 +- include/FLAC/format.h | 10 +- include/FLAC/metadata.h | 8 +- include/FLAC/seekable_stream_decoder.h | 12 +- include/FLAC/stream_decoder.h | 10 +- include/FLAC/stream_encoder.h | 8 +- src/Makefile.am | 2 +- src/flac/decode.c | 5 +- src/flac/encode.c | 31 +- src/libFLAC++/Makefile.am | 8 +- src/libFLAC++/file_decoder.cc | 2 +- src/libFLAC++/metadata.cc | 3 +- src/libFLAC++/seekable_stream_decoder.cc | 2 +- src/libFLAC++/stream_decoder.cc | 2 +- src/libFLAC++/stream_encoder.cc | 16 +- src/libFLAC/Makefile.am | 4 +- src/libFLAC/file_decoder.c | 10 +- src/libFLAC/format.c | 10 +- src/libFLAC/include/private/md5.h | 2 +- src/libFLAC/md5.c | 2 +- src/libFLAC/metadata_iterators.c | 45 +- src/libFLAC/metadata_object.c | 118 ++ src/libFLAC/seekable_stream_decoder.c | 18 +- src/libFLAC/stream_decoder.c | 15 +- src/libFLAC/stream_encoder.c | 27 +- src/plugin_winamp2/in_flac.c | 280 +++-- src/plugin_xmms/plugin.c | 106 +- src/test_libFLAC++/Makefile.am | 34 + src/test_libFLAC++/Makefile.lite | 38 + src/test_libFLAC++/Makefile.vc | 73 ++ src/test_libFLAC++/README | 4 + src/test_libFLAC++/decoders.cc | 2005 ++++++++++++++++++++++++++++++ src/test_libFLAC++/decoders.h | 24 + src/test_libFLAC++/encoders.cc | 414 ++++++ src/test_libFLAC++/encoders.h | 24 + src/test_libFLAC++/file_utils.c | 173 +++ src/test_libFLAC++/file_utils.h | 30 + src/test_libFLAC++/main.cc | 37 + src/test_libFLAC++/metadata.cc | 36 + src/test_libFLAC++/metadata.h | 24 + src/test_libFLAC++/metadata_manip.cc | 1528 +++++++++++++++++++++++ src/test_libFLAC++/metadata_object.cc | 379 ++++++ src/test_unit/Makefile.am | 10 +- src/test_unit/Makefile.lite | 5 +- src/test_unit/Makefile.vc | 9 +- src/test_unit/bitbuffer.c | 154 +-- src/test_unit/bitbuffer.h | 10 +- src/test_unit/decoders.c | 1085 ++++++---------- src/test_unit/decoders.h | 10 +- src/test_unit/encoders.c | 410 ++++++ src/test_unit/encoders.h | 26 + src/test_unit/file_utils.c | 2 +- src/test_unit/file_utils.h | 7 +- src/test_unit/main.c | 12 +- src/test_unit/metadata.c | 14 +- src/test_unit/metadata.h | 10 +- src/test_unit/metadata_manip.c | 17 +- src/test_unit/metadata_object.c | 263 ++-- src/test_unit/metadata_utils.c | 2 +- src/test_unit/metadata_utils.h | 6 +- test/Makefile.am | 6 +- test/Makefile.lite | 3 +- 68 files changed, 6454 insertions(+), 1325 deletions(-) create mode 100644 src/test_libFLAC++/Makefile.am create mode 100644 src/test_libFLAC++/Makefile.lite create mode 100644 src/test_libFLAC++/Makefile.vc create mode 100644 src/test_libFLAC++/README create mode 100644 src/test_libFLAC++/decoders.cc create mode 100644 src/test_libFLAC++/decoders.h create mode 100644 src/test_libFLAC++/encoders.cc create mode 100644 src/test_libFLAC++/encoders.h create mode 100644 src/test_libFLAC++/file_utils.c create mode 100644 src/test_libFLAC++/file_utils.h create mode 100644 src/test_libFLAC++/main.cc create mode 100644 src/test_libFLAC++/metadata.cc create mode 100644 src/test_libFLAC++/metadata.h create mode 100644 src/test_libFLAC++/metadata_manip.cc create mode 100644 src/test_libFLAC++/metadata_object.cc create mode 100644 src/test_unit/encoders.c create mode 100644 src/test_unit/encoders.h diff --git a/Makefile.lite b/Makefile.lite index 65acab0..729167b 100644 --- a/Makefile.lite +++ b/Makefile.lite @@ -27,7 +27,7 @@ # clean : remove all non-distro files # -all: libFLAC libFLAC++ share flac metaflac test_streams test_unit +all: libFLAC libFLAC++ share flac metaflac test_libFLAC test_libFLAC++ test_streams DEFAULT_CONFIG = release @@ -42,7 +42,7 @@ release : all libFLAC: (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) -libFLAC++: libFLAC +libFLAC++: (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) share: @@ -51,7 +51,7 @@ share: flac: libFLAC (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) -metaflac: +metaflac: libFLAC share (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) plugin_xmms: libFLAC @@ -60,7 +60,10 @@ plugin_xmms: libFLAC test_streams: libFLAC (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) -test_unit: libFLAC +test_libFLAC: libFLAC + (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) + +test_libFLAC++: libFLAC libFLAC++ (cd src/$@ ; $(MAKE) -f Makefile.lite $(CONFIG)) test: debug @@ -73,6 +76,7 @@ clean: -(cd src/flac ; $(MAKE) -f Makefile.lite clean) -(cd src/metaflac ; $(MAKE) -f Makefile.lite clean) -(cd src/plugin_xmms ; $(MAKE) -f Makefile.lite clean) + -(cd src/test_libFLAC ; $(MAKE) -f Makefile.lite clean) + -(cd src/test_libFLAC++ ; $(MAKE) -f Makefile.lite clean) -(cd src/test_streams ; $(MAKE) -f Makefile.lite clean) - -(cd src/test_unit ; $(MAKE) -f Makefile.lite clean) -(cd test ; $(MAKE) -f Makefile.lite clean) diff --git a/configure.in b/configure.in index 700b117..66af86c 100644 --- a/configure.in +++ b/configure.in @@ -28,6 +28,7 @@ AM_PROG_LIBTOOL sed -e 's/^build_old_libs=yes/build_old_libs=no/' libtool > libtool-disable-static chmod +x libtool-disable-static +AC_PROG_CXX AC_PROG_MAKE_SET dnl check for getopt in standard library @@ -163,17 +164,17 @@ AC_SUBST(FLaC__USIZE64) AC_SUBST(SHARE_LIBS) -SAVE_CFLAGS="$CFLAGS" -CFLAGS='-I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include' +OUR_CFLAGS_HEAD='-I$(top_builddir) -I$(srcdir)/include -I$(top_srcdir)/include' if test x$debug = xtrue; then - CFLAGS="$CFLAGS -g -O0 -DDEBUG" + OUR_CFLAGS_TAIL="-g -O0 -DDEBUG" else - CFLAGS="$CFLAGS -O3 -DNDEBUG" + OUR_CFLAGS_TAIL="-O3 -DNDEBUG" if test x$GCC = xyes; then - CFLAGS="$CFLAGS -fomit-frame-pointer -funroll-loops -finline-functions -Wall -W -Winline -DFLaC__INLINE=__inline__" + OUR_CFLAGS_TAIL="$OUR_CFLAGS_TAIL -fomit-frame-pointer -funroll-loops -finline-functions -Wall -W -Winline -DFLaC__INLINE=__inline__" fi fi -CFLAGS="$CFLAGS $SAVE_CFLAGS" +CFLAGS="$OUR_CFLAGS_HEAD $CFLAGS $OUR_CFLAGS_TAIL" +CXXFLAGS="$OUR_CFLAGS_HEAD $CXXFLAGS $OUR_CFLAGS_TAIL" AC_OUTPUT( Makefile \ src/Makefile \ @@ -182,12 +183,14 @@ AC_OUTPUT( Makefile \ src/libFLAC/include/Makefile \ src/libFLAC/include/private/Makefile \ src/libFLAC/include/protected/Makefile \ + src/libFLAC++/Makefile \ src/flac/Makefile \ src/metaflac/Makefile \ src/plugin_xmms/Makefile \ src/share/Makefile \ + src/test_libFLAC/Makefile \ + src/test_libFLAC++/Makefile \ src/test_streams/Makefile \ - src/test_unit/Makefile \ include/Makefile \ include/FLAC/Makefile \ include/FLAC/ordinals.h \ diff --git a/flac.pbproj/project.pbxproj b/flac.pbproj/project.pbxproj index 75986d9..c9b93a0 100644 --- a/flac.pbproj/project.pbxproj +++ b/flac.pbproj/project.pbxproj @@ -494,7 +494,7 @@ F59E59BF01972D3E01A8006D, ); isa = PBXGroup; - path = test_unit; + path = test_libFLAC; refType = 4; }; F59E59BD01972D3E01A8006D = { @@ -1061,7 +1061,7 @@ }; F5F561EF019B58E101A8006D = { isa = PBXExecutableFileReference; - path = test_unit; + path = test_libFLAC; refType = 3; }; F5F561F0019B58E101A8006D = { @@ -1139,7 +1139,7 @@ OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; OTHER_REZFLAGS = ""; - PRODUCT_NAME = test_unit; + PRODUCT_NAME = test_libFLAC; REZ_EXECUTABLE = YES; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; @@ -1147,9 +1147,9 @@ dependencies = ( ); isa = PBXToolTarget; - name = test_unit; + name = test_libFLAC; productInstallPath = /usr/local/bin; - productName = test_unit; + productName = test_libFLAC; productReference = F5F561EF019B58E101A8006D; shouldUseHeadermap = 0; }; diff --git a/include/FLAC++/decoder.h b/include/FLAC++/decoder.h index 02c8992..4d29cb6 100644 --- a/include/FLAC++/decoder.h +++ b/include/FLAC++/decoder.h @@ -98,14 +98,14 @@ namespace FLAC { bool process_remaining_frames(); protected: virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes) = 0; - virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 *buffer[]) = 0; + virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0; virtual void metadata_callback(const ::FLAC__StreamMetaData *metadata) = 0; virtual void error_callback(::FLAC__StreamDecoderErrorStatus status) = 0; ::FLAC__StreamDecoder *decoder_; private: static ::FLAC__StreamDecoderReadStatus read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); - static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); + static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static void metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetaData *metadata, void *client_data); static void error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data); @@ -172,7 +172,7 @@ namespace FLAC { virtual ::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset) = 0; virtual ::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length) = 0; virtual bool eof_callback() = 0; - virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 *buffer[]) = 0; + virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0; virtual void metadata_callback(const ::FLAC__StreamMetaData *metadata) = 0; virtual void error_callback(::FLAC__StreamDecoderErrorStatus status) = 0; @@ -183,7 +183,7 @@ namespace FLAC { static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const ::FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); static FLAC__bool eof_callback_(const ::FLAC__SeekableStreamDecoder *decoder, void *client_data); - static FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); + static FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static void metadata_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__StreamMetaData *metadata, void *client_data); static void error_callback_(const ::FLAC__SeekableStreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data); @@ -243,13 +243,13 @@ namespace FLAC { bool seek_absolute(FLAC__uint64 sample); protected: - virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 *buffer[]) = 0; + virtual ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) = 0; virtual void metadata_callback(const ::FLAC__StreamMetaData *metadata) = 0; virtual void error_callback(::FLAC__StreamDecoderErrorStatus status) = 0; ::FLAC__FileDecoder *decoder_; private: - static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__FileDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); + static ::FLAC__StreamDecoderWriteStatus write_callback_(const ::FLAC__FileDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static void metadata_callback_(const ::FLAC__FileDecoder *decoder, const ::FLAC__StreamMetaData *metadata, void *client_data); static void error_callback_(const ::FLAC__FileDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data); diff --git a/include/FLAC++/encoder.h b/include/FLAC++/encoder.h index 071ff7f..69005fa 100644 --- a/include/FLAC++/encoder.h +++ b/include/FLAC++/encoder.h @@ -80,7 +80,7 @@ namespace FLAC { bool set_max_residual_partition_order(unsigned value); bool set_rice_parameter_search_dist(unsigned value); bool set_total_samples_estimate(FLAC__uint64 value); - bool set_metadata(FLAC__StreamMetaData **metadata, unsigned num_blocks); + bool set_metadata(::FLAC__StreamMetaData **metadata, unsigned num_blocks); State get_state() const; bool get_streamable_subset() const; @@ -106,11 +106,11 @@ namespace FLAC { void finish(); - bool process(const FLAC__int32 *buf[], unsigned samples); - bool process_interleaved(const FLAC__int32 buf[], unsigned samples); + bool process(const FLAC__int32 * const buffer[], unsigned samples); + bool process_interleaved(const FLAC__int32 buffer[], unsigned samples); protected: virtual ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame) = 0; - virtual void metadata_callback(const FLAC__StreamMetaData *metadata) = 0; + virtual void metadata_callback(const ::FLAC__StreamMetaData *metadata) = 0; ::FLAC__StreamEncoder *encoder_; private: diff --git a/include/FLAC++/metadata.h b/include/FLAC++/metadata.h index 7e0cbbd..fa74188 100644 --- a/include/FLAC++/metadata.h +++ b/include/FLAC++/metadata.h @@ -47,21 +47,28 @@ namespace FLAC { class Prototype { protected: Prototype(::FLAC__StreamMetaData *object, bool copy); - virtual ~Prototype(); void operator=(const Prototype &); void operator=(const ::FLAC__StreamMetaData &); void operator=(const ::FLAC__StreamMetaData *); + inline bool operator==(const Prototype &) const; + inline bool operator==(const ::FLAC__StreamMetaData &) const; + inline bool operator==(const ::FLAC__StreamMetaData *) const; + inline bool operator!=(const Prototype &) const; + inline bool operator!=(const ::FLAC__StreamMetaData &) const; + inline bool operator!=(const ::FLAC__StreamMetaData *) const; + virtual void clear(); ::FLAC__StreamMetaData *object_; public: + virtual ~Prototype(); + friend class SimpleIterator; friend class Iterator; - inline bool is_valid() const { return 0 != object_; } - inline operator bool() const { return is_valid(); } + inline bool is_valid() const; bool get_is_last() const; FLAC__MetaDataType get_type() const; @@ -74,6 +81,28 @@ namespace FLAC { inline void set_reference(bool x) { is_reference_ = x; } }; + inline bool Prototype::operator==(const Prototype &object) const + { return ::FLAC__metadata_object_is_equal(object_, object.object_); } + + inline bool Prototype::operator==(const ::FLAC__StreamMetaData &object) const + { return ::FLAC__metadata_object_is_equal(object_, &object); } + + inline bool Prototype::operator==(const ::FLAC__StreamMetaData *object) const + { return ::FLAC__metadata_object_is_equal(object_, object); } + + inline bool Prototype::operator!=(const Prototype &object) const + { return !operator==(object); } + + inline bool Prototype::operator!=(const ::FLAC__StreamMetaData &object) const + { return !operator==(object); } + + inline bool Prototype::operator!=(const ::FLAC__StreamMetaData *object) const + { return !operator==(object); } + + inline bool Prototype::is_valid() const + { return 0 != object_; } + + class StreamInfo : public Prototype { public: StreamInfo(); @@ -84,6 +113,13 @@ namespace FLAC { inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + inline bool operator==(const StreamInfo &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + inline bool operator!=(const StreamInfo &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator!=(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + unsigned get_min_blocksize() const; unsigned get_max_blocksize() const; unsigned get_min_framesize() const; @@ -115,6 +151,13 @@ namespace FLAC { inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + inline bool operator==(const Padding &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + inline bool operator!=(const Padding &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator!=(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + void set_length(unsigned length); }; @@ -128,6 +171,13 @@ namespace FLAC { inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + inline bool operator==(const Application &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + inline bool operator!=(const Application &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator!=(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + const FLAC__byte *get_id() const; const FLAC__byte *get_data() const; @@ -145,6 +195,13 @@ namespace FLAC { inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + inline bool operator==(const SeekTable &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + inline bool operator!=(const SeekTable &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator!=(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + unsigned get_num_points() const; ::FLAC__StreamMetaData_SeekPoint get_point(unsigned index) const; @@ -168,7 +225,6 @@ namespace FLAC { virtual ~Entry(); virtual bool is_valid() const; - inline operator bool() const { return is_valid(); } unsigned get_field_length() const; unsigned get_field_name_length() const; @@ -209,6 +265,13 @@ namespace FLAC { inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + inline bool operator==(const VorbisComment &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator==(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + inline bool operator!=(const VorbisComment &object) const { return Prototype::operator!=(object); } + inline bool operator!=(const ::FLAC__StreamMetaData &object) const { return Prototype::operator==(object); } + inline bool operator!=(const ::FLAC__StreamMetaData *object) const { return Prototype::operator==(object); } + unsigned get_num_comments() const; Entry get_vendor_string() const; Entry get_comment(unsigned index) const; @@ -274,7 +337,6 @@ namespace FLAC { bool init(const char *filename, bool preserve_file_stats = false); bool is_valid() const; - inline operator bool() const { return is_valid(); } Status status(); bool is_writable() const; @@ -347,7 +409,6 @@ namespace FLAC { friend class Iterator; bool is_valid() const; - inline operator bool() const { return is_valid(); } Status status(); bool read(const char *filename); @@ -367,7 +428,6 @@ namespace FLAC { virtual ~Iterator(); bool is_valid() const; - inline operator bool() const { return is_valid(); } void init(Chain *chain); diff --git a/include/FLAC/file_decoder.h b/include/FLAC/file_decoder.h index 2771948..c3dc22e 100644 --- a/include/FLAC/file_decoder.h +++ b/include/FLAC/file_decoder.h @@ -37,7 +37,7 @@ typedef enum { FLAC__FILE_DECODER_INVALID_CALLBACK, FLAC__FILE_DECODER_UNINITIALIZED } FLAC__FileDecoderState; -extern const char *FLAC__FileDecoderStateString[]; +extern const char * const FLAC__FileDecoderStateString[]; /*********************************************************************** * @@ -99,7 +99,7 @@ void FLAC__file_decoder_delete(FLAC__FileDecoder *); */ FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value); FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value); /* 'value' may not be 0; use "-" for stdin */ -FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)); +FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)); FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, void (*value)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)); FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, void (*value)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)); FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value); diff --git a/include/FLAC/format.h b/include/FLAC/format.h index 141c8a1..babe687 100644 --- a/include/FLAC/format.h +++ b/include/FLAC/format.h @@ -84,7 +84,7 @@ extern const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */; typedef enum { FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0 } FLAC__EntropyCodingMethodType; -extern const char *FLAC__EntropyCodingMethodTypeString[]; +extern const char * const FLAC__EntropyCodingMethodTypeString[]; /***************************************************************************** * @@ -126,7 +126,7 @@ typedef enum { FLAC__SUBFRAME_TYPE_FIXED = 2, FLAC__SUBFRAME_TYPE_LPC = 3 } FLAC__SubframeType; -extern const char *FLAC__SubframeTypeString[]; +extern const char * const FLAC__SubframeTypeString[]; /***************************************************************************** * @@ -233,13 +233,13 @@ typedef enum { FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 } FLAC__ChannelAssignment; -extern const char *FLAC__ChannelAssignmentString[]; +extern const char * const FLAC__ChannelAssignmentString[]; typedef enum { FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER } FLAC__FrameNumberType; -extern const char *FLAC__FrameNumberTypeString[]; +extern const char * const FLAC__FrameNumberTypeString[]; /***************************************************************************** * @@ -351,7 +351,7 @@ typedef enum { FLAC__METADATA_TYPE_SEEKTABLE = 3, FLAC__METADATA_TYPE_VORBIS_COMMENT = 4 } FLAC__MetaDataType; -extern const char *FLAC__MetaDataTypeString[]; +extern const char * const FLAC__MetaDataTypeString[]; /***************************************************************************** * diff --git a/include/FLAC/metadata.h b/include/FLAC/metadata.h index 021a4c9..a42068f 100644 --- a/include/FLAC/metadata.h +++ b/include/FLAC/metadata.h @@ -24,7 +24,7 @@ /****************************************************************************** (For an example of how all these routines are used, see the source - code for the unit tests in src/test_unit/metadata_*.c, or metaflac + code for the unit tests in src/test_libFLAC/metadata_*.c, or metaflac in src/metaflac/) ******************************************************************************/ @@ -146,7 +146,7 @@ typedef enum { FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR } FLAC__MetaData_SimpleIteratorStatus; -extern const char *FLAC__MetaData_SimpleIteratorStatusString[]; +extern const char * const FLAC__MetaData_SimpleIteratorStatusString[]; /* * Constructor/destructor @@ -335,7 +335,7 @@ typedef enum { FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR } FLAC__MetaData_ChainStatus; -extern const char *FLAC__MetaData_ChainStatusString[]; +extern const char * const FLAC__MetaData_ChainStatusString[]; /*********** FLAC__MetaData_Chain ***********/ @@ -518,6 +518,8 @@ FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__MetaData_Iterator *i FLAC__StreamMetaData *FLAC__metadata_object_new(FLAC__MetaDataType type); FLAC__StreamMetaData *FLAC__metadata_object_copy(const FLAC__StreamMetaData *object); void FLAC__metadata_object_delete(FLAC__StreamMetaData *object); +/* Does a deep comparison of the block data */ +FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetaData *block1, const FLAC__StreamMetaData *block2); /****************************************************************** * FLAC__StreamMetaData_Application diff --git a/include/FLAC/seekable_stream_decoder.h b/include/FLAC/seekable_stream_decoder.h index fa88764..7d69792 100644 --- a/include/FLAC/seekable_stream_decoder.h +++ b/include/FLAC/seekable_stream_decoder.h @@ -39,31 +39,31 @@ typedef enum { FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK, FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED } FLAC__SeekableStreamDecoderState; -extern const char *FLAC__SeekableStreamDecoderStateString[]; +extern const char * const FLAC__SeekableStreamDecoderStateString[]; typedef enum { FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK, FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR } FLAC__SeekableStreamDecoderReadStatus; -extern const char *FLAC__SeekableStreamDecoderReadStatusString[]; +extern const char * const FLAC__SeekableStreamDecoderReadStatusString[]; typedef enum { FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK, FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR } FLAC__SeekableStreamDecoderSeekStatus; -extern const char *FLAC__SeekableStreamDecoderSeekStatusString[]; +extern const char * const FLAC__SeekableStreamDecoderSeekStatusString[]; typedef enum { FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK, FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR } FLAC__SeekableStreamDecoderTellStatus; -extern const char *FLAC__SeekableStreamDecoderTellStatusString[]; +extern const char * const FLAC__SeekableStreamDecoderTellStatusString[]; typedef enum { FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK, FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR } FLAC__SeekableStreamDecoderLengthStatus; -extern const char *FLAC__SeekableStreamDecoderLengthStatusString[]; +extern const char * const FLAC__SeekableStreamDecoderLengthStatusString[]; /*********************************************************************** * @@ -134,7 +134,7 @@ FLAC__bool FLAC__seekable_stream_decoder_set_seek_callback(FLAC__SeekableStreamD FLAC__bool FLAC__seekable_stream_decoder_set_tell_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderTellStatus (*value)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)); FLAC__bool FLAC__seekable_stream_decoder_set_length_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderLengthStatus (*value)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)); FLAC__bool FLAC__seekable_stream_decoder_set_eof_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__bool (*value)(const FLAC__SeekableStreamDecoder *decoder, void *client_data)); -FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)); +FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)); FLAC__bool FLAC__seekable_stream_decoder_set_metadata_callback(FLAC__SeekableStreamDecoder *decoder, void (*value)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)); FLAC__bool FLAC__seekable_stream_decoder_set_error_callback(FLAC__SeekableStreamDecoder *decoder, void (*value)(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)); FLAC__bool FLAC__seekable_stream_decoder_set_client_data(FLAC__SeekableStreamDecoder *decoder, void *value); diff --git a/include/FLAC/stream_decoder.h b/include/FLAC/stream_decoder.h index 90d8eb2..e2cb349 100644 --- a/include/FLAC/stream_decoder.h +++ b/include/FLAC/stream_decoder.h @@ -40,27 +40,27 @@ typedef enum { FLAC__STREAM_DECODER_INVALID_CALLBACK, FLAC__STREAM_DECODER_UNINITIALIZED } FLAC__StreamDecoderState; -extern const char *FLAC__StreamDecoderStateString[]; +extern const char * const FLAC__StreamDecoderStateString[]; typedef enum { FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, FLAC__STREAM_DECODER_READ_STATUS_ABORT } FLAC__StreamDecoderReadStatus; -extern const char *FLAC__StreamDecoderReadStatusString[]; +extern const char * const FLAC__StreamDecoderReadStatusString[]; typedef enum { FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, FLAC__STREAM_DECODER_WRITE_STATUS_ABORT } FLAC__StreamDecoderWriteStatus; -extern const char *FLAC__StreamDecoderWriteStatusString[]; +extern const char * const FLAC__StreamDecoderWriteStatusString[]; typedef enum { FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH } FLAC__StreamDecoderErrorStatus; -extern const char *FLAC__StreamDecoderErrorStatusString[]; +extern const char * const FLAC__StreamDecoderErrorStatusString[]; /*********************************************************************** * @@ -121,7 +121,7 @@ void FLAC__stream_decoder_delete(FLAC__StreamDecoder *); @@@@ update defaults above and in documentation.html about the metadata_respond/ignore defaults */ FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadStatus (*value)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)); -FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)); +FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)); FLAC__bool FLAC__stream_decoder_set_metadata_callback(FLAC__StreamDecoder *decoder, void (*value)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)); FLAC__bool FLAC__stream_decoder_set_error_callback(FLAC__StreamDecoder *decoder, void (*value)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)); FLAC__bool FLAC__stream_decoder_set_client_data(FLAC__StreamDecoder *decoder, void *value); diff --git a/include/FLAC/stream_encoder.h b/include/FLAC/stream_encoder.h index 9c0a013..2278a38 100644 --- a/include/FLAC/stream_encoder.h +++ b/include/FLAC/stream_encoder.h @@ -48,13 +48,13 @@ typedef enum { FLAC__STREAM_ENCODER_ALREADY_INITIALIZED, FLAC__STREAM_ENCODER_UNINITIALIZED } FLAC__StreamEncoderState; -extern const char *FLAC__StreamEncoderStateString[]; +extern const char * const FLAC__StreamEncoderStateString[]; typedef enum { FLAC__STREAM_ENCODER_WRITE_OK = 0, FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR } FLAC__StreamEncoderWriteStatus; -extern const char *FLAC__StreamEncoderWriteStatusString[]; +extern const char * const FLAC__StreamEncoderWriteStatusString[]; /*********************************************************************** * @@ -189,8 +189,8 @@ void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder); /* * Methods for encoding the data */ -FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 *buf[], unsigned samples); -FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buf[], unsigned samples); +FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); +FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); #ifdef __cplusplus } diff --git a/src/Makefile.am b/src/Makefile.am index 6713853..49762f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,4 +19,4 @@ if FLaC__HAS_XMMS XMMS_DIRS = plugin_xmms endif -SUBDIRS = libFLAC libFLAC++ share flac metaflac $(XMMS_DIRS) test_streams test_unit +SUBDIRS = libFLAC libFLAC++ share flac metaflac $(XMMS_DIRS) test_libFLAC test_libFLAC++ test_streams diff --git a/src/flac/decode.c b/src/flac/decode.c index 3dcd292..5d60dc9 100644 --- a/src/flac/decode.c +++ b/src/flac/decode.c @@ -518,10 +518,9 @@ FLAC__bool init(const char *infilename, stream_info_struct *stream_info) FLAC__file_decoder_set_filename(stream_info->decoder.file, infilename); /* * The three ugly casts here are to 'downcast' the 'void *' argument of - * the callback down to 'FLAC__FileDecoder *'. In C++ this would be - * unnecessary but here the cast makes the C compiler happy. + * the callback down to 'FLAC__FileDecoder *'. */ - FLAC__file_decoder_set_write_callback(stream_info->decoder.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 *[], void *))write_callback); + FLAC__file_decoder_set_write_callback(stream_info->decoder.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback); FLAC__file_decoder_set_metadata_callback(stream_info->decoder.file, (void (*)(const FLAC__FileDecoder *, const FLAC__StreamMetaData *, void *))metadata_callback); FLAC__file_decoder_set_error_callback(stream_info->decoder.file, (void (*)(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback); FLAC__file_decoder_set_client_data(stream_info->decoder.file, stream_info); diff --git a/src/flac/encode.c b/src/flac/encode.c index 9be92fb..a2ad9bd 100644 --- a/src/flac/encode.c +++ b/src/flac/encode.c @@ -111,11 +111,11 @@ static FLAC__bool convert_to_seek_table(char *requested_seek_points, int num_req static void append_point_to_seek_table(FLAC__StreamMetaData_SeekTable *seek_table, FLAC__uint64 sample, FLAC__uint64 stream_samples, FLAC__uint64 blocksize); static int seekpoint_compare(const FLAC__StreamMetaData_SeekPoint *l, const FLAC__StreamMetaData_SeekPoint *r); static void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_endian, FLAC__bool is_unsigned_samples, unsigned channels, unsigned bps, encoder_wrapper_struct *encoder_wrapper); -static void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 *input[], unsigned channels, unsigned wide_samples); +static void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 * const input[], unsigned channels, unsigned wide_samples); static FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); static void metadata_callback(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data); static FLAC__StreamDecoderReadStatus verify_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); -static FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); +static FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static void verify_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); static void verify_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); static void print_stats(const encoder_wrapper_struct *encoder_wrapper); @@ -311,11 +311,9 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons * first do any samples in the reservoir */ if(options.sector_align && *options.align_reservoir_samples > 0) { - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - append_to_verify_fifo(&encoder_wrapper, options.align_reservoir, channels, *options.align_reservoir_samples); + append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 * const *)options.align_reservoir, channels, *options.align_reservoir_samples); - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, options.align_reservoir, *options.align_reservoir_samples)) { + if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)options.align_reservoir, *options.align_reservoir_samples)) { fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]); goto wav_abort_; } @@ -358,8 +356,7 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons unsigned wide_samples = bytes_read / bytes_per_wide_sample; format_input(input, wide_samples, false, is_unsigned_samples, channels, bps, &encoder_wrapper); - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, input, wide_samples)) { + if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) { fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]); goto wav_abort_; } @@ -381,11 +378,9 @@ int flac__encode_wav(FILE *infile, long infilesize, const char *infilename, cons data_bytes = wide_samples * bytes_per_wide_sample; for(channel = 0; channel < channels; channel++) memset(input[channel], 0, data_bytes); - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - append_to_verify_fifo(&encoder_wrapper, input, channels, wide_samples); + append_to_verify_fifo(&encoder_wrapper, (const FLAC__int32 * const *)input, channels, wide_samples); - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, input, wide_samples)) { + if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) { fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]); goto wav_abort_; } @@ -596,8 +591,7 @@ int flac__encode_raw(FILE *infile, long infilesize, const char *infilename, cons unsigned wide_samples = bytes_read / bytes_per_wide_sample; format_input(input, wide_samples, options.is_big_endian, options.is_unsigned_samples, options.channels, options.bps, &encoder_wrapper); - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, input, wide_samples)) { + if(!FLAC__stream_encoder_process(encoder_wrapper.encoder, (const FLAC__int32 * const *)input, wide_samples)) { fprintf(stderr, "%s: ERROR during encoding, state = %d:%s\n", encoder_wrapper.inbasefilename, FLAC__stream_encoder_get_state(encoder_wrapper.encoder), FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder_wrapper.encoder)]); goto raw_abort_; } @@ -960,16 +954,15 @@ void format_input(FLAC__int32 *dest[], unsigned wide_samples, FLAC__bool is_big_ FLAC__ASSERT(0); } - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - append_to_verify_fifo(encoder_wrapper, dest, channels, wide_samples); + append_to_verify_fifo(encoder_wrapper, (const FLAC__int32 * const *)dest, channels, wide_samples); } -void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 *src[], unsigned channels, unsigned wide_samples) +void append_to_verify_fifo(encoder_wrapper_struct *encoder_wrapper, const FLAC__int32 * const input[], unsigned channels, unsigned wide_samples) { if(encoder_wrapper->verify) { unsigned channel; for(channel = 0; channel < channels; channel++) - memcpy(&encoder_wrapper->verify_fifo.original[channel][encoder_wrapper->verify_fifo.tail], src[channel], sizeof(FLAC__int32) * wide_samples); + memcpy(&encoder_wrapper->verify_fifo.original[channel][encoder_wrapper->verify_fifo.tail], input[channel], sizeof(FLAC__int32) * wide_samples); encoder_wrapper->verify_fifo.tail += wide_samples; FLAC__ASSERT(encoder_wrapper->verify_fifo.tail <= encoder_wrapper->verify_fifo.size); } @@ -1197,7 +1190,7 @@ FLAC__StreamDecoderReadStatus verify_read_callback(const FLAC__StreamDecoder *de return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } -FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +FLAC__StreamDecoderWriteStatus verify_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { encoder_wrapper_struct *encoder_wrapper = (encoder_wrapper_struct *)client_data; unsigned channel, l, r; diff --git a/src/libFLAC++/Makefile.am b/src/libFLAC++/Makefile.am index 126070b..d760257 100644 --- a/src/libFLAC++/Makefile.am +++ b/src/libFLAC++/Makefile.am @@ -17,12 +17,12 @@ # Boston, MA 02111-1307, USA. lib_LTLIBRARIES = libFLAC++.la -CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ -#@@@@ fix this -libFLAC++_la_LDFLAGS = -version-info 2:1:1 +# see 'http://www.gnu.org/software/libtool/manual.html#Versioning' for numbering convention +libFLAC___la_LDFLAGS = -version-info 1:0:0 -libFLAC++_la_SOURCES = \ +libFLAC___la_SOURCES = \ file_decoder.cc \ metadata.cc \ seekable_stream_decoder.cc \ diff --git a/src/libFLAC++/file_decoder.cc b/src/libFLAC++/file_decoder.cc index 86d1519..abb5ac2 100644 --- a/src/libFLAC++/file_decoder.cc +++ b/src/libFLAC++/file_decoder.cc @@ -176,7 +176,7 @@ namespace FLAC { return (bool)::FLAC__file_decoder_seek_absolute(decoder_, sample); } - ::FLAC__StreamDecoderWriteStatus File::write_callback_(const ::FLAC__FileDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) + ::FLAC__StreamDecoderWriteStatus File::write_callback_(const ::FLAC__FileDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { (void) decoder; FLAC__ASSERT(0 != client_data); diff --git a/src/libFLAC++/metadata.cc b/src/libFLAC++/metadata.cc index 8dc3f09..d1e8272 100644 --- a/src/libFLAC++/metadata.cc +++ b/src/libFLAC++/metadata.cc @@ -61,7 +61,8 @@ namespace FLAC { // Prototype // - Prototype::Prototype(::FLAC__StreamMetaData *object, bool copy) + Prototype::Prototype(::FLAC__StreamMetaData *object, bool copy): + object_(0) { FLAC__ASSERT(0 != object); clear(); diff --git a/src/libFLAC++/seekable_stream_decoder.cc b/src/libFLAC++/seekable_stream_decoder.cc index cd1f529..c12b7c3 100644 --- a/src/libFLAC++/seekable_stream_decoder.cc +++ b/src/libFLAC++/seekable_stream_decoder.cc @@ -232,7 +232,7 @@ namespace FLAC { return instance->eof_callback(); } - FLAC__StreamDecoderWriteStatus SeekableStream::write_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) + FLAC__StreamDecoderWriteStatus SeekableStream::write_callback_(const ::FLAC__SeekableStreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { (void) decoder; FLAC__ASSERT(0 != client_data); diff --git a/src/libFLAC++/stream_decoder.cc b/src/libFLAC++/stream_decoder.cc index efa1206..faa7ece 100644 --- a/src/libFLAC++/stream_decoder.cc +++ b/src/libFLAC++/stream_decoder.cc @@ -174,7 +174,7 @@ namespace FLAC { return instance->read_callback(buffer, bytes); } - ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) + ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { (void)decoder; FLAC__ASSERT(0 != client_data); diff --git a/src/libFLAC++/stream_encoder.cc b/src/libFLAC++/stream_encoder.cc index 5b87d2f..b756cb0 100644 --- a/src/libFLAC++/stream_encoder.cc +++ b/src/libFLAC++/stream_encoder.cc @@ -136,7 +136,7 @@ namespace FLAC { return (bool)::FLAC__stream_encoder_set_total_samples_estimate(encoder_, value); } - bool Stream::set_metadata(FLAC__StreamMetaData **metadata, unsigned num_blocks) + bool Stream::set_metadata(::FLAC__StreamMetaData **metadata, unsigned num_blocks) { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_encoder_set_metadata(encoder_, metadata, num_blocks); @@ -241,9 +241,9 @@ namespace FLAC { Stream::State Stream::init() { FLAC__ASSERT(is_valid()); - FLAC__stream_encoder_set_write_callback(encoder_, write_callback_); - FLAC__stream_encoder_set_metadata_callback(encoder_, metadata_callback_); - FLAC__stream_encoder_set_client_data(encoder_, (void*)this); + ::FLAC__stream_encoder_set_write_callback(encoder_, write_callback_); + ::FLAC__stream_encoder_set_metadata_callback(encoder_, metadata_callback_); + ::FLAC__stream_encoder_set_client_data(encoder_, (void*)this); return State(::FLAC__stream_encoder_init(encoder_)); } @@ -253,16 +253,16 @@ namespace FLAC { ::FLAC__stream_encoder_finish(encoder_); } - bool Stream::process(const FLAC__int32 *buf[], unsigned samples) + bool Stream::process(const FLAC__int32 * const buffer[], unsigned samples) { FLAC__ASSERT(is_valid()); - return (bool)::FLAC__stream_encoder_process(encoder_, buf, samples); + return (bool)::FLAC__stream_encoder_process(encoder_, buffer, samples); } - bool Stream::process_interleaved(const FLAC__int32 buf[], unsigned samples) + bool Stream::process_interleaved(const FLAC__int32 buffer[], unsigned samples) { FLAC__ASSERT(is_valid()); - return (bool)::FLAC__stream_encoder_process_interleaved(encoder_, buf, samples); + return (bool)::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples); } ::FLAC__StreamEncoderWriteStatus Stream::write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) diff --git a/src/libFLAC/Makefile.am b/src/libFLAC/Makefile.am index 7da99d3..24c5b37 100644 --- a/src/libFLAC/Makefile.am +++ b/src/libFLAC/Makefile.am @@ -34,8 +34,8 @@ endif SUBDIRS = $(ARCH_SUBDIRS) include . -#@@@@ fix this -libFLAC_la_LDFLAGS = -version-info 2:1:1 +# see 'http://www.gnu.org/software/libtool/manual.html#Versioning' for numbering convention +libFLAC_la_LDFLAGS = -version-info 3:0:0 libFLAC_la_SOURCES = \ bitbuffer.c \ diff --git a/src/libFLAC/file_decoder.c b/src/libFLAC/file_decoder.c index 21224a0..62a926d 100644 --- a/src/libFLAC/file_decoder.c +++ b/src/libFLAC/file_decoder.c @@ -45,7 +45,7 @@ static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__Seekable static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data); -static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); +static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); @@ -56,7 +56,7 @@ static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__St ***********************************************************************/ typedef struct FLAC__FileDecoderPrivate { - FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); + FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); void (*error_callback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); void *client_data; @@ -71,7 +71,7 @@ typedef struct FLAC__FileDecoderPrivate { * ***********************************************************************/ -const char *FLAC__FileDecoderStateString[] = { +const char * const FLAC__FileDecoderStateString[] = { "FLAC__FILE_DECODER_OK", "FLAC__FILE_DECODER_END_OF_FILE", "FLAC__FILE_DECODER_ERROR_OPENING_FILE", @@ -243,7 +243,7 @@ FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const cha return true; } -FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)) +FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)) { FLAC__ASSERT(decoder != 0); FLAC__ASSERT(decoder->private_ != 0); @@ -603,7 +603,7 @@ FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *clien return feof(file_decoder->private_->file); } -FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; (void)decoder; diff --git a/src/libFLAC/format.c b/src/libFLAC/format.c index 5e5008d..f8eae47 100644 --- a/src/libFLAC/format.c +++ b/src/libFLAC/format.c @@ -68,7 +68,7 @@ const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<type == FLAC__METADATA_TYPE_STREAMINFO && 0 != *streaminfo) - **streaminfo = metadata->data.stream_info; + if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && 0 != cd->streaminfo) { + *(cd->streaminfo) = metadata->data.stream_info; + cd->got_streaminfo = true; + } } void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { - FLAC__StreamMetaData_StreamInfo **streaminfo = (FLAC__StreamMetaData_StreamInfo **)client_data; + level0_client_data *cd = (level0_client_data *)client_data; (void)decoder; if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) - *streaminfo = 0; + cd->got_error = true; } @@ -193,7 +212,7 @@ struct FLAC__MetaData_SimpleIterator { unsigned length; }; -const char *FLAC__MetaData_SimpleIteratorStatusString[] = { +const char * const FLAC__MetaData_SimpleIteratorStatusString[] = { "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK", "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT", "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE", @@ -694,7 +713,7 @@ struct FLAC__MetaData_Iterator { FLAC__MetaData_Node *current; }; -const char *FLAC__MetaData_ChainStatusString[] = { +const char * const FLAC__MetaData_ChainStatusString[] = { "FLAC__METADATA_CHAIN_STATUS_OK", "FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT", "FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE", diff --git a/src/libFLAC/metadata_object.c b/src/libFLAC/metadata_object.c index aa379fa..21f81c4 100644 --- a/src/libFLAC/metadata_object.c +++ b/src/libFLAC/metadata_object.c @@ -340,6 +340,124 @@ void FLAC__metadata_object_delete(FLAC__StreamMetaData *object) free(object); } +static FLAC__bool compare_block_data_streaminfo_(const FLAC__StreamMetaData_StreamInfo *block1, const FLAC__StreamMetaData_StreamInfo *block2) +{ + if(block1->min_blocksize != block2->min_blocksize) + return false; + if(block1->max_blocksize != block2->max_blocksize) + return false; + if(block1->min_framesize != block2->min_framesize) + return false; + if(block1->max_framesize != block2->max_framesize) + return false; + if(block1->sample_rate != block2->sample_rate) + return false; + if(block1->channels != block2->channels) + return false; + if(block1->bits_per_sample != block2->bits_per_sample) + return false; + if(block1->total_samples != block2->total_samples) + return false; + if(0 != memcmp(block1->md5sum, block2->md5sum, 16)) + return false; + return true; +} + +static FLAC__bool compare_block_data_application_(const FLAC__StreamMetaData_Application *block1, const FLAC__StreamMetaData_Application *block2, unsigned block_length) +{ + FLAC__ASSERT(0 != block1); + FLAC__ASSERT(0 != block2); + FLAC__ASSERT(block_length >= sizeof(block1->id)); + + if(0 != memcmp(block1->id, block2->id, sizeof(block1->id))) + return false; + if(0 != block1->data && 0 != block2->data) + return 0 == memcmp(block1->data, block2->data, block_length - sizeof(block1->id)); + else + return block1->data == block2->data; +} + +static FLAC__bool compare_block_data_seektable_(const FLAC__StreamMetaData_SeekTable *block1, const FLAC__StreamMetaData_SeekTable *block2) +{ + unsigned i; + + FLAC__ASSERT(0 != block1); + FLAC__ASSERT(0 != block2); + + if(block1->num_points != block2->num_points) + return false; + + if(0 != block1->points && 0 != block2->points) { + for(i = 0; i < block1->num_points; i++) { + if(block1->points[i].sample_number != block2->points[i].sample_number) + return false; + if(block1->points[i].stream_offset != block2->points[i].stream_offset) + return false; + if(block1->points[i].frame_samples != block2->points[i].frame_samples) + return false; + } + return true; + } + else + return block1->points == block2->points; +} + +static FLAC__bool compare_block_data_vorbiscomment_(const FLAC__StreamMetaData_VorbisComment *block1, const FLAC__StreamMetaData_VorbisComment *block2) +{ + unsigned i; + + if(block1->vendor_string.length != block2->vendor_string.length) + return false; + + if(0 != block1->vendor_string.entry && 0 != block2->vendor_string.entry) { + if(0 != memcmp(block1->vendor_string.entry, block2->vendor_string.entry, block1->vendor_string.length)) + return false; + } + else if(block1->vendor_string.entry != block2->vendor_string.entry) + return false; + + if(block1->num_comments != block2->num_comments) + return false; + + for(i = 0; i < block1->num_comments; i++) { + if(0 != block1->comments[i].entry && 0 != block2->comments[i].entry) { + if(0 != memcmp(block1->comments[i].entry, block2->comments[i].entry, block1->comments[i].length)) + return false; + } + else if(block1->comments[i].entry != block2->comments[i].entry) + return false; + } + return true; +} + +FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetaData *block1, const FLAC__StreamMetaData *block2) +{ + if(block1->type != block2->type) { + return false; + } + if(block1->is_last != block2->is_last) { + return false; + } + if(block1->length != block2->length) { + return false; + } + switch(block1->type) { + case FLAC__METADATA_TYPE_STREAMINFO: + return compare_block_data_streaminfo_(&block1->data.stream_info, &block2->data.stream_info); + case FLAC__METADATA_TYPE_PADDING: + return true; /* we don't compare the padding guts */ + case FLAC__METADATA_TYPE_APPLICATION: + return compare_block_data_application_(&block1->data.application, &block2->data.application, block1->length); + case FLAC__METADATA_TYPE_SEEKTABLE: + return compare_block_data_seektable_(&block1->data.seek_table, &block2->data.seek_table); + case FLAC__METADATA_TYPE_VORBIS_COMMENT: + return compare_block_data_vorbiscomment_(&block1->data.vorbis_comment, &block2->data.vorbis_comment); + default: + FLAC__ASSERT(0); + return false; + } +} + /*@@@@move sets the application data to 'data'. if 'copy' is true, makes, copy, else takes ownership of pointer. returns false if copy==true and malloc fails. FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_APPLICATION); diff --git a/src/libFLAC/seekable_stream_decoder.c b/src/libFLAC/seekable_stream_decoder.c index 2812240..9104e45 100644 --- a/src/libFLAC/seekable_stream_decoder.c +++ b/src/libFLAC/seekable_stream_decoder.c @@ -33,7 +33,7 @@ static void seekable_stream_decoder_set_defaults_(FLAC__SeekableStreamDecoder *decoder); static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); -static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); +static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); static FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample); @@ -50,7 +50,7 @@ typedef struct FLAC__SeekableStreamDecoderPrivate { FLAC__SeekableStreamDecoderTellStatus (*tell_callback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); FLAC__SeekableStreamDecoderLengthStatus (*length_callback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); FLAC__bool (*eof_callback)(const FLAC__SeekableStreamDecoder *decoder, void *client_data); - FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); + FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); void (*metadata_callback)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); void (*error_callback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); void *client_data; @@ -71,7 +71,7 @@ typedef struct FLAC__SeekableStreamDecoderPrivate { * ***********************************************************************/ -const char *FLAC__SeekableStreamDecoderStateString[] = { +const char * const FLAC__SeekableStreamDecoderStateString[] = { "FLAC__SEEKABLE_STREAM_DECODER_OK", "FLAC__SEEKABLE_STREAM_DECODER_SEEKING", "FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM", @@ -84,22 +84,22 @@ const char *FLAC__SeekableStreamDecoderStateString[] = { "FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED" }; -const char *FLAC__SeekableStreamDecoderReadStatusString[] = { +const char * const FLAC__SeekableStreamDecoderReadStatusString[] = { "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK", "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR" }; -const char *FLAC__SeekableStreamDecoderSeekStatusString[] = { +const char * const FLAC__SeekableStreamDecoderSeekStatusString[] = { "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK", "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR" }; -const char *FLAC__SeekableStreamDecoderTellStatusString[] = { +const char * const FLAC__SeekableStreamDecoderTellStatusString[] = { "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK", "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR" }; -const char *FLAC__SeekableStreamDecoderLengthStatusString[] = { +const char * const FLAC__SeekableStreamDecoderLengthStatusString[] = { "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK", "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR" }; @@ -302,7 +302,7 @@ FLAC__bool FLAC__seekable_stream_decoder_set_eof_callback(FLAC__SeekableStreamDe return true; } -FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)) +FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)) { FLAC__ASSERT(decoder != 0); FLAC__ASSERT(decoder->private_ != 0); @@ -670,7 +670,7 @@ FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ } -FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data; (void)decoder; diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index fe8fa15..924c251 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -68,7 +68,7 @@ static FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *cli typedef struct FLAC__StreamDecoderPrivate { FLAC__StreamDecoderReadStatus (*read_callback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); - FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); + FLAC__StreamDecoderWriteStatus (*write_callback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); void (*metadata_callback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); void (*error_callback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); @@ -99,7 +99,7 @@ typedef struct FLAC__StreamDecoderPrivate { * ***********************************************************************/ -const char *FLAC__StreamDecoderStateString[] = { +const char * const FLAC__StreamDecoderStateString[] = { "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", "FLAC__STREAM_DECODER_READ_METADATA", "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", @@ -113,18 +113,18 @@ const char *FLAC__StreamDecoderStateString[] = { "FLAC__STREAM_DECODER_UNINITIALIZED" }; -const char *FLAC__StreamDecoderReadStatusString[] = { +const char * const FLAC__StreamDecoderReadStatusString[] = { "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM", "FLAC__STREAM_DECODER_READ_STATUS_ABORT" }; -const char *FLAC__StreamDecoderWriteStatusString[] = { +const char * const FLAC__StreamDecoderWriteStatusString[] = { "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT" }; -const char *FLAC__StreamDecoderErrorStatusString[] = { +const char * const FLAC__StreamDecoderErrorStatusString[] = { "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH" @@ -302,7 +302,7 @@ FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, return true; } -FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data)) +FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteStatus (*value)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)) { FLAC__ASSERT(decoder != 0); FLAC__ASSERT(decoder->private_ != 0); @@ -1247,8 +1247,7 @@ FLAC__bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool * decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; /* write it */ - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 3 here: */ - if(decoder->private_->write_callback(decoder, &decoder->private_->frame, decoder->private_->output, decoder->private_->client_data) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) + if(decoder->private_->write_callback(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output, decoder->private_->client_data) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) return false; decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 55210cb..4c20b6c 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -142,7 +142,7 @@ typedef struct FLAC__StreamEncoderPrivate { * ***********************************************************************/ -const char *FLAC__StreamEncoderStateString[] = { +const char * const FLAC__StreamEncoderStateString[] = { "FLAC__STREAM_ENCODER_OK", "FLAC__STREAM_ENCODER_INVALID_CALLBACK", "FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS", @@ -164,7 +164,7 @@ const char *FLAC__StreamEncoderStateString[] = { "FLAC__STREAM_ENCODER_UNINITIALIZED" }; -const char *FLAC__StreamEncoderWriteStatusString[] = { +const char * const FLAC__StreamEncoderWriteStatusString[] = { "FLAC__STREAM_ENCODER_WRITE_OK", "FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR" }; @@ -473,7 +473,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(encoder->private_->frame)); { - FLAC__byte *buffer; + const FLAC__byte *buffer; unsigned bytes; FLAC__bitbuffer_get_buffer(encoder->private_->frame, &buffer, &bytes); @@ -799,7 +799,7 @@ unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamE return encoder->protected_->rice_parameter_search_dist; } -FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 *buf[], unsigned samples) +FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) { unsigned i, j, channel; FLAC__int32 x, mid, side; @@ -812,15 +812,15 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC if(encoder->protected_->do_mid_side_stereo && channels == 2) { do { for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { - x = mid = side = buf[0][j]; + x = mid = side = buffer[0][j]; encoder->private_->integer_signal[0][i] = x; encoder->private_->real_signal[0][i] = (FLAC__real)x; - x = buf[1][j]; + x = buffer[1][j]; encoder->private_->integer_signal[1][i] = x; encoder->private_->real_signal[1][i] = (FLAC__real)x; mid += x; side -= x; - mid >>= 1; /* NOTE: not the same as 'mid = (buf[0][j] + buf[1][j]) / 2' ! */ + mid >>= 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */ encoder->private_->integer_signal_mid_side[1][i] = side; encoder->private_->integer_signal_mid_side[0][i] = mid; encoder->private_->real_signal_mid_side[1][i] = (FLAC__real)side; @@ -837,7 +837,7 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC do { for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { for(channel = 0; channel < channels; channel++) { - x = buf[channel][j]; + x = buffer[channel][j]; encoder->private_->integer_signal[channel][i] = x; encoder->private_->real_signal[channel][i] = (FLAC__real)x; } @@ -854,7 +854,7 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC } /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */ -FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buf[], unsigned samples) +FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) { unsigned i, j, k, channel; FLAC__int32 x, mid, side; @@ -867,10 +867,10 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder if(encoder->protected_->do_mid_side_stereo && channels == 2) { do { for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { - x = mid = side = buf[k++]; + x = mid = side = buffer[k++]; encoder->private_->integer_signal[0][i] = x; encoder->private_->real_signal[0][i] = (FLAC__real)x; - x = buf[k++]; + x = buffer[k++]; encoder->private_->integer_signal[1][i] = x; encoder->private_->real_signal[1][i] = (FLAC__real)x; mid += x; @@ -892,7 +892,7 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder do { for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { for(channel = 0; channel < channels; channel++) { - x = buf[k++]; + x = buffer[k++]; encoder->private_->integer_signal[channel][i] = x; encoder->private_->real_signal[channel][i] = (FLAC__real)x; } @@ -977,8 +977,7 @@ FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__boo /* * Accumulate raw signal to the MD5 signature */ - /* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */ - if(!FLAC__MD5Accumulate(&encoder->private_->md5context, encoder->private_->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) { + if(!FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) { encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; return false; } diff --git a/src/plugin_winamp2/in_flac.c b/src/plugin_winamp2/in_flac.c index 9417d1d..a87fe82 100644 --- a/src/plugin_winamp2/in_flac.c +++ b/src/plugin_winamp2/in_flac.c @@ -52,24 +52,26 @@ typedef struct { unsigned channels; unsigned sample_rate; unsigned length_in_ms; -} stream_info_struct; - -static FLAC__bool stream_init(const char *infilename); -static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); -static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); -static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); +} file_info_struct; + +static FLAC__bool safe_decoder_init_(const char *infilename, FLAC__FileDecoder *decoder); +static void safe_decoder_finish_(FLAC__FileDecoder *decoder); +static void safe_decoder_delete_(FLAC__FileDecoder *decoder); +static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); +static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); +static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); static FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag); -In_Module mod; /* the output module (declared near the bottom of this file) */ -char lastfn[MAX_PATH]; /* currently playing file (used for getting info on the current file) */ -int decode_pos_ms; /* current decoding position, in milliseconds */ -int paused; /* are we paused? */ -int seek_needed; /* if != -1, it is the point that the decode thread should seek to, in ms. */ -FLAC__int16 reservoir[FLAC__MAX_BLOCK_SIZE * 2 * 2]; /* *2 for max channels, another *2 for overflow */ -char sample_buffer[576 * 2 * (16/8) * 2]; /* 2 for max channels, (16/8) for max bytes per sample, and 2 for who knows what */ -unsigned samples_in_reservoir; -static stream_info_struct stream_info; -static FLAC__FileDecoder *decoder; +In_Module mod_; /* the output module (declared near the bottom of this file) */ +char lastfn_[MAX_PATH]; /* currently playing file (used for getting info on the current file) */ +int decode_pos_ms_; /* current decoding position, in milliseconds */ +int paused_; /* are we paused? */ +int seek_needed_; /* if != -1, it is the point that the decode thread should seek to, in ms. */ +FLAC__int16 reservoir_[FLAC__MAX_BLOCK_SIZE * 2 * 2]; /* *2 for max channels, another *2 for overflow */ +char sample_buffer_[576 * 2 * (16/8) * 2]; /* 2 for max channels, (16/8) for max bytes per sample, and 2 for who knows what */ +unsigned samples_in_reservoir_; +static file_info_struct file_info_; +static FLAC__FileDecoder *decoder_; int killDecodeThread = 0; /* the kill switch for the decode thread */ HANDLE thread_handle = INVALID_HANDLE_VALUE; /* the handle to the decode thread */ @@ -88,15 +90,14 @@ void about(HWND hwndParent) void init() { - decoder = FLAC__file_decoder_new(); + decoder_ = FLAC__file_decoder_new(); + strcpy(lastfn_, ""); } void quit() { - if(decoder) { - FLAC__file_decoder_delete(decoder); - decoder = 0; - } + safe_decoder_delete_(decoder_); + decoder_ = 0; } int isourfile(char *fn) { return 0; } @@ -108,7 +109,7 @@ int play(char *fn) int thread_id; HANDLE input_file = INVALID_HANDLE_VALUE; - if(0 == decoder) { + if(0 == decoder_) { return 1; } @@ -118,30 +119,30 @@ int play(char *fn) } CloseHandle(input_file); - if(!stream_init(fn)) { + if(!safe_decoder_init_(fn, decoder_)) { return 1; } - strcpy(lastfn, fn); - paused = 0; - decode_pos_ms = 0; - seek_needed = -1; - samples_in_reservoir = 0; + strcpy(lastfn_, fn); + paused_ = 0; + decode_pos_ms_ = 0; + seek_needed_ = -1; + samples_in_reservoir_ = 0; - maxlatency = mod.outMod->Open(stream_info.sample_rate, stream_info.channels, stream_info.bits_per_sample, -1, -1); + maxlatency = mod_.outMod->Open(file_info_.sample_rate, file_info_.channels, file_info_.bits_per_sample, -1, -1); if (maxlatency < 0) { /* error opening device */ return 1; } /* dividing by 1000 for the first parameter of setinfo makes it */ /* display 'H'... for hundred.. i.e. 14H Kbps. */ - mod.SetInfo((stream_info.sample_rate*stream_info.bits_per_sample*stream_info.channels)/1000, stream_info.sample_rate/1000, stream_info.channels, 1); + mod_.SetInfo((file_info_.sample_rate*file_info_.bits_per_sample*file_info_.channels)/1000, file_info_.sample_rate/1000, file_info_.channels, 1); /* initialize vis stuff */ - mod.SAVSAInit(maxlatency, stream_info.sample_rate); - mod.VSASetInfo(stream_info.sample_rate, stream_info.channels); + mod_.SAVSAInit(maxlatency, file_info_.sample_rate); + mod_.VSASetInfo(file_info_.sample_rate, file_info_.channels); - mod.outMod->SetVolume(-666); /* set the output plug-ins default volume */ + mod_.outMod->SetVolume(-666); /* set the output plug-ins default volume */ killDecodeThread = 0; thread_handle = (HANDLE) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DecodeThread, (void *) &killDecodeThread, 0, &thread_id); @@ -151,18 +152,18 @@ int play(char *fn) void pause() { - paused = 1; - mod.outMod->Pause(1); + paused_ = 1; + mod_.outMod->Pause(1); } void unpause() { - paused = 0; - mod.outMod->Pause(0); + paused_ = 0; + mod_.outMod->Pause(0); } int ispaused() { - return paused; + return paused_; } void stop() @@ -170,37 +171,36 @@ void stop() if (thread_handle != INVALID_HANDLE_VALUE) { killDecodeThread = 1; if (WaitForSingleObject(thread_handle, INFINITE) == WAIT_TIMEOUT) { - MessageBox(mod.hMainWindow, "error asking thread to die!\n", "error killing decode thread", 0); + MessageBox(mod_.hMainWindow, "error asking thread to die!\n", "error killing decode thread", 0); TerminateThread(thread_handle, 0); } CloseHandle(thread_handle); thread_handle = INVALID_HANDLE_VALUE; } - if(decoder) - FLAC__file_decoder_finish(decoder); + safe_decoder_finish_(decoder_); - mod.outMod->Close(); + mod_.outMod->Close(); - mod.SAVSADeInit(); + mod_.SAVSADeInit(); } int getlength() { - return (int)stream_info.length_in_ms; + return (int)file_info_.length_in_ms; } int getoutputtime() { - return decode_pos_ms+(mod.outMod->GetOutputTime()-mod.outMod->GetWrittenTime()); + return decode_pos_ms_ + (mod_.outMod->GetOutputTime() - mod_.outMod->GetWrittenTime()); } void setoutputtime(int time_in_ms) { - seek_needed = time_in_ms; + seek_needed_ = time_in_ms; } -void setvolume(int volume) { mod.outMod->SetVolume(volume); } -void setpan(int pan) { mod.outMod->SetPan(pan); } +void setvolume(int volume) { mod_.outMod->SetVolume(volume); } +void setpan(int pan) { mod_.outMod->SetPan(pan); } int infoDlg(char *fn, HWND hwnd) { @@ -211,41 +211,33 @@ int infoDlg(char *fn, HWND hwnd) void getfileinfo(char *filename, char *title, int *length_in_ms) { id3v1_struct tag; + FLAC__StreamMetaData_StreamInfo streaminfo; - if (!filename || !*filename) { /* currently playing file */ + if(0 == filename) { + filename = lastfn_; if (length_in_ms) { *length_in_ms = getlength(); length_in_ms = 0; /* force skip in following code */ } - if (title && lastfn && lastfn[0]) { - filename = lastfn; - } } - if (length_in_ms) { - FLAC__FileDecoder *tmp_decoder = FLAC__file_decoder_new(); - stream_info_struct tmp_stream_info; - tmp_stream_info.abort_flag = false; - FLAC__file_decoder_set_md5_checking(tmp_decoder, false); - FLAC__file_decoder_set_filename(tmp_decoder, filename); - FLAC__file_decoder_set_write_callback(tmp_decoder, write_callback); - FLAC__file_decoder_set_metadata_callback(tmp_decoder, metadata_callback); - FLAC__file_decoder_set_error_callback(tmp_decoder, error_callback); - FLAC__file_decoder_set_client_data(tmp_decoder, &tmp_stream_info); - if(FLAC__file_decoder_init(tmp_decoder) != FLAC__FILE_DECODER_OK) - return; - if(!FLAC__file_decoder_process_metadata(tmp_decoder)) - return; - - *length_in_ms = (int)tmp_stream_info.length_in_ms; - - FLAC__file_decoder_finish(tmp_decoder); - FLAC__file_decoder_delete(tmp_decoder); + if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) { + MessageBox(mod_.hMainWindow, filename, "ERROR: invalid/missing FLAC metadata", 0); + if(title) { + static const char *errtitle = "Invalid FLAC File: "); + sprintf(title, "%s\"%s\"", errtitle, filename); + } + if(length_in_msec) + *length_in_msec = -1; + return; } - if (title) { + + if(title) { (void)get_id3v1_tag_(filename, &tag); strcpy(title, tag.description); } + if(length_in_msec) + *length_in_msec = streaminfo.total_samples * 10 / (streaminfo.sample_rate / 100); } void eq_set(int on, char data[10], int preamp) @@ -257,60 +249,60 @@ DWORD WINAPI __stdcall DecodeThread(void *b) int done = 0; while (! *((int *)b) ) { - unsigned channels = stream_info.channels; - unsigned bits_per_sample = stream_info.bits_per_sample; + unsigned channels = file_info_.channels; + unsigned bits_per_sample = file_info_.bits_per_sample; unsigned bytes_per_sample = (bits_per_sample+7)/8; - unsigned sample_rate = stream_info.sample_rate; - if (seek_needed != -1) { - const double distance = (double)seek_needed / (double)getlength(); - unsigned target_sample = (unsigned)(distance * (double)stream_info.total_samples); - if(FLAC__file_decoder_seek_absolute(decoder, (FLAC__uint64)target_sample)) { - decode_pos_ms = (int)(distance * (double)getlength()); - seek_needed = -1; + unsigned sample_rate = file_info_.sample_rate; + if (seek_needed_ != -1) { + const double distance = (double)seek_needed_ / (double)getlength(); + unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples); + if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) { + decode_pos_ms_ = (int)(distance * (double)getlength()); + seek_needed_ = -1; done = 0; - mod.outMod->Flush(decode_pos_ms); + mod_.outMod->Flush(decode_pos_ms_); } } if (done) { - if (!mod.outMod->IsPlaying()) { - PostMessage(mod.hMainWindow, WM_WA_MPEG_EOF, 0, 0); + if (!mod_.outMod->IsPlaying()) { + PostMessage(mod_.hMainWindow, WM_WA_MPEG_EOF, 0, 0); return 0; } Sleep(10); } - else if (mod.outMod->CanWrite() >= ((int)(576*channels*bytes_per_sample) << (mod.dsp_isactive()?1:0))) { - while(samples_in_reservoir < 576) { - if(FLAC__file_decoder_get_state(decoder) == FLAC__FILE_DECODER_END_OF_FILE) { + else if (mod_.outMod->CanWrite() >= ((int)(576*channels*bytes_per_sample) << (mod_.dsp_isactive()?1:0))) { + while(samples_in_reservoir_ < 576) { + if(FLAC__file_decoder_get_state(decoder_) == FLAC__FILE_DECODER_END_OF_FILE) { done = 1; break; } - else if(!FLAC__file_decoder_process_one_frame(decoder)) + else if(!FLAC__file_decoder_process_one_frame(decoder_)) break; } - if (samples_in_reservoir == 0) { + if (samples_in_reservoir_ == 0) { done = 1; } else { - unsigned i, n = min(samples_in_reservoir, 576), delta; + unsigned i, n = min(samples_in_reservoir_, 576), delta; int bytes; - signed short *ssbuffer = (signed short *)sample_buffer; + signed short *ssbuffer = (signed short *)sample_buffer_; for(i = 0; i < n*channels; i++) - ssbuffer[i] = reservoir[i]; + ssbuffer[i] = reservoir_[i]; delta = i; - for( ; i < samples_in_reservoir*channels; i++) - reservoir[i-delta] = reservoir[i]; - samples_in_reservoir -= n; - - mod.SAAddPCMData((char *)sample_buffer, channels, bits_per_sample, decode_pos_ms); - mod.VSAAddPCMData((char *)sample_buffer, channels, bits_per_sample, decode_pos_ms); - decode_pos_ms += (n*1000 + sample_rate/2)/sample_rate; - if (mod.dsp_isactive()) - bytes = mod.dsp_dosamples((short *)sample_buffer, n, bits_per_sample, channels, sample_rate) * (channels*bytes_per_sample); + for( ; i < samples_in_reservoir_ * channels; i++) + reservoir_[i-delta] = reservoir_[i]; + samples_in_reservoir_ -= n; + + mod_.SAAddPCMData((char *)sample_buffer_, channels, bits_per_sample, decode_pos_ms_); + mod_.VSAAddPCMData((char *)sample_buffer_, channels, bits_per_sample, decode_pos_ms_); + decode_pos_ms_ += (n*1000 + sample_rate/2)/sample_rate; + if (mod_.dsp_isactive()) + bytes = mod_.dsp_dosamples((short *)sample_buffer_, n, bits_per_sample, channels, sample_rate) * (channels*bytes_per_sample); else bytes = n * channels * bytes_per_sample; - mod.outMod->Write(sample_buffer, bytes); + mod_.outMod->Write(sample_buffer_, bytes); } } else Sleep(20); @@ -320,7 +312,7 @@ DWORD WINAPI __stdcall DecodeThread(void *b) -In_Module mod = +In_Module mod_ = { IN_VER, "Reference FLAC Player v" FLAC__VERSION_STRING, @@ -365,80 +357,102 @@ In_Module mod = __declspec( dllexport ) In_Module * winampGetInModule2() { - return &mod; + return &mod_; } /*********************************************************************** * local routines **********************************************************************/ -FLAC__bool stream_init(const char *infilename) +FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder) { + if(decoder == 0) { + MessageBox(mod_.hMainWindow, "Decoder instance is NULL", "ERROR initializing decoder", 0); + return false; + } + + safe_decoder_finish_(decoder); + FLAC__file_decoder_set_md5_checking(decoder, false); - FLAC__file_decoder_set_filename(decoder, infilename); - FLAC__file_decoder_set_write_callback(decoder, write_callback); - FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback); - FLAC__file_decoder_set_error_callback(decoder, error_callback); - FLAC__file_decoder_set_client_data(decoder, &stream_info); + FLAC__file_decoder_set_filename(decoder, filename); + FLAC__file_decoder_set_write_callback(decoder, write_callback_); + FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_); + FLAC__file_decoder_set_error_callback(decoder, error_callback_); + FLAC__file_decoder_set_client_data(decoder, &file_info_); if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) { - MessageBox(mod.hMainWindow, "ERROR initializing decoder, state = %d\n", "ERROR initializing decoder", 0); + MessageBox(mod_.hMainWindow, FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)], "ERROR initializing decoder", 0); return false; } - stream_info.abort_flag = false; + file_info_.abort_flag = false; if(!FLAC__file_decoder_process_metadata(decoder)) { + MessageBox(mod_.hMainWindow, FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)], "ERROR processing metadata", 0); return false; } return true; } -FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +void safe_decoder_finish_(FLAC__FileDecoder *decoder) +{ + if(decoder && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED) + FLAC__file_decoder_finish(decoder); +} + +void safe_decoder_delete_(FLAC__FileDecoder *decoder) +{ + if(decoder) { + safe_decoder_finish_(decoder); + FLAC__file_decoder_delete(decoder); + } +} + +FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) { - stream_info_struct *stream_info = (stream_info_struct *)client_data; - const unsigned bps = stream_info->bits_per_sample, channels = stream_info->channels, wide_samples = frame->header.blocksize; + file_info_struct *file_info_ = (file_info_struct *)client_data; + const unsigned bps = file_info_->bits_per_sample, channels = file_info_->channels, wide_samples = frame->header.blocksize; unsigned wide_sample, sample, channel; (void)decoder; - if(stream_info->abort_flag) + if(file_info_->abort_flag) return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; - for(sample = samples_in_reservoir*channels, wide_sample = 0; wide_sample < wide_samples; wide_sample++) + for(sample = samples_in_reservoir_ * channels, wide_sample = 0; wide_sample < wide_samples; wide_sample++) for(channel = 0; channel < channels; channel++, sample++) - reservoir[sample] = (FLAC__int16)buffer[channel][wide_sample]; + reservoir_[sample] = (FLAC__int16)buffer[channel][wide_sample]; - samples_in_reservoir += wide_samples; + samples_in_reservoir_ += wide_samples; return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } -void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data) +void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data) { - stream_info_struct *stream_info = (stream_info_struct *)client_data; + file_info_struct *file_info_ = (file_info_struct *)client_data; (void)decoder; if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { FLAC__ASSERT(metadata->data.stream_info.total_samples < 0x100000000); /* this plugin can only handle < 4 gigasamples */ - stream_info->total_samples = (unsigned)(metadata->data.stream_info.total_samples&0xffffffff); - stream_info->bits_per_sample = metadata->data.stream_info.bits_per_sample; - stream_info->channels = metadata->data.stream_info.channels; - stream_info->sample_rate = metadata->data.stream_info.sample_rate; - - if(stream_info->bits_per_sample != 16) { - MessageBox(mod.hMainWindow, "ERROR: plugin can only handle 16-bit samples\n", "ERROR: plugin can only handle 16-bit samples", 0); - stream_info->abort_flag = true; + file_info_->total_samples = (unsigned)(metadata->data.stream_info.total_samples&0xffffffff); + file_info_->bits_per_sample = metadata->data.stream_info.bits_per_sample; + file_info_->channels = metadata->data.stream_info.channels; + file_info_->sample_rate = metadata->data.stream_info.sample_rate; + + if(file_info_->bits_per_sample != 16) { + MessageBox(mod_.hMainWindow, "ERROR: plugin can only handle 16-bit samples\n", "ERROR: plugin can only handle 16-bit samples", 0); + file_info_->abort_flag = true; return; } - stream_info->length_in_ms = stream_info->total_samples * 10 / (stream_info->sample_rate / 100); + file_info_->length_in_ms = file_info_->total_samples * 10 / (file_info_->sample_rate / 100); } } -void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { - stream_info_struct *stream_info = (stream_info_struct *)client_data; + file_info_struct *file_info_ = (file_info_struct *)client_data; (void)decoder; if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) - stream_info->abort_flag = true; + file_info_->abort_flag = true; } FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag) diff --git a/src/plugin_xmms/plugin.c b/src/plugin_xmms/plugin.c index 45cc23c..1e1cdff 100644 --- a/src/plugin_xmms/plugin.c +++ b/src/plugin_xmms/plugin.c @@ -69,7 +69,9 @@ static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length); static FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag); static void *play_loop_(void *arg); -static FLAC__bool decoder_init_(const char *filename); +static FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder); +static FLAC__bool safe_decoder_finish_(FLAC__FileDecoder *decoder); +static FLAC__bool safe_decoder_delete_(FLAC__FileDecoder *decoder); static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data); static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data); static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); @@ -150,15 +152,17 @@ void FLAC_XMMS__play_file(char *filename) return; fclose(f); - if(!decoder_init_(filename)) + if(decoder_ == 0) + return; + + if(!safe_decoder_init_(filename, decoder_)) return; file_info_.is_playing = true; if(flac_ip.output->open_audio(file_info_.sample_format, file_info_.sample_rate, file_info_.channels) == 0) { audio_error_ = true; - if(decoder_) - FLAC__file_decoder_finish(decoder_); + safe_decoder_finish_(decoder_); return; } @@ -179,8 +183,7 @@ void FLAC_XMMS__stop() pthread_join(decode_thread_, NULL); } flac_ip.output->close_audio(); - if(decoder_) - FLAC__file_decoder_finish(decoder_); + safe_decoder_finish_(decoder_); } } @@ -210,49 +213,37 @@ int FLAC_XMMS__get_time() void FLAC_XMMS__cleanup() { - if(decoder_) { - FLAC__file_decoder_delete(decoder_); - decoder_ = 0; - } + safe_decoder_delete(decoder_); + decoder_ = 0; } void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec) { id3v1_struct tag; + FLAC__StreamMetaData_StreamInfo streaminfo; + + if(0 == filename) + filename = ""; + + if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) { + /* @@@ how to report the error? */ + if(title) { + static const char *errtitle = "Invalid FLAC File: "); + *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1); + sprintf(*title, "%s\"%s\"", errtitle, filename); + } + if(length_in_msec) + *length_in_msec = -1; + return; + } if(title) { (void)get_id3v1_tag_(filename, &tag); *title = g_malloc(strlen(tag.description)+1); strcpy(*title, tag.description); } - if(length_in_msec) { - FLAC__FileDecoder *tmp_decoder = FLAC__file_decoder_new(); - file_info_struct tmp_file_info; - if(0 == tmp_decoder) { - *length_in_msec = -1; - return; - } - tmp_file_info.abort_flag = false; - FLAC__file_decoder_set_md5_checking(tmp_decoder, false); - FLAC__file_decoder_set_filename(tmp_decoder, filename); - FLAC__file_decoder_set_write_callback(tmp_decoder, write_callback_); - FLAC__file_decoder_set_metadata_callback(tmp_decoder, metadata_callback_); - FLAC__file_decoder_set_error_callback(tmp_decoder, error_callback_); - FLAC__file_decoder_set_client_data(tmp_decoder, &tmp_file_info); - if(FLAC__file_decoder_init(tmp_decoder) != FLAC__FILE_DECODER_OK) { - *length_in_msec = -1; - return; - } - if(!FLAC__file_decoder_process_metadata(tmp_decoder)) { - *length_in_msec = -1; - return; - } - - *length_in_msec = (int)tmp_file_info.length_in_msec; - - FLAC__file_decoder_finish(tmp_decoder); - FLAC__file_decoder_delete(tmp_decoder); - } + if(length_in_msec) + *length_in_msec = streaminfo.total_samples * 10 / (streaminfo.sample_rate / 100); } /*********************************************************************** @@ -357,8 +348,7 @@ void *play_loop_(void *arg) } } - if(decoder_) - FLAC__file_decoder_finish(decoder_); + safe_decoder_finish_(decoder_); /* are these two calls necessary? */ flac_ip.output->buffer_free(); @@ -368,26 +358,42 @@ void *play_loop_(void *arg) return 0; /* to silence the compiler warning about not returning a value */ } -FLAC__bool decoder_init_(const char *filename) +FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder) { - if(decoder_ == 0) + if(decoder == 0) return false; - FLAC__file_decoder_set_md5_checking(decoder_, false); - FLAC__file_decoder_set_filename(decoder_, filename); - FLAC__file_decoder_set_write_callback(decoder_, write_callback_); - FLAC__file_decoder_set_metadata_callback(decoder_, metadata_callback_); - FLAC__file_decoder_set_error_callback(decoder_, error_callback_); - FLAC__file_decoder_set_client_data(decoder_, &file_info_); - if(FLAC__file_decoder_init(decoder_) != FLAC__FILE_DECODER_OK) + safe_decoder_finish_(decoder); + + FLAC__file_decoder_set_md5_checking(decoder, false); + FLAC__file_decoder_set_filename(decoder, filename); + FLAC__file_decoder_set_write_callback(decoder, write_callback_); + FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_); + FLAC__file_decoder_set_error_callback(decoder, error_callback_); + FLAC__file_decoder_set_client_data(decoder, &file_info_); + if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) return false; - if(!FLAC__file_decoder_process_metadata(decoder_)) + if(!FLAC__file_decoder_process_metadata(decoder)) return false; return true; } +void safe_decoder_finish_(FLAC__FileDecoder *decoder) +{ + if(decoder && FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED) + FLAC__file_decoder_finish(decoder); +} + +void safe_decoder_delete_(FLAC__FileDecoder *decoder) +{ + if(decoder) { + safe_decoder_finish_(decoder); + FLAC__file_decoder_delete(decoder); + } +} + FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) { file_info_struct *file_info = (file_info_struct *)client_data; diff --git a/src/test_libFLAC++/Makefile.am b/src/test_libFLAC++/Makefile.am new file mode 100644 index 0000000..6e3202e --- /dev/null +++ b/src/test_libFLAC++/Makefile.am @@ -0,0 +1,34 @@ +# test_libFLAC++ - Unit tester for libFLAC++ +# Copyright (C) 2002 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +CFLAGS = @CFLAGS@ + +noinst_PROGRAMS = test_libFLAC++ +test_libFLAC___LDADD = $(top_builddir)/src/libFLAC++/libFLAC++.la $(top_builddir)/src/libFLAC/libFLAC.la -lm +test_libFLAC___SOURCES = \ + decoders.cc \ + encoders.cc \ + file_utils.c \ + main.cc \ + metadata.cc \ + metadata_manip.cc \ + metadata_object.cc \ + bitbuffer.h \ + decoders.h \ + encoders.h \ + file_utils.h \ + metadata.h diff --git a/src/test_libFLAC++/Makefile.lite b/src/test_libFLAC++/Makefile.lite new file mode 100644 index 0000000..d985090 --- /dev/null +++ b/src/test_libFLAC++/Makefile.lite @@ -0,0 +1,38 @@ +# test_libFLAC++ - Unit tester for libFLAC++ +# Copyright (C) 2002 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# +# GNU makefile +# + +PROGRAM_NAME = test_libFLAC++ +INCLUDES = -I../../include +LIBS = -lFLAC++ -lFLAC -lm +OBJS = \ + decoders.o \ + encoders.o \ + file_utils.o \ + main.o \ + metadata.o \ + metadata_manip.o \ + metadata_object.o + +include ../../build/exe.mk + +LINK = $(CCC) $(LINKAGE) + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/src/test_libFLAC++/Makefile.vc b/src/test_libFLAC++/Makefile.vc new file mode 100644 index 0000000..5af32f8 --- /dev/null +++ b/src/test_libFLAC++/Makefile.vc @@ -0,0 +1,73 @@ +# test_libFLAC++ - Unit tester for libFLAC++ +# Copyright (C) 2002 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +!include + +SUFFIXES = .cpp + +!IFDEF DEBUG +.c.obj: + $(cc) $(cdebug) $(cflags) /I "..\..\include" /I ".\include" -DSTRICT -DVERSION=\"1.0.3\" -YX /Od /D "_DEBUG" $< +!else +.c.obj: + $(cc) /O2 $(crelease) $(cflags) /I "..\..\include" /I ".\include" -DSTRICT -DVERSION=\"1.0.3\" -YX -DNODEBUG $< +!endif + +!IFDEF DEBUG +.cc.obj: + $(cc) /D "_LIB" /GX $(cdebug) $(cflags) /I "..\..\include" -DSTRICT -YX /Od /D "_DEBUG" $< +!else +.cc.obj: + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG $< +!endif + +C_FILES= \ + file_utils.c + +CC_FILES= \ + decoders.cc \ + encoders.cc \ + main.cc \ + metadata.cc \ + metadata_manip.cc \ + metadata_object.cc + +OBJS= $(C_FILES:.c=.obj) +OBJS= $(CC_FILES:.cc=.obj) + +# can't figure out how to get it to take .cc so we just hack it for now: +decoders.obj: decoders.cc + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP decoders.cc +encoders.obj: encoders.cc + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP encoders.cc +main.obj: main.cc + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP main.cc +metadata.obj: metadata.cc + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP metadata.cc +metadata_manip.obj: metadata_manip.cc + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP metadata_manip.cc +metadata_object.obj: metadata_object.cc + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP metadata_object.cc + +all: test_libFLAC++.exe + +test_libFLAC++.exe: $(OBJS) + link.exe /libpath:"..\..\obj\lib" -out:../../obj/bin/$*.exe $(OBJS) libFLAC++.lib libFLAC.lib + +clean: + -del *.obj *.pch + -del ..\..\obj\bin\test_libFLAC++.exe diff --git a/src/test_libFLAC++/README b/src/test_libFLAC++/README new file mode 100644 index 0000000..d2b766c --- /dev/null +++ b/src/test_libFLAC++/README @@ -0,0 +1,4 @@ +NOTE: files file_utils.c and file_utils.h are copied from the +../test_libFLAC directory. It's too much pain to make a +convenience library for these and CVS can't do soft links, so +we put up with having two copies of these sources. diff --git a/src/test_libFLAC++/decoders.cc b/src/test_libFLAC++/decoders.cc new file mode 100644 index 0000000..d592bd2 --- /dev/null +++ b/src/test_libFLAC++/decoders.cc @@ -0,0 +1,2005 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "decoders.h" +extern "C" { +#include "file_utils.h" +} +#include "FLAC/assert.h" +#include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal() +#include "FLAC++/decoder.h" +#include +#include +#include +#include + +static ::FLAC__StreamMetaData streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; +static ::FLAC__StreamMetaData *expected_metadata_sequence_[6]; +static unsigned num_expected_; +static const char *flacfilename_ = "metadata.flac"; +static unsigned flacfilesize_; + +static bool die_(const char *msg) +{ + printf("ERROR: %s\n", msg); + return false; +} + +static void *malloc_or_die_(size_t size) +{ + void *x = malloc(size); + if(0 == x) { + fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size); + exit(1); + } + return x; +} + +static void init_metadata_blocks_() +{ + /* + most of the actual numbers and data in the blocks don't matter, + we just want to make sure the decoder parses them correctly + + remember, the metadata interface gets tested after the decoders, + so we do all the metadata manipulation here without it. + */ + + /* min/max_framesize and md5sum don't get written at first, so we have to leave them 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); + + padding_.is_last = false; + padding_.type = ::FLAC__METADATA_TYPE_PADDING; + padding_.length = 1234; + + seektable_.is_last = false; + seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE; + seektable_.data.seek_table.num_points = 2; + seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + seektable_.data.seek_table.points = (::FLAC__StreamMetaData_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetaData_SeekPoint)); + seektable_.data.seek_table.points[0].sample_number = 0; + seektable_.data.seek_table.points[0].stream_offset = 0; + seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize; + seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + seektable_.data.seek_table.points[1].stream_offset = 1000; + seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize; + + application1_.is_last = false; + application1_.type = ::FLAC__METADATA_TYPE_APPLICATION; + application1_.length = 8; + memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4); + application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4); + memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4); + + application2_.is_last = false; + application2_.type = ::FLAC__METADATA_TYPE_APPLICATION; + application2_.length = 4; + memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4); + application2_.data.application.data = 0; + + vorbiscomment_.is_last = true; + vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT; + vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0); + vorbiscomment_.data.vorbis_comment.vendor_string.length = 8; + vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8); + memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8); + vorbiscomment_.data.vorbis_comment.num_comments = 2; + vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetaData_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetaData_VorbisComment_Entry)); + vorbiscomment_.data.vorbis_comment.comments[0].length = 5; + vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5); + memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5); + vorbiscomment_.data.vorbis_comment.comments[1].length = 0; + vorbiscomment_.data.vorbis_comment.comments[1].entry = 0; +} + +static void free_metadata_blocks_() +{ + free(seektable_.data.seek_table.points); + free(application1_.data.application.data); + free(vorbiscomment_.data.vorbis_comment.vendor_string.entry); + free(vorbiscomment_.data.vorbis_comment.comments[0].entry); + free(vorbiscomment_.data.vorbis_comment.comments); +} + +static bool generate_file_() +{ + printf("\n\ngenerating FLAC file for decoder tests...\n"); + + expected_metadata_sequence_[0] = &padding_; + expected_metadata_sequence_[1] = &seektable_; + expected_metadata_sequence_[2] = &application1_; + expected_metadata_sequence_[3] = &application2_; + expected_metadata_sequence_[4] = &vorbiscomment_; + num_expected_ = 5; + + if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) + return die_("creating the encoded file"); + + return true; +} + + +class DecoderCommon { +public: + FILE *file_; + unsigned current_metadata_number_; + bool ignore_errors_; + bool error_occurred_; + + DecoderCommon(): file_(0), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { } + ::FLAC__StreamDecoderReadStatus common_read_callback_(FLAC__byte buffer[], unsigned *bytes); + ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame); + void common_metadata_callback_(const ::FLAC__StreamMetaData *metadata); + void common_error_callback_(::FLAC__StreamDecoderErrorStatus status); +}; + +::FLAC__StreamDecoderReadStatus DecoderCommon::common_read_callback_(FLAC__byte buffer[], unsigned *bytes) +{ + if(error_occurred_) + return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; + + if(feof(file_)) + return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + else if(*bytes > 0) { + unsigned bytes_read = ::fread(buffer, 1, *bytes, file_); + if(bytes_read == 0) { + if(feof(file_)) + return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; + else + return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + else { + *bytes = bytes_read; + return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + } + } + else + return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ +} + +::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame) +{ + if(error_occurred_) + return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + + 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 DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetaData *metadata) +{ + if(error_occurred_) + return; + + printf("%d... ", current_metadata_number_); + fflush(stdout); + + if(current_metadata_number_ >= num_expected_) { + (void)die_("got more metadata blocks than expected"); + error_occurred_ = true; + } + else { + if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) { + (void)die_("metadata block mismatch"); + error_occurred_ = true; + } + } + current_metadata_number_++; +} + +void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status) +{ + if(!ignore_errors_) { + printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]); + error_occurred_ = true; + } +} + +class StreamDecoder : public FLAC::Decoder::Stream, public DecoderCommon { +public: + StreamDecoder(): FLAC::Decoder::Stream(), DecoderCommon() { } + ~StreamDecoder() { } + + // from FLAC::Decoder::Stream + ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes); + ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); + void metadata_callback(const ::FLAC__StreamMetaData *metadata); + void error_callback(::FLAC__StreamDecoderErrorStatus status); + + bool die(const char *msg = 0) const; + + bool test_respond(); +}; + +::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes) +{ + return common_read_callback_(buffer, bytes); +} + +::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) +{ + (void)buffer; + + return common_write_callback_(frame); +} + +void StreamDecoder::metadata_callback(const ::FLAC__StreamMetaData *metadata) +{ + return common_metadata_callback_(metadata); +} + +void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status) +{ + return common_error_callback_(status); +} + +bool StreamDecoder::die(const char *msg) const +{ + State state = get_state(); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); + else + printf("FAILED, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); + + return false; +} + +bool StreamDecoder::test_respond() +{ + printf("testing init()... "); + if(init() != ::FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) + return die(); + printf("OK\n"); + + current_metadata_number_ = 0; + + if(::fseek(file_, 0, SEEK_SET) < 0) { + printf("FAILED rewinding input, errno = %d\n", errno); + return false; + } + + printf("testing process_whole_stream()... "); + if(!process_whole_stream()) { + State state = get_state(); + printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); + return false; + } + printf("OK\n"); + + printf("testing finish()... "); + finish(); + printf("OK\n"); + + return true; +} + +static bool test_stream_decoder() +{ + StreamDecoder *decoder; + + printf("\n+++ unit test: FLAC::Decoder::Stream\n\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + + printf("allocating decoder instance... "); + decoder = new StreamDecoder(); + if(0 == decoder) { + printf("FAILED, new returned NULL\n"); + return false; + } + printf("OK\n"); + + printf("testing is_valid()... "); + if(!decoder->is_valid()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing init()... "); + if(decoder->init() != ::FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) + return decoder->die(); + printf("OK\n"); + + printf("testing get_state()... "); + FLAC::Decoder::Stream::State state = decoder->get_state(); + printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); + + decoder->current_metadata_number_ = 0; + decoder->ignore_errors_ = false; + decoder->error_occurred_ = false; + + printf("opening FLAC file... "); + decoder->file_ = ::fopen(flacfilename_, "rb"); + if(0 == decoder->file_) { + printf("ERROR\n"); + return false; + } + printf("OK\n"); + + printf("testing process_metadata()... "); + if(!decoder->process_metadata()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing process_one_frame()... "); + if(!decoder->process_one_frame()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing flush()... "); + if(!decoder->flush()) + return decoder->die("returned false"); + printf("OK\n"); + + decoder->ignore_errors_ = true; + printf("testing process_one_frame()... "); + if(!decoder->process_one_frame()) + return decoder->die("returned false"); + printf("OK\n"); + decoder->ignore_errors_ = false; + + printf("testing process_remaining_frames()... "); + if(!decoder->process_remaining_frames()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing get_channels()... "); + { + unsigned channels = decoder->get_channels(); + if(channels != streaminfo_.data.stream_info.channels) { + printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); + return false; + } + } + printf("OK\n"); + + printf("testing get_bits_per_sample()... "); + { + unsigned bits_per_sample = decoder->get_bits_per_sample(); + if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { + printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); + return false; + } + } + printf("OK\n"); + + printf("testing get_sample_rate()... "); + { + unsigned sample_rate = decoder->get_sample_rate(); + if(sample_rate != streaminfo_.data.stream_info.sample_rate) { + printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); + return false; + } + } + printf("OK\n"); + + printf("testing get_blocksize()... "); + { + unsigned blocksize = decoder->get_blocksize(); + /* value could be anything since we're at the last block, so accept any answer */ + printf("returned %u... OK\n", blocksize); + } + + printf("testing get_channel_assignment()... "); + { + ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment(); + printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]); + } + + printf("testing reset()... "); + if(!decoder->reset()) + return decoder->die("returned false"); + printf("OK\n"); + + decoder->current_metadata_number_ = 0; + + printf("rewinding input... "); + if(::fseek(decoder->file_, 0, SEEK_SET) < 0) { + printf("FAILED, errno = %d\n", errno); + return false; + } + printf("OK\n"); + + printf("testing process_whole_stream()... "); + if(!decoder->process_whole_stream()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing finish()... "); + decoder->finish(); + printf("OK\n"); + + /* + * respond all + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore VORBIS_COMMENT + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(VORBIS_COMMENT)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(APPLICATION)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION id of app#1 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION id of app#1 & app#2 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #2)... "); + if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond VORBIS_COMMENT + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(VORBIS_COMMENT)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(APPLICATION)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION id of app#1 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION id of app#1 & app#2 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #2)... "); + if(!decoder->set_metadata_respond_application(application2_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION, respond APPLICATION id of app#1 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(APPLICATION)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(APPLICATION)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* done, now leave the sequence the way we found it... */ + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + ::fclose(decoder->file_); + + printf("freeing decoder instance... "); + delete decoder; + printf("OK\n"); + + printf("\nPASSED!\n"); + + return true; +} + +class SeekableStreamDecoder : public FLAC::Decoder::SeekableStream, public DecoderCommon { +public: + SeekableStreamDecoder(): FLAC::Decoder::SeekableStream(), DecoderCommon() { } + ~SeekableStreamDecoder() { } + + // from FLAC::Decoder::SeekableStream + ::FLAC__SeekableStreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes); + ::FLAC__SeekableStreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); + ::FLAC__SeekableStreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); + ::FLAC__SeekableStreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length); + bool eof_callback(); + ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); + void metadata_callback(const ::FLAC__StreamMetaData *metadata); + void error_callback(::FLAC__StreamDecoderErrorStatus status); + + bool die(const char *msg = 0) const; + + bool test_respond(); +}; + +::FLAC__SeekableStreamDecoderReadStatus SeekableStreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes) +{ + switch(common_read_callback_(buffer, bytes)) { + case ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE: + return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; + case ::FLAC__STREAM_DECODER_READ_STATUS_ABORT: + case ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM: + return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; + default: + FLAC__ASSERT(0); + return ::FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; + } +} + +::FLAC__SeekableStreamDecoderSeekStatus SeekableStreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset) +{ + if(error_occurred_) + return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; + + if(::fseek(file_, absolute_byte_offset, SEEK_SET) < 0) { + error_occurred_ = true; + return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; + } + + return ::FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; +} + +::FLAC__SeekableStreamDecoderTellStatus SeekableStreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset) +{ + if(error_occurred_) + return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR; + + long offset = ::ftell(file_); + *absolute_byte_offset = (FLAC__uint64)offset; + + if(offset < 0) { + error_occurred_ = true; + return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR; + } + + return ::FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; +} + +::FLAC__SeekableStreamDecoderLengthStatus SeekableStreamDecoder::length_callback(FLAC__uint64 *stream_length) +{ + if(error_occurred_) + return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR; + + *stream_length = (FLAC__uint64)flacfilesize_; + return ::FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; +} + +bool SeekableStreamDecoder::eof_callback() +{ + if(error_occurred_) + return true; + + return feof(file_); +} + +::FLAC__StreamDecoderWriteStatus SeekableStreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) +{ + (void)buffer; + + return common_write_callback_(frame); +} + +void SeekableStreamDecoder::metadata_callback(const ::FLAC__StreamMetaData *metadata) +{ + common_metadata_callback_(metadata); +} + +void SeekableStreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status) +{ + common_error_callback_(status); +} + +bool SeekableStreamDecoder::die(const char *msg) const +{ + State state = get_state(); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring()); + else + printf("FAILED, state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring()); + + return false; +} + +bool SeekableStreamDecoder::test_respond() +{ + if(!set_md5_checking(true)) { + printf("FAILED at set_md5_checking(), returned false\n"); + return false; + } + + printf("testing init()... "); + if(init() != ::FLAC__SEEKABLE_STREAM_DECODER_OK) + return die(); + printf("OK\n"); + + current_metadata_number_ = 0; + + if(::fseek(file_, 0, SEEK_SET) < 0) { + printf("FAILED rewinding input, errno = %d\n", errno); + return false; + } + + printf("testing process_whole_stream()... "); + if(!process_whole_stream()) { + State state = get_state(); + printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring()); + return false; + } + printf("OK\n"); + + printf("testing finish()... "); + finish(); + printf("OK\n"); + + return true; +} + +static bool test_seekable_stream_decoder() +{ + SeekableStreamDecoder *decoder; + + printf("\n+++ unit test: FLAC::Decoder::SeekableStream\n\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + + printf("allocating decoder instance... "); + decoder = new SeekableStreamDecoder(); + if(0 == decoder) { + printf("FAILED, new returned NULL\n"); + return false; + } + printf("OK\n"); + + printf("testing is_valid()... "); + if(!decoder->is_valid()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_md5_checking()... "); + if(!decoder->set_md5_checking(true)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing init()... "); + if(decoder->init() != ::FLAC__SEEKABLE_STREAM_DECODER_OK) + return decoder->die(); + printf("OK\n"); + + printf("testing get_state()... "); + FLAC::Decoder::SeekableStream::State state = decoder->get_state(); + printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__SeekableStreamDecoderState)state), state.as_cstring()); + + decoder->current_metadata_number_ = 0; + decoder->ignore_errors_ = false; + decoder->error_occurred_ = false; + + printf("opening FLAC file... "); + decoder->file_ = ::fopen(flacfilename_, "rb"); + if(0 == decoder->file_) { + printf("ERROR\n"); + return false; + } + printf("OK\n"); + + printf("testing get_md5_checking()... "); + if(!decoder->get_md5_checking()) { + printf("FAILED, returned false, expected true\n"); + return false; + } + printf("OK\n"); + + printf("testing process_metadata()... "); + if(!decoder->process_metadata()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing process_one_frame()... "); + if(!decoder->process_one_frame()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing flush()... "); + if(!decoder->flush()) + return decoder->die("returned false"); + printf("OK\n"); + + decoder->ignore_errors_ = true; + printf("testing process_one_frame()... "); + if(!decoder->process_one_frame()) + return decoder->die("returned false"); + printf("OK\n"); + decoder->ignore_errors_ = false; + + printf("testing seek_absolute()... "); + if(!decoder->seek_absolute(0)) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing process_remaining_frames()... "); + if(!decoder->process_remaining_frames()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing get_channels()... "); + { + unsigned channels = decoder->get_channels(); + if(channels != streaminfo_.data.stream_info.channels) { + printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); + return false; + } + } + printf("OK\n"); + + printf("testing get_bits_per_sample()... "); + { + unsigned bits_per_sample = decoder->get_bits_per_sample(); + if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { + printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); + return false; + } + } + printf("OK\n"); + + printf("testing get_sample_rate()... "); + { + unsigned sample_rate = decoder->get_sample_rate(); + if(sample_rate != streaminfo_.data.stream_info.sample_rate) { + printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); + return false; + } + } + printf("OK\n"); + + printf("testing get_blocksize()... "); + { + unsigned blocksize = decoder->get_blocksize(); + /* value could be anything since we're at the last block, so accept any answer */ + printf("returned %u... OK\n", blocksize); + } + + printf("testing get_channel_assignment()... "); + { + ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment(); + printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]); + } + + printf("testing reset()... "); + if(!decoder->reset()) + return decoder->die("returned false"); + printf("OK\n"); + + decoder->current_metadata_number_ = 0; + + printf("rewinding input... "); + if(::fseek(decoder->file_, 0, SEEK_SET) < 0) { + printf("FAILED, errno = %d\n", errno); + return false; + } + printf("OK\n"); + + printf("testing process_whole_stream()... "); + if(!decoder->process_whole_stream()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing finish()... "); + decoder->finish(); + printf("OK\n"); + + /* + * respond all + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore VORBIS_COMMENT + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(VORBIS_COMMENT)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(APPLICATION)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION id of app#1 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION id of app#1 & app#2 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #2)... "); + if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond VORBIS_COMMENT + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(VORBIS_COMMENT)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(APPLICATION)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION id of app#1 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION id of app#1 & app#2 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #2)... "); + if(!decoder->set_metadata_respond_application(application2_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION, respond APPLICATION id of app#1 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(APPLICATION)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(APPLICATION)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* done, now leave the sequence the way we found it... */ + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + ::fclose(decoder->file_); + + printf("freeing decoder instance... "); + delete decoder; + printf("OK\n"); + + printf("\nPASSED!\n"); + + return true; +} + +class FileDecoder : public FLAC::Decoder::File, public DecoderCommon { +public: + FileDecoder(): FLAC::Decoder::File(), DecoderCommon() { } + ~FileDecoder() { } + + // from FLAC::Decoder::File + ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); + void metadata_callback(const ::FLAC__StreamMetaData *metadata); + void error_callback(::FLAC__StreamDecoderErrorStatus status); + + bool die(const char *msg = 0) const; + + bool test_respond(); +}; + +::FLAC__StreamDecoderWriteStatus FileDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) +{ + (void)buffer; + return common_write_callback_(frame); +} + +void FileDecoder::metadata_callback(const ::FLAC__StreamMetaData *metadata) +{ + common_metadata_callback_(metadata); +} + +void FileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status) +{ + common_error_callback_(status); +} + +bool FileDecoder::die(const char *msg) const +{ + State state = get_state(); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring()); + else + printf("FAILED, state = %u (%s)\n", (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring()); + + return false; +} + +bool FileDecoder::test_respond() +{ + if(!set_filename(flacfilename_)) { + printf("FAILED at set_filename(), returned false\n"); + return false; + } + + if(!set_md5_checking(true)) { + printf("FAILED at set_md5_checking(), returned false\n"); + return false; + } + + printf("testing init()... "); + if(init() != ::FLAC__FILE_DECODER_OK) + return die(); + printf("OK\n"); + + current_metadata_number_ = 0; + + printf("testing process_whole_file()... "); + if(!process_whole_file()) { + State state = get_state(); + printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring()); + return false; + } + printf("OK\n"); + + printf("testing finish()... "); + finish(); + printf("OK\n"); + + return true; +} + +static bool test_file_decoder() +{ + FileDecoder *decoder; + + printf("\n+++ unit test: FLAC::Decoder::File\n\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + + printf("allocating decoder instance... "); + decoder = new FileDecoder(); + if(0 == decoder) { + printf("FAILED, new returned NULL\n"); + return false; + } + printf("OK\n"); + + printf("testing is_valid()... "); + if(!decoder->is_valid()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_filename()... "); + if(!decoder->set_filename(flacfilename_)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_md5_checking()... "); + if(!decoder->set_md5_checking(true)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing init()... "); + if(decoder->init() != ::FLAC__FILE_DECODER_OK) + return decoder->die(); + printf("OK\n"); + + printf("testing get_state()... "); + FLAC::Decoder::File::State state = decoder->get_state(); + printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__FileDecoderState)state), state.as_cstring()); + + decoder->current_metadata_number_ = 0; + decoder->ignore_errors_ = false; + decoder->error_occurred_ = false; + + printf("testing get_md5_checking()... "); + if(!decoder->get_md5_checking()) { + printf("FAILED, returned false, expected true\n"); + return false; + } + printf("OK\n"); + + printf("testing process_metadata()... "); + if(!decoder->process_metadata()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing process_one_frame()... "); + if(!decoder->process_one_frame()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing seek_absolute()... "); + if(!decoder->seek_absolute(0)) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing process_remaining_frames()... "); + if(!decoder->process_remaining_frames()) + return decoder->die("returned false"); + printf("OK\n"); + + printf("testing get_channels()... "); + { + unsigned channels = decoder->get_channels(); + if(channels != streaminfo_.data.stream_info.channels) { + printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); + return false; + } + } + printf("OK\n"); + + printf("testing get_bits_per_sample()... "); + { + unsigned bits_per_sample = decoder->get_bits_per_sample(); + if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { + printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); + return false; + } + } + printf("OK\n"); + + printf("testing get_sample_rate()... "); + { + unsigned sample_rate = decoder->get_sample_rate(); + if(sample_rate != streaminfo_.data.stream_info.sample_rate) { + printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); + return false; + } + } + printf("OK\n"); + + printf("testing get_blocksize()... "); + { + unsigned blocksize = decoder->get_blocksize(); + /* value could be anything since we're at the last block, so accept any answer */ + printf("returned %u... OK\n", blocksize); + } + + printf("testing get_channel_assignment()... "); + { + ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment(); + printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]); + } + + printf("testing finish()... "); + decoder->finish(); + printf("OK\n"); + + /* + * respond all + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore VORBIS_COMMENT + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(VORBIS_COMMENT)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(APPLICATION)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION id of app#1 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION id of app#1 & app#2 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #2)... "); + if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond VORBIS_COMMENT + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(VORBIS_COMMENT)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(APPLICATION)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION id of app#1 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION id of app#1 & app#2 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #2)... "); + if(!decoder->set_metadata_respond_application(application2_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* + * respond all, ignore APPLICATION, respond APPLICATION id of app#1 + */ + + printf("testing set_metadata_respond_all()... "); + if(!decoder->set_metadata_respond_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore(APPLICATION)... "); + if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond_application(of app block #1)... "); + if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + if(!decoder->test_respond()) + return false; + + /* + * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 + */ + + printf("testing set_metadata_ignore_all()... "); + if(!decoder->set_metadata_ignore_all()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_respond(APPLICATION)... "); + if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_metadata_ignore_application(of app block #1)... "); + if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &application2_; + + if(!decoder->test_respond()) + return false; + + /* done, now leave the sequence the way we found it... */ + num_expected_ = 0; + expected_metadata_sequence_[num_expected_++] = &streaminfo_; + expected_metadata_sequence_[num_expected_++] = &padding_; + expected_metadata_sequence_[num_expected_++] = &seektable_; + expected_metadata_sequence_[num_expected_++] = &application1_; + expected_metadata_sequence_[num_expected_++] = &application2_; + expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; + + printf("freeing decoder instance... "); + delete decoder; + printf("OK\n"); + + printf("\nPASSED!\n"); + + return true; +} + +bool test_decoders() +{ + init_metadata_blocks_(); + if(!generate_file_()) + return false; + + if(!test_stream_decoder()) + return false; + + if(!test_seekable_stream_decoder()) + return false; + + if(!test_file_decoder()) + return false; + + (void) file_utils__remove_file(flacfilename_); + free_metadata_blocks_(); + + return true; +} diff --git a/src/test_libFLAC++/decoders.h b/src/test_libFLAC++/decoders.h new file mode 100644 index 0000000..a4f7ead --- /dev/null +++ b/src/test_libFLAC++/decoders.h @@ -0,0 +1,24 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__TEST_LIBFLACPP_DECODERS_H +#define FLAC__TEST_LIBFLACPP_DECODERS_H + +bool test_decoders(); + +#endif diff --git a/src/test_libFLAC++/encoders.cc b/src/test_libFLAC++/encoders.cc new file mode 100644 index 0000000..820a5f4 --- /dev/null +++ b/src/test_libFLAC++/encoders.cc @@ -0,0 +1,414 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "encoders.h" +extern "C" { +#include "file_utils.h" +} +#include "FLAC/assert.h" +#include "FLAC++/encoder.h" +#include +#include +#include + +static ::FLAC__StreamMetaData streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; +static ::FLAC__StreamMetaData *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ }; +static const unsigned num_metadata_ = 5; + +static void *malloc_or_die_(size_t size) +{ + void *x = malloc(size); + if(0 == x) { + fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size); + exit(1); + } + return x; +} + +static void init_metadata_blocks_() +{ + /* + most of the actual numbers and data in the blocks don't matter, + we just want to make sure the encoder encodes them correctly + + remember, the metadata interface gets tested after the encoders, + so we do all the metadata manipulation here without it. + */ + + /* min/max_framesize and md5sum don't get written at first, so we have to leave them 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); + + padding_.is_last = false; + padding_.type = ::FLAC__METADATA_TYPE_PADDING; + padding_.length = 1234; + + seektable_.is_last = false; + seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE; + seektable_.data.seek_table.num_points = 2; + seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + seektable_.data.seek_table.points = (::FLAC__StreamMetaData_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetaData_SeekPoint)); + seektable_.data.seek_table.points[0].sample_number = 0; + seektable_.data.seek_table.points[0].stream_offset = 0; + seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize; + seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + seektable_.data.seek_table.points[1].stream_offset = 1000; + seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize; + + application1_.is_last = false; + application1_.type = ::FLAC__METADATA_TYPE_APPLICATION; + application1_.length = 8; + memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4); + application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4); + memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4); + + application2_.is_last = false; + application2_.type = ::FLAC__METADATA_TYPE_APPLICATION; + application2_.length = 4; + memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4); + application2_.data.application.data = 0; + + vorbiscomment_.is_last = true; + vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT; + vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0); + vorbiscomment_.data.vorbis_comment.vendor_string.length = 8; + vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8); + memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8); + vorbiscomment_.data.vorbis_comment.num_comments = 2; + vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetaData_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetaData_VorbisComment_Entry)); + vorbiscomment_.data.vorbis_comment.comments[0].length = 5; + vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5); + memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5); + vorbiscomment_.data.vorbis_comment.comments[1].length = 0; + vorbiscomment_.data.vorbis_comment.comments[1].entry = 0; +} + +static void free_metadata_blocks_() +{ + free(seektable_.data.seek_table.points); + free(application1_.data.application.data); + free(vorbiscomment_.data.vorbis_comment.vendor_string.entry); + free(vorbiscomment_.data.vorbis_comment.comments[0].entry); + free(vorbiscomment_.data.vorbis_comment.comments); +} + +class StreamEncoder : public FLAC::Encoder::Stream { +public: + StreamEncoder(): FLAC::Encoder::Stream() { } + ~StreamEncoder() { } + + // from FLAC::Encoder::Stream + ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame); + void metadata_callback(const ::FLAC__StreamMetaData *metadata); + + bool die(const char *msg = 0) const; +}; + +::FLAC__StreamEncoderWriteStatus StreamEncoder::write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame) +{ + (void)buffer, (void)bytes, (void)samples, (void)current_frame; + + return ::FLAC__STREAM_ENCODER_WRITE_OK; +} + +void StreamEncoder::metadata_callback(const ::FLAC__StreamMetaData *metadata) +{ + (void)metadata; +} + +bool StreamEncoder::die(const char *msg) const +{ + State state = get_state(); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring()); + else + printf("FAILED, state = %u (%s)\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring()); + + return false; +} + +static bool test_stream_encoder() +{ + StreamEncoder *encoder; + FLAC__int32 samples[1024]; + FLAC__int32 *samples_array[1] = { samples }; + unsigned i; + + printf("\n+++ unit test: FLAC::Encoder::Stream\n\n"); + + printf("allocating encoder instance... "); + encoder = new StreamEncoder(); + if(0 == encoder) { + printf("FAILED, new returned NULL\n"); + return false; + } + printf("OK\n"); + + printf("testing is_valid()... "); + if(!encoder->is_valid()) { + printf("FAILED, returned false\n"); + return false; + } + printf("OK\n"); + + printf("testing set_streamable_subset()... "); + if(!encoder->set_streamable_subset(true)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_do_mid_side_stereo()... "); + if(!encoder->set_do_mid_side_stereo(false)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_loose_mid_side_stereo()... "); + if(!encoder->set_loose_mid_side_stereo(false)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_channels()... "); + if(!encoder->set_channels(streaminfo_.data.stream_info.channels)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_bits_per_sample()... "); + if(!encoder->set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_sample_rate()... "); + if(!encoder->set_sample_rate(streaminfo_.data.stream_info.sample_rate)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_blocksize()... "); + if(!encoder->set_blocksize(streaminfo_.data.stream_info.min_blocksize)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_max_lpc_order()... "); + if(!encoder->set_max_lpc_order(0)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_qlp_coeff_precision()... "); + if(!encoder->set_qlp_coeff_precision(0)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_do_qlp_coeff_prec_search()... "); + if(!encoder->set_do_qlp_coeff_prec_search(false)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_do_escape_coding()... "); + if(!encoder->set_do_escape_coding(false)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_do_exhaustive_model_search()... "); + if(!encoder->set_do_exhaustive_model_search(false)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_min_residual_partition_order()... "); + if(!encoder->set_min_residual_partition_order(0)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_max_residual_partition_order()... "); + if(!encoder->set_max_residual_partition_order(0)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_rice_parameter_search_dist()... "); + if(!encoder->set_rice_parameter_search_dist(0)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_total_samples_estimate()... "); + if(!encoder->set_total_samples_estimate(streaminfo_.data.stream_info.total_samples)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing set_metadata()... "); + if(!encoder->set_metadata(metadata_sequence_, num_metadata_)) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing init()... "); + if(encoder->init() != ::FLAC__STREAM_ENCODER_OK) + return encoder->die(); + printf("OK\n"); + + printf("testing get_state()... "); + FLAC::Encoder::Stream::State state = encoder->get_state(); + printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring()); + + printf("testing get_streamable_subset()... "); + if(encoder->get_streamable_subset() != true) { + printf("FAILED, expected true, got false\n"); + return false; + } + printf("OK\n"); + + printf("testing get_do_mid_side_stereo()... "); + if(encoder->get_do_mid_side_stereo() != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing get_loose_mid_side_stereo()... "); + if(encoder->get_loose_mid_side_stereo() != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing get_channels()... "); + if(encoder->get_channels() != streaminfo_.data.stream_info.channels) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.channels, encoder->get_channels()); + return false; + } + printf("OK\n"); + + printf("testing get_bits_per_sample()... "); + if(encoder->get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.bits_per_sample, encoder->get_bits_per_sample()); + return false; + } + printf("OK\n"); + + printf("testing get_sample_rate()... "); + if(encoder->get_sample_rate() != streaminfo_.data.stream_info.sample_rate) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.sample_rate, encoder->get_sample_rate()); + return false; + } + printf("OK\n"); + + printf("testing get_blocksize()... "); + if(encoder->get_blocksize() != streaminfo_.data.stream_info.min_blocksize) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.min_blocksize, encoder->get_blocksize()); + return false; + } + printf("OK\n"); + + printf("testing get_max_lpc_order()... "); + if(encoder->get_max_lpc_order() != 0) { + printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_lpc_order()); + return false; + } + printf("OK\n"); + + printf("testing get_qlp_coeff_precision()... "); + (void)encoder->get_qlp_coeff_precision(); + /* we asked the encoder to auto select this so we accept anything */ + printf("OK\n"); + + printf("testing get_do_qlp_coeff_prec_search()... "); + if(encoder->get_do_qlp_coeff_prec_search() != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing get_do_escape_coding()... "); + if(encoder->get_do_escape_coding() != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing get_do_exhaustive_model_search()... "); + if(encoder->get_do_exhaustive_model_search() != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing get_min_residual_partition_order()... "); + if(encoder->get_min_residual_partition_order() != 0) { + printf("FAILED, expected %u, got %u\n", 0, encoder->get_min_residual_partition_order()); + return false; + } + printf("OK\n"); + + printf("testing get_max_residual_partition_order()... "); + if(encoder->get_max_residual_partition_order() != 0) { + printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_residual_partition_order()); + return false; + } + printf("OK\n"); + + printf("testing get_rice_parameter_search_dist()... "); + if(encoder->get_rice_parameter_search_dist() != 0) { + printf("FAILED, expected %u, got %u\n", 0, encoder->get_rice_parameter_search_dist()); + return false; + } + printf("OK\n"); + + /* init the dummy sample buffer */ + for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++) + samples[i] = i & 7; + + printf("testing process()... "); + if(!encoder->process(samples_array, sizeof(samples) / sizeof(FLAC__int32))) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing process_interleaved()... "); + if(!encoder->process_interleaved(samples, sizeof(samples) / sizeof(FLAC__int32))) + return encoder->die("returned false"); + printf("OK\n"); + + printf("testing finish()... "); + encoder->finish(); + printf("OK\n"); + + printf("freeing encoder instance... "); + delete encoder; + printf("OK\n"); + + printf("\nPASSED!\n"); + + return true; +} + +bool test_encoders() +{ + init_metadata_blocks_(); + + if(!test_stream_encoder()) + return false; + + free_metadata_blocks_(); + + return true; +} diff --git a/src/test_libFLAC++/encoders.h b/src/test_libFLAC++/encoders.h new file mode 100644 index 0000000..b418bd3 --- /dev/null +++ b/src/test_libFLAC++/encoders.h @@ -0,0 +1,24 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__TEST_LIBFLACPP_ENCODERS_H +#define FLAC__TEST_LIBFLACPP_ENCODERS_H + +bool test_encoders(); + +#endif diff --git a/src/test_libFLAC++/file_utils.c b/src/test_libFLAC++/file_utils.c new file mode 100644 index 0000000..31f8063 --- /dev/null +++ b/src/test_libFLAC++/file_utils.c @@ -0,0 +1,173 @@ +/* test_libFLAC - Unit tester for libFLAC + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "file_utils.h" +#include "FLAC/assert.h" +#include "FLAC/stream_encoder.h" +#include +#include +#if defined _MSC_VER || defined __MINGW32__ +#include /* for chmod(), unlink */ +#endif +#include /* for stat(), chmod() */ +#if defined _WIN32 && !defined __CYGWIN__ +#else +#include /* for unlink() */ +#endif + +#ifdef min +#undef min +#endif +#define min(a,b) ((a)<(b)?(a):(b)) + +typedef struct { + FILE *file; +} encoder_client_struct; + +static FLAC__StreamEncoderWriteStatus encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) +{ + encoder_client_struct *ecd = (encoder_client_struct*)client_data; + + (void)encoder, (void)samples, (void)current_frame; + + if(fwrite(buffer, 1, bytes, ecd->file) != bytes) + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + else + return FLAC__STREAM_ENCODER_WRITE_OK; +} + +static void encoder_metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data) +{ + (void)encoder, (void)metadata, (void)client_data; +} + +FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only) +{ + struct stat stats; + + if(0 == 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; + stats.st_mode |= S_IWGRP; + stats.st_mode |= S_IWOTH; + } +#else + if(read_only) + stats.st_mode &= ~S_IWRITE; + else + stats.st_mode |= S_IWRITE; +#endif + if(0 != chmod(filename, stats.st_mode)) + return false; + } + else + return false; + + return true; +} + +FLAC__bool file_utils__remove_file(const char *filename) +{ + return file_utils__change_stats(filename, /*read_only=*/false) && 0 == unlink(filename); +} + +FLAC__bool file_utils__generate_flacfile(const char *output_filename, unsigned *output_filesize, unsigned length, const FLAC__StreamMetaData *streaminfo, FLAC__StreamMetaData **metadata, unsigned num_metadata) +{ + FLAC__int32 samples[1024]; + FLAC__StreamEncoder *encoder; + 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 = 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_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); + FLAC__stream_encoder_set_write_callback(encoder, encoder_write_callback_); + FLAC__stream_encoder_set_metadata_callback(encoder, encoder_metadata_callback_); + FLAC__stream_encoder_set_client_data(encoder, &encoder_client_data); + + if(FLAC__stream_encoder_init(encoder) != FLAC__STREAM_ENCODER_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; + } + + FLAC__stream_encoder_finish(encoder); + + fclose(encoder_client_data.file); + + FLAC__stream_encoder_delete(encoder); + + if(0 != output_filesize) { + struct stat filestats; + + if(stat(output_filename, &filestats) != 0) + return false; + else + *output_filesize = (unsigned)filestats.st_size; + } + + return true; +} diff --git a/src/test_libFLAC++/file_utils.h b/src/test_libFLAC++/file_utils.h new file mode 100644 index 0000000..5944187 --- /dev/null +++ b/src/test_libFLAC++/file_utils.h @@ -0,0 +1,30 @@ +/* test_libFLAC - Unit tester for libFLAC + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__TEST_LIBFLAC_FILE_UTILS_H +#define FLAC__TEST_LIBFLAC_FILE_UTILS_H + +#include "FLAC/format.h" + +FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only); + +FLAC__bool file_utils__remove_file(const char *filename); + +FLAC__bool file_utils__generate_flacfile(const char *output_filename, unsigned *output_filesize, unsigned length, const FLAC__StreamMetaData *streaminfo, FLAC__StreamMetaData **metadata, unsigned num_metadata); + +#endif diff --git a/src/test_libFLAC++/main.cc b/src/test_libFLAC++/main.cc new file mode 100644 index 0000000..a4db680 --- /dev/null +++ b/src/test_libFLAC++/main.cc @@ -0,0 +1,37 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "decoders.h" +#include "encoders.h" +#include "metadata.h" + +int main(int argc, char *argv[]) +{ + (void)argc, (void)argv; + + if(!test_encoders()) + return 1; + + if(!test_decoders()) + return 1; + + if(!test_metadata()) + return 1; + + return 0; +} diff --git a/src/test_libFLAC++/metadata.cc b/src/test_libFLAC++/metadata.cc new file mode 100644 index 0000000..bf1af0e --- /dev/null +++ b/src/test_libFLAC++/metadata.cc @@ -0,0 +1,36 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "metadata.h" +#include + +extern int test_metadata_object(); +extern int test_metadata_file_manipulation(); + +bool test_metadata() +{ + if(!test_metadata_object()) + return false; + + if(!test_metadata_file_manipulation()) + return false; + + printf("\nPASSED!\n"); + + return true; +} diff --git a/src/test_libFLAC++/metadata.h b/src/test_libFLAC++/metadata.h new file mode 100644 index 0000000..7bb7154 --- /dev/null +++ b/src/test_libFLAC++/metadata.h @@ -0,0 +1,24 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__TEST_LIBFLACPP_METADATA_H +#define FLAC__TEST_LIBFLACPP_METADATA_H + +bool test_metadata(); + +#endif diff --git a/src/test_libFLAC++/metadata_manip.cc b/src/test_libFLAC++/metadata_manip.cc new file mode 100644 index 0000000..bf30290 --- /dev/null +++ b/src/test_libFLAC++/metadata_manip.cc @@ -0,0 +1,1528 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +extern "C" { +#include "file_utils.h" +} +#include "FLAC/assert.h" +#include "FLAC/file_decoder.h" +#include "FLAC/metadata.h" +#include +#include /* for malloc() */ +#include /* for memcpy()/memset() */ + +/****************************************************************************** + The general strategy of these tests (for interface levels 1 and 2) is + to create a dummy FLAC file with a known set of initial metadata + blocks, then keep a mirror locally of what we expect the metadata to be + after each operation. Then testing becomes a simple matter of running + a FLAC__FileDecoder over the dummy file after each operation, comparing + the decoded metadata to what's in our local copy. If there are any + differences in the metadata, or the actual audio data is corrupted, we + will catch it while decoding. +******************************************************************************/ + +typedef struct { + FLAC__bool error_occurred; +} decoder_client_struct; + +typedef struct { + FLAC__StreamMetaData *blocks[64]; + unsigned num_blocks; +} our_metadata_struct; + +static const char *flacfile_ = "metadata.flac"; + +/* our copy of the metadata in flacfile_ */ +static our_metadata_struct our_metadata_; + +/* the current block number that corresponds to the position of the iterator we are testing */ +static unsigned mc_our_block_number_ = 0; + +static FLAC__bool die_(const char *msg) +{ + printf("ERROR: %s\n", msg); + return false; +} + +static FLAC__bool die_c_(const char *msg, FLAC__MetaData_ChainStatus status) +{ + printf("ERROR: %s\n", msg); + printf(" status=%s\n", FLAC__MetaData_ChainStatusString[status]); + return false; +} + +static FLAC__bool die_ss_(const char *msg, FLAC__MetaData_SimpleIterator *siterator) +{ + printf("ERROR: %s\n", msg); + printf(" status=%s\n", FLAC__MetaData_SimpleIteratorStatusString[FLAC__metadata_simple_iterator_status(siterator)]); + return false; +} + +/* functions for working with our metadata copy */ + +static FLAC__bool replace_in_our_metadata_(FLAC__StreamMetaData *block, unsigned position, FLAC__bool copy) +{ + unsigned i; + FLAC__StreamMetaData *obj = block; + FLAC__ASSERT(position < our_metadata_.num_blocks); + if(copy) { + if(0 == (obj = FLAC__metadata_object_copy(block))) + return die_("during FLAC__metadata_object_copy()"); + } + FLAC__metadata_object_delete(our_metadata_.blocks[position]); + our_metadata_.blocks[position] = obj; + + /* set the is_last flags */ + for(i = 0; i < our_metadata_.num_blocks - 1; i++) + our_metadata_.blocks[i]->is_last = false; + our_metadata_.blocks[i]->is_last = true; + + return true; +} + +static FLAC__bool insert_to_our_metadata_(FLAC__StreamMetaData *block, unsigned position, FLAC__bool copy) +{ + unsigned i; + FLAC__StreamMetaData *obj = block; + if(copy) { + if(0 == (obj = FLAC__metadata_object_copy(block))) + return die_("during FLAC__metadata_object_copy()"); + } + if(position > our_metadata_.num_blocks) { + position = our_metadata_.num_blocks; + } + else { + for(i = our_metadata_.num_blocks; i > position; i--) + our_metadata_.blocks[i] = our_metadata_.blocks[i-1]; + } + our_metadata_.blocks[position] = obj; + our_metadata_.num_blocks++; + + /* set the is_last flags */ + for(i = 0; i < our_metadata_.num_blocks - 1; i++) + our_metadata_.blocks[i]->is_last = false; + our_metadata_.blocks[i]->is_last = true; + + return true; +} + +static void delete_from_our_metadata_(unsigned position) +{ + unsigned i; + FLAC__ASSERT(position < our_metadata_.num_blocks); + FLAC__metadata_object_delete(our_metadata_.blocks[position]); + for(i = position; i < our_metadata_.num_blocks - 1; i++) + our_metadata_.blocks[i] = our_metadata_.blocks[i+1]; + our_metadata_.num_blocks--; + + /* set the is_last flags */ + if(our_metadata_.num_blocks > 0) { + for(i = 0; i < our_metadata_.num_blocks - 1; i++) + our_metadata_.blocks[i]->is_last = false; + our_metadata_.blocks[i]->is_last = true; + } +} + +/* function for comparing our metadata to a FLAC__MetaData_Chain */ + +static FLAC__bool compare_chain_(FLAC__MetaData_Chain *chain, unsigned current_position, FLAC__StreamMetaData *current_block) +{ + unsigned i; + FLAC__MetaData_Iterator *iterator; + FLAC__StreamMetaData *block; + FLAC__bool next_ok = true; + + FLAC__ASSERT(0 != chain); + + printf("\tcomparing chain... "); + fflush(stdout); + + if(0 == (iterator = FLAC__metadata_iterator_new())) + return die_("allocating memory for iterator"); + + FLAC__metadata_iterator_init(iterator, chain); + + i = 0; + do { + printf("%u... ", i); + fflush(stdout); + + if(0 == (block = FLAC__metadata_iterator_get_block(iterator))) { + FLAC__metadata_iterator_delete(iterator); + return die_("getting block from iterator"); + } + +#if 0 + if(!compare_block_(our_metadata_.blocks[i], block)) { + FLAC__metadata_iterator_delete(iterator); + return die_("metadata block mismatch"); + } +#endif + + i++; + next_ok = FLAC__metadata_iterator_next(iterator); + } while(i < our_metadata_.num_blocks && next_ok); + + FLAC__metadata_iterator_delete(iterator); + + 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 0 + if(!compare_block_(our_metadata_.blocks[current_position], current_block)) + return die_("metadata block mismatch"); +#endif + } + + printf("PASSED\n"); + + return true; +} + +/* decoder callbacks for checking the file */ + +static FLAC__StreamDecoderWriteStatus decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) +{ + (void)decoder, (void)buffer, (void)client_data; + + 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; +} + +static void decoder_error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) +{ + decoder_client_struct *dcd = (decoder_client_struct*)client_data; + (void)decoder; + + dcd->error_occurred = true; + printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status); +} + +/* this version pays no attention to the metadata */ +static void decoder_metadata_callback_null_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data) +{ + (void)decoder, (void)metadata, (void)client_data; + + printf("%d... ", mc_our_block_number_); + fflush(stdout); + + mc_our_block_number_++; +} + +/* this version is used when we want to compare to our metadata copy */ +static void decoder_metadata_callback_compare_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data) +{ + decoder_client_struct *dcd = (decoder_client_struct*)client_data; + + (void)decoder; + + /* don't bother checking if we've already hit an error */ + if(dcd->error_occurred) + return; + + printf("%d... ", mc_our_block_number_); + fflush(stdout); + + if(mc_our_block_number_ >= our_metadata_.num_blocks) { + (void)die_("got more metadata blocks than expected"); + dcd->error_occurred = true; + } + else { +#if 0 + if(!compare_block_(our_metadata_.blocks[mc_our_block_number_], metadata)) { + (void)die_("metadata block mismatch"); + dcd->error_occurred = true; + } +#endif + } + mc_our_block_number_++; +} + +static FLAC__bool generate_file_() +{ + FLAC__StreamMetaData streaminfo, 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); + + padding.is_last = true; + padding.type = FLAC__METADATA_TYPE_PADDING; + padding.length = 1234; + + metadata[0] = &padding; + + if(!insert_to_our_metadata_(&streaminfo, 0, /*copy=*/true) || !insert_to_our_metadata_(&padding, 1, /*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"); + + return true; +} + +static FLAC__bool test_file_(const char *filename, void (*metadata_callback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetaData *metadata, void *client_data)) +{ + FLAC__FileDecoder *decoder; + decoder_client_struct decoder_client_data; + + FLAC__ASSERT(0 != filename); + FLAC__ASSERT(0 != metadata_callback); + + mc_our_block_number_ = 0; + decoder_client_data.error_occurred = false; + + printf("\ttesting '%s'... ", filename); + fflush(stdout); + + if(0 == (decoder = FLAC__file_decoder_new())) + return die_("couldn't allocate memory"); + + FLAC__file_decoder_set_md5_checking(decoder, true); + FLAC__file_decoder_set_filename(decoder, filename); + FLAC__file_decoder_set_write_callback(decoder, decoder_write_callback_); + FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback); + FLAC__file_decoder_set_error_callback(decoder, decoder_error_callback_); + FLAC__file_decoder_set_client_data(decoder, &decoder_client_data); + FLAC__file_decoder_set_metadata_respond_all(decoder); + if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) { + FLAC__file_decoder_finish(decoder); + FLAC__file_decoder_delete(decoder); + return die_("initializing decoder\n"); + } + if(!FLAC__file_decoder_process_whole_file(decoder)) { + FLAC__file_decoder_finish(decoder); + FLAC__file_decoder_delete(decoder); + return die_("decoding file\n"); + } + + FLAC__file_decoder_finish(decoder); + FLAC__file_decoder_delete(decoder); + + if(decoder_client_data.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 FLAC__bool change_stats_(const char *filename, FLAC__bool read_only) +{ + if(!file_utils__change_stats(filename, read_only)) + return die_("during file_utils__change_stats()"); + + return true; +} + +static FLAC__bool remove_file_(const char *filename) +{ + while(our_metadata_.num_blocks > 0) + delete_from_our_metadata_(0); + + if(!file_utils__remove_file(filename)) + return die_("removing file"); + + return true; +} + +static FLAC__bool test_level_0_() +{ + FLAC__StreamMetaData_StreamInfo streaminfo; + + printf("\n\n++++++ testing level 0 interface\n"); + + if(!generate_file_()) + return false; + + if(!test_file_(flacfile_, decoder_metadata_callback_null_)) + return false; + + 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.channels != 1) + return die_("mismatch in streaminfo.channels"); + if(streaminfo.bits_per_sample != 8) + return die_("mismatch in streaminfo.bits_per_sample"); + if(streaminfo.sample_rate != 44100) + return die_("mismatch in streaminfo.sample_rate"); + if(streaminfo.min_blocksize != 576) + return die_("mismatch in streaminfo.min_blocksize"); + if(streaminfo.max_blocksize != 576) + return die_("mismatch in streaminfo.max_blocksize"); + + if(!remove_file_(flacfile_)) + return false; + + return true; +} + +static FLAC__bool test_level_1_() +{ + FLAC__MetaData_SimpleIterator *siterator; + FLAC__StreamMetaData *block, *app, *padding; + FLAC__byte data[1000]; + unsigned our_current_position = 0; + + 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_, decoder_metadata_callback_null_)) + return false; + + if(0 == (siterator = FLAC__metadata_simple_iterator_new())) + return die_("FLAC__metadata_simple_iterator_new()"); + + if(!FLAC__metadata_simple_iterator_init(siterator, flacfile_, false)) + return die_("ERROR: FLAC__metadata_simple_iterator_init()\n"); + + printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(siterator)); + if(FLAC__metadata_simple_iterator_is_writable(siterator)) + return die_("iterator claims file is writable when it should not be\n"); + + printf("iterate forwards\n"); + + if(FLAC__metadata_simple_iterator_get_block_type(siterator) != FLAC__METADATA_TYPE_STREAMINFO) + return die_("expected STREAMINFO type from FLAC__metadata_simple_iterator_get_block_type()"); + if(0 == (block = FLAC__metadata_simple_iterator_get_block(siterator))) + return die_("getting block 0"); + if(block->type != FLAC__METADATA_TYPE_STREAMINFO) + return die_("expected STREAMINFO type"); + if(block->is_last) + return die_("expected is_last to be false"); + if(block->length != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) + return die_("bad STREAMINFO length"); + /* check to see if some basic data matches (c.f. generate_file_()) */ + if(block->data.stream_info.channels != 1) + return die_("mismatch in channels"); + if(block->data.stream_info.bits_per_sample != 8) + return die_("mismatch in bits_per_sample"); + if(block->data.stream_info.sample_rate != 44100) + return die_("mismatch in sample_rate"); + if(block->data.stream_info.min_blocksize != 576) + return die_("mismatch in min_blocksize"); + if(block->data.stream_info.max_blocksize != 576) + return die_("mismatch in max_blocksize"); + + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("forward iterator ended early"); + our_current_position++; + + if(FLAC__metadata_simple_iterator_get_block_type(siterator) != FLAC__METADATA_TYPE_PADDING) + return die_("expected PADDING type from FLAC__metadata_simple_iterator_get_block_type()"); + if(0 == (block = FLAC__metadata_simple_iterator_get_block(siterator))) + return die_("getting block 1"); + if(block->type != FLAC__METADATA_TYPE_PADDING) + return die_("expected PADDING type"); + if(!block->is_last) + return die_("expected is_last to be true"); + /* check to see if some basic data matches (c.f. generate_file_()) */ + if(block->length != 1234) + return die_("bad STREAMINFO length"); + + if(FLAC__metadata_simple_iterator_next(siterator)) + return die_("forward iterator returned true but should have returned false"); + + printf("iterate backwards\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("reverse iterator ended early"); + if(FLAC__metadata_simple_iterator_prev(siterator)) + return die_("reverse iterator returned true but should have returned false"); + + printf("testing FLAC__metadata_simple_iterator_set_block() on read-only file...\n"); + + if(!FLAC__metadata_simple_iterator_set_block(siterator, (::FLAC__StreamMetaData*)99, false)) + printf("PASSED. FLAC__metadata_simple_iterator_set_block() returned false like it should\n"); + else + return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have"); + + FLAC__metadata_simple_iterator_delete(siterator); + + /************************************************************/ + + printf("simple iterator on writable file\n"); + + if(!change_stats_(flacfile_, /*read-only=*/false)) + return false; + + printf("creating APPLICATION block\n"); + + if(0 == (app = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION))) + return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)"); + memcpy(app->data.application.id, "duh", (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); + + printf("creating PADDING block\n"); + + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) + return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)"); + padding->length = 20; + + if(0 == (siterator = FLAC__metadata_simple_iterator_new())) + return die_("FLAC__metadata_simple_iterator_new()"); + + if(!FLAC__metadata_simple_iterator_init(siterator, flacfile_, /*preserve_file_stats=*/false)) + return die_("ERROR: FLAC__metadata_simple_iterator_init()\n"); + our_current_position = 0; + + printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(siterator)); + + printf("[S]P\ttry to write over STREAMINFO block...\n"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, false)) + printf("\tFLAC__metadata_simple_iterator_set_block() returned false like it should\n"); + else + return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have"); + + printf("[S]P\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]\tinsert PADDING after, don't expand into padding\n"); + padding->length = 25; + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)", siterator); + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return false; + + printf("SP[P]\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("S[P]P\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("[S]PP\tinsert PADDING after, don't expand into padding\n"); + padding->length = 30; + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)", siterator); + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return false; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[P]PP\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("[S]PPP\tdelete (STREAMINFO block), must fail\n"); + if(FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false) should have returned false", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]PPP\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]PP\tdelete (middle block), replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, true)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, true)", siterator); + our_current_position--; + + printf("[S]PPP\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]PP\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]PP\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]P\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SP[P]\tdelete (last block), replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, true)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + our_current_position--; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[P]P\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SP[P]\tdelete (last block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[P]\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("[S]P\tset STREAMINFO (change sample rate)\n"); + FLAC__ASSERT(our_current_position == 0); + block = FLAC__metadata_simple_iterator_get_block(siterator); + block->data.stream_info.sample_rate = 32000; + if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, block, false)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, block, false)", siterator); + FLAC__metadata_object_delete(block); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]P\tinsert APPLICATION after, expand into padding of exceeding size\n"); + app->data.application.id[0] = 'e'; /* twiddle the id so that our comparison doesn't miss transposition */ + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)", siterator); + if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true)) + return false; + our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SA[P]\tset APPLICATION, expand into padding of exceeding size\n"); + app->data.application.id[0] = 'f'; /* twiddle the id */ + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + if(!insert_to_our_metadata_(app, our_current_position, /*copy=*/true)) + return false; + our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SA[A]P\tset APPLICATION (grow), don't expand into padding\n"); + app->data.application.id[0] = 'g'; /* twiddle the id */ + if(!FLAC__metadata_object_application_set_data(app, data, sizeof(data), true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, false)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, false)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SA[A]P\tset APPLICATION (shrink), don't fill in with padding\n"); + app->data.application.id[0] = 'h'; /* twiddle the id */ + if(!FLAC__metadata_object_application_set_data(app, data, 12, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, false)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, false)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SA[A]P\tset APPLICATION (grow), expand into padding of exceeding size\n"); + app->data.application.id[0] = 'i'; /* twiddle the id */ + if(!FLAC__metadata_object_application_set_data(app, data, sizeof(data), true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + our_metadata_.blocks[our_current_position+1]->length -= (sizeof(data) - 12); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SA[A]P\tset APPLICATION (shrink), fill in with padding\n"); + app->data.application.id[0] = 'j'; /* twiddle the id */ + if(!FLAC__metadata_object_application_set_data(app, data, 23, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!insert_to_our_metadata_(padding, our_current_position+1, /*copy=*/true)) + return die_("copying object"); + our_metadata_.blocks[our_current_position+1]->length = sizeof(data) - 23 - FLAC__STREAM_METADATA_HEADER_LENGTH; + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SA[A]PP\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SAA[P]P\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SAAP[P]\tset PADDING (shrink), don't fill in with padding\n"); + padding->length = 5; + if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, padding, false)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SAAP[P]\tset APPLICATION (grow)\n"); + app->data.application.id[0] = 'k'; /* twiddle the id */ + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, false)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, false)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SAAP[A]\tset PADDING (equal)\n"); + padding->length = 27; + if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, padding, false)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SAAP[P]\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("SAA[P]P\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SA[A]P\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SA[P]\tinsert PADDING after\n"); + padding->length = 5; + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)", siterator); + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return false; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SAP[P]\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("SA[P]P\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("S[A]PP\tset APPLICATION (grow), try to expand into padding which is too small\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 32, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PP\tset APPLICATION (grow), try to expand into padding which is 'close' but still too small\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 60, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PP\tset APPLICATION (grow), expand into padding which will leave 0-length pad\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 87, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + our_metadata_.blocks[our_current_position+1]->length = 0; + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PP\tset APPLICATION (grow), expand into padding which is exactly consumed\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 91, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + delete_from_our_metadata_(our_current_position+1); + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tset APPLICATION (grow), expand into padding which is exactly consumed\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 100, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + delete_from_our_metadata_(our_current_position+1); + our_metadata_.blocks[our_current_position]->is_last = true; + if(!FLAC__metadata_simple_iterator_set_block(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tset PADDING (equal size)\n"); + padding->length = app->length; + if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_set_block(siterator, padding, true)) + return die_ss_("FLAC__metadata_simple_iterator_set_block(siterator, padding, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[P]\tinsert PADDING after\n"); + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)", siterator); + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return false; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SP[P]\tinsert PADDING after\n"); + padding->length = 5; + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, padding, false)", siterator); + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return false; + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SPP[P]\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("SP[P]P\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("S[P]PP\tprev\n"); + if(!FLAC__metadata_simple_iterator_prev(siterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("[S]PPP\tinsert APPLICATION after, try to expand into padding which is too small\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 101, true)) + return die_("setting APPLICATION data"); + if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PPP\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]PPP\tinsert APPLICATION after, try to expand into padding which is 'close' but still too small\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 97, true)) + return die_("setting APPLICATION data"); + if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PPP\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]PPP\tinsert APPLICATION after, expand into padding which is exactly consumed\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 100, true)) + return die_("setting APPLICATION data"); + if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true)) + return die_("copying object"); + delete_from_our_metadata_(our_current_position+1); + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PP\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]PP\tinsert APPLICATION after, expand into padding which will leave 0-length pad\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 96, true)) + return die_("setting APPLICATION data"); + if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true)) + return die_("copying object"); + our_metadata_.blocks[our_current_position+1]->length = 0; + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]PP\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]PP\tnext\n"); + if(!FLAC__metadata_simple_iterator_next(siterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]P\tdelete (middle block), don't replace with padding\n"); + if(!FLAC__metadata_simple_iterator_delete_block(siterator, false)) + return die_ss_("FLAC__metadata_simple_iterator_delete_block(siterator, false)", siterator); + delete_from_our_metadata_(our_current_position--); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]P\tinsert APPLICATION after, expand into padding which is exactly consumed\n"); + if(!FLAC__metadata_object_application_set_data(app, data, 1, true)) + return die_("setting APPLICATION data"); + if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true)) + return die_("copying object"); + delete_from_our_metadata_(our_current_position+1); + if(!FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)) + return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(siterator, app, true)", siterator); + + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("delete simple iterator\n"); + + FLAC__metadata_simple_iterator_delete(siterator); + + FLAC__metadata_object_delete(app); + FLAC__metadata_object_delete(padding); + + if(!remove_file_(flacfile_)) + return false; + + return true; +} + +static FLAC__bool test_level_2_() +{ + FLAC__MetaData_Iterator *iterator; + FLAC__MetaData_Chain *chain; + FLAC__StreamMetaData *block, *app, *padding; + FLAC__byte data[2000]; + unsigned our_current_position; + + printf("\n\n++++++ testing level 2 interface\n"); + + printf("generate read-only file\n"); + + if(!generate_file_()) + return false; + + if(!change_stats_(flacfile_, /*read_only=*/true)) + return false; + + printf("create chain\n"); + + if(0 == (chain = FLAC__metadata_chain_new())) + return die_("allocating chain"); + + printf("read chain\n"); + + if(!FLAC__metadata_chain_read(chain, flacfile_)) + return die_c_("reading chain", FLAC__metadata_chain_status(chain)); + + printf("[S]P\ttest initial metadata\n"); + + if(!compare_chain_(chain, 0, 0)) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("switch file to read-write\n"); + + if(!change_stats_(flacfile_, /*read-only=*/false)) + return false; + + printf("create iterator\n"); + if(0 == (iterator = FLAC__metadata_iterator_new())) + return die_("allocating memory for iterator"); + + our_current_position = 0; + + FLAC__metadata_iterator_init(iterator, chain); + + if(0 == (block = FLAC__metadata_iterator_get_block(iterator))) + return die_("getting block from iterator"); + + FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_STREAMINFO); + + printf("[S]P\tmodify STREAMINFO, write\n"); + + block->data.stream_info.sample_rate = 32000; + if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true)) + return die_("copying object"); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/true)) + return die_c_("during FLAC__metadata_chain_write(chain, false, true)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("[S]P\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]\treplace PADDING with identical-size APPLICATION\n"); + if(0 == (block = FLAC__metadata_iterator_get_block(iterator))) + return die_("getting block from iterator"); + if(0 == (app = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION))) + return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)"); + memcpy(app->data.application.id, "duh", (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); + if(!FLAC__metadata_object_application_set_data(app, data, block->length-(FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tshrink APPLICATION, don't use padding\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 26, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tgrow APPLICATION, don't use padding\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 28, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tgrow APPLICATION, use padding, but last block is not padding\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 36, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tshrink APPLICATION, use padding, last block is not padding, but delta is too small for new PADDING block\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 33, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tshrink APPLICATION, use padding, last block is not padding, delta is enough for new PADDING block\n"); + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) + return die_("creating PADDING block"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 29, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + padding->length = 0; + if(!insert_to_our_metadata_(padding, our_current_position+1, /*copy=*/false)) + return die_("internal error"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tshrink APPLICATION, use padding, last block is padding\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 16, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + our_metadata_.blocks[our_current_position+1]->length = 13; + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tgrow APPLICATION, use padding, last block is padding, but delta is too small\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 50, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tgrow APPLICATION, use padding, last block is padding of exceeding size\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 56, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + our_metadata_.blocks[our_current_position+1]->length -= (56 - 50); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]P\tgrow APPLICATION, use padding, last block is padding of exact size\n"); + if(0 == (app = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("copying object"); + if(!FLAC__metadata_object_application_set_data(app, data, 67, true)) + return die_("setting APPLICATION data"); + if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true)) + return die_("copying object"); + delete_from_our_metadata_(our_current_position+1); + if(!FLAC__metadata_iterator_set_block(iterator, app)) + return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain)); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S[A]\tprev\n"); + if(!FLAC__metadata_iterator_prev(iterator)) + return die_("iterator ended early\n"); + our_current_position--; + + printf("[S]A\tinsert PADDING before STREAMINFO (should fail)\n"); + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) + return die_("creating PADDING block"); + padding->length = 30; + if(!FLAC__metadata_iterator_insert_block_before(iterator, padding)) + printf("\tFLAC__metadata_iterator_insert_block_before() returned false like it should\n"); + else + return die_("FLAC__metadata_iterator_insert_block_before() should have returned false"); + + printf("[S]A\tinsert PADDING after\n"); + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return die_("copying metadata"); + if(!FLAC__metadata_iterator_insert_block_after(iterator, padding)) + return die_("FLAC__metadata_iterator_insert_block_after(iterator, padding)"); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("S[P]A\tinsert PADDING before\n"); + if(0 == (padding = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("creating PADDING block"); + padding->length = 17; + if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true)) + return die_("copying metadata"); + if(!FLAC__metadata_iterator_insert_block_before(iterator, padding)) + return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)"); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("S[P]PA\tinsert PADDING before\n"); + if(0 == (padding = FLAC__metadata_object_copy(our_metadata_.blocks[our_current_position]))) + return die_("creating PADDING block"); + padding->length = 0; + if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true)) + return die_("copying metadata"); + if(!FLAC__metadata_iterator_insert_block_before(iterator, padding)) + return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)"); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("S[P]PPA\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SP[P]PA\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SPP[P]A\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("SPPP[A]\tinsert PADDING after\n"); + if(0 == (padding = FLAC__metadata_object_copy(our_metadata_.blocks[1]))) + return die_("creating PADDING block"); + padding->length = 57; + if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true)) + return die_("copying metadata"); + if(!FLAC__metadata_iterator_insert_block_after(iterator, padding)) + return die_("FLAC__metadata_iterator_insert_block_after(iterator, padding)"); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("SPPPA[P]\tinsert PADDING before\n"); + if(0 == (padding = FLAC__metadata_object_copy(our_metadata_.blocks[1]))) + return die_("creating PADDING block"); + padding->length = 99; + if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true)) + return die_("copying metadata"); + if(!FLAC__metadata_iterator_insert_block_before(iterator, padding)) + return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)"); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("delete iterator\n"); + FLAC__metadata_iterator_delete(iterator); + our_current_position = 0; + + printf("SPPPAPP\tmerge padding\n"); + FLAC__metadata_chain_merge_padding(chain); + our_metadata_.blocks[1]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->length); + our_metadata_.blocks[1]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[3]->length); + our_metadata_.blocks[5]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[6]->length); + delete_from_our_metadata_(6); + delete_from_our_metadata_(3); + delete_from_our_metadata_(2); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, 0, 0)) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("SPAP\tsort padding\n"); + FLAC__metadata_chain_sort_padding(chain); + our_metadata_.blocks[3]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[1]->length); + delete_from_our_metadata_(1); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/true, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, 0, 0)) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("create iterator\n"); + if(0 == (iterator = FLAC__metadata_iterator_new())) + return die_("allocating memory for iterator"); + + our_current_position = 0; + + FLAC__metadata_iterator_init(iterator, chain); + + printf("[S]AP\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[A]P\tdelete middle block, replace with padding\n"); + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) + return die_("creating PADDING block"); + padding->length = 71; + if(!replace_in_our_metadata_(padding, our_current_position--, /*copy=*/false)) + return die_("copying object"); + if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/true)) + return die_c_("FLAC__metadata_iterator_delete_block(iterator, true)", FLAC__metadata_chain_status(chain)); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("[S]PP\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]P\tdelete middle block, don't replace with padding\n"); + delete_from_our_metadata_(our_current_position--); + if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false)) + return die_c_("FLAC__metadata_iterator_delete_block(iterator, false)", FLAC__metadata_chain_status(chain)); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("[S]P\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]\tdelete last block, replace with padding\n"); + if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) + return die_("creating PADDING block"); + padding->length = 219; + if(!replace_in_our_metadata_(padding, our_current_position--, /*copy=*/false)) + return die_("copying object"); + if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/true)) + return die_c_("FLAC__metadata_iterator_delete_block(iterator, true)", FLAC__metadata_chain_status(chain)); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("[S]P\tnext\n"); + if(!FLAC__metadata_iterator_next(iterator)) + return die_("iterator ended early\n"); + our_current_position++; + + printf("S[P]\tdelete last block, don't replace with padding\n"); + delete_from_our_metadata_(our_current_position--); + if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false)) + return die_c_("FLAC__metadata_iterator_delete_block(iterator, false)", FLAC__metadata_chain_status(chain)); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("[S]\tdelete STREAMINFO block, should fail\n"); + if(FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false)) + return die_("FLAC__metadata_iterator_delete_block() on STREAMINFO should have failed but didn't"); + + if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator))) + return false; + + printf("delete iterator\n"); + FLAC__metadata_iterator_delete(iterator); + our_current_position = 0; + + printf("S\tmerge padding\n"); + FLAC__metadata_chain_merge_padding(chain); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, 0, 0)) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("S\tsort padding\n"); + FLAC__metadata_chain_sort_padding(chain); + + if(!FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false)) + return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain)); + if(!compare_chain_(chain, 0, 0)) + return false; + if(!test_file_(flacfile_, decoder_metadata_callback_compare_)) + return false; + + printf("delete chain\n"); + + FLAC__metadata_chain_delete(chain); + + if(!remove_file_(flacfile_)) + return false; + + return true; +} + +bool test_metadata_file_manipulation() +{ + printf("\n+++ unit test: metadata manipulation\n\n"); + + our_metadata_.num_blocks = 0; + + if(!test_level_0_()) + return false; + + if(!test_level_1_()) + return false; + + if(!test_level_2_()) + return false; + + return true; +} diff --git a/src/test_libFLAC++/metadata_object.cc b/src/test_libFLAC++/metadata_object.cc new file mode 100644 index 0000000..6ce385f --- /dev/null +++ b/src/test_libFLAC++/metadata_object.cc @@ -0,0 +1,379 @@ +/* test_libFLAC++ - Unit tester for libFLAC++ + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "FLAC/assert.h" +#include "FLAC++/metadata.h" +#include +#include /* for malloc() */ +#include /* for memcmp() */ + +static ::FLAC__StreamMetaData streaminfo_, padding_, seektable_, application_, vorbiscomment_; + +static void *malloc_or_die_(size_t size) +{ + void *x = malloc(size); + if(0 == x) { + fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size); + exit(1); + } + return x; +} + +static void init_metadata_blocks_() +{ + 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); + + padding_.is_last = false; + padding_.type = ::FLAC__METADATA_TYPE_PADDING; + padding_.length = 1234; + + seektable_.is_last = false; + seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE; + seektable_.data.seek_table.num_points = 2; + seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + seektable_.data.seek_table.points = (::FLAC__StreamMetaData_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetaData_SeekPoint)); + seektable_.data.seek_table.points[0].sample_number = 0; + seektable_.data.seek_table.points[0].stream_offset = 0; + seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize; + seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + seektable_.data.seek_table.points[1].stream_offset = 1000; + seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize; + + application_.is_last = false; + application_.type = ::FLAC__METADATA_TYPE_APPLICATION; + application_.length = 8; + memcpy(application_.data.application.id, "\xfe\xdc\xba\x98", 4); + application_.data.application.data = (FLAC__byte*)malloc_or_die_(4); + memcpy(application_.data.application.data, "\xf0\xe1\xd2\xc3", 4); + + vorbiscomment_.is_last = true; + vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT; + vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0); + vorbiscomment_.data.vorbis_comment.vendor_string.length = 8; + vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8); + memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8); + vorbiscomment_.data.vorbis_comment.num_comments = 2; + vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetaData_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetaData_VorbisComment_Entry)); + vorbiscomment_.data.vorbis_comment.comments[0].length = 5; + vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5); + memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5); + vorbiscomment_.data.vorbis_comment.comments[1].length = 0; + vorbiscomment_.data.vorbis_comment.comments[1].entry = 0; +} + +static void free_metadata_blocks_() +{ + free(seektable_.data.seek_table.points); + free(application_.data.application.data); + free(vorbiscomment_.data.vorbis_comment.vendor_string.entry); + free(vorbiscomment_.data.vorbis_comment.comments[0].entry); + free(vorbiscomment_.data.vorbis_comment.comments); +} + +bool test_metadata_object_streaminfo() +{ + FLAC::Metadata::StreamInfo block; + unsigned expected_length; + + printf("\n+++ unit test: metadata objects (libFLAC++)\n\n"); + + + printf("testing FLAC::Metadata::StreamInfo\n"); + + printf("testing FLAC::Metadata::StreamInfo::StreamInfo()... "); + if(!block.is_valid()) { + printf("FAILED, !block.is_valid()\n"); + return false; + } + expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; + if(block.get_length() != expected_length) { + printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length()); + return false; + } + printf("OK\n"); + + printf("testing FLAC::MetaData::StreamInfo::StreamInfo(const StreamInfo &)... "); + { + FLAC::Metadata::StreamInfo blockcopy(block); + if(blockcopy != block) { + printf("FAILED, copy is not identical to original\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC::Metadata::StreamInfo::~StreamInfo()... "); + } + printf("OK\n"); + + printf("testing FLAC::Metadata::StreamInfo::operator=(const ::FLAC__StreamMetaData &)... "); + { + FLAC::Metadata::StreamInfo blockcopy(streaminfo_, /*copy=*/true); + if(!blockcopy.is_valid()) { + printf("FAILED, !block.is_valid()\n"); + return false; + } + if(blockcopy != streaminfo_) { + printf("FAILED, copy is not identical to original\n"); + return false; + } + } + printf("OK\n"); + + printf("testing FLAC::Metadata::StreamInfo::operator=(const ::FLAC__StreamMetaData *)... "); + { + FLAC::Metadata::StreamInfo blockcopy(&streaminfo_, /*copy=*/true); + if(!blockcopy.is_valid()) { + printf("FAILED, !block.is_valid()\n"); + return false; + } + if(blockcopy != streaminfo_) { + printf("FAILED, copy is not identical to original\n"); + return false; + } + } + printf("OK\n"); + + printf("testing FLAC::Metadata::StreamInfo::operator=(const StreamInfo &)... "); + { + FLAC::Metadata::StreamInfo blockcopy = block; + if(!blockcopy.is_valid()) { + printf("FAILED, !block.is_valid()\n"); + return false; + } + if(blockcopy != block) { + printf("FAILED, copy is not identical to original\n"); + return false; + } + } + printf("OK\n"); + + return true; +} + +bool test_metadata_object() +{ + init_metadata_blocks_(); + + if(!test_metadata_object_streaminfo()) + return false; + + free_metadata_blocks_(); + + return true; +} + +#if 0 + + + // ============================================================ + // + // Metadata objects + // + // ============================================================ + + // NOTE: When the get_*() methods return you a const pointer, + // DO NOT disobey and write into it. Always use the set_*() + // methods. + + // base class for all metadata blocks + class Prototype { + protected: + Prototype(::FLAC__StreamMetaData *object, bool copy); + virtual ~Prototype(); + + void operator=(const Prototype &); + void operator=(const ::FLAC__StreamMetaData &); + void operator=(const ::FLAC__StreamMetaData *); + + inline bool operator==(const FLAC::Metadata::Prototype &block) + { return ::FLAC__metadata_object_is_equal(object_, block.object_); } + + virtual void clear(); + + ::FLAC__StreamMetaData *object_; + public: + friend class SimpleIterator; + friend class Iterator; + + inline bool is_valid() const { return 0 != object_; } + inline operator bool() const { return is_valid(); } + + bool get_is_last() const; + FLAC__MetaDataType get_type() const; + unsigned get_length() const; // NOTE: does not include the header, per spec + private: + Prototype(); // Private and undefined so you can't use it + + // These are used only by Iterator + bool is_reference_; + inline void set_reference(bool x) { is_reference_ = x; } + }; + + class StreamInfo : public Prototype { + public: + unsigned get_min_blocksize() const; + unsigned get_max_blocksize() const; + unsigned get_min_framesize() const; + unsigned get_max_framesize() const; + unsigned get_sample_rate() const; + unsigned get_channels() const; + unsigned get_bits_per_sample() const; + FLAC__uint64 get_total_samples() const; + const FLAC__byte *get_md5sum() const; + + void set_min_blocksize(unsigned value); + void set_max_blocksize(unsigned value); + void set_min_framesize(unsigned value); + void set_max_framesize(unsigned value); + void set_sample_rate(unsigned value); + void set_channels(unsigned value); + void set_bits_per_sample(unsigned value); + void set_total_samples(FLAC__uint64 value); + void set_md5sum(const FLAC__byte value[16]); + }; + + class Padding : public Prototype { + public: + Padding(); + Padding(::FLAC__StreamMetaData *object, bool copy = false); + ~Padding(); + + inline void operator=(const Padding &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + + void set_length(unsigned length); + }; + + class Application : public Prototype { + public: + Application(); + Application(::FLAC__StreamMetaData *object, bool copy = false); + ~Application(); + + inline void operator=(const Application &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + + const FLAC__byte *get_id() const; + const FLAC__byte *get_data() const; + + void set_id(FLAC__byte value[4]); + bool set_data(FLAC__byte *data, unsigned length, bool copy = false); + }; + + class SeekTable : public Prototype { + public: + SeekTable(); + SeekTable(::FLAC__StreamMetaData *object, bool copy = false); + ~SeekTable(); + + inline void operator=(const SeekTable &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + + unsigned get_num_points() const; + ::FLAC__StreamMetaData_SeekPoint get_point(unsigned index) const; + + void set_point(unsigned index, const ::FLAC__StreamMetaData_SeekPoint &point); + bool insert_point(unsigned index, const ::FLAC__StreamMetaData_SeekPoint &point); + bool delete_point(unsigned index); + + bool is_legal() const; + }; + + class VorbisComment : public Prototype { + public: + class Entry { + public: + Entry(); + Entry(const char *field, unsigned field_length); + Entry(const char *field_name, const char *field_value, unsigned field_value_length); + Entry(const Entry &entry); + void operator=(const Entry &entry); + + virtual ~Entry(); + + virtual bool is_valid() const; + inline operator bool() const { return is_valid(); } + + unsigned get_field_length() const; + unsigned get_field_name_length() const; + unsigned get_field_value_length() const; + + ::FLAC__StreamMetaData_VorbisComment_Entry get_entry() const; + const char *get_field() const; + const char *get_field_name() const; + const char *get_field_value() const; + + bool set_field(const char *field, unsigned field_length); + bool set_field_name(const char *field_name); + bool set_field_value(const char *field_value, unsigned field_value_length); + protected: + bool is_valid_; + ::FLAC__StreamMetaData_VorbisComment_Entry entry_; + char *field_name_; + unsigned field_name_length_; + char *field_value_; + unsigned field_value_length_; + private: + void zero(); + void clear(); + void clear_entry(); + void clear_field_name(); + void clear_field_value(); + void construct(const char *field, unsigned field_length); + void construct(const char *field_name, const char *field_value, unsigned field_value_length); + void compose_field(); + void parse_field(); + }; + + VorbisComment(); + VorbisComment(::FLAC__StreamMetaData *object, bool copy = false); + ~VorbisComment(); + + inline void operator=(const VorbisComment &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); } + inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); } + + unsigned get_num_comments() const; + Entry get_vendor_string() const; + Entry get_comment(unsigned index) const; + + bool set_vendor_string(const Entry &entry); + bool set_comment(unsigned index, const Entry &entry); + bool insert_comment(unsigned index, const Entry &entry); + bool delete_comment(unsigned index); + }; + + + + + +#endif diff --git a/src/test_unit/Makefile.am b/src/test_unit/Makefile.am index 3a1217f..1243112 100644 --- a/src/test_unit/Makefile.am +++ b/src/test_unit/Makefile.am @@ -1,4 +1,4 @@ -# test_unit - Simple FLAC unit tester +# test_libFLAC - Unit tester for libFLAC # Copyright (C) 2000,2001,2002 Josh Coalson # # This program is free software; you can redistribute it and/or @@ -18,11 +18,12 @@ CFLAGS = @CFLAGS@ INCLUDES = -I$(top_srcdir)/src/libFLAC/include -noinst_PROGRAMS = test_unit -test_unit_LDADD = $(top_builddir)/src/libFLAC/libFLAC.la -lm -test_unit_SOURCES = \ +noinst_PROGRAMS = test_libFLAC +test_libFLAC = $(top_builddir)/src/libFLAC/libFLAC.la -lm +test_libFLAC_SOURCES = \ bitbuffer.c \ decoders.c \ + encoders.c \ file_utils.c \ main.c \ metadata.c \ @@ -31,6 +32,7 @@ test_unit_SOURCES = \ metadata_utils.c \ bitbuffer.h \ decoders.h \ + encoders.h \ file_utils.h \ metadata.h \ metadata_utils.h diff --git a/src/test_unit/Makefile.lite b/src/test_unit/Makefile.lite index d1b4901..f348b15 100644 --- a/src/test_unit/Makefile.lite +++ b/src/test_unit/Makefile.lite @@ -1,4 +1,4 @@ -# test_unit - Simple FLAC unit tester +# test_libFLAC - Unit tester for libFLAC # Copyright (C) 2000,2001,2002 Josh Coalson # # This program is free software; you can redistribute it and/or @@ -19,12 +19,13 @@ # GNU makefile # -PROGRAM_NAME = test_unit +PROGRAM_NAME = test_libFLAC INCLUDES = -I../libFLAC/include -I../../include LIBS = -lFLAC -lm OBJS = \ bitbuffer.o \ decoders.o \ + encoders.o \ file_utils.o \ main.o \ metadata.o \ diff --git a/src/test_unit/Makefile.vc b/src/test_unit/Makefile.vc index eb0a168..ab6ef53 100644 --- a/src/test_unit/Makefile.vc +++ b/src/test_unit/Makefile.vc @@ -1,4 +1,4 @@ -# test_unit - Simple FLAC unit tester +# test_libFLAC - Unit tester for libFLAC # Copyright (C) 2001,2002 Josh Coalson # # This program is free software; you can redistribute it and/or @@ -28,6 +28,7 @@ C_FILES= \ bitbuffer.c \ decoders.c \ + encoders.c \ file_utils.c \ main.c \ metadata.c \ @@ -37,11 +38,11 @@ C_FILES= \ OBJS= $(C_FILES:.c=.obj) -all: test_unit.exe +all: test_libFLAC.exe -test_unit.exe: $(OBJS) +test_libFLAC.exe: $(OBJS) link.exe /libpath:"..\..\obj\lib" -out:../../obj/bin/$*.exe $(OBJS) libFLAC.lib clean: -del *.obj *.pch - -del ..\..\obj\bin\test_unit.exe + -del ..\..\obj\bin\test_libFLAC.exe diff --git a/src/test_unit/bitbuffer.c b/src/test_unit/bitbuffer.c index 75f8c51..e50da77 100644 --- a/src/test_unit/bitbuffer.c +++ b/src/test_unit/bitbuffer.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2000,2001,2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -47,7 +47,7 @@ static FLAC__bool dummy_read_callback(FLAC__byte buffer[], unsigned *bytes, void return true; } -int test_bitbuffer() +FLAC__bool test_bitbuffer() { FLAC__BitBuffer *bb, *bb_zero, *bb_one, *bbcopy; FLAC__bool ok; @@ -74,13 +74,13 @@ int test_bitbuffer() ok = FLAC__bitbuffer_clear(bb) && FLAC__bitbuffer_clear(bb_zero) && FLAC__bitbuffer_clear(bb_one) && FLAC__bitbuffer_clear(bbcopy); printf("%s\n", ok?"OK":"FAILED"); if(!ok) - return 1; + return false; printf("setting up bb_one... "); ok = FLAC__bitbuffer_write_raw_uint32(bb_one, 1, 7) && FLAC__bitbuffer_read_raw_uint32(bb_one, &i, 6, dummy_read_callback, 0); printf("%s\n", ok?"OK":"FAILED"); if(!ok) - return 1; + return false; FLAC__bitbuffer_dump(bb_one, stdout); printf("capacity = %u\n", bb->capacity); @@ -103,27 +103,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 0) { printf("FAILED bit count %u != 0\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -133,27 +133,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 6) { printf("FAILED bit count %u != 6\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs] != 0x3d) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -163,27 +163,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 6) { printf("FAILED bit count %u != 6\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs] != 0x3d) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -193,27 +193,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 7) { printf("FAILED bit count %u != 7\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs] != 0x7b) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -225,27 +225,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)+1) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)+1); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 0) { printf("FAILED bit count %u != 0\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs-1] != 0xf7) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -257,27 +257,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)+1) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)+1); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 4) { printf("FAILED bit count %u != 4\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs] != 0x08) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -289,27 +289,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)+2) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)+2); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 4) { printf("FAILED bit count %u != 4\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs-1] != 0x8a || bb->buffer[bb->blurbs] != 0x0a) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -320,27 +320,27 @@ int test_bitbuffer() if(!ok) { printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->blurbs != sizeof(test_pattern1)+4) { printf("FAILED byte count %u != %u\n", bb->blurbs, sizeof(test_pattern1)+4); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->bits != 5) { printf("FAILED bit count %u != 5\n", bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(bb->total_bits != 8*bb->blurbs+bb->bits) { printf("FAILED total_bits count %u != %u (%u:%u)\n", bb->total_bits, 8*bb->blurbs+bb->bits, bb->blurbs, bb->bits); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } if(memcmp(bb->buffer, test_pattern1, sizeof(FLAC__byte)*sizeof(test_pattern1)) != 0 || bb->buffer[bb->blurbs-3] != 0x8a || bb->buffer[bb->blurbs-2] != 0xaa || bb->buffer[bb->blurbs-1] != 0xaa || bb->buffer[bb->blurbs] != 0x15) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("OK\n"); FLAC__bitbuffer_dump(bb, stdout); @@ -352,7 +352,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x0000007F)... "); @@ -362,7 +362,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x00000080)... "); @@ -372,7 +372,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x000007FF)... "); @@ -382,7 +382,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x00000800)... "); @@ -392,7 +392,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x0000FFFF)... "); @@ -402,7 +402,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x00010000)... "); @@ -412,7 +412,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x001FFFFF)... "); @@ -422,7 +422,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x00200000)... "); @@ -432,7 +432,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x03FFFFFF)... "); @@ -442,7 +442,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x04000000)... "); @@ -452,7 +452,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint32(0x7FFFFFFF)... "); @@ -462,7 +462,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000000000000)... "); @@ -472,7 +472,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x000000000000007F)... "); @@ -482,7 +482,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000000000080)... "); @@ -492,7 +492,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x00000000000007FF)... "); @@ -502,7 +502,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000000000800)... "); @@ -512,7 +512,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x000000000000FFFF)... "); @@ -522,7 +522,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000000010000)... "); @@ -532,7 +532,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x00000000001FFFFF)... "); @@ -542,7 +542,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000000200000)... "); @@ -552,7 +552,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000003FFFFFF)... "); @@ -562,7 +562,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000004000000)... "); @@ -572,7 +572,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x000000007FFFFFFF)... "); @@ -582,7 +582,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000080000000)... "); @@ -592,7 +592,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing utf8_uint64(0x0000000FFFFFFFFF)... "); @@ -602,7 +602,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("testing grow... "); @@ -615,7 +615,7 @@ int test_bitbuffer() printf("%s\n", ok?"OK":"FAILED"); if(!ok) { FLAC__bitbuffer_dump(bb, stdout); - return 1; + return false; } printf("capacity = %u\n", bb->capacity); @@ -625,31 +625,31 @@ int test_bitbuffer() printf("FAILED\n"); FLAC__bitbuffer_dump(bb, stdout); FLAC__bitbuffer_dump(bbcopy, stdout); - return 1; + return false; } if(bb->blurbs != bbcopy->blurbs) { printf("FAILED byte count %u != %u\n", bb->blurbs, bbcopy->blurbs); FLAC__bitbuffer_dump(bb, stdout); FLAC__bitbuffer_dump(bbcopy, stdout); - return 1; + return false; } if(bb->bits != bbcopy->bits) { printf("FAILED bit count %u != %u\n", bb->bits, bbcopy->bits); FLAC__bitbuffer_dump(bb, stdout); FLAC__bitbuffer_dump(bbcopy, stdout); - return 1; + return false; } if(bb->total_bits != bbcopy->total_bits) { printf("FAILED total_bits count %u != %u\n", bb->total_bits, bbcopy->total_bits); FLAC__bitbuffer_dump(bb, stdout); FLAC__bitbuffer_dump(bbcopy, stdout); - return 1; + return false; } if(memcmp(bb->buffer, bbcopy->buffer, sizeof(FLAC__byte)*bb->capacity) != 0) { printf("FAILED pattern match\n"); FLAC__bitbuffer_dump(bb, stdout); FLAC__bitbuffer_dump(bbcopy, stdout); - return 1; + return false; } printf("OK\n"); @@ -658,5 +658,5 @@ int test_bitbuffer() FLAC__bitbuffer_free(bbcopy); printf("\nPASSED!\n"); - return 0; + return true; } diff --git a/src/test_unit/bitbuffer.h b/src/test_unit/bitbuffer.h index e1df813..140722f 100644 --- a/src/test_unit/bitbuffer.h +++ b/src/test_unit/bitbuffer.h @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2000,2001,2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -16,9 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef FLAC__TEST_UNIT_BITBUFFER_H -#define FLAC__TEST_UNIT_BITBUFFER_H +#ifndef FLAC__TEST_LIBFLAC_BITBUFFER_H +#define FLAC__TEST_LIBFLAC_BITBUFFER_H -int test_bitbuffer(); +#include "FLAC/ordinals.h" + +FLAC__bool test_bitbuffer(); #endif diff --git a/src/test_unit/decoders.c b/src/test_unit/decoders.c index b11a21a..a22dbdc 100644 --- a/src/test_unit/decoders.c +++ b/src/test_unit/decoders.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -50,6 +50,42 @@ static FLAC__bool die_(const char *msg) return false; } +static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder) +{ + FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)state, FLAC__StreamDecoderStateString[state]); + else + printf("FAILED, state = %u (%s)\n", (unsigned)state, FLAC__StreamDecoderStateString[state]); + + return false; +} + +static FLAC__bool die_ss_(const char *msg, const FLAC__SeekableStreamDecoder *decoder) +{ + FLAC__SeekableStreamDecoderState state = FLAC__seekable_stream_decoder_get_state(decoder); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)state, FLAC__SeekableStreamDecoderStateString[state]); + else + printf("FAILED, state = %u (%s)\n", (unsigned)state, FLAC__SeekableStreamDecoderStateString[state]); + + return false; +} + +static FLAC__bool die_f_(const char *msg, const FLAC__FileDecoder *decoder) +{ + FLAC__FileDecoderState state = FLAC__file_decoder_get_state(decoder); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)state, FLAC__FileDecoderStateString[state]); + else + printf("FAILED, state = %u (%s)\n", (unsigned)state, FLAC__FileDecoderStateString[state]); + + return false; +} + static void *malloc_or_die_(size_t size) { void *x = malloc(size); @@ -187,11 +223,11 @@ static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const FLAC__S return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ } -static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { stream_decoder_client_data_struct *dcd = (stream_decoder_client_data_struct*)client_data; - (void)decoder, (void)frame, (void)buffer; + (void)decoder, (void)buffer; if(0 == dcd) { printf("ERROR: client_data in write callback is NULL\n"); @@ -261,65 +297,46 @@ static void stream_decoder_error_callback_(const FLAC__StreamDecoder *decoder, F static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, stream_decoder_client_data_struct *dcd) { - FLAC__StreamDecoderState state; + if(!FLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_)) + return die_s_("at FLAC__stream_decoder_set_read_callback(), returned false", decoder); - if(!FLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_)) { - printf("FAILED at FLAC__stream_decoder_set_read_callback(), returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_write_callback(decoder, stream_decoder_write_callback_)) + return die_s_("at FLAC__stream_decoder_set_write_callback(), returned false", decoder); - if(!FLAC__stream_decoder_set_write_callback(decoder, stream_decoder_write_callback_)) { - printf("FAILED at FLAC__stream_decoder_set_write_callback(), returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_callback(decoder, stream_decoder_metadata_callback_)) + return die_s_("at FLAC__stream_decoder_set_metadata_callback(), returned false", decoder); - if(!FLAC__stream_decoder_set_metadata_callback(decoder, stream_decoder_metadata_callback_)) { - printf("FAILED at FLAC__stream_decoder_set_metadata_callback(), returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_error_callback(decoder, stream_decoder_error_callback_)) + return die_s_("at FLAC__stream_decoder_set_error_callback(), returned false", decoder); - if(!FLAC__stream_decoder_set_error_callback(decoder, stream_decoder_error_callback_)) { - printf("FAILED at FLAC__stream_decoder_set_error_callback(), returned false\n"); - return false; - } - - if(!FLAC__stream_decoder_set_client_data(decoder, dcd)) { - printf("FAILED at FLAC__stream_decoder_set_client_data(), returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_client_data(decoder, dcd)) + return die_s_("at FLAC__stream_decoder_set_client_data(), returned false", decoder); printf("testing FLAC__stream_decoder_init()... "); - if((state = FLAC__stream_decoder_init(decoder)) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { - printf("FAILED, returned state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(FLAC__stream_decoder_init(decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) + return die_s_(0, decoder); printf("OK\n"); dcd->current_metadata_number = 0; - printf("rewinding input... "); if(fseek(dcd->file, 0, SEEK_SET) < 0) { - printf("FAILED, errno = %d\n", errno); + printf("FAILED rewinding input, errno = %d\n", errno); return false; } - printf("OK\n"); printf("testing FLAC__stream_decoder_process_whole_stream()... "); - if(!FLAC__stream_decoder_process_whole_stream(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_process_whole_stream(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_finish()... "); FLAC__stream_decoder_finish(decoder); printf("OK\n"); - return true;; + return true; } -FLAC__bool test_stream_decoder() +static FLAC__bool test_stream_decoder() { FLAC__StreamDecoder *decoder; FLAC__StreamDecoderState state; @@ -339,45 +356,33 @@ FLAC__bool test_stream_decoder() printf("OK\n"); printf("testing FLAC__stream_decoder_set_read_callback()... "); - if(!FLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_read_callback(decoder, stream_decoder_read_callback_)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_write_callback()... "); - if(!FLAC__stream_decoder_set_write_callback(decoder, stream_decoder_write_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_write_callback(decoder, stream_decoder_write_callback_)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_callback()... "); - if(!FLAC__stream_decoder_set_metadata_callback(decoder, stream_decoder_metadata_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_callback(decoder, stream_decoder_metadata_callback_)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_error_callback()... "); - if(!FLAC__stream_decoder_set_error_callback(decoder, stream_decoder_error_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_error_callback(decoder, stream_decoder_error_callback_)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_client_data()... "); - if(!FLAC__stream_decoder_set_client_data(decoder, &decoder_client_data)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_client_data(decoder, &decoder_client_data)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_init()... "); - if((state = FLAC__stream_decoder_init(decoder)) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { - printf("FAILED, returned state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(FLAC__stream_decoder_init(decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) + return die_s_(0, decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_get_state()... "); @@ -397,45 +402,30 @@ FLAC__bool test_stream_decoder() printf("OK\n"); printf("testing FLAC__stream_decoder_process_metadata()... "); - if(!FLAC__stream_decoder_process_metadata(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_process_metadata(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_process_one_frame()... "); - if(!FLAC__stream_decoder_process_one_frame(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_process_one_frame(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_flush()... "); - if(!FLAC__stream_decoder_flush(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_flush(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = true; printf("testing FLAC__stream_decoder_process_one_frame()... "); - if(!FLAC__stream_decoder_process_one_frame(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_process_one_frame(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = false; printf("testing FLAC__stream_decoder_process_remaining_frames()... "); - if(!FLAC__stream_decoder_process_remaining_frames(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_process_remaining_frames(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_get_channels()... "); @@ -499,11 +489,8 @@ FLAC__bool test_stream_decoder() printf("OK\n"); printf("testing FLAC__stream_decoder_process_whole_stream()... "); - if(!FLAC__stream_decoder_process_whole_stream(decoder)) { - state = FLAC__stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); - return false; - } + if(!FLAC__stream_decoder_process_whole_stream(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_finish()... "); @@ -515,10 +502,8 @@ FLAC__bool test_stream_decoder() */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -530,40 +515,34 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all */ printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore VORBIS_COMMENT */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... "); - if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -574,24 +553,20 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... "); - if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -601,24 +576,20 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION id of app#1 */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -629,31 +600,25 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION id of app#1 & app#2 */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... "); - if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -663,48 +628,40 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond VORBIS_COMMENT */ printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... "); - if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION */ printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... "); - if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -712,55 +669,45 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION id of app#1 */ printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &application1_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION id of app#1 & app#2 */ printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... "); - if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -768,31 +715,25 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION, respond APPLICATION id of app#1 */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... "); - if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -803,38 +744,32 @@ FLAC__bool test_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 */ printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... "); - if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &application2_; if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* done, now leave the sequence the way we found it... */ num_expected_ = 0; @@ -954,7 +889,7 @@ static FLAC__bool seekable_stream_decoder_eof_callback_(const FLAC__SeekableStre return feof(dcd->file); } -static FLAC__StreamDecoderWriteStatus seekable_stream_decoder_write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +static FLAC__StreamDecoderWriteStatus seekable_stream_decoder_write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { (void)decoder; return stream_decoder_write_callback_(0, frame, buffer, client_data); @@ -974,63 +909,39 @@ static void seekable_stream_decoder_error_callback_(const FLAC__SeekableStreamDe static FLAC__bool seekable_stream_decoder_test_respond_(FLAC__SeekableStreamDecoder *decoder, seekable_stream_decoder_client_data_struct *dcd) { - FLAC__SeekableStreamDecoderState state; + if(!FLAC__seekable_stream_decoder_set_read_callback(decoder, seekable_stream_decoder_read_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_read_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_read_callback(decoder, seekable_stream_decoder_read_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_read_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekable_stream_decoder_seek_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_seek_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekable_stream_decoder_seek_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_seek_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_tell_callback(decoder, seekable_stream_decoder_tell_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_tell_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_tell_callback(decoder, seekable_stream_decoder_tell_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_tell_callback(), returned false\n"); - return false; - } - - if(!FLAC__seekable_stream_decoder_set_length_callback(decoder, seekable_stream_decoder_length_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_length_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_length_callback(decoder, seekable_stream_decoder_length_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_length_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_eof_callback(decoder, seekable_stream_decoder_eof_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_eof_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_eof_callback(decoder, seekable_stream_decoder_eof_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_eof_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_write_callback(decoder, seekable_stream_decoder_write_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_write_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_write_callback(decoder, seekable_stream_decoder_write_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_write_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_metadata_callback(decoder, seekable_stream_decoder_metadata_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_metadata_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_callback(decoder, seekable_stream_decoder_metadata_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_metadata_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_error_callback(decoder, seekable_stream_decoder_error_callback_)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_error_callback(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_error_callback(decoder, seekable_stream_decoder_error_callback_)) + return die_ss_("at FLAC__seekable_stream_decoder_set_error_callback(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_client_data(decoder, dcd)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_client_data(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_client_data(decoder, dcd)) + return die_ss_("at FLAC__seekable_stream_decoder_set_client_data(), returned false", decoder); - if(!FLAC__seekable_stream_decoder_set_md5_checking(decoder, true)) { - printf("FAILED at FLAC__seekable_stream_decoder_set_md5_checking(), returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_md5_checking(decoder, true)) + return die_ss_("at FLAC__seekable_stream_decoder_set_md5_checking(), returned false", decoder); printf("testing FLAC__seekable_stream_decoder_init()... "); - if((state = FLAC__seekable_stream_decoder_init(decoder)) != FLAC__SEEKABLE_STREAM_DECODER_OK) { - printf("FAILED, returned state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) + return die_ss_(0, decoder); printf("OK\n"); dcd->current_metadata_number = 0; @@ -1041,21 +952,18 @@ static FLAC__bool seekable_stream_decoder_test_respond_(FLAC__SeekableStreamDeco } printf("testing FLAC__seekable_stream_decoder_process_whole_stream()... "); - if(!FLAC__seekable_stream_decoder_process_whole_stream(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_process_whole_stream(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_finish()... "); (void) FLAC__seekable_stream_decoder_finish(decoder); printf("OK\n"); - return true;; + return true; } -FLAC__bool test_seekable_stream_decoder() +static FLAC__bool test_seekable_stream_decoder() { FLAC__SeekableStreamDecoder *decoder; FLAC__SeekableStreamDecoderState state; @@ -1075,80 +983,58 @@ FLAC__bool test_seekable_stream_decoder() printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_read_callback()... "); - if(!FLAC__seekable_stream_decoder_set_read_callback(decoder, seekable_stream_decoder_read_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_read_callback(decoder, seekable_stream_decoder_read_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_seek_callback()... "); - if(!FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekable_stream_decoder_seek_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_seek_callback(decoder, seekable_stream_decoder_seek_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_tell_callback()... "); - if(!FLAC__seekable_stream_decoder_set_tell_callback(decoder, seekable_stream_decoder_tell_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_tell_callback(decoder, seekable_stream_decoder_tell_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_length_callback()... "); - if(!FLAC__seekable_stream_decoder_set_length_callback(decoder, seekable_stream_decoder_length_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_length_callback(decoder, seekable_stream_decoder_length_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_eof_callback()... "); - if(!FLAC__seekable_stream_decoder_set_eof_callback(decoder, seekable_stream_decoder_eof_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_eof_callback(decoder, seekable_stream_decoder_eof_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_write_callback()... "); - if(!FLAC__seekable_stream_decoder_set_write_callback(decoder, seekable_stream_decoder_write_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_write_callback(decoder, seekable_stream_decoder_write_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_callback()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_callback(decoder, seekable_stream_decoder_metadata_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_callback(decoder, seekable_stream_decoder_metadata_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_error_callback()... "); - if(!FLAC__seekable_stream_decoder_set_error_callback(decoder, seekable_stream_decoder_error_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_error_callback(decoder, seekable_stream_decoder_error_callback_)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_client_data()... "); - if(!FLAC__seekable_stream_decoder_set_client_data(decoder, &decoder_client_data)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_client_data(decoder, &decoder_client_data)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_md5_checking()... "); - if(!FLAC__seekable_stream_decoder_set_md5_checking(decoder, true)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_md5_checking(decoder, true)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_init()... "); - if((state = FLAC__seekable_stream_decoder_init(decoder)) != FLAC__SEEKABLE_STREAM_DECODER_OK) { - printf("FAILED, returned state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) + return die_ss_(0, decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_get_state()... "); @@ -1175,53 +1061,35 @@ FLAC__bool test_seekable_stream_decoder() printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_process_metadata()... "); - if(!FLAC__seekable_stream_decoder_process_metadata(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_process_metadata(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_process_one_frame()... "); - if(!FLAC__seekable_stream_decoder_process_one_frame(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_process_one_frame(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_flush()... "); - if(!FLAC__seekable_stream_decoder_flush(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_flush(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = true; printf("testing FLAC__seekable_stream_decoder_process_one_frame()... "); - if(!FLAC__seekable_stream_decoder_process_one_frame(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_process_one_frame(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = false; printf("testing FLAC__seekable_stream_decoder_seek_absolute()... "); - if(!FLAC__seekable_stream_decoder_seek_absolute(decoder, 0)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_seek_absolute(decoder, 0)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_process_remaining_frames()... "); - if(!FLAC__seekable_stream_decoder_process_remaining_frames(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_process_remaining_frames(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_get_channels()... "); @@ -1268,26 +1136,22 @@ FLAC__bool test_seekable_stream_decoder() } printf("testing FLAC__seekable_stream_decoder_reset()... "); - if(!FLAC__seekable_stream_decoder_reset(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_reset(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); decoder_client_data.current_metadata_number = 0; + printf("rewinding input... "); if(fseek(decoder_client_data.file, 0, SEEK_SET) < 0) { - printf("FAILED rewinding input, errno = %d\n", errno); + printf("FAILED, errno = %d\n", errno); return false; } + printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_process_whole_stream()... "); - if(!FLAC__seekable_stream_decoder_process_whole_stream(decoder)) { - state = FLAC__seekable_stream_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__SeekableStreamDecoderStateString[state]); - return false; - } + if(!FLAC__seekable_stream_decoder_process_whole_stream(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_finish()... "); @@ -1299,10 +1163,8 @@ FLAC__bool test_seekable_stream_decoder() */ printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1314,40 +1176,34 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all */ printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore VORBIS_COMMENT */ printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1358,24 +1214,20 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION */ printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore(APPLICATION)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1385,24 +1237,20 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION id of app#1 */ printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1413,31 +1261,25 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION id of app#1 & app#2 */ printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_application(of app block #2)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1447,48 +1289,40 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond VORBIS_COMMENT */ printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond(VORBIS_COMMENT)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION */ printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond(APPLICATION)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1496,55 +1330,45 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION id of app#1 */ printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &application1_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION id of app#1 & app#2 */ printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_application(of app block #2)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1552,31 +1376,25 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION, respond APPLICATION id of app#1 */ printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore(APPLICATION)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1587,38 +1405,32 @@ FLAC__bool test_seekable_stream_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 */ printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_all()... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_respond(APPLICATION)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_ss_("returned false", decoder); printf("OK\n"); printf("testing FLAC__seekable_stream_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_ss_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &application2_; if(!seekable_stream_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* done, now leave the sequence the way we found it... */ num_expected_ = 0; @@ -1640,7 +1452,7 @@ FLAC__bool test_seekable_stream_decoder() return true; } -static FLAC__StreamDecoderWriteStatus file_decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +static FLAC__StreamDecoderWriteStatus file_decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { (void)decoder; return stream_decoder_write_callback_(0, frame, buffer, client_data); @@ -1660,63 +1472,44 @@ static void file_decoder_error_callback_(const FLAC__FileDecoder *decoder, FLAC_ static FLAC__bool file_decoder_test_respond_(FLAC__FileDecoder *decoder, file_decoder_client_data_struct *dcd) { - FLAC__FileDecoderState state; - - if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_)) { - printf("FAILED at FLAC__file_decoder_set_write_callback(), returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_)) + return die_f_("at FLAC__file_decoder_set_write_callback(), returned false", decoder); - if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_)) { - printf("FAILED at FLAC__file_decoder_set_metadata_callback(), returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_)) + return die_f_("at FLAC__file_decoder_set_metadata_callback(), returned false", decoder); - if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_)) { - printf("FAILED at FLAC__file_decoder_set_error_callback(), returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_)) + return die_f_("at FLAC__file_decoder_set_error_callback(), returned false", decoder); - if(!FLAC__file_decoder_set_client_data(decoder, dcd)) { - printf("FAILED at FLAC__file_decoder_set_client_data(), returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_client_data(decoder, dcd)) + return die_f_("at FLAC__file_decoder_set_client_data(), returned false", decoder); - if(!FLAC__file_decoder_set_filename(decoder, flacfilename_)) { - printf("FAILED at FLAC__file_decoder_set_filename(), returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_filename(decoder, flacfilename_)) + return die_f_("at FLAC__file_decoder_set_filename(), returned false", decoder); - if(!FLAC__file_decoder_set_md5_checking(decoder, true)) { - printf("FAILED at FLAC__file_decoder_set_md5_checking(), returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_md5_checking(decoder, true)) + return die_f_("at FLAC__file_decoder_set_md5_checking(), returned false", decoder); printf("testing FLAC__file_decoder_init()... "); - if((state = FLAC__file_decoder_init(decoder)) != FLAC__FILE_DECODER_OK) { - printf("FAILED, returned state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) + return die_f_(0, decoder); printf("OK\n"); dcd->current_metadata_number = 0; printf("testing FLAC__file_decoder_process_whole_file()... "); - if(!FLAC__file_decoder_process_whole_file(decoder)) { - state = FLAC__file_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(!FLAC__file_decoder_process_whole_file(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_finish()... "); (void) FLAC__file_decoder_finish(decoder); printf("OK\n"); - return true;; + return true; } -FLAC__bool test_file_decoder() +static FLAC__bool test_file_decoder() { FLAC__FileDecoder *decoder; FLAC__FileDecoderState state; @@ -1736,52 +1529,38 @@ FLAC__bool test_file_decoder() printf("OK\n"); printf("testing FLAC__file_decoder_set_write_callback()... "); - if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_callback()... "); - if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_error_callback()... "); - if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_client_data()... "); - if(!FLAC__file_decoder_set_client_data(decoder, &decoder_client_data)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_client_data(decoder, &decoder_client_data)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_filename()... "); - if(!FLAC__file_decoder_set_filename(decoder, flacfilename_)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_filename(decoder, flacfilename_)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_md5_checking()... "); - if(!FLAC__file_decoder_set_md5_checking(decoder, true)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_md5_checking(decoder, true)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_init()... "); - if((state = FLAC__file_decoder_init(decoder)) != FLAC__FILE_DECODER_OK) { - printf("FAILED, returned state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK) + return die_f_(0, decoder); printf("OK\n"); printf("testing FLAC__file_decoder_get_state()... "); @@ -1800,35 +1579,23 @@ FLAC__bool test_file_decoder() printf("OK\n"); printf("testing FLAC__file_decoder_process_metadata()... "); - if(!FLAC__file_decoder_process_metadata(decoder)) { - state = FLAC__file_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(!FLAC__file_decoder_process_metadata(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_process_one_frame()... "); - if(!FLAC__file_decoder_process_one_frame(decoder)) { - state = FLAC__file_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(!FLAC__file_decoder_process_one_frame(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_seek_absolute()... "); - if(!FLAC__file_decoder_seek_absolute(decoder, 0)) { - state = FLAC__file_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(!FLAC__file_decoder_seek_absolute(decoder, 0)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_process_remaining_frames()... "); - if(!FLAC__file_decoder_process_remaining_frames(decoder)) { - state = FLAC__file_decoder_get_state(decoder); - printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__FileDecoderStateString[state]); - return false; - } + if(!FLAC__file_decoder_process_remaining_frames(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_get_channels()... "); @@ -1883,10 +1650,8 @@ FLAC__bool test_file_decoder() */ printf("testing FLAC__file_decoder_set_metadata_respond_all()... "); - if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1898,40 +1663,34 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all */ printf("testing FLAC__file_decoder_set_metadata_ignore_all()... "); - if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore VORBIS_COMMENT */ printf("testing FLAC__file_decoder_set_metadata_respond_all()... "); - if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore(VORBIS_COMMENT)... "); - if(!FLAC__file_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1942,24 +1701,20 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION */ printf("testing FLAC__file_decoder_set_metadata_respond_all()... "); - if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore(APPLICATION)... "); - if(!FLAC__file_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1969,24 +1724,20 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION id of app#1 */ printf("testing FLAC__file_decoder_set_metadata_respond_all()... "); - if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -1997,31 +1748,25 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION id of app#1 & app#2 */ printf("testing FLAC__file_decoder_set_metadata_respond_all()... "); - if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore_application(of app block #2)... "); - if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -2031,48 +1776,40 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond VORBIS_COMMENT */ printf("testing FLAC__file_decoder_set_metadata_ignore_all()... "); - if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond(VORBIS_COMMENT)... "); - if(!FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION */ printf("testing FLAC__file_decoder_set_metadata_ignore_all()... "); - if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond(APPLICATION)... "); - if(!FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -2080,55 +1817,45 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION id of app#1 */ printf("testing FLAC__file_decoder_set_metadata_ignore_all()... "); - if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &application1_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION id of app#1 & app#2 */ printf("testing FLAC__file_decoder_set_metadata_ignore_all()... "); - if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond_application(of app block #2)... "); - if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -2136,31 +1863,25 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &application2_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * respond all, ignore APPLICATION, respond APPLICATION id of app#1 */ printf("testing FLAC__file_decoder_set_metadata_respond_all()... "); - if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore(APPLICATION)... "); - if(!FLAC__file_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond_application(of app block #1)... "); - if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; @@ -2171,38 +1892,32 @@ FLAC__bool test_file_decoder() expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 */ printf("testing FLAC__file_decoder_set_metadata_ignore_all()... "); - if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_all(decoder)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_respond(APPLICATION)... "); - if(!FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) + return die_f_("returned false", decoder); printf("OK\n"); printf("testing FLAC__file_decoder_set_metadata_ignore_application(of app block #1)... "); - if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) { - printf("FAILED, returned false\n"); - return false; - } + if(!FLAC__file_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) + return die_f_("returned false", decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &application2_; if(!file_decoder_test_respond_(decoder, &decoder_client_data)) - return 1; + return false; /* done, now leave the sequence the way we found it... */ num_expected_ = 0; @@ -2219,52 +1934,26 @@ FLAC__bool test_file_decoder() printf("\nPASSED!\n"); - printf("\nPASSED!\n"); - return true; } -int test_decoders() +FLAC__bool test_decoders() { init_metadata_blocks_(); if(!generate_file_()) - return 1; + return false; if(!test_stream_decoder()) - return 1; + return false; if(!test_seekable_stream_decoder()) - return 1; + return false; if(!test_file_decoder()) - return 1; + return false; (void) file_utils__remove_file(flacfilename_); free_metadata_blocks_(); - return 0; + return true; } -#if 0 -typedef enum { - FLAC__FILE_DECODER_OK = 0, - FLAC__FILE_DECODER_END_OF_FILE, - FLAC__FILE_DECODER_ERROR_OPENING_FILE, - FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR, - FLAC__FILE_DECODER_SEEK_ERROR, - FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR, - FLAC__FILE_DECODER_ALREADY_INITIALIZED, - FLAC__FILE_DECODER_INVALID_CALLBACK, - FLAC__FILE_DECODER_UNINITIALIZED -} FLAC__FileDecoderState; -extern const char *FLAC__FileDecoderStateString[]; - -/* - * Methods for decoding the data - */ -FLAC__bool FLAC__file_decoder_process_whole_file(FLAC__FileDecoder *decoder); -FLAC__bool FLAC__file_decoder_process_metadata(FLAC__FileDecoder *decoder); -FLAC__bool FLAC__file_decoder_process_one_frame(FLAC__FileDecoder *decoder); -FLAC__bool FLAC__file_decoder_process_remaining_frames(FLAC__FileDecoder *decoder); - -FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample); -#endif diff --git a/src/test_unit/decoders.h b/src/test_unit/decoders.h index 5b7fe62..eefdab0 100644 --- a/src/test_unit/decoders.h +++ b/src/test_unit/decoders.h @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -16,9 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef FLAC__TEST_UNIT_DECODERS_H -#define FLAC__TEST_UNIT_DECODERS_H +#ifndef FLAC__TEST_LIBFLAC_DECODERS_H +#define FLAC__TEST_LIBFLAC_DECODERS_H -int test_decoders(); +#include "FLAC/ordinals.h" + +FLAC__bool test_decoders(); #endif diff --git a/src/test_unit/encoders.c b/src/test_unit/encoders.c new file mode 100644 index 0000000..c234385 --- /dev/null +++ b/src/test_unit/encoders.c @@ -0,0 +1,410 @@ +/* test_libFLAC - Unit tester for libFLAC + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "encoders.h" +#include "file_utils.h" +#include "FLAC/assert.h" +#include "FLAC/stream_encoder.h" +#include +#include +#include + +static FLAC__StreamMetaData streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; +static FLAC__StreamMetaData *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ }; +static const unsigned num_metadata_ = 5; +static const char *flacfilename_ = "metadata.flac"; + +static FLAC__bool die_s_(const char *msg, const FLAC__StreamEncoder *encoder) +{ + FLAC__StreamEncoderState state = FLAC__stream_encoder_get_state(encoder); + + if(msg) + printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)state, FLAC__StreamEncoderStateString[state]); + else + printf("FAILED, state = %u (%s)\n", (unsigned)state, FLAC__StreamEncoderStateString[state]); + + return false; +} + +static void *malloc_or_die_(size_t size) +{ + void *x = malloc(size); + if(0 == x) { + fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size); + exit(1); + } + return x; +} + +static void init_metadata_blocks_() +{ + /* + most of the actual numbers and data in the blocks don't matter, + we just want to make sure the encoder encodes them correctly + + remember, the metadata interface gets tested after the encoders, + so we do all the metadata manipulation here without it. + */ + + /* min/max_framesize and md5sum don't get written at first, so we have to leave them 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); + + padding_.is_last = false; + padding_.type = FLAC__METADATA_TYPE_PADDING; + padding_.length = 1234; + + seektable_.is_last = false; + seektable_.type = FLAC__METADATA_TYPE_SEEKTABLE; + seektable_.data.seek_table.num_points = 2; + seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; + seektable_.data.seek_table.points = malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(FLAC__StreamMetaData_SeekPoint)); + seektable_.data.seek_table.points[0].sample_number = 0; + seektable_.data.seek_table.points[0].stream_offset = 0; + seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize; + seektable_.data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + seektable_.data.seek_table.points[1].stream_offset = 1000; + seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize; + + application1_.is_last = false; + application1_.type = FLAC__METADATA_TYPE_APPLICATION; + application1_.length = 8; + memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4); + application1_.data.application.data = malloc_or_die_(4); + memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4); + + application2_.is_last = false; + application2_.type = FLAC__METADATA_TYPE_APPLICATION; + application2_.length = 4; + memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4); + application2_.data.application.data = 0; + + vorbiscomment_.is_last = true; + vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT; + vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0); + vorbiscomment_.data.vorbis_comment.vendor_string.length = 8; + vorbiscomment_.data.vorbis_comment.vendor_string.entry = malloc_or_die_(8); + memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8); + vorbiscomment_.data.vorbis_comment.num_comments = 2; + vorbiscomment_.data.vorbis_comment.comments = malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetaData_VorbisComment_Entry)); + vorbiscomment_.data.vorbis_comment.comments[0].length = 5; + vorbiscomment_.data.vorbis_comment.comments[0].entry = malloc_or_die_(5); + memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5); + vorbiscomment_.data.vorbis_comment.comments[1].length = 0; + vorbiscomment_.data.vorbis_comment.comments[1].entry = 0; +} + +static void free_metadata_blocks_() +{ + free(seektable_.data.seek_table.points); + free(application1_.data.application.data); + free(vorbiscomment_.data.vorbis_comment.vendor_string.entry); + free(vorbiscomment_.data.vorbis_comment.comments[0].entry); + free(vorbiscomment_.data.vorbis_comment.comments); +} + +static FLAC__StreamEncoderWriteStatus encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) +{ + (void)encoder, (void)buffer, (void)bytes, (void)samples, (void)current_frame, (void)client_data; + return FLAC__STREAM_ENCODER_WRITE_OK; +} + +static void encoder_metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data) +{ + (void)encoder, (void)metadata, (void)client_data; +} + +static FLAC__bool test_stream_encoder() +{ + FLAC__StreamEncoder *encoder; + FLAC__StreamEncoderState state; + FLAC__int32 samples[1024]; + FLAC__int32 *samples_array[1] = { samples }; + unsigned i; + + printf("\n+++ unit test: FLAC__StreamEncoder\n\n"); + + printf("testing FLAC__stream_encoder_new()... "); + encoder = FLAC__stream_encoder_new(); + if(0 == encoder) { + printf("FAILED, returned NULL\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_streamable_subset()... "); + if(!FLAC__stream_encoder_set_streamable_subset(encoder, true)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_do_mid_side_stereo()... "); + if(!FLAC__stream_encoder_set_do_mid_side_stereo(encoder, false)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_loose_mid_side_stereo()... "); + if(!FLAC__stream_encoder_set_loose_mid_side_stereo(encoder, false)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_channels()... "); + if(!FLAC__stream_encoder_set_channels(encoder, streaminfo_.data.stream_info.channels)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_bits_per_sample()... "); + if(!FLAC__stream_encoder_set_bits_per_sample(encoder, streaminfo_.data.stream_info.bits_per_sample)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_sample_rate()... "); + if(!FLAC__stream_encoder_set_sample_rate(encoder, streaminfo_.data.stream_info.sample_rate)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_blocksize()... "); + if(!FLAC__stream_encoder_set_blocksize(encoder, streaminfo_.data.stream_info.min_blocksize)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_max_lpc_order()... "); + if(!FLAC__stream_encoder_set_max_lpc_order(encoder, 0)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_qlp_coeff_precision()... "); + if(!FLAC__stream_encoder_set_qlp_coeff_precision(encoder, 0)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_do_qlp_coeff_prec_search()... "); + if(!FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder, false)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_do_escape_coding()... "); + if(!FLAC__stream_encoder_set_do_escape_coding(encoder, false)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_do_exhaustive_model_search()... "); + if(!FLAC__stream_encoder_set_do_exhaustive_model_search(encoder, false)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_min_residual_partition_order()... "); + if(!FLAC__stream_encoder_set_min_residual_partition_order(encoder, 0)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_max_residual_partition_order()... "); + if(!FLAC__stream_encoder_set_max_residual_partition_order(encoder, 0)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_rice_parameter_search_dist()... "); + if(!FLAC__stream_encoder_set_rice_parameter_search_dist(encoder, 0)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_total_samples_estimate()... "); + if(!FLAC__stream_encoder_set_total_samples_estimate(encoder, streaminfo_.data.stream_info.total_samples)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_metadata()... "); + if(!FLAC__stream_encoder_set_metadata(encoder, metadata_sequence_, num_metadata_)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_write_callback()... "); + if(!FLAC__stream_encoder_set_write_callback(encoder, encoder_write_callback_)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_metadata_callback()... "); + if(!FLAC__stream_encoder_set_metadata_callback(encoder, encoder_metadata_callback_)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_set_client_data()... "); + if(!FLAC__stream_encoder_set_client_data(encoder, 0)) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_init()... "); + if(FLAC__stream_encoder_init(encoder) != FLAC__STREAM_ENCODER_OK) + return die_s_(0, encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_state()... "); + state = FLAC__stream_encoder_get_state(encoder); + printf("returned state = %u (%s)... OK\n", (unsigned)state, FLAC__StreamEncoderStateString[state]); + + printf("testing FLAC__stream_encoder_get_streamable_subset()... "); + if(FLAC__stream_encoder_get_streamable_subset(encoder) != true) { + printf("FAILED, expected true, got false\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_do_mid_side_stereo()... "); + if(FLAC__stream_encoder_get_do_mid_side_stereo(encoder) != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_loose_mid_side_stereo()... "); + if(FLAC__stream_encoder_get_loose_mid_side_stereo(encoder) != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_channels()... "); + if(FLAC__stream_encoder_get_channels(encoder) != streaminfo_.data.stream_info.channels) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.channels, FLAC__stream_encoder_get_channels(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_bits_per_sample()... "); + if(FLAC__stream_encoder_get_bits_per_sample(encoder) != streaminfo_.data.stream_info.bits_per_sample) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.bits_per_sample, FLAC__stream_encoder_get_bits_per_sample(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_sample_rate()... "); + if(FLAC__stream_encoder_get_sample_rate(encoder) != streaminfo_.data.stream_info.sample_rate) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.sample_rate, FLAC__stream_encoder_get_sample_rate(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_blocksize()... "); + if(FLAC__stream_encoder_get_blocksize(encoder) != streaminfo_.data.stream_info.min_blocksize) { + printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.min_blocksize, FLAC__stream_encoder_get_blocksize(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_max_lpc_order()... "); + if(FLAC__stream_encoder_get_max_lpc_order(encoder) != 0) { + printf("FAILED, expected %u, got %u\n", 0, FLAC__stream_encoder_get_max_lpc_order(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_qlp_coeff_precision()... "); + (void)FLAC__stream_encoder_get_qlp_coeff_precision(encoder); + /* we asked the encoder to auto select this so we accept anything */ + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_do_qlp_coeff_prec_search()... "); + if(FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder) != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_do_escape_coding()... "); + if(FLAC__stream_encoder_get_do_escape_coding(encoder) != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_do_exhaustive_model_search()... "); + if(FLAC__stream_encoder_get_do_exhaustive_model_search(encoder) != false) { + printf("FAILED, expected false, got true\n"); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_min_residual_partition_order()... "); + if(FLAC__stream_encoder_get_min_residual_partition_order(encoder) != 0) { + printf("FAILED, expected %u, got %u\n", 0, FLAC__stream_encoder_get_min_residual_partition_order(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_max_residual_partition_order()... "); + if(FLAC__stream_encoder_get_max_residual_partition_order(encoder) != 0) { + printf("FAILED, expected %u, got %u\n", 0, FLAC__stream_encoder_get_max_residual_partition_order(encoder)); + return false; + } + printf("OK\n"); + + printf("testing FLAC__stream_encoder_get_rice_parameter_search_dist()... "); + if(FLAC__stream_encoder_get_rice_parameter_search_dist(encoder) != 0) { + printf("FAILED, expected %u, got %u\n", 0, FLAC__stream_encoder_get_rice_parameter_search_dist(encoder)); + return false; + } + printf("OK\n"); + + /* init the dummy sample buffer */ + for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++) + samples[i] = i & 7; + + printf("testing FLAC__stream_encoder_process()... "); + if(!FLAC__stream_encoder_process(encoder, (const FLAC__int32 * const *)samples_array, sizeof(samples) / sizeof(FLAC__int32))) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_process_interleaved()... "); + if(!FLAC__stream_encoder_process_interleaved(encoder, samples, sizeof(samples) / sizeof(FLAC__int32))) + return die_s_("returned false", encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_finish()... "); + FLAC__stream_encoder_finish(encoder); + printf("OK\n"); + + printf("testing FLAC__stream_encoder_delete()... "); + FLAC__stream_encoder_delete(encoder); + printf("OK\n"); + + printf("\nPASSED!\n"); + + return true; +} + +FLAC__bool test_encoders() +{ + init_metadata_blocks_(); + + if(!test_stream_encoder()) + return false; + + (void) file_utils__remove_file(flacfilename_); + free_metadata_blocks_(); + + return true; +} diff --git a/src/test_unit/encoders.h b/src/test_unit/encoders.h new file mode 100644 index 0000000..803befb --- /dev/null +++ b/src/test_unit/encoders.h @@ -0,0 +1,26 @@ +/* test_libFLAC - Unit tester for libFLAC + * Copyright (C) 2002 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__TEST_LIBFLAC_ENCODERS_H +#define FLAC__TEST_LIBFLAC_ENCODERS_H + +#include "FLAC/ordinals.h" + +FLAC__bool test_encoders(); + +#endif diff --git a/src/test_unit/file_utils.c b/src/test_unit/file_utils.c index ac5473e..31f8063 100644 --- a/src/test_unit/file_utils.c +++ b/src/test_unit/file_utils.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or diff --git a/src/test_unit/file_utils.h b/src/test_unit/file_utils.h index e78e257..5944187 100644 --- a/src/test_unit/file_utils.h +++ b/src/test_unit/file_utils.h @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef FLAC__TEST_LIBFLAC_FILE_UTILS_H +#define FLAC__TEST_LIBFLAC_FILE_UTILS_H + #include "FLAC/format.h" FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only); @@ -23,3 +26,5 @@ FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only); FLAC__bool file_utils__remove_file(const char *filename); FLAC__bool file_utils__generate_flacfile(const char *output_filename, unsigned *output_filesize, unsigned length, const FLAC__StreamMetaData *streaminfo, FLAC__StreamMetaData **metadata, unsigned num_metadata); + +#endif diff --git a/src/test_unit/main.c b/src/test_unit/main.c index 0e74655..4600aed 100644 --- a/src/test_unit/main.c +++ b/src/test_unit/main.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2000,2001,2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -18,21 +18,23 @@ #include "bitbuffer.h" #include "decoders.h" +#include "encoders.h" #include "metadata.h" int main(int argc, char *argv[]) { (void)argc, (void)argv; - if(0 != test_bitbuffer()) + if(!test_bitbuffer()) return 1; - if(0 != test_decoders()) + if(!test_encoders()) return 1; - /* the encoder is tested relatively well in the file_utils */ + if(!test_decoders()) + return 1; - if(0 != test_metadata()) + if(!test_metadata()) return 1; return 0; diff --git a/src/test_unit/metadata.c b/src/test_unit/metadata.c index b3c2be9..115e693 100644 --- a/src/test_unit/metadata.c +++ b/src/test_unit/metadata.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -22,15 +22,15 @@ extern int test_metadata_object(); extern int test_metadata_file_manipulation(); -int test_metadata() +FLAC__bool test_metadata() { - if(0 != test_metadata_object()) - return 1; + if(!test_metadata_object()) + return false; - if(0 != test_metadata_file_manipulation()) - return 1; + if(!test_metadata_file_manipulation()) + return false; printf("\nPASSED!\n"); - return 0; + return true; } diff --git a/src/test_unit/metadata.h b/src/test_unit/metadata.h index 11bc964..833232a 100644 --- a/src/test_unit/metadata.h +++ b/src/test_unit/metadata.h @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -16,9 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef FLAC__TEST_UNIT_METADATA_H -#define FLAC__TEST_UNIT_METADATA_H +#ifndef FLAC__TEST_LIBFLAC_METADATA_H +#define FLAC__TEST_LIBFLAC_METADATA_H -int test_metadata(); +#include "FLAC/ordinals.h" + +FLAC__bool test_metadata(); #endif diff --git a/src/test_unit/metadata_manip.c b/src/test_unit/metadata_manip.c index 2a8d95f..fc7ae3d 100644 --- a/src/test_unit/metadata_manip.c +++ b/src/test_unit/metadata_manip.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -23,7 +23,6 @@ #include "FLAC/metadata.h" #include #include /* for malloc() */ -#include /* for memcmp() */ /****************************************************************************** The general strategy of these tests (for interface levels 1 and 2) is @@ -199,7 +198,7 @@ static FLAC__bool compare_chain_(FLAC__MetaData_Chain *chain, unsigned current_p /* decoder callbacks for checking the file */ -static FLAC__StreamDecoderWriteStatus decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *buffer[], void *client_data) +static FLAC__StreamDecoderWriteStatus decoder_write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { (void)decoder, (void)buffer, (void)client_data; @@ -482,7 +481,7 @@ static FLAC__bool test_level_1_() printf("testing FLAC__metadata_simple_iterator_set_block() on read-only file...\n"); - if(!FLAC__metadata_simple_iterator_set_block(siterator, (void*)99, false)) + if(!FLAC__metadata_simple_iterator_set_block(siterator, (FLAC__StreamMetaData*)99, false)) printf("PASSED. FLAC__metadata_simple_iterator_set_block() returned false like it should\n"); else return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have"); @@ -1502,20 +1501,20 @@ static FLAC__bool test_level_2_() return true; } -int test_metadata_file_manipulation() +FLAC__bool test_metadata_file_manipulation() { printf("\n+++ unit test: metadata manipulation\n\n"); our_metadata_.num_blocks = 0; if(!test_level_0_()) - return 1; + return false; if(!test_level_1_()) - return 1; + return false; if(!test_level_2_()) - return 1; + return false; - return 0; + return true; } diff --git a/src/test_unit/metadata_object.c b/src/test_unit/metadata_object.c index 2bea9a8..7196414 100644 --- a/src/test_unit/metadata_object.c +++ b/src/test_unit/metadata_object.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -27,7 +27,7 @@ static FLAC__byte *make_dummydata_(FLAC__byte *dummydata, unsigned len) { FLAC__byte *ret; - if(0 == (ret = malloc(len))) { + if(0 == (ret = (FLAC__byte*)malloc(len))) { printf("FAILED, malloc error\n"); exit(1); } @@ -92,14 +92,14 @@ static FLAC__bool check_seektable_(const FLAC__StreamMetaData *block, unsigned n static void entry_new_(FLAC__StreamMetaData_VorbisComment_Entry *entry, const char *field) { entry->length = strlen(field); - entry->entry = malloc(entry->length); + entry->entry = (FLAC__byte*)malloc(entry->length); FLAC__ASSERT(0 != entry->entry); memcpy(entry->entry, field, entry->length); } static void entry_clone_(FLAC__StreamMetaData_VorbisComment_Entry *entry) { - FLAC__byte *x = malloc(entry->length); + FLAC__byte *x = (FLAC__byte*)malloc(entry->length); FLAC__ASSERT(0 != x); memcpy(x, entry->entry, entry->length); entry->entry = x; @@ -140,7 +140,7 @@ static void vc_resize_(FLAC__StreamMetaData *block, unsigned num) } } else { - vc->comments = realloc(vc->comments, sizeof(FLAC__StreamMetaData_VorbisComment_Entry)*num); + vc->comments = (FLAC__StreamMetaData_VorbisComment_Entry*)realloc(vc->comments, sizeof(FLAC__StreamMetaData_VorbisComment_Entry)*num); FLAC__ASSERT(0 != vc->comments); if(num > vc->num_comments) memset(vc->comments+vc->num_comments, 0, sizeof(FLAC__StreamMetaData_VorbisComment_Entry)*(num-vc->num_comments)); @@ -183,7 +183,7 @@ static void vc_delete_(FLAC__StreamMetaData *block, unsigned pos) vc_calc_len_(block); } -int test_metadata_object() +FLAC__bool test_metadata_object() { FLAC__StreamMetaData *block, *blockcopy, *vorbiscomment; FLAC__StreamMetaData_SeekPoint seekpoint_array[4]; @@ -200,12 +200,12 @@ int test_metadata_object() block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_STREAMINFO); if(0 == block) { printf("FAILED, returned NULL\n"); - return 1; + return false; } expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; if(block->length != expected_length) { printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length); - return 1; + return false; } printf("OK\n"); @@ -213,10 +213,10 @@ int test_metadata_object() blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -231,12 +231,12 @@ int test_metadata_object() block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING); if(0 == block) { printf("FAILED, returned NULL\n"); - return 1; + return false; } expected_length = 0; if(block->length != expected_length) { printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length); - return 1; + return false; } printf("OK\n"); @@ -244,10 +244,10 @@ int test_metadata_object() blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -262,12 +262,12 @@ int test_metadata_object() block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION); if(0 == block) { printf("FAILED, returned NULL\n"); - return 1; + return false; } expected_length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; if(block->length != expected_length) { printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length); - return 1; + return false; } printf("OK\n"); @@ -275,10 +275,10 @@ int test_metadata_object() blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -288,16 +288,16 @@ int test_metadata_object() printf("testing FLAC__metadata_object_application_set_data(copy)... "); if(!FLAC__metadata_object_application_set_data(block, dummydata, sizeof(dummydata), true/*copy*/)) { printf("FAILED, returned false\n"); - return 1; + return false; } expected_length = (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) + sizeof(dummydata); if(block->length != expected_length) { printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length); - return 1; + return false; } if(0 != memcmp(block->data.application.data, dummydata, sizeof(dummydata))) { printf("FAILED, data mismatch\n"); - return 1; + return false; } printf("OK\n"); @@ -305,10 +305,10 @@ int test_metadata_object() blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -318,16 +318,16 @@ int test_metadata_object() printf("testing FLAC__metadata_object_application_set_data(own)... "); if(!FLAC__metadata_object_application_set_data(block, make_dummydata_(dummydata, sizeof(dummydata)), sizeof(dummydata), false/*own*/)) { printf("FAILED, returned false\n"); - return 1; + return false; } expected_length = (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) + sizeof(dummydata); if(block->length != expected_length) { printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length); - return 1; + return false; } if(0 != memcmp(block->data.application.data, dummydata, sizeof(dummydata))) { printf("FAILED, data mismatch\n"); - return 1; + return false; } printf("OK\n"); @@ -335,10 +335,10 @@ int test_metadata_object() blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -360,19 +360,19 @@ int test_metadata_object() block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE); if(0 == block) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, 0)) - return 1; + return false; printf("testing FLAC__metadata_object_copy()... "); blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -383,24 +383,24 @@ int test_metadata_object() printf("testing FLAC__metadata_object_seektable_resize_points(grow to %u)...", seekpoints); if(!FLAC__metadata_object_seektable_resize_points(block, seekpoints)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; seekpoints = 1; printf("testing FLAC__metadata_object_seektable_resize_points(shrink to %u)...", seekpoints); if(!FLAC__metadata_object_seektable_resize_points(block, seekpoints)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; printf("testing FLAC__metadata_object_seektable_is_legal()..."); if(!FLAC__metadata_object_seektable_is_legal(block)) { printf("FAILED, returned false\n"); - return 1; + return false; } printf("OK\n"); @@ -408,58 +408,58 @@ int test_metadata_object() printf("testing FLAC__metadata_object_seektable_resize_points(shrink to %u)...", seekpoints); if(!FLAC__metadata_object_seektable_resize_points(block, seekpoints)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, 0)) - return 1; + return false; seekpoints++; printf("testing FLAC__metadata_object_seektable_insert_point() on empty array..."); if(!FLAC__metadata_object_seektable_insert_point(block, 0, seekpoint_array[0])) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; seekpoint_array[0].sample_number = 1; seekpoints++; printf("testing FLAC__metadata_object_seektable_insert_point() on beginning of non-empty array..."); if(!FLAC__metadata_object_seektable_insert_point(block, 0, seekpoint_array[0])) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; seekpoint_array[1].sample_number = 2; seekpoints++; printf("testing FLAC__metadata_object_seektable_insert_point() on middle of non-empty array..."); if(!FLAC__metadata_object_seektable_insert_point(block, 1, seekpoint_array[1])) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; seekpoint_array[3].sample_number = 3; seekpoints++; printf("testing FLAC__metadata_object_seektable_insert_point() on end of non-empty array..."); if(!FLAC__metadata_object_seektable_insert_point(block, 3, seekpoint_array[3])) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; printf("testing FLAC__metadata_object_copy()... "); blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -471,33 +471,33 @@ int test_metadata_object() printf("testing FLAC__metadata_object_seektable_delete_point() on middle of array..."); if(!FLAC__metadata_object_seektable_delete_point(block, 2)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; seekpoints--; printf("testing FLAC__metadata_object_seektable_delete_point() on end of array..."); if(!FLAC__metadata_object_seektable_delete_point(block, 2)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; seekpoints--; printf("testing FLAC__metadata_object_seektable_delete_point() on beginning of array..."); if(!FLAC__metadata_object_seektable_delete_point(block, 0)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!check_seektable_(block, seekpoints, seekpoint_array+1)) - return 1; + return false; printf("testing FLAC__metadata_object_seektable_set_point()..."); FLAC__metadata_object_seektable_set_point(block, 0, seekpoint_array[0]); if(!check_seektable_(block, seekpoints, seekpoint_array)) - return 1; + return false; @@ -507,12 +507,12 @@ int test_metadata_object() block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); if(0 == block) { printf("FAILED, returned NULL\n"); - return 1; + return false; } expected_length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN + FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8; if(block->length != expected_length) { printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length); - return 1; + return false; } printf("OK\n"); @@ -520,90 +520,90 @@ int test_metadata_object() vorbiscomment = FLAC__metadata_object_copy(block); if(0 == vorbiscomment) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); vc_resize_(vorbiscomment, 2); printf("testing FLAC__metadata_object_vorbiscomment_resize_comments(grow to %u)...", vorbiscomment->data.vorbis_comment.num_comments); if(!FLAC__metadata_object_vorbiscomment_resize_comments(block, vorbiscomment->data.vorbis_comment.num_comments)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); vc_resize_(vorbiscomment, 1); printf("testing FLAC__metadata_object_vorbiscomment_resize_comments(shrink to %u)...", vorbiscomment->data.vorbis_comment.num_comments); if(!FLAC__metadata_object_vorbiscomment_resize_comments(block, vorbiscomment->data.vorbis_comment.num_comments)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); vc_resize_(vorbiscomment, 0); printf("testing FLAC__metadata_object_vorbiscomment_resize_comments(shrink to %u)...", vorbiscomment->data.vorbis_comment.num_comments); if(!FLAC__metadata_object_vorbiscomment_resize_comments(block, vorbiscomment->data.vorbis_comment.num_comments)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on empty array..."); vc_insert_new_(&entry, vorbiscomment, 0, "name1=field1"); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/true)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on beginning of non-empty array..."); vc_insert_new_(&entry, vorbiscomment, 0, "name2=field2"); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/true)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on middle of non-empty array..."); vc_insert_new_(&entry, vorbiscomment, 1, "name3=field3"); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 1, entry, /*copy=*/true)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(copy) on end of non-empty array..."); vc_insert_new_(&entry, vorbiscomment, 3, "name4=field4"); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 3, entry, /*copy=*/true)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_copy()... "); blockcopy = FLAC__metadata_object_copy(block); if(0 == blockcopy) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(block, blockcopy)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -614,44 +614,44 @@ int test_metadata_object() vc_delete_(vorbiscomment, 2); if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on end of array..."); vc_delete_(vorbiscomment, 2); if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on beginning of array..."); vc_delete_(vorbiscomment, 0); if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 0)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_set_comment(copy)..."); vc_set_new_(&entry, vorbiscomment, 0, "name5=field5"); FLAC__metadata_object_vorbiscomment_set_comment(block, 0, entry, /*copy=*/true); if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_set_vendor_string(copy)..."); vc_set_vs_new_(&entry, vorbiscomment, "name6=field6"); FLAC__metadata_object_vorbiscomment_set_vendor_string(block, entry, /*copy=*/true); if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -664,7 +664,7 @@ int test_metadata_object() block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); if(0 == block) { printf("FAILED, returned NULL\n"); - return 1; + return false; } printf("OK\n"); @@ -672,10 +672,10 @@ int test_metadata_object() vorbiscomment = FLAC__metadata_object_copy(block); if(0 == vorbiscomment) { printf("FAILED, returned NULL\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on empty array..."); @@ -683,10 +683,10 @@ int test_metadata_object() entry_clone_(&entry); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/false)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on beginning of non-empty array..."); @@ -694,10 +694,10 @@ int test_metadata_object() entry_clone_(&entry); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 0, entry, /*copy=*/false)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on middle of non-empty array..."); @@ -705,10 +705,10 @@ int test_metadata_object() entry_clone_(&entry); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 1, entry, /*copy=*/false)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_insert_comment(own) on end of non-empty array..."); @@ -716,40 +716,40 @@ int test_metadata_object() entry_clone_(&entry); if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, 3, entry, /*copy=*/false)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on middle of array..."); vc_delete_(vorbiscomment, 2); if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on end of array..."); vc_delete_(vorbiscomment, 2); if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 2)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_delete_comment() on beginning of array..."); vc_delete_(vorbiscomment, 0); if(!FLAC__metadata_object_vorbiscomment_delete_comment(block, 0)) { printf("FAILED, returned false\n"); - return 1; + return false; } if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_set_comment(own)..."); @@ -757,7 +757,7 @@ int test_metadata_object() entry_clone_(&entry); FLAC__metadata_object_vorbiscomment_set_comment(block, 0, entry, /*copy=*/false); if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_vorbiscomment_set_vendor_string(own)..."); @@ -765,7 +765,7 @@ int test_metadata_object() entry_clone_(&entry); FLAC__metadata_object_vorbiscomment_set_vendor_string(block, entry, /*copy=*/false); if(!compare_block_(vorbiscomment, block)) - return 1; + return false; printf("OK\n"); printf("testing FLAC__metadata_object_delete()... "); @@ -774,60 +774,5 @@ int test_metadata_object() printf("OK\n"); - return 0; -} - -#if 0 -int test_metadata_object_pp() -{ - FLAC::Metadata::Prototype *block, *blockcopy; - FLAC__StreamMetaData_SeekPoint *seekpoint_array, *seekpoint_array_copy; - FLAC__StreamMetaData_VorbisComment_Entry *vorbiscomment_entry_array, *vorbiscomment_entry_array_copy; - unsigned expected_length; - static FLAC__byte dummydata[4] = { 'a', 'b', 'c', 'd' }; - - printf("\n+++ unit test: metadata objects (libFLAC++)\n\n"); - - - printf("testing STREAMINFO\n"); - - printf("testing FLAC::Metadata::StreamInfo::StreamInfo()... "); - block = new FLAC::Metadata::StreamInfo(); - if(0 == block) { - printf("FAILED, new returned NULL\n"); - return 1; - } - if(!block->is_valid()) { - printf("FAILED, !block->is_valid()\n"); - return 1; - } - if(block->is_valid() != *block) { - printf("FAILED, FLAC::Metadata::Prototype::operator bool() is broken\n"); - return 1; - } - expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; - if(block->length() != expected_length) { - printf("FAILED, bad length, expected %u, got %u\n", expected_length, block->length()); - return 1; - } - printf("OK\n"); - - printf("testing FLAC__metadata_object_copy()... "); - blockcopy = new FLAC::Metadata::StreamInfo(block); - if(0 == blockcopy) { - printf("FAILED, new returned NULL\n"); - return 1; - } - if(!compare_block_(block, blockcopy)) - return 1; - printf("OK\n"); - - printf("testing FLAC__metadata_object_delete()... "); - FLAC__metadata_object_delete(blockcopy); - FLAC__metadata_object_delete(block); - printf("OK\n"); - - - return 0; + return true; } -#endif diff --git a/src/test_unit/metadata_utils.c b/src/test_unit/metadata_utils.c index 1bec04c..6e69b44 100644 --- a/src/test_unit/metadata_utils.c +++ b/src/test_unit/metadata_utils.c @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or diff --git a/src/test_unit/metadata_utils.h b/src/test_unit/metadata_utils.h index ab982c1..8f403df 100644 --- a/src/test_unit/metadata_utils.h +++ b/src/test_unit/metadata_utils.h @@ -1,4 +1,4 @@ -/* test_unit - Simple FLAC unit tester +/* test_libFLAC - Unit tester for libFLAC * Copyright (C) 2002 Josh Coalson * * This program is free software; you can redistribute it and/or @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef FLAC__TEST_UNIT_METADATA_H -#define FLAC__TEST_UNIT_METADATA_H +#ifndef FLAC__TEST_LIBFLAC_METADATA_H +#define FLAC__TEST_LIBFLAC_METADATA_H /* * These are not tests, just utility functions used by the metadata tests diff --git a/test/Makefile.am b/test/Makefile.am index 01f2e9e..e1850f6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -15,9 +15,11 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -TESTS = ./test_unit.sh ./test_streams.sh ./test_bins.sh +TESTS = ./test_libFLAC.sh ./test_libFLAC++.sh ./test_streams.sh ./test_bins.sh -EXTRA_DIST = test_unit.sh \ +EXTRA_DIST = \ + test_libFLAC.sh \ + test_libFLAC++.sh \ test_streams.sh \ test_bins.sh diff --git a/test/Makefile.lite b/test/Makefile.lite index 26b1097..4605f7e 100644 --- a/test/Makefile.lite +++ b/test/Makefile.lite @@ -19,7 +19,8 @@ # GNU makefile # all: clean - ./test_unit.sh + ./test_libFLAC.sh + ./test_libFLAC++.sh ./test_streams.sh ./test_bins.sh -- 2.7.4