mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 13:10:26 -04:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3ccc390155 | ||
|
fbbead3efd | ||
|
ee1931b811 | ||
|
648f5e5882 | ||
|
c1c60ebeea | ||
|
3bc0ea0ecb | ||
|
225c73e181 | ||
|
90f62a3c94 | ||
|
5b6f9ef848 |
@ -48,7 +48,10 @@ set(TAGLIB_INSTALL_SUFFIX "" CACHE STRING
|
||||
"Suffix added to installed files (include directory, libraries, .pc)")
|
||||
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
set(TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/")
|
||||
set(TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/" CACHE STRING
|
||||
"Tests directory, is path to unit test data when 'data' is appended")
|
||||
set(TESTS_TMPDIR "" CACHE STRING
|
||||
"Directory for temporary files created during unit tests, system tmpdir is used if undefined")
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
@ -97,6 +100,16 @@ set(TAGLIB_SOVERSION_PATCH 2)
|
||||
|
||||
include(ConfigureChecks.cmake)
|
||||
|
||||
option(WITH_APE "Build with APE, MPC, WavPack" ON)
|
||||
option(WITH_ASF "Build with ASF" ON)
|
||||
option(WITH_DSF "Build with DSF" ON)
|
||||
option(WITH_MOD "Build with Tracker modules" ON)
|
||||
option(WITH_MP4 "Build with MP4" ON)
|
||||
option(WITH_RIFF "Build with AIFF, RIFF, WAV" ON)
|
||||
option(WITH_SHORTEN "Build with Shorten" ON)
|
||||
option(WITH_TRUEAUDIO "Build with TrueAudio" ON)
|
||||
option(WITH_VORBIS "Build with Vorbis, FLAC, Ogg, Opus" ON)
|
||||
|
||||
# Determine whether zlib is installed.
|
||||
option(WITH_ZLIB "Build with ZLIB" ON)
|
||||
|
||||
@ -178,6 +191,36 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_APE)
|
||||
set(TAGLIB_WITH_APE TRUE)
|
||||
endif()
|
||||
if(WITH_ASF)
|
||||
set(TAGLIB_WITH_ASF TRUE)
|
||||
endif()
|
||||
if(WITH_DSF)
|
||||
set(TAGLIB_WITH_DSF TRUE)
|
||||
endif()
|
||||
if(WITH_MOD)
|
||||
set(TAGLIB_WITH_MOD TRUE)
|
||||
endif()
|
||||
if(WITH_MP4)
|
||||
set(TAGLIB_WITH_MP4 TRUE)
|
||||
endif()
|
||||
if(WITH_RIFF)
|
||||
set(TAGLIB_WITH_RIFF TRUE)
|
||||
endif()
|
||||
if(WITH_SHORTEN)
|
||||
set(TAGLIB_WITH_SHORTEN TRUE)
|
||||
endif()
|
||||
if(WITH_TRUEAUDIO)
|
||||
set(TAGLIB_WITH_TRUEAUDIO TRUE)
|
||||
endif()
|
||||
if(WITH_VORBIS)
|
||||
set(TAGLIB_WITH_VORBIS TRUE)
|
||||
endif()
|
||||
|
||||
configure_file(taglib/taglib_config.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/taglib_config.h")
|
||||
|
||||
add_subdirectory(taglib)
|
||||
|
||||
if(BUILD_BINDINGS)
|
||||
|
78
INSTALL.md
78
INSTALL.md
@ -42,6 +42,9 @@ CMakeLists.txt file.
|
||||
| `TAGLIB_INSTALL_SUFFIX` | Suffix added to installed libraries, includes, ... |
|
||||
| `ENABLE_STATIC_RUNTIME` | Link with MSVC runtime statically |
|
||||
| `BUILD_FRAMEWORK` | Build a macOS framework |
|
||||
| `TESTS_DIR` | Where to find unit test data (with data appended) |
|
||||
| `TESTS_TMPDIR` | Where to create temporary files in unit tests |
|
||||
|
||||
|
||||
If you want to install TagLib 2 alongside TagLib 1, you can use
|
||||
`-DTAGLIB_INSTALL_SUFFIX=-2` and make sure that `BUILD_EXAMPLES` is not `ON`
|
||||
@ -49,6 +52,30 @@ for both versions. The installed files will then include bin/taglib-2-config,
|
||||
include/taglib-2, cmake/taglib-2, pkgconfig/taglib-2.pc,
|
||||
pkgconfig/taglib_c-2.pc and the libraries have a suffix "-2".
|
||||
|
||||
### Compile Time Configuration of Supported Formats
|
||||
|
||||
To reduce the size of the library, it is possible to switch off supported file
|
||||
formats. By default, all formats are enabled. Support for MPEG files (MP3, AAC)
|
||||
and ID3 tags cannot be disabled. The following CMake options are available:
|
||||
|
||||
| Option | Description |
|
||||
|-------------------------|----------------------------------------------------|
|
||||
| `WITH_APE` | Build with APE, MPC, WavPack (default ON) |
|
||||
| `WITH_ASF` | Build with ASF (default ON) |
|
||||
| `WITH_DSF` | Build with DSF (default ON) |
|
||||
| `WITH_MOD` | Build with Tracker modules (default ON) |
|
||||
| `WITH_MP4` | Build with MP4 (default ON) |
|
||||
| `WITH_RIFF` | Build with AIFF, RIFF, WAV (default ON) |
|
||||
| `WITH_SHORTEN` | Build with Shorten (default ON) |
|
||||
| `WITH_TRUEAUDIO` | Build with TrueAudio (default ON) |
|
||||
| `WITH_VORBIS` | Build with Vorbis, FLAC, Ogg, Opus (default ON) |
|
||||
|
||||
Note that disabling formats will remove exported symbols from the library and
|
||||
thus break binary compatibility. These options should therefore only be used
|
||||
if the library is built specifically for a certain project. The public header
|
||||
files still contain the full API, if you use TagLib with a reduced set of
|
||||
formats, you can include taglib_config.h and use its definitions (prefixed with
|
||||
`TAGLIB_`, e.g. `TAGLIB_WITH_APE`), as it is done in examples/framelist.cpp.
|
||||
|
||||
## Dependencies
|
||||
|
||||
@ -438,3 +465,54 @@ cmake --build build_mingw --config Release
|
||||
PATH=$PATH:$TAGLIB_PREFIX/bin
|
||||
build_mingw/tagreader /path/to/audio-file
|
||||
```
|
||||
|
||||
## Android
|
||||
|
||||
### Using vcpkg
|
||||
|
||||
The bash script below can be used to build TagLib for Android using vcpkg.
|
||||
It must be started in the parent folder of the taglib source folder and will
|
||||
build in a folder _android_build_ and install into _android_pkg_.
|
||||
The package and the unit tests are then transferred to an Android device
|
||||
and the unit tests are run on the device.
|
||||
|
||||
Note that `TESTS_TMPDIR` is set because there is no system-wide temporary folder
|
||||
on Android. `TESTS_DIR` is set to run the tests on the target.
|
||||
|
||||
```
|
||||
# You may have to adapt the NDK and vcpkg paths and the ABI/triplet.
|
||||
|
||||
export ANDROID_NDK_HOME=$HOME/Development/android-sdk/ndk/23.1.7779620
|
||||
export VCPKG_ROOT=$HOME/Development/vcpkg
|
||||
PATH=$PATH:$VCPKG_ROOT
|
||||
|
||||
# armeabi-v7a/arm-android or arm64-v8a/arm64-android or x86/x86-android or x86_64/x64-android
|
||||
android_abi=armeabi-v7a
|
||||
vcpkg_target_triplet=arm-android
|
||||
|
||||
vcpkg_toolchain_file=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
|
||||
android_toolchain_file=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake
|
||||
|
||||
vcpkg install --triplet $vcpkg_target_triplet utfcpp zlib cppunit
|
||||
|
||||
cmake -B android_build -S taglib \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$vcpkg_toolchain_file \
|
||||
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=$android_toolchain_file \
|
||||
-DVCPKG_TARGET_TRIPLET=$vcpkg_target_triplet \
|
||||
-DANDROID_ABI=$android_abi \
|
||||
-GNinja -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \
|
||||
-DVISIBILITY_HIDDEN=ON -DENABLE_CCACHE=ON -DBUILD_EXAMPLES=ON -DBUILD_TESTING=ON \
|
||||
-DTESTS_DIR=/data/local/tmp/tests/ -DTESTS_TMPDIR=/data/local/tmp
|
||||
cmake --build android_build --config Release
|
||||
cmake --install android_build --config Release --prefix android_pkg --strip
|
||||
cp -a android_build/tests/test_runner android_pkg/bin/
|
||||
|
||||
if hash adb 2>/dev/null; then
|
||||
adb push android_pkg /data/local/tmp/
|
||||
adb push android_build/tests/test_runner /data/local/tmp/tests/test_runner
|
||||
adb push taglib/tests/data /data/local/tmp/tests/
|
||||
adb shell "env LD_LIBRARY_PATH=/data/local/tmp/android_pkg/lib /data/local/tmp/tests/test_runner"
|
||||
# You could also try an example binary:
|
||||
# adb shell "env LD_LIBRARY_PATH=/data/local/tmp/android_pkg/lib /data/local/tmp/android_pkg/bin/tagreader '/sdcard/Music/Some Album/A Track.mp3'"
|
||||
fi
|
||||
```
|
||||
|
@ -1,31 +1,69 @@
|
||||
include_directories(
|
||||
set(tag_c_HDR_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/toolkit
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/asf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/vorbis
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mp4
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2/frames
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/riff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/riff/aiff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/riff/wav
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ape
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/it
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mod
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/s3m
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/xm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/opus
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/dsf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/dsdiff
|
||||
)
|
||||
if(WITH_ASF)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/asf
|
||||
)
|
||||
endif()
|
||||
if(WITH_VORBIS)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/vorbis
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/opus
|
||||
)
|
||||
endif()
|
||||
if(WITH_APE)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ape
|
||||
)
|
||||
endif()
|
||||
if(WITH_MP4)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mp4
|
||||
)
|
||||
endif()
|
||||
if(WITH_TRUEAUDIO)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio
|
||||
)
|
||||
endif()
|
||||
if(WITH_RIFF)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/riff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/riff/aiff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/riff/wav
|
||||
)
|
||||
endif()
|
||||
if(WITH_MOD)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/it
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mod
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/s3m
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/xm
|
||||
)
|
||||
endif()
|
||||
if(WITH_DSF)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/dsf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/dsdiff
|
||||
)
|
||||
endif()
|
||||
if(WITH_SHORTEN)
|
||||
set(tag_c_HDR_DIRS ${tag_c_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/shorten
|
||||
)
|
||||
endif()
|
||||
include_directories(${tag_c_HDR_DIRS})
|
||||
|
||||
set(tag_c_HDRS tag_c.h)
|
||||
|
||||
|
@ -29,34 +29,57 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tstringlist.h"
|
||||
#include "tbytevectorstream.h"
|
||||
#include "tiostream.h"
|
||||
#include "tfile.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "fileref.h"
|
||||
#include "asffile.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "mpegfile.h"
|
||||
#include "tag.h"
|
||||
#include "id3v2framefactory.h"
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include "asffile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "vorbisfile.h"
|
||||
#include "flacfile.h"
|
||||
#include "oggflacfile.h"
|
||||
#include "speexfile.h"
|
||||
#include "opusfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "mpcfile.h"
|
||||
#include "wavpackfile.h"
|
||||
#include "speexfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
#include "trueaudiofile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include "mp4file.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
#include "aifffile.h"
|
||||
#include "wavfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apefile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
#include "itfile.h"
|
||||
#include "modfile.h"
|
||||
#include "s3mfile.h"
|
||||
#include "xmfile.h"
|
||||
#include "opusfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
#include "dsffile.h"
|
||||
#include "dsdifffile.h"
|
||||
#include "tag.h"
|
||||
#include "id3v2framefactory.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
#include "shortenfile.h"
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -126,49 +149,73 @@ TagLib_File *taglib_file_new(const char *filename)
|
||||
return reinterpret_cast<TagLib_File *>(new FileRef(filename));
|
||||
}
|
||||
|
||||
TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
|
||||
#ifdef _WIN32
|
||||
TagLib_File *taglib_file_new_wchar(const wchar_t *filename)
|
||||
{
|
||||
return reinterpret_cast<TagLib_File *>(new FileRef(filename));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
TagLib_File *taglib_file_new_type_any_char(const T *filename, TagLib_File_Type type)
|
||||
{
|
||||
File *file = NULL;
|
||||
switch(type) {
|
||||
case TagLib_File_MPEG:
|
||||
file = new MPEG::File(filename);
|
||||
break;
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
case TagLib_File_OggVorbis:
|
||||
file = new Ogg::Vorbis::File(filename);
|
||||
break;
|
||||
case TagLib_File_FLAC:
|
||||
file = new FLAC::File(filename);
|
||||
break;
|
||||
case TagLib_File_MPC:
|
||||
file = new MPC::File(filename);
|
||||
break;
|
||||
case TagLib_File_OggFlac:
|
||||
file = new Ogg::FLAC::File(filename);
|
||||
break;
|
||||
case TagLib_File_WavPack:
|
||||
file = new WavPack::File(filename);
|
||||
break;
|
||||
case TagLib_File_Speex:
|
||||
file = new Ogg::Speex::File(filename);
|
||||
break;
|
||||
case TagLib_File_Opus:
|
||||
file = new Ogg::Opus::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
case TagLib_File_MPC:
|
||||
file = new MPC::File(filename);
|
||||
break;
|
||||
case TagLib_File_WavPack:
|
||||
file = new WavPack::File(filename);
|
||||
break;
|
||||
case TagLib_File_APE:
|
||||
file = new APE::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
case TagLib_File_TrueAudio:
|
||||
file = new TrueAudio::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
case TagLib_File_MP4:
|
||||
file = new MP4::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
case TagLib_File_ASF:
|
||||
file = new ASF::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
case TagLib_File_AIFF:
|
||||
file = new RIFF::AIFF::File(filename);
|
||||
break;
|
||||
case TagLib_File_WAV:
|
||||
file = new RIFF::WAV::File(filename);
|
||||
break;
|
||||
case TagLib_File_APE:
|
||||
file = new APE::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
case TagLib_File_IT:
|
||||
file = new IT::File(filename);
|
||||
break;
|
||||
@ -181,21 +228,38 @@ TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
|
||||
case TagLib_File_XM:
|
||||
file = new XM::File(filename);
|
||||
break;
|
||||
case TagLib_File_Opus:
|
||||
file = new Ogg::Opus::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
case TagLib_File_DSF:
|
||||
file = new DSF::File(filename);
|
||||
break;
|
||||
case TagLib_File_DSDIFF:
|
||||
file = new DSDIFF::File(filename);
|
||||
break;
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
case TagLib_File_SHORTEN:
|
||||
file = new Shorten::File(filename);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return file ? reinterpret_cast<TagLib_File *>(new FileRef(file)) : NULL;
|
||||
}
|
||||
|
||||
TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
|
||||
{
|
||||
return taglib_file_new_type_any_char(filename, type);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TagLib_File *taglib_file_new_type_wchar(const wchar_t *filename, TagLib_File_Type type)
|
||||
{
|
||||
return taglib_file_new_type_any_char(filename, type);
|
||||
}
|
||||
#endif
|
||||
|
||||
TagLib_File *taglib_file_new_iostream(TagLib_IOStream *stream)
|
||||
{
|
||||
return reinterpret_cast<TagLib_File *>(
|
||||
|
@ -130,7 +130,8 @@ typedef enum {
|
||||
TagLib_File_XM,
|
||||
TagLib_File_Opus,
|
||||
TagLib_File_DSF,
|
||||
TagLib_File_DSDIFF
|
||||
TagLib_File_DSDIFF,
|
||||
TagLib_File_SHORTEN
|
||||
} TagLib_File_Type;
|
||||
|
||||
/*!
|
||||
@ -141,12 +142,18 @@ typedef enum {
|
||||
* be opened.
|
||||
*/
|
||||
TAGLIB_C_EXPORT TagLib_File *taglib_file_new(const char *filename);
|
||||
#ifdef _WIN32
|
||||
TAGLIB_C_EXPORT TagLib_File *taglib_file_new_wchar(const wchar_t *filename);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a TagLib file based on \a filename. Rather than attempting to guess
|
||||
* the type, it will use the one specified by \a type.
|
||||
*/
|
||||
TAGLIB_C_EXPORT TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type);
|
||||
#ifdef _WIN32
|
||||
TAGLIB_C_EXPORT TagLib_File *taglib_file_new_type_wchar(const wchar_t *filename, TagLib_File_Type type);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a TagLib file from a \a stream.
|
||||
|
@ -20,5 +20,6 @@
|
||||
#cmakedefine TRACE_IN_RELEASE 1
|
||||
|
||||
#cmakedefine TESTS_DIR "@TESTS_DIR@"
|
||||
#cmakedefine TESTS_TMPDIR "@TESTS_TMPDIR@"
|
||||
|
||||
#endif
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tbytevector.h"
|
||||
#include "mpegfile.h"
|
||||
#include "id3v2tag.h"
|
||||
@ -32,7 +33,9 @@
|
||||
#include "id3v2header.h"
|
||||
#include "commentsframe.h"
|
||||
#include "id3v1tag.h"
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -90,6 +93,7 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
std::cout << "file does not have a valid id3v1 tag" << std::endl;
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
APE::Tag *ape = f.APETag();
|
||||
|
||||
std::cout << std::endl << "APE" << std::endl;
|
||||
@ -106,6 +110,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
std::cout << "file does not have a valid APE tag" << std::endl;
|
||||
#endif
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
@ -1,38 +1,77 @@
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
include_directories(
|
||||
set(tag_HDR_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/toolkit
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/asf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mpeg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mpc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mp4
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/opus
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2/frames
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ape
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wavpack
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/trueaudio
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/riff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/riff/aiff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/riff/wav
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mod
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s3m
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/it
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dsf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dsdiff
|
||||
)
|
||||
if(WITH_ASF)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/asf
|
||||
)
|
||||
endif()
|
||||
if(WITH_VORBIS)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ogg/opus
|
||||
)
|
||||
endif()
|
||||
if(WITH_APE)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mpc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ape
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wavpack
|
||||
)
|
||||
endif()
|
||||
if(WITH_MP4)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mp4
|
||||
)
|
||||
endif()
|
||||
if(WITH_TRUEAUDIO)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/trueaudio
|
||||
)
|
||||
endif()
|
||||
if(WITH_RIFF)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/riff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/riff/aiff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/riff/wav
|
||||
)
|
||||
endif()
|
||||
if(WITH_MOD)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mod
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s3m
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/it
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xm
|
||||
)
|
||||
endif()
|
||||
if(WITH_DSF)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dsf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dsdiff
|
||||
)
|
||||
endif()
|
||||
if(WITH_SHORTEN)
|
||||
set(tag_HDR_DIRS ${tag_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shorten
|
||||
)
|
||||
endif()
|
||||
include_directories(${tag_HDR_DIRS})
|
||||
|
||||
set(tag_HDRS
|
||||
tag.h
|
||||
fileref.h
|
||||
audioproperties.h
|
||||
taglib_export.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h
|
||||
toolkit/taglib.h
|
||||
toolkit/tstring.h
|
||||
toolkit/tlist.h
|
||||
@ -82,66 +121,105 @@ set(tag_HDRS
|
||||
mpeg/id3v2/frames/chapterframe.h
|
||||
mpeg/id3v2/frames/tableofcontentsframe.h
|
||||
mpeg/id3v2/frames/podcastframe.h
|
||||
ogg/oggfile.h
|
||||
ogg/oggpage.h
|
||||
ogg/oggpageheader.h
|
||||
ogg/xiphcomment.h
|
||||
ogg/vorbis/vorbisfile.h
|
||||
ogg/vorbis/vorbisproperties.h
|
||||
ogg/flac/oggflacfile.h
|
||||
ogg/speex/speexfile.h
|
||||
ogg/speex/speexproperties.h
|
||||
ogg/opus/opusfile.h
|
||||
ogg/opus/opusproperties.h
|
||||
flac/flacfile.h
|
||||
flac/flacpicture.h
|
||||
flac/flacproperties.h
|
||||
flac/flacmetadatablock.h
|
||||
ape/apefile.h
|
||||
ape/apeproperties.h
|
||||
ape/apetag.h
|
||||
ape/apefooter.h
|
||||
ape/apeitem.h
|
||||
mpc/mpcfile.h
|
||||
mpc/mpcproperties.h
|
||||
wavpack/wavpackfile.h
|
||||
wavpack/wavpackproperties.h
|
||||
trueaudio/trueaudiofile.h
|
||||
trueaudio/trueaudioproperties.h
|
||||
riff/rifffile.h
|
||||
riff/aiff/aifffile.h
|
||||
riff/aiff/aiffproperties.h
|
||||
riff/wav/wavfile.h
|
||||
riff/wav/wavproperties.h
|
||||
riff/wav/infotag.h
|
||||
asf/asffile.h
|
||||
asf/asfproperties.h
|
||||
asf/asftag.h
|
||||
asf/asfattribute.h
|
||||
asf/asfpicture.h
|
||||
mp4/mp4file.h
|
||||
mp4/mp4atom.h
|
||||
mp4/mp4tag.h
|
||||
mp4/mp4item.h
|
||||
mp4/mp4properties.h
|
||||
mp4/mp4coverart.h
|
||||
mp4/mp4itemfactory.h
|
||||
mod/modfilebase.h
|
||||
mod/modfile.h
|
||||
mod/modtag.h
|
||||
mod/modproperties.h
|
||||
it/itfile.h
|
||||
it/itproperties.h
|
||||
s3m/s3mfile.h
|
||||
s3m/s3mproperties.h
|
||||
xm/xmfile.h
|
||||
xm/xmproperties.h
|
||||
dsf/dsffile.h
|
||||
dsf/dsfproperties.h
|
||||
dsdiff/dsdifffile.h
|
||||
dsdiff/dsdiffproperties.h
|
||||
dsdiff/dsdiffdiintag.h
|
||||
)
|
||||
if(WITH_VORBIS)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
ogg/oggfile.h
|
||||
ogg/oggpage.h
|
||||
ogg/oggpageheader.h
|
||||
ogg/xiphcomment.h
|
||||
ogg/vorbis/vorbisfile.h
|
||||
ogg/vorbis/vorbisproperties.h
|
||||
ogg/flac/oggflacfile.h
|
||||
ogg/speex/speexfile.h
|
||||
ogg/speex/speexproperties.h
|
||||
ogg/opus/opusfile.h
|
||||
ogg/opus/opusproperties.h
|
||||
flac/flacfile.h
|
||||
flac/flacpicture.h
|
||||
flac/flacproperties.h
|
||||
flac/flacmetadatablock.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_APE)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
ape/apefile.h
|
||||
ape/apeproperties.h
|
||||
ape/apetag.h
|
||||
ape/apefooter.h
|
||||
ape/apeitem.h
|
||||
mpc/mpcfile.h
|
||||
mpc/mpcproperties.h
|
||||
wavpack/wavpackfile.h
|
||||
wavpack/wavpackproperties.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_TRUEAUDIO)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
trueaudio/trueaudiofile.h
|
||||
trueaudio/trueaudioproperties.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_RIFF)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
riff/rifffile.h
|
||||
riff/aiff/aifffile.h
|
||||
riff/aiff/aiffproperties.h
|
||||
riff/wav/wavfile.h
|
||||
riff/wav/wavproperties.h
|
||||
riff/wav/infotag.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_ASF)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
asf/asffile.h
|
||||
asf/asfproperties.h
|
||||
asf/asftag.h
|
||||
asf/asfattribute.h
|
||||
asf/asfpicture.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_MP4)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
mp4/mp4file.h
|
||||
mp4/mp4atom.h
|
||||
mp4/mp4tag.h
|
||||
mp4/mp4item.h
|
||||
mp4/mp4properties.h
|
||||
mp4/mp4coverart.h
|
||||
mp4/mp4itemfactory.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_MOD)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
mod/modfilebase.h
|
||||
mod/modfile.h
|
||||
mod/modtag.h
|
||||
mod/modproperties.h
|
||||
it/itfile.h
|
||||
it/itproperties.h
|
||||
s3m/s3mfile.h
|
||||
s3m/s3mproperties.h
|
||||
xm/xmfile.h
|
||||
xm/xmproperties.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_DSF)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
dsf/dsffile.h
|
||||
dsf/dsfproperties.h
|
||||
dsdiff/dsdifffile.h
|
||||
dsdiff/dsdiffproperties.h
|
||||
dsdiff/dsdiffdiintag.h
|
||||
)
|
||||
endif()
|
||||
if(WITH_SHORTEN)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
shorten/shortenfile.h
|
||||
shorten/shortenproperties.h
|
||||
shorten/shortentag.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set(mpeg_SRCS
|
||||
mpeg/mpegfile.cpp
|
||||
@ -185,128 +263,152 @@ set(frames_SRCS
|
||||
mpeg/id3v2/frames/podcastframe.cpp
|
||||
)
|
||||
|
||||
set(ogg_SRCS
|
||||
ogg/oggfile.cpp
|
||||
ogg/oggpage.cpp
|
||||
ogg/oggpageheader.cpp
|
||||
ogg/xiphcomment.cpp
|
||||
)
|
||||
if(WITH_VORBIS)
|
||||
set(ogg_SRCS
|
||||
ogg/oggfile.cpp
|
||||
ogg/oggpage.cpp
|
||||
ogg/oggpageheader.cpp
|
||||
ogg/xiphcomment.cpp
|
||||
)
|
||||
|
||||
set(vorbis_SRCS
|
||||
ogg/vorbis/vorbisfile.cpp
|
||||
ogg/vorbis/vorbisproperties.cpp
|
||||
)
|
||||
set(vorbis_SRCS
|
||||
ogg/vorbis/vorbisfile.cpp
|
||||
ogg/vorbis/vorbisproperties.cpp
|
||||
)
|
||||
|
||||
set(flacs_SRCS
|
||||
flac/flacfile.cpp
|
||||
flac/flacpicture.cpp
|
||||
flac/flacproperties.cpp
|
||||
flac/flacmetadatablock.cpp
|
||||
flac/flacunknownmetadatablock.cpp
|
||||
)
|
||||
set(flacs_SRCS
|
||||
flac/flacfile.cpp
|
||||
flac/flacpicture.cpp
|
||||
flac/flacproperties.cpp
|
||||
flac/flacmetadatablock.cpp
|
||||
flac/flacunknownmetadatablock.cpp
|
||||
)
|
||||
|
||||
set(oggflacs_SRCS
|
||||
ogg/flac/oggflacfile.cpp
|
||||
)
|
||||
set(oggflacs_SRCS
|
||||
ogg/flac/oggflacfile.cpp
|
||||
)
|
||||
|
||||
set(mpc_SRCS
|
||||
mpc/mpcfile.cpp
|
||||
mpc/mpcproperties.cpp
|
||||
)
|
||||
set(speex_SRCS
|
||||
ogg/speex/speexfile.cpp
|
||||
ogg/speex/speexproperties.cpp
|
||||
)
|
||||
|
||||
set(mp4_SRCS
|
||||
mp4/mp4file.cpp
|
||||
mp4/mp4atom.cpp
|
||||
mp4/mp4tag.cpp
|
||||
mp4/mp4item.cpp
|
||||
mp4/mp4properties.cpp
|
||||
mp4/mp4coverart.cpp
|
||||
mp4/mp4itemfactory.cpp
|
||||
)
|
||||
set(opus_SRCS
|
||||
ogg/opus/opusfile.cpp
|
||||
ogg/opus/opusproperties.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(ape_SRCS
|
||||
ape/apetag.cpp
|
||||
ape/apefooter.cpp
|
||||
ape/apeitem.cpp
|
||||
ape/apefile.cpp
|
||||
ape/apeproperties.cpp
|
||||
)
|
||||
if(WITH_APE)
|
||||
set(mpc_SRCS
|
||||
mpc/mpcfile.cpp
|
||||
mpc/mpcproperties.cpp
|
||||
)
|
||||
|
||||
set(wavpack_SRCS
|
||||
wavpack/wavpackfile.cpp
|
||||
wavpack/wavpackproperties.cpp
|
||||
)
|
||||
set(ape_SRCS
|
||||
ape/apetag.cpp
|
||||
ape/apefooter.cpp
|
||||
ape/apeitem.cpp
|
||||
ape/apefile.cpp
|
||||
ape/apeproperties.cpp
|
||||
)
|
||||
|
||||
set(speex_SRCS
|
||||
ogg/speex/speexfile.cpp
|
||||
ogg/speex/speexproperties.cpp
|
||||
)
|
||||
set(wavpack_SRCS
|
||||
wavpack/wavpackfile.cpp
|
||||
wavpack/wavpackproperties.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(opus_SRCS
|
||||
ogg/opus/opusfile.cpp
|
||||
ogg/opus/opusproperties.cpp
|
||||
)
|
||||
if(WITH_MP4)
|
||||
set(mp4_SRCS
|
||||
mp4/mp4file.cpp
|
||||
mp4/mp4atom.cpp
|
||||
mp4/mp4tag.cpp
|
||||
mp4/mp4item.cpp
|
||||
mp4/mp4properties.cpp
|
||||
mp4/mp4coverart.cpp
|
||||
mp4/mp4itemfactory.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(trueaudio_SRCS
|
||||
trueaudio/trueaudiofile.cpp
|
||||
trueaudio/trueaudioproperties.cpp
|
||||
)
|
||||
if(WITH_TRUEAUDIO)
|
||||
set(trueaudio_SRCS
|
||||
trueaudio/trueaudiofile.cpp
|
||||
trueaudio/trueaudioproperties.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(asf_SRCS
|
||||
asf/asftag.cpp
|
||||
asf/asffile.cpp
|
||||
asf/asfproperties.cpp
|
||||
asf/asfattribute.cpp
|
||||
asf/asfpicture.cpp
|
||||
)
|
||||
if(WITH_ASF)
|
||||
set(asf_SRCS
|
||||
asf/asftag.cpp
|
||||
asf/asffile.cpp
|
||||
asf/asfproperties.cpp
|
||||
asf/asfattribute.cpp
|
||||
asf/asfpicture.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(riff_SRCS
|
||||
riff/rifffile.cpp
|
||||
)
|
||||
if(WITH_RIFF)
|
||||
set(riff_SRCS
|
||||
riff/rifffile.cpp
|
||||
)
|
||||
|
||||
set(aiff_SRCS
|
||||
riff/aiff/aifffile.cpp
|
||||
riff/aiff/aiffproperties.cpp
|
||||
)
|
||||
set(aiff_SRCS
|
||||
riff/aiff/aifffile.cpp
|
||||
riff/aiff/aiffproperties.cpp
|
||||
)
|
||||
|
||||
set(wav_SRCS
|
||||
riff/wav/wavfile.cpp
|
||||
riff/wav/wavproperties.cpp
|
||||
riff/wav/infotag.cpp
|
||||
)
|
||||
set(wav_SRCS
|
||||
riff/wav/wavfile.cpp
|
||||
riff/wav/wavproperties.cpp
|
||||
riff/wav/infotag.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(mod_SRCS
|
||||
mod/modfilebase.cpp
|
||||
mod/modfile.cpp
|
||||
mod/modtag.cpp
|
||||
mod/modproperties.cpp
|
||||
)
|
||||
if(WITH_MOD)
|
||||
set(mod_SRCS
|
||||
mod/modfilebase.cpp
|
||||
mod/modfile.cpp
|
||||
mod/modtag.cpp
|
||||
mod/modproperties.cpp
|
||||
)
|
||||
|
||||
set(s3m_SRCS
|
||||
s3m/s3mfile.cpp
|
||||
s3m/s3mproperties.cpp
|
||||
)
|
||||
set(s3m_SRCS
|
||||
s3m/s3mfile.cpp
|
||||
s3m/s3mproperties.cpp
|
||||
)
|
||||
|
||||
set(it_SRCS
|
||||
it/itfile.cpp
|
||||
it/itproperties.cpp
|
||||
)
|
||||
set(it_SRCS
|
||||
it/itfile.cpp
|
||||
it/itproperties.cpp
|
||||
)
|
||||
|
||||
set(xm_SRCS
|
||||
xm/xmfile.cpp
|
||||
xm/xmproperties.cpp
|
||||
)
|
||||
set(xm_SRCS
|
||||
xm/xmfile.cpp
|
||||
xm/xmproperties.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(dsf_SRCS
|
||||
dsf/dsffile.cpp
|
||||
dsf/dsfproperties.cpp
|
||||
)
|
||||
if(WITH_DSF)
|
||||
set(dsf_SRCS
|
||||
dsf/dsffile.cpp
|
||||
dsf/dsfproperties.cpp
|
||||
)
|
||||
|
||||
set(dsdiff_SRCS
|
||||
dsdiff/dsdifffile.cpp
|
||||
dsdiff/dsdiffproperties.cpp
|
||||
dsdiff/dsdiffdiintag.cpp
|
||||
)
|
||||
set(dsdiff_SRCS
|
||||
dsdiff/dsdifffile.cpp
|
||||
dsdiff/dsdiffproperties.cpp
|
||||
dsdiff/dsdiffdiintag.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_SHORTEN)
|
||||
set(shorten_SRCS
|
||||
shorten/shortenfile.cpp
|
||||
shorten/shortenproperties.cpp
|
||||
shorten/shortentag.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(toolkit_SRCS
|
||||
toolkit/tstring.cpp
|
||||
@ -331,7 +433,7 @@ set(tag_LIB_SRCS
|
||||
${vorbis_SRCS} ${oggflacs_SRCS} ${mpc_SRCS} ${ape_SRCS} ${toolkit_SRCS} ${flacs_SRCS}
|
||||
${wavpack_SRCS} ${speex_SRCS} ${trueaudio_SRCS} ${riff_SRCS} ${aiff_SRCS} ${wav_SRCS}
|
||||
${asf_SRCS} ${mp4_SRCS} ${mod_SRCS} ${s3m_SRCS} ${it_SRCS} ${xm_SRCS} ${opus_SRCS}
|
||||
${dsf_SRCS} ${dsdiff_SRCS}
|
||||
${dsf_SRCS} ${dsdiff_SRCS} ${shorten_SRCS}
|
||||
tag.cpp
|
||||
tagunion.cpp
|
||||
fileref.cpp
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef TAGLIB_DSDIFFFILE_H
|
||||
#define TAGLIB_DSDIFFFILE_H
|
||||
|
||||
#include "rifffile.h"
|
||||
#include "tfile.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "dsdiffproperties.h"
|
||||
#include "dsdiffdiintag.h"
|
||||
|
@ -32,31 +32,51 @@
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tfilestream.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tstringlist.h"
|
||||
#include "tvariant.h"
|
||||
#include "tdebug.h"
|
||||
#include "aifffile.h"
|
||||
#include "apefile.h"
|
||||
#include "asffile.h"
|
||||
#include "flacfile.h"
|
||||
#include "itfile.h"
|
||||
#include "modfile.h"
|
||||
#include "mp4file.h"
|
||||
#include "mpcfile.h"
|
||||
#include "mpegfile.h"
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
#include "aifffile.h"
|
||||
#include "wavfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apefile.h"
|
||||
#include "mpcfile.h"
|
||||
#include "wavpackfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include "asffile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "flacfile.h"
|
||||
#include "speexfile.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "oggflacfile.h"
|
||||
#include "opusfile.h"
|
||||
#include "s3mfile.h"
|
||||
#include "speexfile.h"
|
||||
#include "trueaudiofile.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "wavfile.h"
|
||||
#include "wavpackfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
#include "itfile.h"
|
||||
#include "modfile.h"
|
||||
#include "xmfile.h"
|
||||
#include "s3mfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include "mp4file.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
#include "trueaudiofile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
#include "dsffile.h"
|
||||
#include "dsdifffile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
#include "shortenfile.h"
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -135,6 +155,7 @@ namespace
|
||||
|
||||
if(ext == "MP3" || ext == "MP2" || ext == "AAC")
|
||||
file = new MPEG::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
else if(ext == "OGG")
|
||||
file = new Ogg::Vorbis::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "OGA") {
|
||||
@ -147,26 +168,38 @@ namespace
|
||||
}
|
||||
else if(ext == "FLAC")
|
||||
file = new FLAC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "MPC")
|
||||
file = new MPC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "WV")
|
||||
file = new WavPack::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "SPX")
|
||||
file = new Ogg::Speex::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "OPUS")
|
||||
file = new Ogg::Opus::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
else if(ext == "MPC")
|
||||
file = new MPC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "WV")
|
||||
file = new WavPack::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "APE")
|
||||
file = new APE::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
else if(ext == "TTA")
|
||||
file = new TrueAudio::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
else if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2" || ext == "M4V")
|
||||
file = new MP4::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
else if(ext == "WMA" || ext == "ASF")
|
||||
file = new ASF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
else if(ext == "AIF" || ext == "AIFF" || ext == "AFC" || ext == "AIFC")
|
||||
file = new RIFF::AIFF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "WAV")
|
||||
file = new RIFF::WAV::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "APE")
|
||||
file = new APE::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
// module, nst and wow are possible but uncommon extensions
|
||||
else if(ext == "MOD" || ext == "MODULE" || ext == "NST" || ext == "WOW")
|
||||
file = new Mod::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
@ -176,10 +209,17 @@ namespace
|
||||
file = new IT::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "XM")
|
||||
file = new XM::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
else if(ext == "DSF")
|
||||
file = new DSF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(ext == "DFF" || ext == "DSDIFF")
|
||||
file = new DSDIFF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
else if(ext == "SHN")
|
||||
file = new Shorten::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
|
||||
// if file is not valid, leave it to content-based detection.
|
||||
|
||||
@ -201,36 +241,54 @@ namespace
|
||||
|
||||
if(MPEG::File::isSupported(stream))
|
||||
file = new MPEG::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
else if(Ogg::Vorbis::File::isSupported(stream))
|
||||
file = new Ogg::Vorbis::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(Ogg::FLAC::File::isSupported(stream))
|
||||
file = new Ogg::FLAC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(FLAC::File::isSupported(stream))
|
||||
file = new FLAC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(MPC::File::isSupported(stream))
|
||||
file = new MPC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(WavPack::File::isSupported(stream))
|
||||
file = new WavPack::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(Ogg::Speex::File::isSupported(stream))
|
||||
file = new Ogg::Speex::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(Ogg::Opus::File::isSupported(stream))
|
||||
file = new Ogg::Opus::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
else if(MPC::File::isSupported(stream))
|
||||
file = new MPC::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(WavPack::File::isSupported(stream))
|
||||
file = new WavPack::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(APE::File::isSupported(stream))
|
||||
file = new APE::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
else if(TrueAudio::File::isSupported(stream))
|
||||
file = new TrueAudio::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
else if(MP4::File::isSupported(stream))
|
||||
file = new MP4::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
else if(ASF::File::isSupported(stream))
|
||||
file = new ASF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
else if(RIFF::AIFF::File::isSupported(stream))
|
||||
file = new RIFF::AIFF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(RIFF::WAV::File::isSupported(stream))
|
||||
file = new RIFF::WAV::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(APE::File::isSupported(stream))
|
||||
file = new APE::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
else if(DSF::File::isSupported(stream))
|
||||
file = new DSF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
else if(DSDIFF::File::isSupported(stream))
|
||||
file = new DSDIFF::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
else if(Shorten::File::isSupported(stream))
|
||||
file = new Shorten::File(stream, readAudioProperties, audioPropertiesStyle);
|
||||
#endif
|
||||
|
||||
// isSupported() only does a quick check, so double check the file here.
|
||||
|
||||
@ -400,17 +458,25 @@ StringList FileRef::defaultFileExtensions()
|
||||
{
|
||||
StringList l;
|
||||
|
||||
l.append("mp3");
|
||||
l.append("mp2");
|
||||
l.append("aac");
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
l.append("ogg");
|
||||
l.append("flac");
|
||||
l.append("oga");
|
||||
l.append("opus");
|
||||
l.append("mp3");
|
||||
l.append("mp2");
|
||||
l.append("spx");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
l.append("mpc");
|
||||
l.append("wv");
|
||||
l.append("spx");
|
||||
l.append("ape");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
l.append("tta");
|
||||
l.append("aac");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
l.append("m4a");
|
||||
l.append("m4r");
|
||||
l.append("m4b");
|
||||
@ -418,14 +484,19 @@ StringList FileRef::defaultFileExtensions()
|
||||
l.append("3g2");
|
||||
l.append("mp4");
|
||||
l.append("m4v");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
l.append("wma");
|
||||
l.append("asf");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
l.append("aif");
|
||||
l.append("aiff");
|
||||
l.append("afc");
|
||||
l.append("aifc");
|
||||
l.append("wav");
|
||||
l.append("ape");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
l.append("mod");
|
||||
l.append("module"); // alias for "mod"
|
||||
l.append("nst"); // alias for "mod"
|
||||
@ -433,9 +504,15 @@ StringList FileRef::defaultFileExtensions()
|
||||
l.append("s3m");
|
||||
l.append("it");
|
||||
l.append("xm");
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
l.append("dsf");
|
||||
l.append("dff");
|
||||
l.append("dsdiff"); // alias for "dff"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
l.append("shn");
|
||||
#endif
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -265,12 +265,19 @@ bool FLAC::File::save()
|
||||
// Render data for the metadata blocks
|
||||
|
||||
ByteVector data;
|
||||
for(const auto &block : std::as_const(d->blocks)) {
|
||||
ByteVector blockData = block->render();
|
||||
for(auto it = d->blocks.begin(); it != d->blocks.end();) {
|
||||
ByteVector blockData = (*it)->render();
|
||||
ByteVector blockHeader = ByteVector::fromUInt(blockData.size());
|
||||
blockHeader[0] = block->code();
|
||||
if(blockHeader[0] != 0) {
|
||||
debug("FLAC::File::save() -- Removing too large block.");
|
||||
delete *it;
|
||||
it = d->blocks.erase(it);
|
||||
continue;
|
||||
}
|
||||
blockHeader[0] = (*it)->code();
|
||||
data.append(blockHeader);
|
||||
data.append(blockData);
|
||||
++it;
|
||||
}
|
||||
|
||||
// Compute the amount of padding, and append that to data.
|
||||
|
@ -60,8 +60,8 @@ namespace TagLib {
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
struct AtomData {
|
||||
AtomData(AtomDataType type, const ByteVector &data) :
|
||||
type(type), data(data) { }
|
||||
AtomData(AtomDataType ptype, const ByteVector &pdata) :
|
||||
type(ptype), data(pdata) { }
|
||||
AtomDataType type;
|
||||
int locale { 0 };
|
||||
ByteVector data;
|
||||
|
@ -56,6 +56,28 @@ namespace
|
||||
|
||||
constexpr long MinPaddingSize = 1024;
|
||||
constexpr long MaxPaddingSize = 1024 * 1024;
|
||||
|
||||
/*!
|
||||
* Downgrade ID3v2.4 text \a encoding to value supported by ID3v2.3.
|
||||
*/
|
||||
String::Type downgradeTextEncoding(String::Type encoding)
|
||||
{
|
||||
return encoding == String::Latin1 ? String::Latin1 : String::UTF16;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Downgrade ID3v2.4 text encoding to value supported by ID3v2.3.
|
||||
* \param frame1 first contributing ID3v2.4 frame, can be null
|
||||
* \param frame2 second contributing ID3v2.4 frame, can be null
|
||||
* \return ID3v2.3 encoding suitable for both contributing source frames.
|
||||
*/
|
||||
String::Type downgradeTextEncoding(ID3v2::TextIdentificationFrame *frame1,
|
||||
ID3v2::TextIdentificationFrame *frame2)
|
||||
{
|
||||
return (!frame1 || frame1->textEncoding() == String::Latin1) &&
|
||||
(!frame2 || frame2->textEncoding() == String::Latin1)
|
||||
? String::Latin1 : String::UTF16;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ID3v2::Tag::TagPrivate
|
||||
@ -578,7 +600,8 @@ void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
String content = frameTDOR->toString();
|
||||
|
||||
if(content.size() >= 4) {
|
||||
auto frameTORY = new ID3v2::TextIdentificationFrame("TORY", String::Latin1);
|
||||
auto frameTORY = new ID3v2::TextIdentificationFrame(
|
||||
"TORY", downgradeTextEncoding(frameTDOR->textEncoding()));
|
||||
frameTORY->setText(content.substr(0, 4));
|
||||
frames->append(frameTORY);
|
||||
newFrames->append(frameTORY);
|
||||
@ -587,17 +610,20 @@ void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
|
||||
if(frameTDRC) {
|
||||
if(String content = frameTDRC->toString(); content.size() >= 4) {
|
||||
auto frameTYER = new ID3v2::TextIdentificationFrame("TYER", String::Latin1);
|
||||
auto frameTYER = new ID3v2::TextIdentificationFrame(
|
||||
"TYER", downgradeTextEncoding(frameTDRC->textEncoding()));
|
||||
frameTYER->setText(content.substr(0, 4));
|
||||
frames->append(frameTYER);
|
||||
newFrames->append(frameTYER);
|
||||
if(content.size() >= 10 && content[4] == '-' && content[7] == '-') {
|
||||
auto frameTDAT = new ID3v2::TextIdentificationFrame("TDAT", String::Latin1);
|
||||
auto frameTDAT = new ID3v2::TextIdentificationFrame(
|
||||
"TDAT", downgradeTextEncoding(frameTDRC->textEncoding()));
|
||||
frameTDAT->setText(content.substr(8, 2) + content.substr(5, 2));
|
||||
frames->append(frameTDAT);
|
||||
newFrames->append(frameTDAT);
|
||||
if(content.size() >= 16 && content[10] == 'T' && content[13] == ':') {
|
||||
auto frameTIME = new ID3v2::TextIdentificationFrame("TIME", String::Latin1);
|
||||
auto frameTIME = new ID3v2::TextIdentificationFrame(
|
||||
"TIME", downgradeTextEncoding(frameTDRC->textEncoding()));
|
||||
frameTIME->setText(content.substr(11, 2) + content.substr(14, 2));
|
||||
frames->append(frameTIME);
|
||||
newFrames->append(frameTIME);
|
||||
@ -607,7 +633,8 @@ void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
}
|
||||
|
||||
if(frameTIPL || frameTMCL) {
|
||||
auto frameIPLS = new ID3v2::TextIdentificationFrame("IPLS", String::Latin1);
|
||||
auto frameIPLS = new ID3v2::TextIdentificationFrame(
|
||||
"IPLS", downgradeTextEncoding(frameTIPL, frameTMCL));
|
||||
|
||||
StringList people;
|
||||
|
||||
@ -653,7 +680,8 @@ void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
if(!genreText.isEmpty())
|
||||
combined += genreText;
|
||||
|
||||
frameTCON = new ID3v2::TextIdentificationFrame("TCON", String::Latin1);
|
||||
frameTCON = new ID3v2::TextIdentificationFrame(
|
||||
"TCON", downgradeTextEncoding(frameTCON->textEncoding()));
|
||||
frameTCON->setText(combined);
|
||||
frames->append(frameTCON);
|
||||
newFrames->append(frameTCON);
|
||||
|
@ -25,11 +25,14 @@
|
||||
|
||||
#include "mpegfile.h"
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "id3v2framefactory.h"
|
||||
#include "tdebug.h"
|
||||
#include "tpropertymap.h"
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apefooter.h"
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
#include "id3v1tag.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "tagunion.h"
|
||||
@ -277,6 +280,7 @@ bool MPEG::File::save(int tags, StripTags strip, ID3v2::Version version, Duplica
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
if(APE & tags) {
|
||||
|
||||
if(APETag() && !APETag()->isEmpty()) {
|
||||
@ -305,6 +309,7 @@ bool MPEG::File::save(int tags, StripTags strip, ID3v2::Version version, Duplica
|
||||
File::strip(APE, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -321,7 +326,11 @@ ID3v1::Tag *MPEG::File::ID3v1Tag(bool create)
|
||||
|
||||
APE::Tag *MPEG::File::APETag(bool create)
|
||||
{
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
return d->tag.access<APE::Tag>(APEIndex, create);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MPEG::File::strip(int tags, bool freeMemory)
|
||||
@ -480,6 +489,7 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle readStyle)
|
||||
if(d->ID3v1Location >= 0)
|
||||
d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
// Look for an APE tag
|
||||
|
||||
d->APELocation = Utils::findAPE(this, d->ID3v1Location);
|
||||
@ -489,6 +499,7 @@ void MPEG::File::read(bool readProperties, Properties::ReadStyle readStyle)
|
||||
d->APEOriginalSize = APETag()->footer()->completeTagSize();
|
||||
d->APELocation = d->APELocation + APE::Footer::size() - d->APEOriginalSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(readProperties)
|
||||
d->properties = std::make_unique<Properties>(this, readStyle);
|
||||
|
@ -25,10 +25,13 @@
|
||||
|
||||
#include "mpegproperties.h"
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tdebug.h"
|
||||
#include "mpegfile.h"
|
||||
#include "xingheader.h"
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
|
@ -113,6 +113,17 @@ bool Ogg::FLAC::File::save()
|
||||
// Put the size in the first 32 bit (I assume no more than 24 bit are used)
|
||||
|
||||
ByteVector v = ByteVector::fromUInt(d->xiphCommentData.size());
|
||||
if(v[0] != 0) {
|
||||
// Block size uses more than 24 bits, try again with pictures removed.
|
||||
d->comment->removeAllPictures();
|
||||
d->xiphCommentData = d->comment->render(false);
|
||||
v = ByteVector::fromUInt(d->xiphCommentData.size());
|
||||
if(v[0] != 0) {
|
||||
debug("Ogg::FLAC::File::save() -- Invalid, metadata block is too large.");
|
||||
return false;
|
||||
}
|
||||
debug("Ogg::FLAC::File::save() -- Metadata block is too large, pictures removed.");
|
||||
}
|
||||
|
||||
// Set the type of the metadata-block to be a Xiph / Vorbis comment
|
||||
|
||||
|
542
taglib/shorten/shortenfile.cpp
Normal file
542
taglib/shorten/shortenfile.cpp
Normal file
@ -0,0 +1,542 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "shortenfile.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "shortenutils.h"
|
||||
|
||||
#include "tdebug.h"
|
||||
#include "tutils.h"
|
||||
#include "tagutils.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace {
|
||||
|
||||
// MARK: Constants
|
||||
|
||||
constexpr int minSupportedVersion = 1;
|
||||
constexpr int maxSupportedVersion = 3;
|
||||
|
||||
// Possible values of k
|
||||
constexpr int32_t channelCountCodeSize = 0;
|
||||
constexpr int32_t functionCodeSize = 2;
|
||||
constexpr int32_t verbatimChunkSizeCodeSize = 5;
|
||||
constexpr int32_t verbatimByteCodeSize = 8;
|
||||
constexpr int32_t uInt32CodeSize = 2;
|
||||
constexpr int32_t skipBytesCodeSize = 1;
|
||||
constexpr int32_t lpcqCodeSize = 2;
|
||||
constexpr int32_t extraByteCodeSize = 7;
|
||||
constexpr int32_t fileTypeCodeSize = 4;
|
||||
|
||||
constexpr int32_t functionVerbatim = 9;
|
||||
|
||||
constexpr int32_t canonicalHeaderSize = 44;
|
||||
constexpr int32_t verbatimChunkMaxSize = 256;
|
||||
|
||||
constexpr uint32_t maxChannelCount = 8;
|
||||
|
||||
constexpr uint32_t defaultBlockSize = 256;
|
||||
constexpr uint32_t maxBlockSize = 65535;
|
||||
|
||||
constexpr int waveFormatPCMTag = 0x0001;
|
||||
|
||||
// MARK: Variable-Length Input
|
||||
|
||||
//! Variable-length input using Golomb-Rice coding.
|
||||
class VariableLengthInput {
|
||||
public:
|
||||
//! Creates a new \c VariableLengthInput object.
|
||||
VariableLengthInput(File *file) : file(file) {}
|
||||
|
||||
~VariableLengthInput() = default;
|
||||
|
||||
VariableLengthInput() = delete;
|
||||
VariableLengthInput(const VariableLengthInput &) = delete;
|
||||
VariableLengthInput(VariableLengthInput &&) = delete;
|
||||
VariableLengthInput &operator=(const VariableLengthInput &) = delete;
|
||||
VariableLengthInput &operator=(VariableLengthInput &&) = delete;
|
||||
|
||||
bool getRiceGolombCode(int32_t &i32, int k);
|
||||
bool getUInt(uint32_t &ui32, int version, int32_t k);
|
||||
|
||||
private:
|
||||
//! Refills \c bitBuffer with a single \c uint32_t from \c buffer,
|
||||
//! refilling \c buffer if necessary.
|
||||
bool refillBitBuffer();
|
||||
|
||||
//! Input stream
|
||||
File *file { nullptr };
|
||||
//! Byte buffer
|
||||
ByteVector buffer;
|
||||
//! Current position in buffer
|
||||
unsigned int bufferPosition { 0 };
|
||||
//! Bit buffer
|
||||
uint32_t bitBuffer { 0 };
|
||||
//! Bits available in \c bitBuffer, 0..32
|
||||
int bitsAvailable { 0 };
|
||||
};
|
||||
|
||||
bool VariableLengthInput::getRiceGolombCode(int32_t &i32, int32_t k)
|
||||
{
|
||||
static constexpr uint32_t sMaskTable[] = {
|
||||
0x0,
|
||||
0x1, 0x3, 0x7, 0xf,
|
||||
0x1f, 0x3f, 0x7f, 0xff,
|
||||
0x1ff, 0x3ff, 0x7ff, 0xfff,
|
||||
0x1fff, 0x3fff, 0x7fff, 0xffff,
|
||||
0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
|
||||
0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
|
||||
0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
|
||||
0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
|
||||
};
|
||||
|
||||
if(bitsAvailable == 0 && !refillBitBuffer())
|
||||
return false;
|
||||
|
||||
int32_t result;
|
||||
for(result = 0; !(bitBuffer & (1L << --bitsAvailable)); ++result) {
|
||||
if(bitsAvailable == 0 && !refillBitBuffer())
|
||||
return false;
|
||||
}
|
||||
|
||||
while(k != 0) {
|
||||
if(bitsAvailable >= k) {
|
||||
result = (result << k) | static_cast<int32_t>(
|
||||
(bitBuffer >> (bitsAvailable - k)) & sMaskTable[k]);
|
||||
bitsAvailable -= k;
|
||||
k = 0;
|
||||
}
|
||||
else {
|
||||
result = (result << bitsAvailable) | static_cast<int32_t>(
|
||||
bitBuffer & sMaskTable[bitsAvailable]);
|
||||
k -= bitsAvailable;
|
||||
if(!refillBitBuffer())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
i32 = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VariableLengthInput::getUInt(uint32_t &ui32, int version, int32_t k)
|
||||
{
|
||||
if(version > 0 && !getRiceGolombCode(k, uInt32CodeSize))
|
||||
return false;
|
||||
|
||||
int32_t i32;
|
||||
if(!getRiceGolombCode(i32, k))
|
||||
return false;
|
||||
ui32 = static_cast<uint32_t>(i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VariableLengthInput::refillBitBuffer()
|
||||
{
|
||||
if(buffer.size() - bufferPosition < 4) {
|
||||
static constexpr size_t bufferSize = 512;
|
||||
auto block = file->readBlock(bufferSize);
|
||||
if(block.size() < 4)
|
||||
return false;
|
||||
buffer = block;
|
||||
bufferPosition = 0;
|
||||
}
|
||||
|
||||
bitBuffer = buffer.toUInt(bufferPosition, true);
|
||||
bufferPosition += 4;
|
||||
bitsAvailable = 32;
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class Shorten::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() = default;
|
||||
~FilePrivate() = default;
|
||||
|
||||
FilePrivate(const FilePrivate &) = delete;
|
||||
FilePrivate &operator=(const FilePrivate &) = delete;
|
||||
|
||||
std::unique_ptr<Properties> properties;
|
||||
std::unique_ptr<Tag> tag;
|
||||
};
|
||||
|
||||
bool Shorten::File::isSupported(IOStream *stream)
|
||||
{
|
||||
// A Shorten file has to start with "ajkg"
|
||||
const ByteVector id = Utils::readHeader(stream, 4, false);
|
||||
return id.startsWith("ajkg");
|
||||
}
|
||||
|
||||
Shorten::File::File(FileName file, bool readProperties,
|
||||
AudioProperties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(file),
|
||||
d(std::make_unique<FilePrivate>())
|
||||
{
|
||||
if(isOpen())
|
||||
read(propertiesStyle);
|
||||
}
|
||||
|
||||
Shorten::File::File(IOStream *stream, bool readProperties,
|
||||
AudioProperties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(stream),
|
||||
d(std::make_unique<FilePrivate>())
|
||||
{
|
||||
if(isOpen())
|
||||
read(propertiesStyle);
|
||||
}
|
||||
|
||||
Shorten::File::~File() = default;
|
||||
|
||||
Shorten::Tag *Shorten::File::tag() const
|
||||
{
|
||||
return d->tag.get();
|
||||
}
|
||||
|
||||
PropertyMap Shorten::File::properties() const
|
||||
{
|
||||
return d->tag->properties();
|
||||
}
|
||||
|
||||
PropertyMap Shorten::File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
return d->tag->setProperties(properties);
|
||||
}
|
||||
|
||||
Shorten::Properties *Shorten::File::audioProperties() const
|
||||
{
|
||||
return d->properties.get();
|
||||
}
|
||||
|
||||
bool Shorten::File::save()
|
||||
{
|
||||
if(readOnly()) {
|
||||
debug("Shorten::File::save() - Cannot save to a read only file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
debug("Shorten::File::save() - Saving not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
void Shorten::File::read(AudioProperties::ReadStyle propertiesStyle)
|
||||
{
|
||||
if(!isOpen())
|
||||
return;
|
||||
|
||||
// Read magic number
|
||||
auto magic = readBlock(4);
|
||||
if(magic != "ajkg") {
|
||||
debug("Shorten::File::read() -- Not a Shorten file.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyValues props{};
|
||||
|
||||
// Read file version
|
||||
int version = readBlock(1).toUInt();
|
||||
if(version < minSupportedVersion || version > maxSupportedVersion) {
|
||||
debug("Shorten::File::read() -- Unsupported version.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
props.version = version;
|
||||
|
||||
// Set up variable length input
|
||||
VariableLengthInput input(this);
|
||||
|
||||
// Read file type
|
||||
uint32_t fileType;
|
||||
if(!input.getUInt(fileType, version, fileTypeCodeSize)) {
|
||||
debug("Shorten::File::read() -- Unable to read file type.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
props.fileType = static_cast<int>(fileType);
|
||||
|
||||
// Read number of channels
|
||||
uint32_t channelCount = 0;
|
||||
if(!input.getUInt(channelCount, version, channelCountCodeSize) ||
|
||||
channelCount == 0 || channelCount > maxChannelCount) {
|
||||
debug("Shorten::File::read() -- Invalid or unsupported channel count.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
props.channelCount = static_cast<int>(channelCount);
|
||||
|
||||
// Read block size if version > 0
|
||||
if(version > 0) {
|
||||
uint32_t blockSize = 0;
|
||||
if(!input.getUInt(blockSize, version,
|
||||
static_cast<int32_t>(std::log2(defaultBlockSize))) ||
|
||||
blockSize == 0 || blockSize > maxBlockSize) {
|
||||
debug("Shorten::File::read() -- Invalid or unsupported block size.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t maxnlpc = 0;
|
||||
if(!input.getUInt(maxnlpc, version, lpcqCodeSize) /*|| maxnlpc > 1024*/) {
|
||||
debug("Shorten::File::read() -- Invalid maximum nlpc.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t nmean = 0;
|
||||
if(!input.getUInt(nmean, version, 0) /*|| nmean > 32768*/) {
|
||||
debug("Shorten::File::read() -- Invalid nmean.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t skipCount;
|
||||
if(!input.getUInt(skipCount, version, skipBytesCodeSize)) {
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < skipCount; ++i) {
|
||||
uint32_t dummy;
|
||||
if(!input.getUInt(dummy, version, extraByteCodeSize)) {
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the WAVE or AIFF header in the verbatim section
|
||||
|
||||
int32_t function;
|
||||
if(!input.getRiceGolombCode(function, functionCodeSize) ||
|
||||
function != functionVerbatim) {
|
||||
debug("Shorten::File::read() -- Missing initial verbatim section.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t header_size;
|
||||
if(!input.getRiceGolombCode(header_size, verbatimChunkSizeCodeSize) ||
|
||||
header_size < canonicalHeaderSize || header_size > verbatimChunkMaxSize) {
|
||||
debug("Shorten::File::read() -- Incorrect header size.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteVector header(header_size, 0);
|
||||
|
||||
auto it = header.begin();
|
||||
for(int32_t i = 0; i < header_size; ++i) {
|
||||
int32_t byte;
|
||||
if(!input.getRiceGolombCode(byte, verbatimByteCodeSize)) {
|
||||
debug("Shorten::File::read() -- Unable to read header.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
*it++ = static_cast<uint8_t>(byte);
|
||||
}
|
||||
|
||||
// header is at least canonicalHeaderSize (44) bytes in size
|
||||
|
||||
auto chunkID = header.toUInt(0, true);
|
||||
// auto chunkSize = header.toUInt(4, true);
|
||||
|
||||
const auto chunkData = ByteVector(header, 8, header.size() - 8);
|
||||
|
||||
// WAVE
|
||||
if(chunkID == 0x52494646 /*'RIFF'*/) {
|
||||
unsigned int offset = 0;
|
||||
|
||||
chunkID = chunkData.toUInt(offset, true);
|
||||
offset += 4;
|
||||
if(chunkID != 0x57415645 /*'WAVE'*/) {
|
||||
debug("Shorten::File::read() -- Missing 'WAVE' in 'RIFF' chunk.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto sawFormatChunk = false;
|
||||
uint32_t dataChunkSize = 0;
|
||||
uint16_t blockAlign = 0;
|
||||
|
||||
while(offset < chunkData.size()) {
|
||||
chunkID = chunkData.toUInt(offset, true);
|
||||
offset += 4;
|
||||
|
||||
auto chunkSize = chunkData.toUInt(offset, false);
|
||||
offset += 4;
|
||||
|
||||
switch(chunkID) {
|
||||
case 0x666d7420 /*'fmt '*/:
|
||||
{
|
||||
if(chunkSize < 16) {
|
||||
debug("Shorten::File::read() -- 'fmt ' chunk is too small.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int formatTag = chunkData.toUShort(offset, false);
|
||||
offset += 2;
|
||||
if(formatTag != waveFormatPCMTag) {
|
||||
debug("Shorten::File::read() -- Unsupported WAVE format tag.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int fmtChannelCount = chunkData.toUShort(offset, false);
|
||||
offset += 2;
|
||||
if(props.channelCount != fmtChannelCount)
|
||||
debug("Shorten::File::read() -- Channel count mismatch between Shorten and 'fmt ' chunk.");
|
||||
|
||||
props.sampleRate = static_cast<int>(chunkData.toUInt(offset, false));
|
||||
offset += 4;
|
||||
|
||||
// Skip average bytes per second
|
||||
offset += 4;
|
||||
|
||||
blockAlign = chunkData.toUShort(offset, false);
|
||||
offset += 2;
|
||||
|
||||
props.bitsPerSample = static_cast<int>(chunkData.toUShort(offset, false));
|
||||
offset += 2;
|
||||
|
||||
sawFormatChunk = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x64617461 /*'data'*/:
|
||||
dataChunkSize = chunkSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!sawFormatChunk) {
|
||||
debug("Shorten::File::read() -- Missing 'fmt ' chunk.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if(dataChunkSize && blockAlign)
|
||||
props.sampleFrames = static_cast<unsigned long>(dataChunkSize / blockAlign);
|
||||
}
|
||||
// AIFF
|
||||
else if(chunkID == 0x464f524d /*'FORM'*/) {
|
||||
unsigned int offset = 0;
|
||||
|
||||
chunkID = chunkData.toUInt(offset, true);
|
||||
offset += 4;
|
||||
if(chunkID != 0x41494646 /*'AIFF'*/ && chunkID != 0x41494643 /*'AIFC'*/) {
|
||||
debug("Shorten::File::read() -- Missing 'AIFF' or 'AIFC' in 'FORM' chunk.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// if(chunkID == 0x41494643 /*'AIFC'*/)
|
||||
// props.big_endian = true;
|
||||
|
||||
auto sawCommonChunk = false;
|
||||
while(offset < chunkData.size()) {
|
||||
chunkID = chunkData.toUInt(offset, true);
|
||||
offset += 4;
|
||||
|
||||
auto chunkSize = chunkData.toUInt(offset, true);
|
||||
offset += 4;
|
||||
|
||||
// All chunks must have an even length but the pad byte is not included in chunkSize
|
||||
chunkSize += (chunkSize & 1);
|
||||
|
||||
switch(chunkID) {
|
||||
case 0x434f4d4d /*'COMM'*/:
|
||||
{
|
||||
if(chunkSize < 18) {
|
||||
debug("Shorten::File::read() -- 'COMM' chunk is too small.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int commChannelCount = chunkData.toUShort(offset, true);
|
||||
offset += 2;
|
||||
if(props.channelCount != commChannelCount)
|
||||
debug("Shorten::File::read() -- Channel count mismatch between Shorten and 'COMM' chunk.");
|
||||
|
||||
props.sampleFrames = static_cast<unsigned long>(chunkData.toUInt(offset, true));
|
||||
offset += 4;
|
||||
|
||||
props.bitsPerSample = static_cast<int>(chunkData.toUShort(offset, true));
|
||||
offset += 2;
|
||||
|
||||
// sample rate is IEEE 754 80-bit extended float
|
||||
// (16-bit exponent, 1-bit integer part, 63-bit fraction)
|
||||
auto exp = static_cast<int16_t>(chunkData.toUShort(offset, true)) - 16383 - 63;
|
||||
offset += 2;
|
||||
if(exp < -63 || exp > 63) {
|
||||
debug("Shorten::File::read() -- exp out of range.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto frac = chunkData.toULongLong(offset, true);
|
||||
offset += 8;
|
||||
if(exp >= 0)
|
||||
props.sampleRate = static_cast<int>(frac << exp);
|
||||
else
|
||||
props.sampleRate = static_cast<int>(
|
||||
(frac + (static_cast<uint64_t>(1) << (-exp - 1))) >> -exp);
|
||||
|
||||
sawCommonChunk = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip all other chunks
|
||||
default:
|
||||
offset += chunkSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!sawCommonChunk) {
|
||||
debug("Shorten::File::read() -- Missing 'COMM' chunk");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
debug("Shorten::File::read() -- Unsupported data format.");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
d->tag = std::make_unique<Tag>();
|
||||
d->properties = std::make_unique<Properties>(&props, propertiesStyle);
|
||||
}
|
140
taglib/shorten/shortenfile.h
Normal file
140
taglib/shorten/shortenfile.h
Normal file
@ -0,0 +1,140 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_SHORTENFILE_H
|
||||
#define TAGLIB_SHORTENFILE_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "tfile.h"
|
||||
|
||||
#include "shortenproperties.h"
|
||||
#include "shortentag.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! An implementation of Shorten metadata
|
||||
|
||||
/*!
|
||||
* This is an implementation of Shorten metadata.
|
||||
*/
|
||||
|
||||
namespace Shorten {
|
||||
|
||||
//! An implementation of \c TagLib::File with Shorten specific methods
|
||||
|
||||
/*!
|
||||
* This implements and provides an interface for Shorten files to the
|
||||
* \c TagLib::Tag and \c TagLib::AudioProperties interfaces by way of implementing
|
||||
* the abstract \c TagLib::File API as well as providing some additional
|
||||
* information specific to Shorten files.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File : public TagLib::File {
|
||||
public:
|
||||
/*!
|
||||
* Constructs a Shorten file from \a file.
|
||||
*
|
||||
* \note In the current implementation, both \a readProperties and
|
||||
* \a propertiesStyle are ignored. The audio properties are always
|
||||
* read.
|
||||
*/
|
||||
File(FileName file, bool readProperties = true,
|
||||
AudioProperties::ReadStyle propertiesStyle =
|
||||
AudioProperties::Average);
|
||||
|
||||
/*!
|
||||
* Constructs a Shorten file from \a stream.
|
||||
*
|
||||
* \note In the current implementation, both \a readProperties and
|
||||
* \a propertiesStyle are ignored. The audio properties are always
|
||||
* read.
|
||||
*
|
||||
* \note TagLib will *not* take ownership of the stream, the caller is
|
||||
* responsible for deleting it after the File object.
|
||||
*/
|
||||
File(IOStream *stream, bool readProperties = true,
|
||||
AudioProperties::ReadStyle propertiesStyle =
|
||||
AudioProperties::Average);
|
||||
|
||||
/*!
|
||||
* Destroys this instance of the File.
|
||||
*/
|
||||
~File() override;
|
||||
|
||||
File(const File &) = delete;
|
||||
File &operator=(const File &) = delete;
|
||||
|
||||
/*!
|
||||
* Returns the \c Shorten::Tag for this file.
|
||||
*
|
||||
* \note While the returned \c Tag instance is non-null Shorten tags are not supported.
|
||||
*/
|
||||
Tag *tag() const override;
|
||||
|
||||
/*!
|
||||
* Implements the unified property interface -- export function.
|
||||
*/
|
||||
PropertyMap properties() const override;
|
||||
|
||||
/*!
|
||||
* Implements the unified property interface -- import function.
|
||||
*/
|
||||
PropertyMap setProperties(const PropertyMap &) override;
|
||||
|
||||
/*!
|
||||
* Returns the \c Shorten::Properties for this file. If no audio properties
|
||||
* were read then this will return a null pointer.
|
||||
*/
|
||||
Properties *audioProperties() const override;
|
||||
|
||||
/*!
|
||||
* Save the file.
|
||||
*
|
||||
* \note Saving Shorten tags is not supported.
|
||||
*/
|
||||
bool save() override;
|
||||
|
||||
/*!
|
||||
* Returns whether or not the given \a stream can be opened as a Shorten
|
||||
* file.
|
||||
*
|
||||
* \note This method is designed to do a quick check. The result may
|
||||
* not necessarily be correct.
|
||||
*/
|
||||
static bool isSupported(IOStream *stream);
|
||||
|
||||
private:
|
||||
void read(AudioProperties::ReadStyle propertiesStyle);
|
||||
|
||||
class FilePrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<FilePrivate> d;
|
||||
};
|
||||
} // namespace Shorten
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
112
taglib/shorten/shortenproperties.cpp
Normal file
112
taglib/shorten/shortenproperties.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "shortenproperties.h"
|
||||
|
||||
#include "shortenutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class Shorten::Properties::PropertiesPrivate
|
||||
{
|
||||
public:
|
||||
PropertiesPrivate() = default;
|
||||
~PropertiesPrivate() = default;
|
||||
|
||||
PropertiesPrivate(const PropertiesPrivate &) = delete;
|
||||
PropertiesPrivate &operator=(const PropertiesPrivate &) = delete;
|
||||
|
||||
int version { 0 };
|
||||
int fileType { 0 };
|
||||
int channelCount { 0 };
|
||||
int sampleRate { 0 };
|
||||
int bitsPerSample { 0 };
|
||||
unsigned long sampleFrames { 0 };
|
||||
|
||||
// Computed
|
||||
int bitrate { 0 };
|
||||
int length { 0 };
|
||||
};
|
||||
|
||||
Shorten::Properties::Properties(const PropertyValues *values, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(std::make_unique<PropertiesPrivate>())
|
||||
{
|
||||
if(values) {
|
||||
d->version = values->version;
|
||||
d->fileType = values->fileType;
|
||||
d->channelCount = values->channelCount;
|
||||
d->sampleRate = values->sampleRate;
|
||||
d->bitsPerSample = values->bitsPerSample;
|
||||
d->sampleFrames = values->sampleFrames;
|
||||
|
||||
d->bitrate = static_cast<int>(d->sampleRate * d->bitsPerSample * d->channelCount / 1000.0 + 0.5);
|
||||
if(d->sampleRate > 0)
|
||||
d->length = static_cast<int>(d->sampleFrames * 1000.0 / d->sampleRate + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
Shorten::Properties::~Properties() = default;
|
||||
|
||||
int Shorten::Properties::lengthInMilliseconds() const
|
||||
{
|
||||
return d->length;
|
||||
}
|
||||
|
||||
int Shorten::Properties::bitrate() const
|
||||
{
|
||||
return d->bitrate;
|
||||
}
|
||||
|
||||
int Shorten::Properties::sampleRate() const
|
||||
{
|
||||
return d->sampleRate;
|
||||
}
|
||||
|
||||
int Shorten::Properties::channels() const
|
||||
{
|
||||
return d->channelCount;
|
||||
}
|
||||
|
||||
int Shorten::Properties::shortenVersion() const
|
||||
{
|
||||
return d->version;
|
||||
}
|
||||
|
||||
int Shorten::Properties::fileType() const
|
||||
{
|
||||
return d->fileType;
|
||||
}
|
||||
|
||||
int Shorten::Properties::bitsPerSample() const
|
||||
{
|
||||
return d->bitsPerSample;
|
||||
}
|
||||
|
||||
unsigned long Shorten::Properties::sampleFrames() const
|
||||
{
|
||||
return d->sampleFrames;
|
||||
}
|
74
taglib/shorten/shortenproperties.h
Normal file
74
taglib/shorten/shortenproperties.h
Normal file
@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_SHORTENPROPERTIES_H
|
||||
#define TAGLIB_SHORTENPROPERTIES_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Shorten {
|
||||
|
||||
struct PropertyValues;
|
||||
|
||||
//! An implementation of audio properties for Shorten
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties {
|
||||
public:
|
||||
Properties(const PropertyValues *values, ReadStyle style = Average);
|
||||
~Properties() override;
|
||||
|
||||
Properties(const Properties &) = delete;
|
||||
Properties &operator=(const Properties &) = delete;
|
||||
|
||||
int lengthInMilliseconds() const override;
|
||||
int bitrate() const override;
|
||||
int sampleRate() const override;
|
||||
int channels() const override;
|
||||
|
||||
//! Returns the Shorten file version (1-3).
|
||||
int shortenVersion() const;
|
||||
//! Returns the file type (0-9).
|
||||
//! 0 = 8-bit µ-law,
|
||||
//! 1 = signed 8-bit PCM, 2 = unsigned 8-bit PCM,
|
||||
//! 3 = signed big-endian 16-bit PCM, 4 = unsigned big-endian 16-bit PCM,
|
||||
//! 5 = signed little-endian 16-bit PCM, 6 = unsigned little-endian 16-bit PCM,
|
||||
//! 7 = 8-bit ITU-T G.711 µ-law, 8 = 8-bit µ-law,
|
||||
//! 9 = 8-bit A-law, 10 = 8-bit ITU-T G.711 A-law
|
||||
int fileType() const;
|
||||
int bitsPerSample() const;
|
||||
unsigned long sampleFrames() const;
|
||||
|
||||
private:
|
||||
class PropertiesPrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<PropertiesPrivate> d;
|
||||
};
|
||||
} // namespace Shorten
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
114
taglib/shorten/shortentag.cpp
Normal file
114
taglib/shorten/shortentag.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "shortentag.h"
|
||||
|
||||
#include "tpropertymap.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class Shorten::Tag::TagPrivate
|
||||
{
|
||||
};
|
||||
|
||||
Shorten::Tag::Tag() :
|
||||
d(std::make_unique<TagPrivate>())
|
||||
{
|
||||
}
|
||||
|
||||
Shorten::Tag::~Tag() = default;
|
||||
|
||||
String Shorten::Tag::title() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
|
||||
String Shorten::Tag::artist() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
|
||||
String Shorten::Tag::album() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
|
||||
String Shorten::Tag::comment() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
|
||||
String Shorten::Tag::genre() const
|
||||
{
|
||||
return String();
|
||||
}
|
||||
|
||||
unsigned int Shorten::Tag::year() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Shorten::Tag::track() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Shorten::Tag::setTitle(const String &)
|
||||
{
|
||||
}
|
||||
|
||||
void Shorten::Tag::setArtist(const String &)
|
||||
{
|
||||
}
|
||||
|
||||
void Shorten::Tag::setAlbum(const String &)
|
||||
{
|
||||
}
|
||||
|
||||
void Shorten::Tag::setComment(const String &)
|
||||
{
|
||||
}
|
||||
|
||||
void Shorten::Tag::setGenre(const String &)
|
||||
{
|
||||
}
|
||||
|
||||
void Shorten::Tag::setYear(unsigned int)
|
||||
{
|
||||
}
|
||||
|
||||
void Shorten::Tag::setTrack(unsigned int)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap Shorten::Tag::properties() const
|
||||
{
|
||||
return PropertyMap{};
|
||||
}
|
||||
|
||||
PropertyMap Shorten::Tag::setProperties(const PropertyMap &origProps)
|
||||
{
|
||||
return PropertyMap{origProps};
|
||||
}
|
139
taglib/shorten/shortentag.h
Normal file
139
taglib/shorten/shortentag.h
Normal file
@ -0,0 +1,139 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_SHORTENTAG_H
|
||||
#define TAGLIB_SHORTENTAG_H
|
||||
|
||||
#include "tag.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Shorten {
|
||||
|
||||
//! A Shorten file tag implementation
|
||||
|
||||
/*!
|
||||
* Tags for Shorten files.
|
||||
*
|
||||
* This is a stub class; Shorten files do not support tags.
|
||||
*/
|
||||
class TAGLIB_EXPORT Tag : public TagLib::Tag
|
||||
{
|
||||
public:
|
||||
Tag();
|
||||
~Tag() override;
|
||||
|
||||
Tag(const Tag &) = delete;
|
||||
Tag &operator=(const Tag &) = delete;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns an empty string.
|
||||
*/
|
||||
String title() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns an empty string.
|
||||
*/
|
||||
String artist() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns an empty string.
|
||||
*/
|
||||
String album() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns an empty string.
|
||||
*/
|
||||
String comment() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns an empty string.
|
||||
*/
|
||||
String genre() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns 0.
|
||||
*/
|
||||
unsigned int year() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files. Therefore always returns 0.
|
||||
*/
|
||||
unsigned int track() const override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setTitle(const String &title) override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setArtist(const String &artist) override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setAlbum(const String &album) override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setComment(const String &comment) override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setGenre(const String &genre) override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setYear(unsigned int year) override;
|
||||
|
||||
/*!
|
||||
* Not supported by Shorten files and therefore ignored.
|
||||
*/
|
||||
void setTrack(unsigned int track) override;
|
||||
|
||||
/*!
|
||||
* Implements the unified property interface -- export function.
|
||||
*/
|
||||
PropertyMap properties() const override;
|
||||
|
||||
/*!
|
||||
* Implements the unified property interface -- import function.
|
||||
*/
|
||||
PropertyMap setProperties(const PropertyMap &) override;
|
||||
|
||||
private:
|
||||
class TagPrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<TagPrivate> d;
|
||||
};
|
||||
|
||||
} // namespace Shorten
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
51
taglib/shorten/shortenutils.h
Normal file
51
taglib/shorten/shortenutils.h
Normal file
@ -0,0 +1,51 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2020-2024 Stephen F. Booth
|
||||
email : me@sbooth.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_SHORTENUTILS_H
|
||||
#define TAGLIB_SHORTENUTILS_H
|
||||
|
||||
// THIS FILE IS NOT A PART OF THE TAGLIB API
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
|
||||
|
||||
namespace TagLib {
|
||||
namespace Shorten {
|
||||
|
||||
/// Values shared with \c Shorten::Properties by \c Shorten::File
|
||||
struct PropertyValues
|
||||
{
|
||||
int version { 0 };
|
||||
int fileType { 0 };
|
||||
int channelCount { 0 };
|
||||
int sampleRate { 0 };
|
||||
int bitsPerSample { 0 };
|
||||
unsigned long sampleFrames { 0 };
|
||||
};
|
||||
} // namespace Shorten
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
16
taglib/taglib_config.h.cmake
Normal file
16
taglib/taglib_config.h.cmake
Normal file
@ -0,0 +1,16 @@
|
||||
/* taglib_config.h. Generated by cmake from taglib_config.h.cmake */
|
||||
|
||||
#ifndef TAGLIB_TAGLIB_CONFIG_H
|
||||
#define TAGLIB_TAGLIB_CONFIG_H
|
||||
|
||||
#cmakedefine TAGLIB_WITH_APE 1
|
||||
#cmakedefine TAGLIB_WITH_ASF 1
|
||||
#cmakedefine TAGLIB_WITH_DSF 1
|
||||
#cmakedefine TAGLIB_WITH_MOD 1
|
||||
#cmakedefine TAGLIB_WITH_MP4 1
|
||||
#cmakedefine TAGLIB_WITH_RIFF 1
|
||||
#cmakedefine TAGLIB_WITH_SHORTEN 1
|
||||
#cmakedefine TAGLIB_WITH_TRUEAUDIO 1
|
||||
#cmakedefine TAGLIB_WITH_VORBIS 1
|
||||
|
||||
#endif
|
@ -25,11 +25,14 @@
|
||||
|
||||
#include "tagutils.h"
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tfile.h"
|
||||
|
||||
#include "id3v1tag.h"
|
||||
#include "id3v2header.h"
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -45,7 +48,13 @@ offset_t Utils::findID3v1(File *file)
|
||||
const offset_t p = file->tell() + 3;
|
||||
|
||||
if(const TagLib::ByteVector data = file->readBlock(8);
|
||||
data.containsAt(ID3v1::Tag::fileIdentifier(), 3) && data != APE::Tag::fileIdentifier())
|
||||
data.containsAt(ID3v1::Tag::fileIdentifier(), 3) &&
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
data != APE::Tag::fileIdentifier()
|
||||
#else
|
||||
data != ByteVector::fromCString("APETAGEX")
|
||||
#endif
|
||||
)
|
||||
return p;
|
||||
} else {
|
||||
file->seek(-128, File::End);
|
||||
@ -83,7 +92,13 @@ offset_t Utils::findAPE(File *file, offset_t id3v1Location)
|
||||
|
||||
const offset_t p = file->tell();
|
||||
|
||||
if(file->readBlock(8) == APE::Tag::fileIdentifier())
|
||||
if(file->readBlock(8) ==
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
APE::Tag::fileIdentifier()
|
||||
#else
|
||||
ByteVector::fromCString("APETAGEX")
|
||||
#endif
|
||||
)
|
||||
return p;
|
||||
|
||||
return -1;
|
||||
|
@ -158,7 +158,7 @@ ByteVector fromNumber(T value, bool mostSignificantByteFirst)
|
||||
template <typename TFloat, typename TInt, Utils::ByteOrder ENDIAN>
|
||||
TFloat toFloat(const ByteVector &v, size_t offset)
|
||||
{
|
||||
if(offset > v.size() - sizeof(TInt)) {
|
||||
if(offset + sizeof(TInt) > v.size()) {
|
||||
debug("toFloat() - offset is out of range. Returning 0.");
|
||||
return 0.0;
|
||||
}
|
||||
@ -195,7 +195,7 @@ long double toFloat80(const ByteVector &v, size_t offset)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
if(offset > v.size() - 10) {
|
||||
if(offset + 10 > v.size()) {
|
||||
debug("toFloat80() - offset is out of range. Returning 0.");
|
||||
return 0.0;
|
||||
}
|
||||
@ -282,47 +282,47 @@ ByteVector ByteVector::fromCString(const char *s, unsigned int length)
|
||||
|
||||
ByteVector ByteVector::fromUInt(unsigned int value, bool mostSignificantByteFirst)
|
||||
{
|
||||
return fromNumber<unsigned int>(value, mostSignificantByteFirst);
|
||||
return fromNumber<uint32_t>(value, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromShort(short value, bool mostSignificantByteFirst)
|
||||
{
|
||||
return fromNumber<unsigned short>(value, mostSignificantByteFirst);
|
||||
return fromNumber<uint16_t>(value, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromUShort(unsigned short value, bool mostSignificantByteFirst)
|
||||
{
|
||||
return fromNumber<unsigned short>(value, mostSignificantByteFirst);
|
||||
return fromNumber<uint16_t>(value, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromLongLong(long long value, bool mostSignificantByteFirst)
|
||||
{
|
||||
return fromNumber<unsigned long long>(value, mostSignificantByteFirst);
|
||||
return fromNumber<uint64_t>(value, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromULongLong(unsigned long long value, bool mostSignificantByteFirst)
|
||||
{
|
||||
return fromNumber<unsigned long long>(value, mostSignificantByteFirst);
|
||||
return fromNumber<uint64_t>(value, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromFloat32LE(float value)
|
||||
{
|
||||
return fromFloat<float, unsigned int, Utils::LittleEndian>(value);
|
||||
return fromFloat<float, uint32_t, Utils::LittleEndian>(value);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromFloat32BE(float value)
|
||||
{
|
||||
return fromFloat<float, unsigned int, Utils::BigEndian>(value);
|
||||
return fromFloat<float, uint32_t, Utils::BigEndian>(value);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromFloat64LE(double value)
|
||||
{
|
||||
return fromFloat<double, unsigned long long, Utils::LittleEndian>(value);
|
||||
return fromFloat<double, uint64_t, Utils::LittleEndian>(value);
|
||||
}
|
||||
|
||||
ByteVector ByteVector::fromFloat64BE(double value)
|
||||
{
|
||||
return fromFloat<double, unsigned long long, Utils::BigEndian>(value);
|
||||
return fromFloat<double, uint64_t, Utils::BigEndian>(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -360,7 +360,7 @@ ByteVector::ByteVector(const char *data, unsigned int length) :
|
||||
}
|
||||
|
||||
ByteVector::ByteVector(const char *data) :
|
||||
d(std::make_unique<ByteVectorPrivate>(data, static_cast<unsigned int>(::strlen(data))))
|
||||
d(std::make_unique<ByteVectorPrivate>(data, data ? static_cast<unsigned int>(::strlen(data)) : 0))
|
||||
{
|
||||
}
|
||||
|
||||
@ -656,79 +656,86 @@ bool ByteVector::isEmpty() const
|
||||
return d->length == 0;
|
||||
}
|
||||
|
||||
// Sanity checks
|
||||
static_assert(sizeof(unsigned short) == sizeof(uint16_t), "unsigned short and uint16_t are different sizes");
|
||||
static_assert(sizeof(unsigned int) == sizeof(uint32_t), "unsigned int and uint32_t are different sizes");
|
||||
static_assert(sizeof(unsigned long long) == sizeof(uint64_t), "unsigned long long and uint64_t are different sizes");
|
||||
static_assert(sizeof(float) == sizeof(uint32_t), "float and uint32_t are different sizes");
|
||||
static_assert(sizeof(double) == sizeof(uint64_t), "double and uint64_t are different sizes");
|
||||
|
||||
unsigned int ByteVector::toUInt(bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned int>(*this, 0, mostSignificantByteFirst);
|
||||
return toNumber<uint32_t>(*this, 0, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
unsigned int ByteVector::toUInt(unsigned int offset, bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned int>(*this, offset, mostSignificantByteFirst);
|
||||
return toNumber<uint32_t>(*this, offset, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
unsigned int ByteVector::toUInt(unsigned int offset, unsigned int length, bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned int>(*this, offset, length, mostSignificantByteFirst);
|
||||
return toNumber<uint32_t>(*this, offset, length, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
short ByteVector::toShort(bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned short>(*this, 0, mostSignificantByteFirst);
|
||||
return toNumber<uint16_t>(*this, 0, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
short ByteVector::toShort(unsigned int offset, bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned short>(*this, offset, mostSignificantByteFirst);
|
||||
return toNumber<uint16_t>(*this, offset, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
unsigned short ByteVector::toUShort(bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned short>(*this, 0, mostSignificantByteFirst);
|
||||
return toNumber<uint16_t>(*this, 0, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
unsigned short ByteVector::toUShort(unsigned int offset, bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned short>(*this, offset, mostSignificantByteFirst);
|
||||
return toNumber<uint16_t>(*this, offset, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
long long ByteVector::toLongLong(bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned long long>(*this, 0, mostSignificantByteFirst);
|
||||
return toNumber<uint64_t>(*this, 0, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
long long ByteVector::toLongLong(unsigned int offset, bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned long long>(*this, offset, mostSignificantByteFirst);
|
||||
return toNumber<uint64_t>(*this, offset, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
unsigned long long ByteVector::toULongLong(bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned long long>(*this, 0, mostSignificantByteFirst);
|
||||
return toNumber<uint64_t>(*this, 0, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
unsigned long long ByteVector::toULongLong(unsigned int offset, bool mostSignificantByteFirst) const
|
||||
{
|
||||
return toNumber<unsigned long long>(*this, offset, mostSignificantByteFirst);
|
||||
return toNumber<uint64_t>(*this, offset, mostSignificantByteFirst);
|
||||
}
|
||||
|
||||
float ByteVector::toFloat32LE(size_t offset) const
|
||||
{
|
||||
return toFloat<float, unsigned int, Utils::LittleEndian>(*this, offset);
|
||||
return toFloat<float, uint32_t, Utils::LittleEndian>(*this, offset);
|
||||
}
|
||||
|
||||
float ByteVector::toFloat32BE(size_t offset) const
|
||||
{
|
||||
return toFloat<float, unsigned int, Utils::BigEndian>(*this, offset);
|
||||
return toFloat<float, uint32_t, Utils::BigEndian>(*this, offset);
|
||||
}
|
||||
|
||||
double ByteVector::toFloat64LE(size_t offset) const
|
||||
{
|
||||
return toFloat<double, unsigned long long, Utils::LittleEndian>(*this, offset);
|
||||
return toFloat<double, uint64_t, Utils::LittleEndian>(*this, offset);
|
||||
}
|
||||
|
||||
double ByteVector::toFloat64BE(size_t offset) const
|
||||
{
|
||||
return toFloat<double, unsigned long long, Utils::BigEndian>(*this, offset);
|
||||
return toFloat<double, uint64_t, Utils::BigEndian>(*this, offset);
|
||||
}
|
||||
|
||||
long double ByteVector::toFloat80LE(size_t offset) const
|
||||
@ -767,6 +774,9 @@ bool ByteVector::operator!=(const ByteVector &v) const
|
||||
|
||||
bool ByteVector::operator==(const char *s) const
|
||||
{
|
||||
if(!s)
|
||||
return isEmpty();
|
||||
|
||||
if(size() != ::strlen(s))
|
||||
return false;
|
||||
|
||||
|
@ -195,23 +195,27 @@ String::String(const wchar_t *s) :
|
||||
String::String(const wchar_t *s, Type t) :
|
||||
d(std::make_shared<StringPrivate>())
|
||||
{
|
||||
if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
|
||||
copyFromUTF16(d->data, s, ::wcslen(s), t);
|
||||
}
|
||||
else {
|
||||
debug("String::String() -- const wchar_t * should not contain Latin1 or UTF-8.");
|
||||
if(s) {
|
||||
if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
|
||||
copyFromUTF16(d->data, s, ::wcslen(s), t);
|
||||
}
|
||||
else {
|
||||
debug("String::String() -- const wchar_t * should not contain Latin1 or UTF-8.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String::String(const char *s, Type t) :
|
||||
d(std::make_shared<StringPrivate>())
|
||||
{
|
||||
if(t == Latin1)
|
||||
copyFromLatin1(d->data, s, ::strlen(s));
|
||||
else if(t == String::UTF8)
|
||||
copyFromUTF8(d->data, s, ::strlen(s));
|
||||
else {
|
||||
debug("String::String() -- const char * should not contain UTF16.");
|
||||
if(s) {
|
||||
if(t == Latin1)
|
||||
copyFromLatin1(d->data, s, ::strlen(s));
|
||||
else if(t == String::UTF8)
|
||||
copyFromUTF8(d->data, s, ::strlen(s));
|
||||
else {
|
||||
debug("String::String() -- const char * should not contain UTF16.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,6 +550,10 @@ bool String::operator!=(const String &s) const
|
||||
|
||||
bool String::operator==(const char *s) const
|
||||
{
|
||||
if(!s) {
|
||||
return isEmpty();
|
||||
}
|
||||
|
||||
const wchar_t *p = toCWString();
|
||||
|
||||
while(*p != L'\0' || *s != '\0') {
|
||||
@ -562,6 +570,10 @@ bool String::operator!=(const char *s) const
|
||||
|
||||
bool String::operator==(const wchar_t *s) const
|
||||
{
|
||||
if(!s) {
|
||||
return isEmpty();
|
||||
}
|
||||
|
||||
return d->data == s;
|
||||
}
|
||||
|
||||
@ -580,18 +592,22 @@ String &String::operator+=(const String &s)
|
||||
|
||||
String &String::operator+=(const wchar_t *s)
|
||||
{
|
||||
detach();
|
||||
if(s) {
|
||||
detach();
|
||||
|
||||
d->data += s;
|
||||
d->data += s;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(const char *s)
|
||||
{
|
||||
detach();
|
||||
if(s) {
|
||||
detach();
|
||||
|
||||
for(int i = 0; s[i] != 0; i++)
|
||||
d->data += static_cast<unsigned char>(s[i]);
|
||||
for(int i = 0; s[i] != 0; i++)
|
||||
d->data += static_cast<unsigned char>(s[i]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
@ -60,7 +61,7 @@ namespace TagLib
|
||||
/*!
|
||||
* Reverses the order of bytes in a 16-bit integer.
|
||||
*/
|
||||
inline unsigned short byteSwap(unsigned short x)
|
||||
inline uint16_t byteSwap(uint16_t x)
|
||||
{
|
||||
#if defined(HAVE_GCC_BYTESWAP)
|
||||
|
||||
@ -92,7 +93,7 @@ namespace TagLib
|
||||
/*!
|
||||
* Reverses the order of bytes in a 32-bit integer.
|
||||
*/
|
||||
inline unsigned int byteSwap(unsigned int x)
|
||||
inline uint32_t byteSwap(uint32_t x)
|
||||
{
|
||||
#if defined(HAVE_GCC_BYTESWAP)
|
||||
|
||||
@ -127,7 +128,7 @@ namespace TagLib
|
||||
/*!
|
||||
* Reverses the order of bytes in a 64-bit integer.
|
||||
*/
|
||||
inline unsigned long long byteSwap(unsigned long long x)
|
||||
inline uint64_t byteSwap(uint64_t x)
|
||||
{
|
||||
#if defined(HAVE_GCC_BYTESWAP)
|
||||
|
||||
|
@ -1,33 +1,71 @@
|
||||
INCLUDE_DIRECTORIES(
|
||||
SET(test_HDR_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/toolkit
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../bindings/c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ape
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/asf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v1
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2/frames
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mp4
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/aiff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/wav
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/trueaudio
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/vorbis
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/speex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/opus
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/wavpack
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mod
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/s3m
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/it
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/xm
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/dsf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/dsdiff
|
||||
)
|
||||
IF(WITH_APE)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ape
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/wavpack
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_ASF)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/asf
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_MP4)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mp4
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_RIFF)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/aiff
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/riff/wav
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_TRUEAUDIO)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/trueaudio
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_VORBIS)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/vorbis
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/flac
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/speex
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ogg/opus
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/flac
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_MOD)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mod
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/s3m
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/it
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/xm
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_DSF)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/dsf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/dsdiff
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_SHORTEN)
|
||||
SET(test_HDR_DIRS ${test_HDR_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/shorten
|
||||
)
|
||||
ENDIF()
|
||||
INCLUDE_DIRECTORIES(${test_HDR_DIRS})
|
||||
|
||||
SET(test_runner_SRCS
|
||||
main.cpp
|
||||
@ -35,7 +73,6 @@ SET(test_runner_SRCS
|
||||
test_map.cpp
|
||||
test_mpeg.cpp
|
||||
test_synchdata.cpp
|
||||
test_trueaudio.cpp
|
||||
test_bytevector.cpp
|
||||
test_bytevectorlist.cpp
|
||||
test_bytevectorstream.cpp
|
||||
@ -48,35 +85,73 @@ SET(test_runner_SRCS
|
||||
test_id3v1.cpp
|
||||
test_id3v2.cpp
|
||||
test_id3v2framefactory.cpp
|
||||
test_xiphcomment.cpp
|
||||
test_aiff.cpp
|
||||
test_riff.cpp
|
||||
test_ogg.cpp
|
||||
test_oggflac.cpp
|
||||
test_flac.cpp
|
||||
test_flacpicture.cpp
|
||||
test_flacunknownmetadatablock.cpp
|
||||
test_ape.cpp
|
||||
test_apetag.cpp
|
||||
test_wav.cpp
|
||||
test_info.cpp
|
||||
test_wavpack.cpp
|
||||
test_mp4.cpp
|
||||
test_mp4item.cpp
|
||||
test_mp4coverart.cpp
|
||||
test_asf.cpp
|
||||
test_mod.cpp
|
||||
test_s3m.cpp
|
||||
test_it.cpp
|
||||
test_xm.cpp
|
||||
test_mpc.cpp
|
||||
test_opus.cpp
|
||||
test_speex.cpp
|
||||
test_dsf.cpp
|
||||
test_dsdiff.cpp
|
||||
test_sizes.cpp
|
||||
test_versionnumber.cpp
|
||||
)
|
||||
IF(WITH_TRUEAUDIO)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_trueaudio.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_VORBIS)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_xiphcomment.cpp
|
||||
test_ogg.cpp
|
||||
test_oggflac.cpp
|
||||
test_flac.cpp
|
||||
test_flacpicture.cpp
|
||||
test_flacunknownmetadatablock.cpp
|
||||
test_opus.cpp
|
||||
test_speex.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_RIFF)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_aiff.cpp
|
||||
test_riff.cpp
|
||||
test_wav.cpp
|
||||
test_info.cpp
|
||||
)
|
||||
ENDIF()
|
||||
if(WITH_APE)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_ape.cpp
|
||||
test_apetag.cpp
|
||||
test_wavpack.cpp
|
||||
test_mpc.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_MP4)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_mp4.cpp
|
||||
test_mp4item.cpp
|
||||
test_mp4coverart.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_ASF)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_asf.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_MOD)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_mod.cpp
|
||||
test_s3m.cpp
|
||||
test_it.cpp
|
||||
test_xm.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_DSF)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_dsf.cpp
|
||||
test_dsdiff.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(WITH_SHORTEN)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_shorten.cpp
|
||||
)
|
||||
ENDIF()
|
||||
IF(BUILD_BINDINGS)
|
||||
SET(test_runner_SRCS ${test_runner_SRCS}
|
||||
test_tag_c.cpp
|
||||
|
12
tests/data/2sec-silence.shn
Normal file
12
tests/data/2sec-silence.shn
Normal file
File diff suppressed because one or more lines are too long
@ -23,6 +23,7 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
|
||||
@ -53,6 +54,7 @@ class TestByteVector : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testAppend1);
|
||||
CPPUNIT_TEST(testAppend2);
|
||||
CPPUNIT_TEST(testBase64);
|
||||
CPPUNIT_TEST(testEmpty);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -612,6 +614,94 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void testEmpty()
|
||||
{
|
||||
const ByteVector empty;
|
||||
const ByteVector notEmpty("A");
|
||||
ByteVector mutEmpty;
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(""));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector("", 0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(0U));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(empty, 0, 0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(notEmpty, 1, 0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(static_cast<const char *>(nullptr)));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, ByteVector(static_cast<const char *>(nullptr), 0));
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData("", 0), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData(""), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData(nullptr, 0), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.setData(nullptr), empty);
|
||||
CPPUNIT_ASSERT(!empty.data());
|
||||
CPPUNIT_ASSERT(!mutEmpty.data());
|
||||
CPPUNIT_ASSERT_EQUAL(empty.mid(0), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.at(0), '\0');
|
||||
// Note that the behavior of ByteVector::find() with an empty pattern is
|
||||
// not consistent with String::find() and std::string::find().
|
||||
CPPUNIT_ASSERT_EQUAL(empty.find(mutEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.find(notEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(notEmpty.find(empty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.find('\0'), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.rfind(mutEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.rfind(notEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(notEmpty.rfind(empty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.containsAt(mutEmpty, 0), false);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.startsWith(mutEmpty), false);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.startsWith(notEmpty), false);
|
||||
CPPUNIT_ASSERT_EQUAL(notEmpty.startsWith(empty), false);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.endsWith(mutEmpty), false);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.endsWithPartialMatch(mutEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.replace('a', 'b'), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.replace("abc", ""), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(empty), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(notEmpty), notEmpty);
|
||||
mutEmpty.clear();
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector(notEmpty).append(empty), notEmpty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.append('A'), notEmpty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.resize(0), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.size(), 0U);
|
||||
CPPUNIT_ASSERT(empty.begin() == empty.end());
|
||||
CPPUNIT_ASSERT(empty.cbegin() == empty.cend());
|
||||
CPPUNIT_ASSERT(empty.rbegin() == empty.rend());
|
||||
CPPUNIT_ASSERT(mutEmpty.begin() == mutEmpty.end());
|
||||
CPPUNIT_ASSERT(mutEmpty.rbegin() == mutEmpty.rend());
|
||||
CPPUNIT_ASSERT(empty.isEmpty());
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toUInt(), 0U);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toUInt(0, true), 0U);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toUInt(0, 0, true), 0U);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toShort(), static_cast<short>(0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toShort(0, true), static_cast<short>(0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toUShort(), static_cast<unsigned short>(0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toUShort(0, true), static_cast<unsigned short>(0));
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toLongLong(), 0LL);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toLongLong(0, true), 0LL);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toULongLong(), 0ULL);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toULongLong(0, true), 0ULL);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toFloat32LE(0), 0.f);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toFloat32BE(0), 0.f);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toFloat64LE(0), 0.);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toFloat64BE(0), 0.);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toFloat80LE(0), 0.l);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toFloat80BE(0), 0.l);
|
||||
CPPUNIT_ASSERT(empty == mutEmpty);
|
||||
CPPUNIT_ASSERT(empty != notEmpty);
|
||||
CPPUNIT_ASSERT(empty == "");
|
||||
CPPUNIT_ASSERT(empty != " ");
|
||||
CPPUNIT_ASSERT(empty == static_cast<const char *>(nullptr));
|
||||
CPPUNIT_ASSERT(!(empty != static_cast<const char *>(nullptr)));
|
||||
CPPUNIT_ASSERT(empty < notEmpty);
|
||||
CPPUNIT_ASSERT(!(empty > notEmpty));
|
||||
CPPUNIT_ASSERT_EQUAL(empty + mutEmpty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty + notEmpty, notEmpty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty = static_cast<const char *>(nullptr), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty = notEmpty, notEmpty);
|
||||
ByteVector tmp;
|
||||
mutEmpty.swap(tmp);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toHex(), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toBase64(), empty);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector);
|
||||
|
@ -23,21 +23,30 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "asfpicture.h"
|
||||
#include "flacpicture.h"
|
||||
#include "flacfile.h"
|
||||
#include "taglib_config.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tvariant.h"
|
||||
#include "tzlib.h"
|
||||
#include "fileref.h"
|
||||
#include "apetag.h"
|
||||
#include "asftag.h"
|
||||
#include "mp4tag.h"
|
||||
#include "xiphcomment.h"
|
||||
#include "id3v1tag.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "attachedpictureframe.h"
|
||||
#include "generalencapsulatedobjectframe.h"
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include "asfpicture.h"
|
||||
#include "asftag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "flacpicture.h"
|
||||
#include "flacfile.h"
|
||||
#include "xiphcomment.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include "mp4tag.h"
|
||||
#endif
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "utils.h"
|
||||
|
||||
@ -69,17 +78,25 @@ class TestComplexProperties : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestComplexProperties);
|
||||
CPPUNIT_TEST(testReadMp3Picture);
|
||||
CPPUNIT_TEST(testSetGetId3Geob);
|
||||
CPPUNIT_TEST(testSetGetId3Picture);
|
||||
CPPUNIT_TEST(testNonExistent);
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
CPPUNIT_TEST(testReadM4aPicture);
|
||||
CPPUNIT_TEST(testSetGetMp4Picture);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_TEST(testReadOggPicture);
|
||||
CPPUNIT_TEST(testReadWriteFlacPicture);
|
||||
CPPUNIT_TEST(testReadWriteMultipleProperties);
|
||||
CPPUNIT_TEST(testSetGetId3Geob);
|
||||
CPPUNIT_TEST(testSetGetId3Picture);
|
||||
CPPUNIT_TEST(testSetGetApePicture);
|
||||
CPPUNIT_TEST(testSetGetAsfPicture);
|
||||
CPPUNIT_TEST(testSetGetMp4Picture);
|
||||
CPPUNIT_TEST(testSetGetXiphPicture);
|
||||
CPPUNIT_TEST(testNonExistent);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_TEST(testSetGetApePicture);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
CPPUNIT_TEST(testSetGetAsfPicture);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -103,6 +120,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
void testReadM4aPicture()
|
||||
{
|
||||
const ByteVector expectedData1(
|
||||
@ -145,7 +163,9 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(String("image/jpeg"),
|
||||
picture.value("mimeType").value<String>());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testReadOggPicture()
|
||||
{
|
||||
FileRef f(TEST_FILE_PATH_C("lowercase-fields.ogg"), false);
|
||||
@ -217,6 +237,7 @@ public:
|
||||
CPPUNIT_ASSERT(f.pictureList().isEmpty());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void testReadWriteMultipleProperties()
|
||||
{
|
||||
@ -311,6 +332,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::FrontCover, frame->type());
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
void testSetGetApePicture()
|
||||
{
|
||||
const String FRONT_COVER("COVER ART (FRONT)");
|
||||
@ -326,7 +348,9 @@ public:
|
||||
.append(picture.value("data").value<ByteVector>()),
|
||||
item.binaryData());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
void testSetGetAsfPicture()
|
||||
{
|
||||
VariantMap picture(TEST_PICTURE);
|
||||
@ -344,7 +368,9 @@ public:
|
||||
asfPicture.description());
|
||||
CPPUNIT_ASSERT_EQUAL(ASF::Picture::FrontCover, asfPicture.type());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
void testSetGetMp4Picture()
|
||||
{
|
||||
VariantMap picture(TEST_PICTURE);
|
||||
@ -360,7 +386,9 @@ public:
|
||||
covr.data());
|
||||
CPPUNIT_ASSERT_EQUAL(MP4::CoverArt::JPEG, covr.format());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testSetGetXiphPicture()
|
||||
{
|
||||
VariantMap picture(TEST_PICTURE);
|
||||
@ -386,6 +414,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(1, pic->width());
|
||||
CPPUNIT_ASSERT_EQUAL(1, pic->height());
|
||||
}
|
||||
#endif
|
||||
|
||||
void testNonExistent()
|
||||
{
|
||||
|
@ -26,27 +26,44 @@
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tfilestream.h"
|
||||
#include "tbytevectorstream.h"
|
||||
#include "tag.h"
|
||||
#include "fileref.h"
|
||||
#include "mpegfile.h"
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "oggflacfile.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "mpegfile.h"
|
||||
#include "mpcfile.h"
|
||||
#include "asffile.h"
|
||||
#include "speexfile.h"
|
||||
#include "flacfile.h"
|
||||
#include "trueaudiofile.h"
|
||||
#include "mp4file.h"
|
||||
#include "wavfile.h"
|
||||
#include "apefile.h"
|
||||
#include "aifffile.h"
|
||||
#include "wavpackfile.h"
|
||||
#include "opusfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "mpcfile.h"
|
||||
#include "apefile.h"
|
||||
#include "wavpackfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include "asffile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
#include "trueaudiofile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include "mp4file.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
#include "wavfile.h"
|
||||
#include "aifffile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
#include "xmfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
#include "dsffile.h"
|
||||
#include "dsdifffile.h"
|
||||
#endif
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "utils.h"
|
||||
|
||||
@ -55,6 +72,7 @@ using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
class DummyResolver : public FileRef::FileTypeResolver
|
||||
{
|
||||
public:
|
||||
@ -63,7 +81,9 @@ namespace
|
||||
return new Ogg::Vorbis::File(fileName);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
class DummyStreamResolver : public FileRef::StreamTypeResolver
|
||||
{
|
||||
public:
|
||||
@ -77,36 +97,51 @@ namespace
|
||||
return new MP4::File(s);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
class TestFileRef : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestFileRef);
|
||||
CPPUNIT_TEST(testASF);
|
||||
CPPUNIT_TEST(testMusepack);
|
||||
CPPUNIT_TEST(testVorbis);
|
||||
CPPUNIT_TEST(testSpeex);
|
||||
CPPUNIT_TEST(testFLAC);
|
||||
CPPUNIT_TEST(testMP3);
|
||||
CPPUNIT_TEST(testOGA_FLAC);
|
||||
CPPUNIT_TEST(testOGA_Vorbis);
|
||||
CPPUNIT_TEST(testMP4_1);
|
||||
CPPUNIT_TEST(testMP4_2);
|
||||
CPPUNIT_TEST(testMP4_3);
|
||||
CPPUNIT_TEST(testMP4_4);
|
||||
CPPUNIT_TEST(testTrueAudio);
|
||||
CPPUNIT_TEST(testAPE);
|
||||
CPPUNIT_TEST(testWav);
|
||||
CPPUNIT_TEST(testAIFF_1);
|
||||
CPPUNIT_TEST(testAIFF_2);
|
||||
CPPUNIT_TEST(testWavPack);
|
||||
CPPUNIT_TEST(testOpus);
|
||||
CPPUNIT_TEST(testDSF);
|
||||
CPPUNIT_TEST(testDSDIFF);
|
||||
CPPUNIT_TEST(testUnsupported);
|
||||
CPPUNIT_TEST(testAudioProperties);
|
||||
CPPUNIT_TEST(testDefaultFileExtensions);
|
||||
CPPUNIT_TEST(testFileResolver);
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
CPPUNIT_TEST(testASF);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_TEST(testMusepack);
|
||||
CPPUNIT_TEST(testAPE);
|
||||
CPPUNIT_TEST(testWavPack);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_TEST(testVorbis);
|
||||
CPPUNIT_TEST(testSpeex);
|
||||
CPPUNIT_TEST(testFLAC);
|
||||
CPPUNIT_TEST(testOGA_FLAC);
|
||||
CPPUNIT_TEST(testOGA_Vorbis);
|
||||
CPPUNIT_TEST(testOpus);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
CPPUNIT_TEST(testMP4_1);
|
||||
CPPUNIT_TEST(testMP4_2);
|
||||
CPPUNIT_TEST(testMP4_3);
|
||||
CPPUNIT_TEST(testMP4_4);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
CPPUNIT_TEST(testTrueAudio);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
CPPUNIT_TEST(testWav);
|
||||
CPPUNIT_TEST(testAIFF_1);
|
||||
CPPUNIT_TEST(testAIFF_2);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
CPPUNIT_TEST(testDSF);
|
||||
CPPUNIT_TEST(testDSDIFF);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -239,16 +274,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
void testMusepack()
|
||||
{
|
||||
fileRefSave<MPC::File>("click", ".mpc");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
void testASF()
|
||||
{
|
||||
fileRefSave<ASF::File>("silence-1", ".wma");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testVorbis()
|
||||
{
|
||||
fileRefSave<Ogg::Vorbis::File>("empty", ".ogg");
|
||||
@ -263,17 +303,21 @@ public:
|
||||
{
|
||||
fileRefSave<FLAC::File>("no-tags", ".flac");
|
||||
}
|
||||
#endif
|
||||
|
||||
void testMP3()
|
||||
{
|
||||
fileRefSave<MPEG::File>("xing", ".mp3");
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
void testTrueAudio()
|
||||
{
|
||||
fileRefSave<TrueAudio::File>("empty", ".tta");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
void testMP4_1()
|
||||
{
|
||||
fileRefSave<MP4::File>("has-tags", ".m4a");
|
||||
@ -293,12 +337,16 @@ public:
|
||||
{
|
||||
fileRefSave<MP4::File>("blank_video", ".m4v");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
void testWav()
|
||||
{
|
||||
fileRefSave<RIFF::WAV::File>("empty", ".wav");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testOGA_FLAC()
|
||||
{
|
||||
fileRefSave<Ogg::FLAC::File>("empty_flac", ".oga");
|
||||
@ -308,12 +356,16 @@ public:
|
||||
{
|
||||
fileRefSave<Ogg::Vorbis::File>("empty_vorbis", ".oga");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
void testAPE()
|
||||
{
|
||||
fileRefSave<APE::File>("mac-399", ".ape");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
void testAIFF_1()
|
||||
{
|
||||
fileRefSave<RIFF::AIFF::File>("empty", ".aiff");
|
||||
@ -323,17 +375,23 @@ public:
|
||||
{
|
||||
fileRefSave<RIFF::AIFF::File>("alaw", ".aifc");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
void testWavPack()
|
||||
{
|
||||
fileRefSave<WavPack::File>("click", ".wv");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testOpus()
|
||||
{
|
||||
fileRefSave<Ogg::Opus::File>("correctness_gain_silent_output", ".opus");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
void testDSF()
|
||||
{
|
||||
fileRefSave<DSF::File>("empty10ms",".dsf");
|
||||
@ -343,6 +401,7 @@ public:
|
||||
{
|
||||
fileRefSave<DSDIFF::File>("empty10ms",".dff");
|
||||
}
|
||||
#endif
|
||||
|
||||
void testUnsupported()
|
||||
{
|
||||
@ -364,27 +423,56 @@ public:
|
||||
void testDefaultFileExtensions()
|
||||
{
|
||||
const StringList extensions = FileRef::defaultFileExtensions();
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_ASSERT(extensions.contains("mpc"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
CPPUNIT_ASSERT(extensions.contains("wma"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_ASSERT(extensions.contains("ogg"));
|
||||
CPPUNIT_ASSERT(extensions.contains("spx"));
|
||||
CPPUNIT_ASSERT(extensions.contains("flac"));
|
||||
#endif
|
||||
CPPUNIT_ASSERT(extensions.contains("mp3"));
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
CPPUNIT_ASSERT(extensions.contains("tta"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
CPPUNIT_ASSERT(extensions.contains("m4a"));
|
||||
CPPUNIT_ASSERT(extensions.contains("3g2"));
|
||||
CPPUNIT_ASSERT(extensions.contains("m4v"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
CPPUNIT_ASSERT(extensions.contains("wav"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_ASSERT(extensions.contains("oga"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_ASSERT(extensions.contains("ape"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
CPPUNIT_ASSERT(extensions.contains("aiff"));
|
||||
CPPUNIT_ASSERT(extensions.contains("aifc"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_ASSERT(extensions.contains("wv"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_ASSERT(extensions.contains("opus"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
CPPUNIT_ASSERT(extensions.contains("xm"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
CPPUNIT_ASSERT(extensions.contains("dsf"));
|
||||
CPPUNIT_ASSERT(extensions.contains("dff"));
|
||||
CPPUNIT_ASSERT(extensions.contains("dsdiff"));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
CPPUNIT_ASSERT(extensions.contains("shn"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void testFileResolver()
|
||||
@ -394,6 +482,7 @@ public:
|
||||
CPPUNIT_ASSERT(dynamic_cast<MPEG::File *>(f.file()) != nullptr);
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
DummyResolver resolver;
|
||||
FileRef::addFileTypeResolver(&resolver);
|
||||
|
||||
@ -401,7 +490,9 @@ public:
|
||||
FileRef f(TEST_FILE_PATH_C("xing.mp3"));
|
||||
CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f.file()) != nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
DummyStreamResolver streamResolver;
|
||||
FileRef::addFileTypeResolver(&streamResolver);
|
||||
|
||||
@ -410,6 +501,7 @@ public:
|
||||
FileRef f(&s);
|
||||
CPPUNIT_ASSERT(dynamic_cast<MP4::File *>(f.file()) != nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
FileRef::clearFileTypeResolvers();
|
||||
}
|
||||
|
@ -26,21 +26,30 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "flacproperties.h"
|
||||
#include "taglib_config.h"
|
||||
#include "mpegproperties.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "mpegfile.h"
|
||||
#include "flacfile.h"
|
||||
#include "trueaudiofile.h"
|
||||
#include "trueaudioproperties.h"
|
||||
#include "wavfile.h"
|
||||
#include "aifffile.h"
|
||||
#include "dsffile.h"
|
||||
#include "dsdifffile.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "id3v2frame.h"
|
||||
#include "id3v2framefactory.h"
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "flacproperties.h"
|
||||
#include "flacfile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
#include "trueaudiofile.h"
|
||||
#include "trueaudioproperties.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
#include "wavfile.h"
|
||||
#include "aifffile.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
#include "dsffile.h"
|
||||
#include "dsdifffile.h"
|
||||
#endif
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "utils.h"
|
||||
|
||||
@ -118,12 +127,20 @@ class TestId3v2FrameFactory : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestId3v2FrameFactory);
|
||||
CPPUNIT_TEST(testMPEG);
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_TEST(testFLAC);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
CPPUNIT_TEST(testTrueAudio);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
CPPUNIT_TEST(testWAV);
|
||||
CPPUNIT_TEST(testAIFF);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
CPPUNIT_TEST(testDSF);
|
||||
CPPUNIT_TEST(testDSDIFF);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -236,6 +253,7 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testFLAC()
|
||||
{
|
||||
ScopedFileCopy copy("no-tags", ".flac");
|
||||
@ -260,7 +278,9 @@ public:
|
||||
}
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
void testTrueAudio()
|
||||
{
|
||||
ScopedFileCopy copy("empty", ".tta");
|
||||
@ -285,7 +305,9 @@ public:
|
||||
}
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
void testWAV()
|
||||
{
|
||||
ScopedFileCopy copy("empty", ".wav");
|
||||
@ -335,7 +357,9 @@ public:
|
||||
}
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
void testDSF()
|
||||
{
|
||||
ScopedFileCopy copy("empty10ms", ".dsf");
|
||||
@ -385,6 +409,7 @@ public:
|
||||
}
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
@ -27,12 +27,15 @@
|
||||
#include <cstdio>
|
||||
#include <array>
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tstring.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "mpegfile.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "id3v1tag.h"
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
#include "mpegproperties.h"
|
||||
#include "xingheader.h"
|
||||
#include "mpegheader.h"
|
||||
@ -67,7 +70,9 @@ class TestMPEG : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testRepeatedSave3);
|
||||
CPPUNIT_TEST(testEmptyID3v2);
|
||||
CPPUNIT_TEST(testEmptyID3v1);
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_TEST(testEmptyAPE);
|
||||
#endif
|
||||
CPPUNIT_TEST(testIgnoreGarbage);
|
||||
CPPUNIT_TEST(testExtendedHeader);
|
||||
CPPUNIT_TEST(testReadStyleFast);
|
||||
@ -304,7 +309,9 @@ public:
|
||||
{
|
||||
MPEG::File f(copy.fileName().c_str());
|
||||
f.ID3v2Tag(true)->setTitle("ID3v2");
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
f.APETag(true)->setTitle("APE");
|
||||
#endif
|
||||
f.ID3v1Tag(true)->setTitle("ID3v1");
|
||||
f.save();
|
||||
}
|
||||
@ -312,8 +319,10 @@ public:
|
||||
MPEG::File f(copy.fileName().c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(String("ID3v2"), f.properties()["TITLE"].front());
|
||||
f.strip(MPEG::File::ID3v2);
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_ASSERT_EQUAL(String("APE"), f.properties()["TITLE"].front());
|
||||
f.strip(MPEG::File::APE);
|
||||
#endif
|
||||
CPPUNIT_ASSERT_EQUAL(String("ID3v1"), f.properties()["TITLE"].front());
|
||||
f.strip(MPEG::File::ID3v1);
|
||||
CPPUNIT_ASSERT(f.properties().isEmpty());
|
||||
@ -464,17 +473,23 @@ public:
|
||||
CPPUNIT_ASSERT(!f.hasAPETag());
|
||||
CPPUNIT_ASSERT(!f.hasID3v1Tag());
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
f.APETag(true)->setTitle("01234 56789 ABCDE FGHIJ");
|
||||
f.save();
|
||||
f.APETag()->setTitle("0");
|
||||
f.save();
|
||||
#endif
|
||||
f.ID3v1Tag(true)->setTitle("01234 56789 ABCDE FGHIJ");
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
f.APETag()->setTitle("01234 56789 ABCDE FGHIJ 01234 56789 ABCDE FGHIJ 01234 56789");
|
||||
#endif
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
MPEG::File f(copy.fileName().c_str());
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_ASSERT(f.hasAPETag());
|
||||
#endif
|
||||
CPPUNIT_ASSERT(f.hasID3v1Tag());
|
||||
}
|
||||
}
|
||||
@ -519,6 +534,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
void testEmptyAPE()
|
||||
{
|
||||
ScopedFileCopy copy("xing", ".mp3");
|
||||
@ -538,6 +554,7 @@ public:
|
||||
CPPUNIT_ASSERT(!f.hasAPETag());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void testIgnoreGarbage()
|
||||
{
|
||||
|
@ -23,15 +23,26 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tag.h"
|
||||
#include "apetag.h"
|
||||
#include "asftag.h"
|
||||
#include "id3v1tag.h"
|
||||
#include "id3v2tag.h"
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apetag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include "asftag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
#include "infotag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include "mp4tag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "xiphcomment.h"
|
||||
#endif
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "utils.h"
|
||||
|
||||
@ -41,14 +52,24 @@ class TestPropertyMap : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestPropertyMap);
|
||||
CPPUNIT_TEST(testInvalidKeys);
|
||||
CPPUNIT_TEST(testGetSetApe);
|
||||
CPPUNIT_TEST(testGetSetAsf);
|
||||
CPPUNIT_TEST(testGetSetId3v1);
|
||||
CPPUNIT_TEST(testGetSetId3v2);
|
||||
CPPUNIT_TEST(testGetSetInfo);
|
||||
CPPUNIT_TEST(testGetSetMp4);
|
||||
CPPUNIT_TEST(testGetSetXiphComment);
|
||||
CPPUNIT_TEST(testGetSet);
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_TEST(testGetSetApe);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
CPPUNIT_TEST(testGetSetAsf);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
CPPUNIT_TEST(testGetSetInfo);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
CPPUNIT_TEST(testGetSetMp4);
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_TEST(testGetSetXiphComment);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -141,30 +162,40 @@ public:
|
||||
tagGetSet<ID3v2::Tag>();
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testGetSetXiphComment()
|
||||
{
|
||||
tagGetSet<Ogg::XiphComment>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
void testGetSetApe()
|
||||
{
|
||||
tagGetSet<APE::Tag>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
void testGetSetAsf()
|
||||
{
|
||||
tagGetSet<ASF::Tag>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
void testGetSetMp4()
|
||||
{
|
||||
tagGetSet<MP4::Tag>();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
void testGetSetInfo()
|
||||
{
|
||||
tagGetSet<RIFF::Info::Tag>();
|
||||
}
|
||||
#endif
|
||||
|
||||
void testGetSet()
|
||||
{
|
||||
|
44
tests/test_shorten.cpp
Normal file
44
tests/test_shorten.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include "tbytevectorlist.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tag.h"
|
||||
#include "shortenfile.h"
|
||||
#include "plainfile.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace TagLib;
|
||||
|
||||
class TestShorten : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestShorten);
|
||||
CPPUNIT_TEST(testBasic);
|
||||
CPPUNIT_TEST(testTags);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
|
||||
void testBasic()
|
||||
{
|
||||
Shorten::File f(TEST_FILE_PATH_C("2sec-silence.shn"));
|
||||
CPPUNIT_ASSERT(f.audioProperties());
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->lengthInSeconds());
|
||||
CPPUNIT_ASSERT_EQUAL(2000, f.audioProperties()->lengthInMilliseconds());
|
||||
CPPUNIT_ASSERT_EQUAL(1411, f.audioProperties()->bitrate());
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->channels());
|
||||
CPPUNIT_ASSERT_EQUAL(44100, f.audioProperties()->sampleRate());
|
||||
CPPUNIT_ASSERT_EQUAL(2, f.audioProperties()->shortenVersion());
|
||||
CPPUNIT_ASSERT_EQUAL(5, f.audioProperties()->fileType());
|
||||
CPPUNIT_ASSERT_EQUAL(16, f.audioProperties()->bitsPerSample());
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<unsigned long>(88200), f.audioProperties()->sampleFrames());
|
||||
}
|
||||
|
||||
void testTags()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestShorten);
|
@ -25,34 +25,25 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "aifffile.h"
|
||||
#include "aiffproperties.h"
|
||||
#include "apefile.h"
|
||||
#include "apefooter.h"
|
||||
#include "apeitem.h"
|
||||
#include "apeproperties.h"
|
||||
#include "apetag.h"
|
||||
#include "asfattribute.h"
|
||||
#include "asffile.h"
|
||||
#include "asfpicture.h"
|
||||
#include "asfproperties.h"
|
||||
#include "asftag.h"
|
||||
#include "attachedpictureframe.h"
|
||||
#include "audioproperties.h"
|
||||
#include "chapterframe.h"
|
||||
#include "commentsframe.h"
|
||||
#include "dsffile.h"
|
||||
#include "dsfproperties.h"
|
||||
#include "dsdifffile.h"
|
||||
#include "dsdiffproperties.h"
|
||||
#include "eventtimingcodesframe.h"
|
||||
#include "taglib_config.h"
|
||||
#include "tag.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tbytevectorlist.h"
|
||||
#include "tbytevectorstream.h"
|
||||
#include "tdebuglistener.h"
|
||||
#include "tfile.h"
|
||||
#include "tfilestream.h"
|
||||
#include "tiostream.h"
|
||||
#include "tlist.h"
|
||||
#include "tmap.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tstring.h"
|
||||
#include "tstringlist.h"
|
||||
#include "fileref.h"
|
||||
#include "flacfile.h"
|
||||
#include "flacmetadatablock.h"
|
||||
#include "flacunknownmetadatablock.h"
|
||||
#include "flacpicture.h"
|
||||
#include "flacproperties.h"
|
||||
#include "generalencapsulatedobjectframe.h"
|
||||
#include "mpegfile.h"
|
||||
#include "mpegheader.h"
|
||||
#include "mpegproperties.h"
|
||||
#include "xingheader.h"
|
||||
#include "id3v1tag.h"
|
||||
#include "id3v2extendedheader.h"
|
||||
#include "id3v2footer.h"
|
||||
@ -60,72 +51,103 @@
|
||||
#include "id3v2framefactory.h"
|
||||
#include "id3v2header.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "attachedpictureframe.h"
|
||||
#include "audioproperties.h"
|
||||
#include "chapterframe.h"
|
||||
#include "commentsframe.h"
|
||||
#include "eventtimingcodesframe.h"
|
||||
#include "generalencapsulatedobjectframe.h"
|
||||
#include "ownershipframe.h"
|
||||
#include "podcastframe.h"
|
||||
#include "popularimeterframe.h"
|
||||
#include "privateframe.h"
|
||||
#include "relativevolumeframe.h"
|
||||
#include "synchronizedlyricsframe.h"
|
||||
#include "tableofcontentsframe.h"
|
||||
#include "textidentificationframe.h"
|
||||
#include "uniquefileidentifierframe.h"
|
||||
#include "unknownframe.h"
|
||||
#include "unsynchronizedlyricsframe.h"
|
||||
#include "urllinkframe.h"
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
#include "aifffile.h"
|
||||
#include "aiffproperties.h"
|
||||
#include "infotag.h"
|
||||
#include "itfile.h"
|
||||
#include "itproperties.h"
|
||||
#include "modfile.h"
|
||||
#include "modfilebase.h"
|
||||
#include "modproperties.h"
|
||||
#include "modtag.h"
|
||||
#include "mp4coverart.h"
|
||||
#include "mp4file.h"
|
||||
#include "mp4item.h"
|
||||
#include "mp4itemfactory.h"
|
||||
#include "mp4properties.h"
|
||||
#include "mp4tag.h"
|
||||
#include "rifffile.h"
|
||||
#include "wavfile.h"
|
||||
#include "wavproperties.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
#include "apefile.h"
|
||||
#include "apefooter.h"
|
||||
#include "apeitem.h"
|
||||
#include "apeproperties.h"
|
||||
#include "apetag.h"
|
||||
#include "mpcfile.h"
|
||||
#include "mpcproperties.h"
|
||||
#include "mpegfile.h"
|
||||
#include "mpegheader.h"
|
||||
#include "mpegproperties.h"
|
||||
#include "wavpackfile.h"
|
||||
#include "wavpackproperties.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
#include "asfattribute.h"
|
||||
#include "asffile.h"
|
||||
#include "asfpicture.h"
|
||||
#include "asfproperties.h"
|
||||
#include "asftag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
#include "dsffile.h"
|
||||
#include "dsfproperties.h"
|
||||
#include "dsdifffile.h"
|
||||
#include "dsdiffproperties.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
#include "flacfile.h"
|
||||
#include "flacmetadatablock.h"
|
||||
#include "flacunknownmetadatablock.h"
|
||||
#include "flacpicture.h"
|
||||
#include "flacproperties.h"
|
||||
#include "oggfile.h"
|
||||
#include "oggflacfile.h"
|
||||
#include "oggpage.h"
|
||||
#include "oggpageheader.h"
|
||||
#include "opusfile.h"
|
||||
#include "opusproperties.h"
|
||||
#include "ownershipframe.h"
|
||||
#include "podcastframe.h"
|
||||
#include "popularimeterframe.h"
|
||||
#include "privateframe.h"
|
||||
#include "relativevolumeframe.h"
|
||||
#include "rifffile.h"
|
||||
#include "s3mfile.h"
|
||||
#include "s3mproperties.h"
|
||||
#include "speexfile.h"
|
||||
#include "speexproperties.h"
|
||||
#include "synchronizedlyricsframe.h"
|
||||
#include "tableofcontentsframe.h"
|
||||
#include "tag.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tbytevectorlist.h"
|
||||
#include "tbytevectorstream.h"
|
||||
#include "tdebuglistener.h"
|
||||
#include "textidentificationframe.h"
|
||||
#include "tfile.h"
|
||||
#include "tfilestream.h"
|
||||
#include "tiostream.h"
|
||||
#include "tlist.h"
|
||||
#include "tmap.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "trueaudiofile.h"
|
||||
#include "trueaudioproperties.h"
|
||||
#include "tstring.h"
|
||||
#include "tstringlist.h"
|
||||
#include "uniquefileidentifierframe.h"
|
||||
#include "unknownframe.h"
|
||||
#include "unsynchronizedlyricsframe.h"
|
||||
#include "urllinkframe.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "vorbisproperties.h"
|
||||
#include "wavfile.h"
|
||||
#include "wavpackfile.h"
|
||||
#include "wavpackproperties.h"
|
||||
#include "wavproperties.h"
|
||||
#include "xingheader.h"
|
||||
#include "xiphcomment.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
#include "itfile.h"
|
||||
#include "itproperties.h"
|
||||
#include "modfile.h"
|
||||
#include "modfilebase.h"
|
||||
#include "modproperties.h"
|
||||
#include "modtag.h"
|
||||
#include "s3mfile.h"
|
||||
#include "s3mproperties.h"
|
||||
#include "xmfile.h"
|
||||
#include "xmproperties.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
#include "mp4coverart.h"
|
||||
#include "mp4file.h"
|
||||
#include "mp4item.h"
|
||||
#include "mp4itemfactory.h"
|
||||
#include "mp4properties.h"
|
||||
#include "mp4tag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
#include "shortenfile.h"
|
||||
#include "shortenproperties.h"
|
||||
#include "shortentag.h"
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
#include "trueaudiofile.h"
|
||||
#include "trueaudioproperties.h"
|
||||
#endif
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
@ -144,31 +166,11 @@ public:
|
||||
// Class list was built by generating XML docs with Doxygen, and then running:
|
||||
// $ grep kind=\"class\" index.xml | sed -E -e 's/(.*<name>|<\/name>.*)//g'
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::APE::Footer));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::APE::Item));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::ASF::Attribute));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::ASF::Picture));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::AudioProperties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::ByteVector));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, false), sizeof(TagLib::ByteVectorList));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ByteVectorStream));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::DebugListener));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSDIFF::DIIN::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSDIFF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSDIFF::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSF::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::FLAC::MetadataBlock));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::Picture));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::UnknownMetadataBlock));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::FileRef));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::FileRef::FileTypeResolver));
|
||||
@ -204,26 +206,47 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::ID3v2::UserTextIdentificationFrame));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::ID3v2::UserUrlLinkFrame));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::IOStream));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::IT::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::IT::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::List<int>));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::MP4::CoverArt));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::MP4::Item));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::MP4::ItemFactory));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPC::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPC::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPEG::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::MPEG::Header));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPEG::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::MPEG::XingHeader));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::Map<int, int>));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Mod::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::FileBase));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, false), sizeof(TagLib::PropertyMap));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::String));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, false), sizeof(TagLib::StringList));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::Tag));
|
||||
#ifdef TAGLIB_WITH_APE
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::APE::Footer));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, false), sizeof(TagLib::APE::Item));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::APE::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPC::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MPC::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::WavPack::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::WavPack::Properties));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_ASF
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::ASF::Attribute));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::ASF::Picture));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::ASF::Tag));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_DSF
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSDIFF::DIIN::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSDIFF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSDIFF::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::DSF::Properties));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::FLAC::MetadataBlock));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::Picture));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::FLAC::UnknownMetadataBlock));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::FLAC::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::Opus::File));
|
||||
@ -235,7 +258,29 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Ogg::Vorbis::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::Vorbis::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Ogg::XiphComment));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, false), sizeof(TagLib::PropertyMap));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MOD
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::IT::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::IT::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::Mod::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::FileBase));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Mod::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::S3M::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::S3M::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::XM::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::XM::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::Variant));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_MP4
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::MP4::CoverArt));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::MP4::Item));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::MP4::ItemFactory));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::MP4::Tag));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_RIFF
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::RIFF::AIFF::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::AIFF::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::File));
|
||||
@ -243,18 +288,16 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::Info::Tag));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::RIFF::WAV::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::RIFF::WAV::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::S3M::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::S3M::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::String));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, false), sizeof(TagLib::StringList));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(0, true), sizeof(TagLib::Tag));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_SHORTEN
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Shorten::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Shorten::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::Shorten::Tag));
|
||||
#endif
|
||||
#ifdef TAGLIB_WITH_TRUEAUDIO
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::TrueAudio::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::TrueAudio::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::WavPack::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::WavPack::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(2, true), sizeof(TagLib::XM::File));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, true), sizeof(TagLib::XM::Properties));
|
||||
CPPUNIT_ASSERT_EQUAL(classSize(1, false), sizeof(TagLib::Variant));
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -23,9 +23,12 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "tstring.h"
|
||||
#include "tstringlist.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tutils.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
@ -54,6 +57,7 @@ class TestString : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testEncodeNonBMP);
|
||||
CPPUNIT_TEST(testIterator);
|
||||
CPPUNIT_TEST(testInvalidUTF8);
|
||||
CPPUNIT_TEST(testEmpty);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -370,6 +374,80 @@ public:
|
||||
CPPUNIT_ASSERT(String(ByteVector("\xED\xB0\x80\xED\xA0\x80"), String::UTF8).isEmpty());
|
||||
}
|
||||
|
||||
void testEmpty()
|
||||
{
|
||||
const String empty;
|
||||
const String notEmpty("A");
|
||||
String mutEmpty;
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(empty, String(""));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, String(std::wstring()));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, String(static_cast<const wchar_t *>(nullptr)));
|
||||
CPPUNIT_ASSERT(empty != String('\0'));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, String(L'\0'));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, String(static_cast<const char *>(nullptr)));
|
||||
CPPUNIT_ASSERT_EQUAL(empty, String(ByteVector()));
|
||||
CPPUNIT_ASSERT_EQUAL(empty.to8Bit(), std::string());
|
||||
CPPUNIT_ASSERT_EQUAL(empty.toWString(), std::wstring());
|
||||
CPPUNIT_ASSERT_EQUAL(::strlen(empty.toCString()), (size_t)0);
|
||||
CPPUNIT_ASSERT_EQUAL(::wcslen(empty.toCWString()), (size_t)0);
|
||||
CPPUNIT_ASSERT(empty.begin() == empty.end());
|
||||
CPPUNIT_ASSERT(empty.cbegin() == empty.cend());
|
||||
CPPUNIT_ASSERT(mutEmpty.begin() == mutEmpty.end());
|
||||
CPPUNIT_ASSERT_EQUAL(empty.find(mutEmpty), 0);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.find(notEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(notEmpty.find(empty), 0);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.rfind(mutEmpty), 0);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.rfind(notEmpty), -1);
|
||||
CPPUNIT_ASSERT_EQUAL(notEmpty.rfind(empty), 1);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.split(), StringList(empty));
|
||||
CPPUNIT_ASSERT_EQUAL(empty.startsWith(mutEmpty), true);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.startsWith(notEmpty), false);
|
||||
CPPUNIT_ASSERT_EQUAL(notEmpty.startsWith(empty), true);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.substr(0), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(empty), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty.append(notEmpty), notEmpty);
|
||||
mutEmpty.clear();
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(String(notEmpty).append(empty), notEmpty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.upper(), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.size(), 0U);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.length(), 0U);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.isEmpty(), true);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.data(String::Latin1), ByteVector());
|
||||
CPPUNIT_ASSERT_EQUAL(empty.data(String::UTF16LE), ByteVector());
|
||||
bool ok;
|
||||
empty.toInt(&ok);
|
||||
CPPUNIT_ASSERT(!ok);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.stripWhiteSpace(), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.isLatin1(), true);
|
||||
CPPUNIT_ASSERT_EQUAL(empty.isAscii(), true);
|
||||
CPPUNIT_ASSERT(empty == mutEmpty);
|
||||
CPPUNIT_ASSERT(empty != notEmpty);
|
||||
CPPUNIT_ASSERT(empty == "");
|
||||
CPPUNIT_ASSERT(empty != " ");
|
||||
CPPUNIT_ASSERT(empty == L"");
|
||||
CPPUNIT_ASSERT(empty != L" ");
|
||||
CPPUNIT_ASSERT(empty == static_cast<const char *>(nullptr));
|
||||
CPPUNIT_ASSERT(!(empty != static_cast<const char *>(nullptr)));
|
||||
CPPUNIT_ASSERT(empty == static_cast<const wchar_t *>(nullptr));
|
||||
CPPUNIT_ASSERT(!(empty != static_cast<const wchar_t *>(nullptr)));
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty += empty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty += notEmpty, notEmpty);
|
||||
mutEmpty.clear();
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty += static_cast<const char *>(nullptr), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty += static_cast<const wchar_t *>(nullptr), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty = static_cast<const char *>(nullptr), empty);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty = static_cast<const wchar_t *>(nullptr), empty);
|
||||
String tmp;
|
||||
mutEmpty.swap(tmp);
|
||||
CPPUNIT_ASSERT_EQUAL(mutEmpty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty < notEmpty, true);
|
||||
CPPUNIT_ASSERT_EQUAL(empty + mutEmpty, empty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty + notEmpty, notEmpty);
|
||||
CPPUNIT_ASSERT_EQUAL(empty + static_cast<const char *>(nullptr), empty);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestString);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include "tag_c.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tstring.h"
|
||||
@ -77,7 +78,9 @@ class TestTagC : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestTagC);
|
||||
CPPUNIT_TEST(testMp3);
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
CPPUNIT_TEST(testStream);
|
||||
#endif
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -165,6 +168,7 @@ public:
|
||||
taglib_tag_free_strings();
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_WITH_VORBIS
|
||||
void testStream()
|
||||
{
|
||||
// Only fetch the beginning of a FLAC file
|
||||
@ -233,6 +237,7 @@ public:
|
||||
|
||||
taglib_tag_free_strings();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestTagC);
|
||||
|
@ -54,12 +54,14 @@ inline string copyFile(const string &filename, const string &ext)
|
||||
{
|
||||
char testFileName[1024];
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef TESTS_TMPDIR
|
||||
snprintf(testFileName, sizeof(testFileName), "%s/taglib-test%s", TESTS_TMPDIR, ext.c_str());
|
||||
#elif defined _WIN32
|
||||
char tempDir[MAX_PATH + 1];
|
||||
GetTempPathA(sizeof(tempDir), tempDir);
|
||||
wsprintfA(testFileName, "%s\\taglib-test%s", tempDir, ext.c_str());
|
||||
#else
|
||||
snprintf(testFileName, sizeof(testFileName), "/%s/taglib-test%s", P_tmpdir, ext.c_str());
|
||||
snprintf(testFileName, sizeof(testFileName), "%s/taglib-test%s", P_tmpdir, ext.c_str());
|
||||
#endif
|
||||
|
||||
string sourceFileName = testFilePath(filename) + ext;
|
||||
|
Loading…
Reference in New Issue
Block a user