From c956386b6e8dd36f27fc124229440db15d8fbc71 Mon Sep 17 00:00:00 2001 From: TaurusXin Date: Wed, 6 Oct 2021 17:34:29 +0100 Subject: [PATCH] feat: added project files --- .gitignore | 2 + .vscode/c_cpp_properties.json | 16 + Makefile | 11 + aes.cpp | 305 ++ aes.h | 57 + base64.h | 96 + cJSON.cpp | 2932 +++++++++++++++++ cJSON.h | 277 ++ main.cpp | 28 + ncmcrypt.cpp | 379 +++ ncmcrypt.h | 69 + taglib/bin/taglib-config.cmd | 36 + taglib/include/taglib/aifffile.h | 157 + taglib/include/taglib/aiffproperties.h | 166 + taglib/include/taglib/apefile.h | 235 ++ taglib/include/taglib/apefooter.h | 173 + taglib/include/taglib/apeitem.h | 224 ++ taglib/include/taglib/apeproperties.h | 143 + taglib/include/taglib/apetag.h | 208 ++ taglib/include/taglib/asfattribute.h | 208 ++ taglib/include/taglib/asffile.h | 138 + taglib/include/taglib/asfpicture.h | 222 ++ taglib/include/taglib/asfproperties.h | 186 ++ taglib/include/taglib/asftag.h | 210 ++ taglib/include/taglib/attachedpictureframe.h | 230 ++ taglib/include/taglib/audioproperties.h | 127 + taglib/include/taglib/chapterframe.h | 249 ++ taglib/include/taglib/commentsframe.h | 179 + taglib/include/taglib/eventtimingcodesframe.h | 185 ++ taglib/include/taglib/fileref.h | 287 ++ taglib/include/taglib/flacfile.h | 343 ++ taglib/include/taglib/flacmetadatablock.h | 75 + taglib/include/taglib/flacpicture.h | 208 ++ taglib/include/taglib/flacproperties.h | 148 + .../taglib/generalencapsulatedobjectframe.h | 179 + taglib/include/taglib/id3v1genres.h | 66 + taglib/include/taglib/id3v1tag.h | 202 ++ taglib/include/taglib/id3v2.h | 24 + taglib/include/taglib/id3v2extendedheader.h | 93 + taglib/include/taglib/id3v2footer.h | 82 + taglib/include/taglib/id3v2frame.h | 521 +++ taglib/include/taglib/id3v2framefactory.h | 169 + taglib/include/taglib/id3v2header.h | 176 + taglib/include/taglib/id3v2synchdata.h | 70 + taglib/include/taglib/id3v2tag.h | 411 +++ taglib/include/taglib/infotag.h | 192 ++ taglib/include/taglib/itfile.h | 109 + taglib/include/taglib/itproperties.h | 107 + taglib/include/taglib/modfile.h | 114 + taglib/include/taglib/modfilebase.h | 66 + taglib/include/taglib/modproperties.h | 71 + taglib/include/taglib/modtag.h | 194 ++ taglib/include/taglib/mp4atom.h | 111 + taglib/include/taglib/mp4coverart.h | 84 + taglib/include/taglib/mp4file.h | 143 + taglib/include/taglib/mp4item.h | 93 + taglib/include/taglib/mp4properties.h | 120 + taglib/include/taglib/mp4tag.h | 164 + taglib/include/taglib/mpcfile.h | 238 ++ taglib/include/taglib/mpcproperties.h | 158 + taglib/include/taglib/mpegfile.h | 387 +++ taglib/include/taglib/mpegheader.h | 178 + taglib/include/taglib/mpegproperties.h | 152 + taglib/include/taglib/oggfile.h | 127 + taglib/include/taglib/oggflacfile.h | 170 + taglib/include/taglib/oggpage.h | 228 ++ taglib/include/taglib/oggpageheader.h | 232 ++ taglib/include/taglib/opusfile.h | 138 + taglib/include/taglib/opusproperties.h | 134 + taglib/include/taglib/ownershipframe.h | 151 + taglib/include/taglib/podcastframe.h | 82 + taglib/include/taglib/popularimeterframe.h | 132 + taglib/include/taglib/privateframe.h | 111 + taglib/include/taglib/relativevolumeframe.h | 274 ++ taglib/include/taglib/rifffile.h | 161 + taglib/include/taglib/s3mfile.h | 112 + taglib/include/taglib/s3mproperties.h | 94 + taglib/include/taglib/speexfile.h | 138 + taglib/include/taglib/speexproperties.h | 129 + .../include/taglib/synchronizedlyricsframe.h | 231 ++ taglib/include/taglib/tableofcontentsframe.h | 260 ++ taglib/include/taglib/tag.h | 201 ++ taglib/include/taglib/tag_c.h | 299 ++ taglib/include/taglib/taglib.h | 179 + taglib/include/taglib/taglib_config.h | 11 + taglib/include/taglib/taglib_export.h | 43 + taglib/include/taglib/tbytevector.h | 635 ++++ taglib/include/taglib/tbytevectorlist.h | 91 + taglib/include/taglib/tbytevectorstream.h | 145 + taglib/include/taglib/tdebuglistener.h | 74 + .../include/taglib/textidentificationframe.h | 313 ++ taglib/include/taglib/tfile.h | 323 ++ taglib/include/taglib/tfilestream.h | 159 + taglib/include/taglib/tiostream.h | 170 + taglib/include/taglib/tlist.h | 270 ++ taglib/include/taglib/tlist.tcc | 323 ++ taglib/include/taglib/tmap.h | 204 ++ taglib/include/taglib/tmap.tcc | 199 ++ taglib/include/taglib/tpropertymap.h | 242 ++ taglib/include/taglib/trefcounter.h | 114 + taglib/include/taglib/trueaudiofile.h | 259 ++ taglib/include/taglib/trueaudioproperties.h | 133 + taglib/include/taglib/tstring.h | 580 ++++ taglib/include/taglib/tstringlist.h | 115 + .../taglib/uniquefileidentifierframe.h | 123 + taglib/include/taglib/unknownframe.h | 79 + .../taglib/unsynchronizedlyricsframe.h | 179 + taglib/include/taglib/urllinkframe.h | 190 ++ taglib/include/taglib/vorbisfile.h | 157 + taglib/include/taglib/vorbisproperties.h | 160 + taglib/include/taglib/wavfile.h | 215 ++ taglib/include/taglib/wavpackfile.h | 223 ++ taglib/include/taglib/wavpackproperties.h | 149 + taglib/include/taglib/wavproperties.h | 163 + taglib/include/taglib/xingheader.h | 129 + taglib/include/taglib/xiphcomment.h | 275 ++ taglib/include/taglib/xmfile.h | 112 + taglib/include/taglib/xmproperties.h | 85 + taglib/lib/libtag.a | Bin 0 -> 2316966 bytes taglib/lib/libtag_c.a | Bin 0 -> 20496 bytes taglib/lib/pkgconfig/taglib.pc | 11 + taglib/lib/pkgconfig/taglib_c.pc | 12 + 122 files changed, 23431 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/c_cpp_properties.json create mode 100644 Makefile create mode 100644 aes.cpp create mode 100644 aes.h create mode 100644 base64.h create mode 100644 cJSON.cpp create mode 100644 cJSON.h create mode 100644 main.cpp create mode 100644 ncmcrypt.cpp create mode 100644 ncmcrypt.h create mode 100644 taglib/bin/taglib-config.cmd create mode 100644 taglib/include/taglib/aifffile.h create mode 100644 taglib/include/taglib/aiffproperties.h create mode 100644 taglib/include/taglib/apefile.h create mode 100644 taglib/include/taglib/apefooter.h create mode 100644 taglib/include/taglib/apeitem.h create mode 100644 taglib/include/taglib/apeproperties.h create mode 100644 taglib/include/taglib/apetag.h create mode 100644 taglib/include/taglib/asfattribute.h create mode 100644 taglib/include/taglib/asffile.h create mode 100644 taglib/include/taglib/asfpicture.h create mode 100644 taglib/include/taglib/asfproperties.h create mode 100644 taglib/include/taglib/asftag.h create mode 100644 taglib/include/taglib/attachedpictureframe.h create mode 100644 taglib/include/taglib/audioproperties.h create mode 100644 taglib/include/taglib/chapterframe.h create mode 100644 taglib/include/taglib/commentsframe.h create mode 100644 taglib/include/taglib/eventtimingcodesframe.h create mode 100644 taglib/include/taglib/fileref.h create mode 100644 taglib/include/taglib/flacfile.h create mode 100644 taglib/include/taglib/flacmetadatablock.h create mode 100644 taglib/include/taglib/flacpicture.h create mode 100644 taglib/include/taglib/flacproperties.h create mode 100644 taglib/include/taglib/generalencapsulatedobjectframe.h create mode 100644 taglib/include/taglib/id3v1genres.h create mode 100644 taglib/include/taglib/id3v1tag.h create mode 100644 taglib/include/taglib/id3v2.h create mode 100644 taglib/include/taglib/id3v2extendedheader.h create mode 100644 taglib/include/taglib/id3v2footer.h create mode 100644 taglib/include/taglib/id3v2frame.h create mode 100644 taglib/include/taglib/id3v2framefactory.h create mode 100644 taglib/include/taglib/id3v2header.h create mode 100644 taglib/include/taglib/id3v2synchdata.h create mode 100644 taglib/include/taglib/id3v2tag.h create mode 100644 taglib/include/taglib/infotag.h create mode 100644 taglib/include/taglib/itfile.h create mode 100644 taglib/include/taglib/itproperties.h create mode 100644 taglib/include/taglib/modfile.h create mode 100644 taglib/include/taglib/modfilebase.h create mode 100644 taglib/include/taglib/modproperties.h create mode 100644 taglib/include/taglib/modtag.h create mode 100644 taglib/include/taglib/mp4atom.h create mode 100644 taglib/include/taglib/mp4coverart.h create mode 100644 taglib/include/taglib/mp4file.h create mode 100644 taglib/include/taglib/mp4item.h create mode 100644 taglib/include/taglib/mp4properties.h create mode 100644 taglib/include/taglib/mp4tag.h create mode 100644 taglib/include/taglib/mpcfile.h create mode 100644 taglib/include/taglib/mpcproperties.h create mode 100644 taglib/include/taglib/mpegfile.h create mode 100644 taglib/include/taglib/mpegheader.h create mode 100644 taglib/include/taglib/mpegproperties.h create mode 100644 taglib/include/taglib/oggfile.h create mode 100644 taglib/include/taglib/oggflacfile.h create mode 100644 taglib/include/taglib/oggpage.h create mode 100644 taglib/include/taglib/oggpageheader.h create mode 100644 taglib/include/taglib/opusfile.h create mode 100644 taglib/include/taglib/opusproperties.h create mode 100644 taglib/include/taglib/ownershipframe.h create mode 100644 taglib/include/taglib/podcastframe.h create mode 100644 taglib/include/taglib/popularimeterframe.h create mode 100644 taglib/include/taglib/privateframe.h create mode 100644 taglib/include/taglib/relativevolumeframe.h create mode 100644 taglib/include/taglib/rifffile.h create mode 100644 taglib/include/taglib/s3mfile.h create mode 100644 taglib/include/taglib/s3mproperties.h create mode 100644 taglib/include/taglib/speexfile.h create mode 100644 taglib/include/taglib/speexproperties.h create mode 100644 taglib/include/taglib/synchronizedlyricsframe.h create mode 100644 taglib/include/taglib/tableofcontentsframe.h create mode 100644 taglib/include/taglib/tag.h create mode 100644 taglib/include/taglib/tag_c.h create mode 100644 taglib/include/taglib/taglib.h create mode 100644 taglib/include/taglib/taglib_config.h create mode 100644 taglib/include/taglib/taglib_export.h create mode 100644 taglib/include/taglib/tbytevector.h create mode 100644 taglib/include/taglib/tbytevectorlist.h create mode 100644 taglib/include/taglib/tbytevectorstream.h create mode 100644 taglib/include/taglib/tdebuglistener.h create mode 100644 taglib/include/taglib/textidentificationframe.h create mode 100644 taglib/include/taglib/tfile.h create mode 100644 taglib/include/taglib/tfilestream.h create mode 100644 taglib/include/taglib/tiostream.h create mode 100644 taglib/include/taglib/tlist.h create mode 100644 taglib/include/taglib/tlist.tcc create mode 100644 taglib/include/taglib/tmap.h create mode 100644 taglib/include/taglib/tmap.tcc create mode 100644 taglib/include/taglib/tpropertymap.h create mode 100644 taglib/include/taglib/trefcounter.h create mode 100644 taglib/include/taglib/trueaudiofile.h create mode 100644 taglib/include/taglib/trueaudioproperties.h create mode 100644 taglib/include/taglib/tstring.h create mode 100644 taglib/include/taglib/tstringlist.h create mode 100644 taglib/include/taglib/uniquefileidentifierframe.h create mode 100644 taglib/include/taglib/unknownframe.h create mode 100644 taglib/include/taglib/unsynchronizedlyricsframe.h create mode 100644 taglib/include/taglib/urllinkframe.h create mode 100644 taglib/include/taglib/vorbisfile.h create mode 100644 taglib/include/taglib/vorbisproperties.h create mode 100644 taglib/include/taglib/wavfile.h create mode 100644 taglib/include/taglib/wavpackfile.h create mode 100644 taglib/include/taglib/wavpackproperties.h create mode 100644 taglib/include/taglib/wavproperties.h create mode 100644 taglib/include/taglib/xingheader.h create mode 100644 taglib/include/taglib/xiphcomment.h create mode 100644 taglib/include/taglib/xmfile.h create mode 100644 taglib/include/taglib/xmproperties.h create mode 100644 taglib/lib/libtag.a create mode 100644 taglib/lib/libtag_c.a create mode 100644 taglib/lib/pkgconfig/taglib.pc create mode 100644 taglib/lib/pkgconfig/taglib_c.pc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eaeaa30 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +ncmdump*.exe +ncmdump \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..7ae3bba --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${default}" + ], + "windowsSdkVersion": "10.0.19041.0", + "compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-msvc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7b18066 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +win32: + g++ main.cpp cJSON.cpp aes.cpp ncmcrypt.cpp -o ncmdump -ltag -Ltaglib/lib -Itaglib/include -static -O + strip ncmdump.exe + +linux: + g++ main.cpp cJSON.cpp aes.cpp ncmcrypt.cpp -o ncmdump -ltag + strip ncmdump + +macos: + g++ main.cpp cJSON.cpp aes.cpp ncmcrypt.cpp -o ncmdump -ltag + strip ncmdump diff --git a/aes.cpp b/aes.cpp new file mode 100644 index 0000000..ff5c684 --- /dev/null +++ b/aes.cpp @@ -0,0 +1,305 @@ +#include "aes.h" + +unsigned char AES::sBox[] = +{ // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2 + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3 + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4 + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5 + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6 + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7 + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8 + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9 + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //a + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //b + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //c + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //d + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //e + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 //f +}; +unsigned char AES::invSBox[] = +{ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, //0 + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, //1 + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, //2 + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, //3 + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, //4 + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, //5 + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, //6 + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, //7 + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, //8 + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, //9 + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, //a + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, //b + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, //c + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, //d + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, //e + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d //f +}; + +unsigned char AES::rcon[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +AES::AES() +{ + //If no key is input,use the default key + unsigned char key[16] = { + 0x0f, 0x15, 0x71, 0xc9, + 0x47, 0xd9, 0xe8, 0x59, + 0x0c, 0xb7, 0xad, 0xd6, + 0xaf, 0x7f, 0x67, 0x98 + }; + setKey(key); + keyExpansion(); +} + +AES::AES(const unsigned char *key){ + setKey(key); + keyExpansion(); +} + +void AES::setKey(const unsigned char key[]){ + mNb = 4; + mNk = 4; + mNr = 10; + memcpy(mKey, key, mNk * 4); +} + +void AES::keyExpansion() { + //the first mNk words will be filled in mW derictly + for (int i = 0; i < mNk; i++){ + for (int j = 0; j < 4; j++){ + //arranged vertically + mW[i][j] = mKey[j+i*4]; + } + } + + //generate the secret key words + for (int i = mNk; i < mNb*(mNr + 1); i++){ + //last secret key word + unsigned char pre_w[4]; + + for (int k = 0; k < 4; k++){ + pre_w[k] = mW[i-1][k]; + } + + if(i%mNk == 0){ + rotWord(pre_w); + subWord(pre_w); + pre_w[0] = pre_w[0] ^= rcon[i / mNk - 1]; + } + else if ((mNk>6)&&(i%mNk==4)){ + subWord(pre_w); + } + + for (int k = 0; k < 4; k++){ + mW[i][k] = pre_w[k] ^ mW[i-mNk][k]; + } + } + +} + +void AES::subBytes(unsigned char state[][4]) +{ + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + state[i][j] = sBox[state[i][j]]; + } + } +} + +void AES::shiftRows(unsigned char state[][4]) +{ + unsigned char t[4]; + for (int i = 1; i < 4; i++){ + for (int j = 0; j < 4; j++){ + t[j] = state[i][(i + j) % 4]; + } + for (int j = 0; j < 4; j++){ + state[i][j] = t[j]; + } + } +} + +void AES::mixColumns(unsigned char state[][4]) +{ + unsigned char t[4]; + for (int j = 0; j < 4; j++){ + for (int i = 0; i < 4; i++){ + t[i] = state[i][j]; + } + for (int i = 0; i < 4; i++){ + state[i][j] = GF28Multi(t[i], 0x02) + ^ GF28Multi(t[(i + 1) % 4], 0x03) + ^ GF28Multi(t[(i + 2) % 4], 0x01) + ^ GF28Multi(t[(i + 3) % 4], 0x01); + } + } +} + +void AES::addRoundKey(unsigned char state[][4], unsigned char w[][4]) +{ + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + state[i][j] ^= w[i][j]; + } + } +} + +void AES::invSubBytes(unsigned char state[][4]) +{ + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + state[i][j] = invSBox[state[i][j]]; + } + } +} + +void AES::invShiftRows(unsigned char state[][4]) +{ + unsigned char t[4]; + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + t[j] = state[i][(j-i + 4) % 4]; + } + for (int j = 0; j < 4; j++){ + state[i][j] = t[j]; + } + } +} + +void AES::invMixColumns(unsigned char state[][4]) +{ + unsigned char t[4]; + //calculate columns by columns + for (int j = 0; j < 4; j++){ + for (int i = 0; i < 4; i++){ + t[i] = state[i][j]; + } + for (int i = 0; i < 4; i++){ + state[i][j] = GF28Multi(t[i], 0x0e) + ^ GF28Multi(t[(i+1)%4],0x0b) + ^ GF28Multi(t[(i+2)%4],0x0d) + ^ GF28Multi(t[(i+3)%4],0x09); + } + } +} + + + +void AES::rotWord(unsigned char w[]) +{ + unsigned char t; + t = w[0]; + w[0] = w[1]; + w[1] = w[2]; + w[2] = w[3]; + w[3] = t; +} + +void AES::subWord(unsigned char w[]) +{ + for (int i = 0; i < 4; i++){ + w[i] = sBox[w[i]]; + } +} + +//calculate the least significant unsigned char only for we only need +//the least significant byte +unsigned char AES::GF28Multi(unsigned char s,unsigned char a){ + unsigned char t[4]; + unsigned char result = 0; + t[0] = s; + + //calculate s*{02},s*{03},s*{04} + for (int i = 1; i < 4; i++){ + t[i] = t[i - 1] << 1; + if (t[i - 1] & 0x80){ + t[i] ^= 0x1b; + } + } + //multiply a and s bit by bit and sum together + for (int i = 0; i < 4; i++){ + if ((a >> i) & 0x01){ + result ^= t[i]; + } + } + + return result; +} + +void AES::encrypt(const unsigned char data[16], unsigned char out[16]) +{ + unsigned char state[4][4]; + unsigned char key[4][4]; + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + state[i][j] = data[i+j*4]; + } + } + + getKeyAt(key, 0); + + addRoundKey(state, key); + + for (int i = 1; i <= mNr; i++){ + subBytes(state); + shiftRows(state); + if (i != mNr){ + mixColumns(state); + } + getKeyAt(key, i); + addRoundKey(state, key); + } + + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + out[i+j*4] = state[i][j]; + } + } +} + +void AES::decrypt(const unsigned char data[16], unsigned char out[16]) +{ + unsigned char state[4][4]; + unsigned char key[4][4]; + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + state[i][j] = data[i+j*4]; + } + } + + getKeyAt(key, mNr); + addRoundKey(state,key); + + for (int i = (mNr - 1); i >= 0; i--){ + invShiftRows(state); + invSubBytes(state); + getKeyAt(key, i); + addRoundKey(state,key); + if (i){ + invMixColumns(state); + } + } + + for (int i = 0; i < 4; i++){ + for (int j = 0; j < 4; j++){ + out[i + j * 4] = state[i][j]; + } + } +} + +//get the secret key for round "index",which will +//be arranged vetically +void AES::getKeyAt(unsigned char key[][4], int index){ + for (int i = index*4; i < index*4+4; i++){ + for (int j = 0; j < 4; j++){ + key[j][i-index*4] = mW[i][j]; + } + } +} + +AES::~AES() +{ +} diff --git a/aes.h b/aes.h new file mode 100644 index 0000000..5606ebf --- /dev/null +++ b/aes.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include + +class AES { + +public: + AES(); + AES(const unsigned char *key); + virtual ~AES(); + void encrypt(const unsigned char data[16], unsigned char out[16]); + void decrypt(const unsigned char data[16], unsigned char out[16]); + +private: + // + int mNb; + + //word length of the secret key used in one turn + int mNk; + + //number of turns + int mNr; + + //the secret key,which can be 16bytes,24bytes or 32bytes + unsigned char mKey[32]; + + //the extended key,which can be 176bytes,208bytes,240bytes + unsigned char mW[60][4]; + + static unsigned char sBox[]; + static unsigned char invSBox[]; + //constant + static unsigned char rcon[]; + void setKey(const unsigned char *key); + + void subBytes(unsigned char state[][4]); + void shiftRows(unsigned char state[][4]); + void mixColumns(unsigned char state[][4]); + void addRoundKey(unsigned char state[][4], unsigned char w[][4]); + + void invSubBytes(unsigned char state[][4]); + void invShiftRows(unsigned char state[][4]); + void invMixColumns(unsigned char state[][4]); + + void keyExpansion(); + + // + unsigned char GF28Multi(unsigned char s, unsigned char a); + + void rotWord(unsigned char w[]); + void subWord(unsigned char w[]); + + //get the secret key + void getKeyAt(unsigned char key[][4],int i); + +}; diff --git a/base64.h b/base64.h new file mode 100644 index 0000000..c3e3931 --- /dev/null +++ b/base64.h @@ -0,0 +1,96 @@ +#ifndef _MACARON_BASE64_H_ +#define _MACARON_BASE64_H_ + +#include + +static const char sEncodingTable[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/' +}; + +static const unsigned char kDecodingTable[] = { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + +class Base64 { + public: + + static std::string Encode(const std::string data) { + size_t in_len = data.size(); + size_t out_len = 4 * ((in_len + 2) / 3); + std::string ret(out_len, '\0'); + size_t i; + char *p = const_cast(ret.c_str()); + + for (i = 0; i < in_len - 2; i += 3) { + *p++ = sEncodingTable[(data[i] >> 2) & 0x3F]; + *p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)]; + *p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int) (data[i + 2] & 0xC0) >> 6)]; + *p++ = sEncodingTable[data[i + 2] & 0x3F]; + } + if (i < in_len) { + *p++ = sEncodingTable[(data[i] >> 2) & 0x3F]; + if (i == (in_len - 1)) { + *p++ = sEncodingTable[((data[i] & 0x3) << 4)]; + *p++ = '='; + } + else { + *p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int) (data[i + 1] & 0xF0) >> 4)]; + *p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)]; + } + *p++ = '='; + } + + return ret; + } + + static std::string Decode(const std::string& input, std::string& out) { + size_t in_len = input.size(); + if (in_len % 4 != 0) return "Input data size is not a multiple of 4"; + + size_t out_len = in_len / 4 * 3; + if (input[in_len - 1] == '=') out_len--; + if (input[in_len - 2] == '=') out_len--; + + out.resize(out_len); + + for (size_t i = 0, j = 0; i < in_len;) { + uint32_t a = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast(input[i++])]; + uint32_t b = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast(input[i++])]; + uint32_t c = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast(input[i++])]; + uint32_t d = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast(input[i++])]; + + uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6); + + if (j < out_len) out[j++] = (triple >> 2 * 8) & 0xFF; + if (j < out_len) out[j++] = (triple >> 1 * 8) & 0xFF; + if (j < out_len) out[j++] = (triple >> 0 * 8) & 0xFF; + } + + return ""; + } + +}; + +#endif /* _MACARON_BASE64_H_ */ \ No newline at end of file diff --git a/cJSON.cpp b/cJSON.cpp new file mode 100644 index 0000000..cbdec41 --- /dev/null +++ b/cJSON.cpp @@ -0,0 +1,2932 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#define true ((cJSON_bool)1) +#define false ((cJSON_bool)0) + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) { + if (!cJSON_IsString(item)) { + return NULL; + } + + return item->valuestring; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 7) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(*allocate)(size_t size); + void (*deallocate)(void *pointer); + void *(*reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dillimport '...' is not static */ +static void *internal_malloc(size_t size) +{ + return malloc(size); +} +static void internal_free(void *pointer) +{ + free(pointer); +} +static void *internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + if (newbuffer) + { + memcpy(newbuffer, p->buffer, p->offset + 1); + } + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26]; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if ((d * 0) != 0) + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occured */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = strlen((const char*)value) + sizeof(""); + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +#define cjson_min(a, b) ((a < b) ? a : b) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((len < 0) || (buf == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buf; + p.length = (size_t)len; + p.offset = 0; + p.noalloc = true; + p.format = fmt; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* faile to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL)) + { + return false; + } + + child = array->child; + + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + } + else + { + /* append to the end */ + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return; + } + + add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return; + } + + add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item->prev != NULL) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + add_item_to_array(array, newitem); + return; + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (parent->child == item) + { + parent->child = replacement; + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return; + } + + cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); + + return true; +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = b ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + unsigned char *into = (unsigned char*)json; + + if (json == NULL) + { + return; + } + + while (*json) + { + if (*json == ' ') + { + json++; + } + else if (*json == '\t') + { + /* Whitespace characters. */ + json++; + } + else if (*json == '\r') + { + json++; + } + else if (*json=='\n') + { + json++; + } + else if ((*json == '/') && (json[1] == '/')) + { + /* double-slash comments, to end of line. */ + while (*json && (*json != '\n')) + { + json++; + } + } + else if ((*json == '/') && (json[1] == '*')) + { + /* multiline comments. */ + while (*json && !((*json == '*') && (json[1] == '/'))) + { + json++; + } + json += 2; + } + else if (*json == '\"') + { + /* string literals, which are \" sensitive. */ + *into++ = (unsigned char)*json++; + while (*json && (*json != '\"')) + { + if (*json == '\\') + { + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + else + { + /* All other characters. */ + *into++ = (unsigned char)*json++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (a->valuedouble == b->valuedouble) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/cJSON.h b/cJSON.h new file mode 100644 index 0000000..6e0bde9 --- /dev/null +++ b/cJSON.h @@ -0,0 +1,277 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 7 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type __stdcall +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall +#endif +#else /* !WIN32 */ +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check if the item is a string and return its valuestring */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/arrray that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + + +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6baa9f2 --- /dev/null +++ b/main.cpp @@ -0,0 +1,28 @@ +#include "ncmcrypt.h" + +#include + +int main(int argc, char *argv[]) { + + if (argc <= 1) { + std::cout << "Please input file path!" << std::endl; + return 1; + } + + try { + int i; + for (i = 1; i < argc; i++) { + NeteaseCrypt crypt(argv[i]); + crypt.Dump(); + crypt.FixMetadata(); + + std::cout << crypt.dumpFilepath() << std::endl; + } + } catch (std::invalid_argument e) { + std::cout << "Exception: " << e.what() << std::endl; + } catch (...) { + std::cout << "Unexcept exception!" << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/ncmcrypt.cpp b/ncmcrypt.cpp new file mode 100644 index 0000000..1585bbf --- /dev/null +++ b/ncmcrypt.cpp @@ -0,0 +1,379 @@ +#include "ncmcrypt.h" +#include "aes.h" +#include "base64.h" +#include "cJSON.h" + +#define TAGLIB_STATIC +#include +#include +#include +#include +#include + +#include +#include + +const unsigned char NeteaseCrypt::sCoreKey[17] = {0x68, 0x7A, 0x48, 0x52, 0x41, 0x6D, 0x73, 0x6F, 0x35, 0x6B, 0x49, 0x6E, 0x62, 0x61, 0x78, 0x57, 0}; +const unsigned char NeteaseCrypt::sModifyKey[17] = {0x23, 0x31, 0x34, 0x6C, 0x6A, 0x6B, 0x5F, 0x21, 0x5C, 0x5D, 0x26, 0x30, 0x55, 0x3C, 0x27, 0x28, 0}; + +const unsigned char NeteaseCrypt::mPng[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; + +static void aesEcbDecrypt(const unsigned char *key, std::string& src, std::string& dst) { + int n, i; + + unsigned char out[16]; + + n = src.length() >> 4; + + dst.clear(); + + AES aes(key); + + for (i = 0; i < n-1; i++) { + aes.decrypt((unsigned char*)src.c_str() + (i << 4), out); + dst += std::string((char*)out, 16); + } + + aes.decrypt((unsigned char*)src.c_str() + (i << 4), out); + char pad = out[15]; + if (pad > 16) { + pad = 0; + } + dst += std::string((char*)out, 16-pad); +} + +static void replace(std::string& str, const std::string& from, const std::string& to) { + if(from.empty()) + return; + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' + } +} + +static std::string fileNameWithoutExt(const std::string& str) +{ + size_t lastPath = str.find_last_of("/\\"); + std::string path = str.substr(lastPath+1); + size_t lastExt = path.find_last_of("."); + return path.substr(0, lastExt); +} + +NeteaseMusicMetadata::~NeteaseMusicMetadata() { + cJSON_Delete(mRaw); +} + +NeteaseMusicMetadata::NeteaseMusicMetadata(cJSON* raw) { + if (!raw) { + return; + } + + cJSON *swap; + int artistLen, i; + + mRaw = raw; + + swap = cJSON_GetObjectItem(raw, "musicName"); + if (swap) { + mName = std::string(cJSON_GetStringValue(swap)); + } + + swap = cJSON_GetObjectItem(raw, "album"); + if (swap) { + mAlbum = std::string(cJSON_GetStringValue(swap)); + } + + swap = cJSON_GetObjectItem(raw, "artist"); + if (swap) { + artistLen = cJSON_GetArraySize(swap); + + i = 0; + for (i = 0; i < artistLen-1; i++) { + mArtist += std::string(cJSON_GetStringValue(cJSON_GetArrayItem(cJSON_GetArrayItem(swap, i), 0))); + mArtist += "/"; + } + mArtist += std::string(cJSON_GetStringValue(cJSON_GetArrayItem(cJSON_GetArrayItem(swap, i), 0))); + } + + swap = cJSON_GetObjectItem(raw, "bitrate"); + if (swap) { + mBitrate = swap->valueint; + } + + swap = cJSON_GetObjectItem(raw, "duration"); + if (swap) { + mDuration = swap->valueint; + } + + swap = cJSON_GetObjectItem(raw, "format"); + if (swap) { + mFormat = std::string(cJSON_GetStringValue(swap)); + } +} + +bool NeteaseCrypt::openFile(std::string const& path) { + try { + mFile.open(path, std::ios::in | std::ios::binary); + } catch (...) { + return false; + } + return true; +} + +bool NeteaseCrypt::isNcmFile() { + unsigned int header; + + mFile.read(reinterpret_cast(&header), sizeof(header)); + if (header != (unsigned int)0x4e455443) { + return false; + } + + mFile.read(reinterpret_cast(&header), sizeof(header)); + if (header != (unsigned int)0x4d414446) { + return false; + } + + return true; +} + +int NeteaseCrypt::read(char *s, std::streamsize n) { + mFile.read(s, n); + + int gcount = mFile.gcount(); + + if (gcount <= 0) { + throw std::invalid_argument("can't read file"); + } + + return gcount; +} + +void NeteaseCrypt::buildKeyBox(unsigned char *key, int keyLen) { + int i; + for (i = 0; i < 256; ++i) { + mKeyBox[i] = (unsigned char)i; + } + + unsigned char swap = 0; + unsigned char c = 0; + unsigned char last_byte = 0; + unsigned char key_offset = 0; + + for (i = 0; i < 256; ++i) + { + swap = mKeyBox[i]; + c = ((swap + last_byte + key[key_offset++]) & 0xff); + if (key_offset >= keyLen) key_offset = 0; + mKeyBox[i] = mKeyBox[c]; mKeyBox[c] = swap; + last_byte = c; + } +} + +std::string NeteaseCrypt::mimeType(std::string& data) { + if (memcmp(data.c_str(), mPng, 8) == 0) { + return std::string("image/png"); + } + + return std::string("image/jpeg"); +} + +void NeteaseCrypt::FixMetadata() { + if (mDumpFilepath.length() <= 0) { + throw std::invalid_argument("must dump before"); + } + + TagLib::File *audioFile; + TagLib::Tag *tag; + TagLib::ByteVector vector(mImageData.c_str(), mImageData.length()); + + if (mFormat == NeteaseCrypt::MP3) { + audioFile = new TagLib::MPEG::File(mDumpFilepath.c_str()); + tag = dynamic_cast(audioFile)->ID3v2Tag(true); + + if (mImageData.length() > 0) { + TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame; + + frame->setMimeType(mimeType(mImageData)); + frame->setPicture(vector); + + dynamic_cast(tag)->addFrame(frame); + } + } else if (mFormat == NeteaseCrypt::FLAC) { + audioFile = new TagLib::FLAC::File(mDumpFilepath.c_str()); + tag = audioFile->tag(); + + if (mImageData.length() > 0) { + TagLib::FLAC::Picture *cover = new TagLib::FLAC::Picture; + cover->setMimeType(mimeType(mImageData)); + cover->setType(TagLib::FLAC::Picture::FrontCover); + cover->setData(vector); + + dynamic_cast(audioFile)->addPicture(cover); + } + } + + if (mMetaData != NULL) { + tag->setTitle(TagLib::String(mMetaData->name(), TagLib::String::UTF8)); + tag->setArtist(TagLib::String(mMetaData->artist(), TagLib::String::UTF8)); + tag->setAlbum(TagLib::String(mMetaData->album(), TagLib::String::UTF8)); + } + + tag->setComment(TagLib::String("Create by netease copyright protected dump tool. author 5L", TagLib::String::UTF8)); + + audioFile->save(); +} + +void NeteaseCrypt::Dump() { + int n, i; + + // mDumpFilepath.clear(); + // mDumpFilepath.resize(1024); + + // if (mMetaData) { + // mDumpFilepath = mMetaData->name(); + + // replace(mDumpFilepath, "\\", "\"); + // replace(mDumpFilepath, "/", "/"); + // replace(mDumpFilepath, "?", "?"); + // replace(mDumpFilepath, ":", ":"); + // replace(mDumpFilepath, "*", "*"); + // replace(mDumpFilepath, "\"", """); + // replace(mDumpFilepath, "<", "<"); + // replace(mDumpFilepath, ">", ">"); + // replace(mDumpFilepath, "|", "|"); + // } else { + mDumpFilepath = fileNameWithoutExt(mFilepath); + // } + + n = 0x8000; + i = 0; + + unsigned char buffer[n]; + + std::ofstream output; + + while (!mFile.eof()) { + n = read((char*)buffer, n); + + for (i = 0; i < n; i++) { + int j = (i + 1) & 0xff; + buffer[i] ^= mKeyBox[(mKeyBox[j] + mKeyBox[(mKeyBox[j] + j) & 0xff]) & 0xff]; + } + + if (!output.is_open()) { + // identify format + // ID3 format mp3 + if (buffer[0] == 0x49 && buffer[1] == 0x44 && buffer[2] == 0x33) { + mDumpFilepath += ".mp3"; + mFormat = NeteaseCrypt::MP3; + } else { + mDumpFilepath += ".flac"; + mFormat = NeteaseCrypt::FLAC; + } + + output.open(mDumpFilepath, output.out | output.binary); + } + + output.write((char*)buffer, n); + } + + output.flush(); + output.close(); +} + +NeteaseCrypt::~NeteaseCrypt() { + if (mMetaData != NULL) { + delete mMetaData; + } + + mFile.close(); +} + +NeteaseCrypt::NeteaseCrypt(std::string const& path) { + if (!openFile(path)) { + throw std::invalid_argument("can't open file"); + } + + if (!isNcmFile()) { + throw std::invalid_argument("not netease protected file"); + } + + if (!mFile.seekg(2, mFile.cur)) { + throw std::invalid_argument("can't seek file"); + } + + mFilepath = path; + + int i; + + unsigned int n; + read(reinterpret_cast(&n), sizeof(n)); + + if (n <= 0) { + throw std::invalid_argument("broken ncm file"); + } + + char keydata[n]; + read(keydata, n); + + for (i = 0; i < n; i++) { + keydata[i] ^= 0x64; + } + + std::string rawKeyData(keydata, n); + std::string mKeyData; + + aesEcbDecrypt(sCoreKey, rawKeyData, mKeyData); + + buildKeyBox((unsigned char*)mKeyData.c_str()+17, mKeyData.length()-17); + + read(reinterpret_cast(&n), sizeof(n)); + + if (n <= 0) { + printf("[Warn] `%s` missing metadata infomation can't fix some infomation!\n", path.c_str()); + + mMetaData = NULL; + } else { + char modifyData[n]; + read(modifyData, n); + + for (i = 0; i < n; i++) { + modifyData[i] ^= 0x63; + } + + std::string swapModifyData; + std::string modifyOutData; + std::string modifyDecryptData; + + swapModifyData = std::string(modifyData + 22, n - 22); + + // escape `163 key(Don't modify):` + Base64::Decode(swapModifyData, modifyOutData); + + aesEcbDecrypt(sModifyKey, modifyOutData, modifyDecryptData); + + // escape `music:` + modifyDecryptData = std::string(modifyDecryptData.begin()+6, modifyDecryptData.end()); + + // std::cout << modifyDecryptData << std::endl; + + mMetaData = new NeteaseMusicMetadata(cJSON_Parse(modifyDecryptData.c_str())); + } + + // skip crc32 & unuse charset + if (!mFile.seekg(9, mFile.cur)) { + throw std::invalid_argument("can't seek file"); + } + + read(reinterpret_cast(&n), sizeof(n)); + + if (n > 0) { + char *imageData = (char*)malloc(n); + read(imageData, n); + + mImageData = std::string(imageData, n); + } else { + printf("[Warn] `%s` missing album can't fix album image!\n", path.c_str()); + } +} diff --git a/ncmcrypt.h b/ncmcrypt.h new file mode 100644 index 0000000..8765450 --- /dev/null +++ b/ncmcrypt.h @@ -0,0 +1,69 @@ +#pragma once + +#include "aes.h" +#include "cJSON.h" + +#include +#include + +class NeteaseMusicMetadata { + +private: + std::string mAlbum; + std::string mArtist; + std::string mFormat; + std::string mName; + int mDuration; + int mBitrate; + +private: + cJSON* mRaw; + +public: + NeteaseMusicMetadata(cJSON*); + ~NeteaseMusicMetadata(); + const std::string& name() const { return mName; } + const std::string& album() const { return mAlbum; } + const std::string& artist() const { return mArtist; } + const std::string& format() const { return mFormat; } + const int duration() const { return mDuration; } + const int bitrate() const { return mBitrate; } + +}; + +class NeteaseCrypt { + +private: + static const unsigned char sCoreKey[17]; + static const unsigned char sModifyKey[17]; + static const unsigned char mPng[8]; + enum NcmFormat { MP3, FLAC }; + +private: + std::string mFilepath; + std::string mDumpFilepath; + NcmFormat mFormat; + std::string mImageData; + std::ifstream mFile; + unsigned char mKeyBox[256]; + NeteaseMusicMetadata* mMetaData; + +private: + bool isNcmFile(); + bool openFile(std::string const&); + int read(char *s, std::streamsize n); + void buildKeyBox(unsigned char *key, int keyLen); + std::string mimeType(std::string& data); + +public: + const std::string& filepath() const { return mFilepath; } + const std::string& dumpFilepath() const { return mDumpFilepath; } + +public: + NeteaseCrypt(std::string const&); + ~NeteaseCrypt(); + +public: + void Dump(); + void FixMetadata(); +}; \ No newline at end of file diff --git a/taglib/bin/taglib-config.cmd b/taglib/bin/taglib-config.cmd new file mode 100644 index 0000000..817cf0d --- /dev/null +++ b/taglib/bin/taglib-config.cmd @@ -0,0 +1,36 @@ +@echo off +goto beginning + * + * It is what it is, you can do with it as you please. + * + * Just don't blame me if it teaches your computer to smoke! + * + * -Enjoy + * fh :)_~ + * +:beginning +if /i "%1#" == "--libs#" goto doit +if /i "%1#" == "--cflags#" goto doit +if /i "%1#" == "--version#" goto doit +if /i "%1#" == "--prefix#" goto doit + +echo "usage: %0 [OPTIONS]" +echo [--libs] +echo [--cflags] +echo [--version] +echo [--prefix] +goto theend + + * + * NOTE: Windows does not assume libraries are prefixed with 'lib'. + * NOTE: If '-llibtag' is the last element, it is easily appended in the users installation/makefile process + * to allow for static, shared or debug builds. + * It would be preferable if the top level CMakeLists.txt provided the library name during config. ?? +:doit +if /i "%1#" == "--libs#" echo -LC:/taglib/lib -llibtag +if /i "%1#" == "--cflags#" echo -IC:/taglib/include -IC:/taglib/include/taglib +if /i "%1#" == "--version#" echo 1.12 +if /i "%1#" == "--prefix#" echo C:/taglib + +:theend + diff --git a/taglib/include/taglib/aifffile.h b/taglib/include/taglib/aifffile.h new file mode 100644 index 0000000..ceac576 --- /dev/null +++ b/taglib/include/taglib/aifffile.h @@ -0,0 +1,157 @@ +/*************************************************************************** + copyright : (C) 2008 by Scott Wheeler + email : wheeler@kde.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_AIFFFILE_H +#define TAGLIB_AIFFFILE_H + +#include "rifffile.h" +#include "id3v2tag.h" +#include "aiffproperties.h" + +namespace TagLib { + + namespace RIFF { + + //! An implementation of AIFF metadata + + /*! + * This is implementation of AIFF metadata. + * + * This supports an ID3v2 tag as well as reading stream from the ID3 RIFF + * chunk as well as properties from the file. + */ + + namespace AIFF { + + //! An implementation of TagLib::File with AIFF specific methods + + /*! + * This implements and provides an interface for AIFF files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to AIFF files. + */ + + class TAGLIB_EXPORT File : public TagLib::RIFF::File + { + public: + /*! + * Constructs an AIFF file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an AIFF file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. + * + * \note This always returns a valid pointer regardless of whether or not + * the file on disk has an ID3v2 tag. Use hasID3v2Tag() to check if the file + * on disk actually has an ID3v2 tag. + * + * \see hasID3v2Tag() + */ + virtual ID3v2::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * This method forwards to ID3v2::Tag::properties(). + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * This method forwards to ID3v2::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the AIFF::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Saves the file. + */ + virtual bool save(); + + /*! + * Save using a specific ID3v2 version (e.g. v3) + */ + bool save(ID3v2::Version version); + + /*! + * Returns whether or not the file on disk actually has an ID3v2 tag. + * + * \see ID3v2Tag() + */ + bool hasID3v2Tag() const; + + /*! + * Check if the given \a stream can be opened as an AIFF file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + friend class Properties; + + class FilePrivate; + FilePrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/aiffproperties.h b/taglib/include/taglib/aiffproperties.h new file mode 100644 index 0000000..dbb4c21 --- /dev/null +++ b/taglib/include/taglib/aiffproperties.h @@ -0,0 +1,166 @@ +/*************************************************************************** + copyright : (C) 2008 by Scott Wheeler + email : wheeler@kde.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_AIFFPROPERTIES_H +#define TAGLIB_AIFFPROPERTIES_H + +#include "audioproperties.h" + +namespace TagLib { + + namespace RIFF { + + namespace AIFF { + + class File; + + //! An implementation of audio property reading for AIFF + + /*! + * This reads the data from an AIFF stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of AIFF::Properties with the data read from the + * ByteVector \a data. + * + * \deprecated + */ + TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style); + + /*! + * Create an instance of AIFF::Properties with the data read from the + * AIFF::File \a file. + */ + Properties(File *file, ReadStyle style); + + /*! + * Destroys this AIFF::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns the number of bits per audio sample. + * + * \note This method is just an alias of bitsPerSample(). + * + * \deprecated + */ + TAGLIB_DEPRECATED int sampleWidth() const; + + /*! + * Returns the number of sample frames + */ + unsigned int sampleFrames() const; + + /*! + * Returns true if the file is in AIFF-C format, false if AIFF format. + */ + bool isAiffC() const; + + /*! + * Returns the compression type of the AIFF-C file. For example, "NONE" for + * not compressed, "ACE2" for ACE 2-to-1. + * + * If the file is in AIFF format, always returns an empty vector. + * + * \see isAiffC() + */ + ByteVector compressionType() const; + + /*! + * Returns the concrete compression name of the AIFF-C file. + * + * If the file is in AIFF format, always returns an empty string. + * + * \see isAiffC() + */ + String compressionName() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/apefile.h b/taglib/include/taglib/apefile.h new file mode 100644 index 0000000..267778b --- /dev/null +++ b/taglib/include/taglib/apefile.h @@ -0,0 +1,235 @@ +/*************************************************************************** + copyright : (C) 2010 by Alex Novichkov + email : novichko@atnet.ru + + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + (original WavPack implementation) + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.org + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * 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_APEFILE_H +#define TAGLIB_APEFILE_H + +#include "tfile.h" +#include "taglib_export.h" +#include "apeproperties.h" + +namespace TagLib { + + class Tag; + + namespace ID3v1 { class Tag; } + namespace APE { class Tag; } + + //! An implementation of APE metadata + + /*! + * This is implementation of APE metadata. + * + * This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream + * properties from the file. + */ + + namespace APE { + + //! An implementation of TagLib::File with APE specific methods + + /*! + * This implements and provides an interface for APE files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to APE files. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v1 tags. + ID3v1 = 0x0001, + //! Matches APE tags. + APE = 0x0002, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs an APE file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an APE file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag + * or a combination of the two. + */ + virtual TagLib::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only APE + * will be converted to the PropertyMap. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties. Forwards to the actual Tag's + * removeUnsupportedProperties() function. + */ + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * Creates an APEv2 tag if necessary. A potentially existing ID3v1 + * tag will be updated as well. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the APE::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Saves the file. + * + * \note According to the official Monkey's Audio SDK, an APE file + * can only have either ID3V1 or APE tags, so a parameter is used here. + */ + virtual bool save(); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid ID3v1 tag. If \a create is true it will create + * an ID3v1 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file + * on disk actually has an ID3v1 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v1Tag() + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the APE tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid APE tag. If \a create is true it will create + * an APE tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an APE tag. Use hasAPETag() to check if the file + * on disk actually has an APE tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasAPETag() + */ + APE::Tag *APETag(bool create = false); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from the + * file. By default it removes all tags. + * + * \note This will also invalidate pointers to the tags + * as their memory will be freed. + * \note In order to make the removal permanent save() still needs to be called + */ + void strip(int tags = AllTags); + + /*! + * Returns whether or not the file on disk actually has an APE tag. + * + * \see APETag() + */ + bool hasAPETag() const; + + /*! + * Returns whether or not the file on disk actually has an ID3v1 tag. + * + * \see ID3v1Tag() + */ + bool hasID3v1Tag() const; + + /*! + * Returns whether or not the given \a stream can be opened as an APE + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/apefooter.h b/taglib/include/taglib/apefooter.h new file mode 100644 index 0000000..47741d0 --- /dev/null +++ b/taglib/include/taglib/apefooter.h @@ -0,0 +1,173 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.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_APEFOOTER_H +#define TAGLIB_APEFOOTER_H + +#include "tbytevector.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace APE { + + //! An implementation of APE footers + + /*! + * This class implements APE footers (and headers). It attempts to follow, both + * semantically and programmatically, the structure specified in + * the APE v2.0 standard. The API is based on the properties of APE footer and + * headers specified there. + */ + + class TAGLIB_EXPORT Footer + { + public: + /*! + * Constructs an empty APE footer. + */ + Footer(); + + /*! + * Constructs an APE footer based on \a data. parse() is called + * immediately. + */ + Footer(const ByteVector &data); + + /*! + * Destroys the footer. + */ + virtual ~Footer(); + + /*! + * Returns the version number. (Note: This is the 1000 or 2000.) + */ + unsigned int version() const; + + /*! + * Returns true if a header is present in the tag. + */ + bool headerPresent() const; + + /*! + * Returns true if a footer is present in the tag. + */ + bool footerPresent() const; + + /*! + * Returns true this is actually the header. + */ + bool isHeader() const; + + /*! + * Sets whether the header should be rendered or not + */ + void setHeaderPresent(bool b) const; + + /*! + * Returns the number of items in the tag. + */ + unsigned int itemCount() const; + + /*! + * Set the item count to \a s. + * \see itemCount() + */ + void setItemCount(unsigned int s); + + /*! + * Returns the tag size in bytes. This is the size of the frame content and footer. + * The size of the \e entire tag will be this plus the header size, if present. + * + * \see completeTagSize() + */ + unsigned int tagSize() const; + + /*! + * Returns the tag size, including if present, the header + * size. + * + * \see tagSize() + */ + unsigned int completeTagSize() const; + + /*! + * Set the tag size to \a s. + * \see tagSize() + */ + void setTagSize(unsigned int s); + + /*! + * Returns the size of the footer. Presently this is always 32 bytes. + */ + static unsigned int size(); + + /*! + * Returns the string used to identify an APE tag inside of a file. + * Presently this is always "APETAGEX". + */ + static ByteVector fileIdentifier(); + + /*! + * Sets the data that will be used as the footer. 32 bytes, + * starting from \a data will be used. + */ + void setData(const ByteVector &data); + + /*! + * Renders the footer back to binary format. + */ + ByteVector renderFooter() const; + + /*! + * Renders the header corresponding to the footer. If headerPresent is + * set to false, it returns an empty ByteVector. + */ + ByteVector renderHeader() const; + + protected: + /*! + * Called by setData() to parse the footer data. It makes this information + * available through the public API. + */ + void parse(const ByteVector &data); + + /*! + * Called by renderFooter and renderHeader + */ + ByteVector render(bool isHeader) const; + + private: + Footer(const Footer &); + Footer &operator=(const Footer &); + + class FooterPrivate; + FooterPrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/apeitem.h b/taglib/include/taglib/apeitem.h new file mode 100644 index 0000000..cfd157c --- /dev/null +++ b/taglib/include/taglib/apeitem.h @@ -0,0 +1,224 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.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_APEITEM_H +#define TAGLIB_APEITEM_H + +#include "tbytevector.h" +#include "tstring.h" +#include "tstringlist.h" + +namespace TagLib { + + namespace APE { + + //! An implementation of APE-items + + /*! + * This class provides the features of items in the APEv2 standard. + */ + class TAGLIB_EXPORT Item + { + public: + /*! + * Enum of types an Item can have. The value of 3 is reserved. + */ + enum ItemTypes { + //! Item contains text information coded in UTF-8 + Text = 0, + //! Item contains binary information + Binary = 1, + //! Item is a locator of external stored information + Locator = 2 + }; + /*! + * Constructs an empty item. + */ + Item(); + + /*! + * Constructs a text item with \a key and \a value. + */ + // BIC: Remove this, StringList has a constructor from a single string + Item(const String &key, const String &value); + + /*! + * Constructs a text item with \a key and \a values. + */ + Item(const String &key, const StringList &values); + + /*! + * Constructs an item with \a key and \a value. + * If \a binary is true a Binary item will be created, otherwise \a value will be interpreted as text + */ + Item(const String &key, const ByteVector &value, bool binary); + + /*! + * Construct an item as a copy of \a item. + */ + Item(const Item &item); + + /*! + * Destroys the item. + */ + virtual ~Item(); + + /*! + * Copies the contents of \a item into this item. + */ + Item &operator=(const Item &item); + + /*! + * Exchanges the content of this item by the content of \a item. + */ + void swap(Item &item); + + /*! + * Returns the key. + */ + String key() const; + + /*! + * Returns the binary value. + * If the item type is not \a Binary, always returns an empty ByteVector. + */ + ByteVector binaryData() const; + + /*! + * Set the binary value to \a value + * The item's type will also be set to \a Binary + */ + void setBinaryData(const ByteVector &value); + +#ifndef DO_NOT_DOCUMENT + /* Remove in next binary incompatible release */ + ByteVector value() const; +#endif + + /*! + * Sets the key for the item to \a key. + */ + void setKey(const String &key); + + /*! + * Sets the text value of the item to \a value and clears any previous contents. + * + * \see toString() + */ + void setValue(const String &value); + + /*! + * Sets the text value of the item to the list of values in \a value and clears + * any previous contents. + * + * \see toStringList() + */ + void setValues(const StringList &values); + + /*! + * Appends \a value to create (or extend) the current list of text values. + * + * \see toString() + */ + void appendValue(const String &value); + + /*! + * Appends \a values to extend the current list of text values. + * + * \see toStringList() + */ + void appendValues(const StringList &values); + + /*! + * Returns the size of the full item. + */ + int size() const; + + /*! + * Returns the value as a single string. In case of multiple strings, + * the first is returned. If the data type is not \a Text, always returns + * an empty String. + */ + String toString() const; + +#ifndef DO_NOT_DOCUMENT + /* Remove in next binary incompatible release */ + StringList toStringList() const; +#endif + + /*! + * Returns the list of text values. If the data type is not \a Text, always + * returns an empty StringList. + */ + StringList values() const; + + /*! + * Render the item to a ByteVector. + */ + ByteVector render() const; + + /*! + * Parse the item from the ByteVector \a data. + */ + void parse(const ByteVector& data); + + /*! + * Set the item to read-only. + */ + void setReadOnly(bool readOnly); + + /*! + * Return true if the item is read-only. + */ + bool isReadOnly() const; + + /*! + * Sets the type of the item to \a type. + * + * \see ItemTypes + */ + void setType(ItemTypes type); + + /*! + * Returns the type of the item. + */ + ItemTypes type() const; + + /*! + * Returns if the item has any real content. + */ + bool isEmpty() const; + + private: + class ItemPrivate; + ItemPrivate *d; + }; + } + +} + +#endif + + diff --git a/taglib/include/taglib/apeproperties.h b/taglib/include/taglib/apeproperties.h new file mode 100644 index 0000000..ebbf949 --- /dev/null +++ b/taglib/include/taglib/apeproperties.h @@ -0,0 +1,143 @@ +/*************************************************************************** + copyright : (C) 2010 by Alex Novichkov + email : novichko@atnet.ru + + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + (original WavPack implementation) + ***************************************************************************/ + +/*************************************************************************** + * 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_APEPROPERTIES_H +#define TAGLIB_APEPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace APE { + + class File; + + //! An implementation of audio property reading for APE + + /*! + * This reads the data from an APE stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of APE::Properties with the data read from the + * APE::File \a file. + * + * \deprecated + */ + TAGLIB_DEPRECATED Properties(File *file, ReadStyle style = Average); + + /*! + * Create an instance of APE::Properties with the data read from the + * APE::File \a file. + */ + Properties(File *file, long streamLength, ReadStyle style = Average); + + /*! + * Destroys this APE::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns the total number of audio samples in file. + */ + unsigned int sampleFrames() const; + + /*! + * Returns APE version. + */ + int version() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file, long streamLength); + + void analyzeCurrent(File *file); + void analyzeOld(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/apetag.h b/taglib/include/taglib/apetag.h new file mode 100644 index 0000000..f4d4fba --- /dev/null +++ b/taglib/include/taglib/apetag.h @@ -0,0 +1,208 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.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_APETAG_H +#define TAGLIB_APETAG_H + +#include "tag.h" +#include "tbytevector.h" +#include "tmap.h" +#include "tstring.h" +#include "taglib_export.h" + +#include "apeitem.h" + +namespace TagLib { + + class File; + + //! An implementation of the APE tagging format + + namespace APE { + + class Footer; + + /*! + * A mapping between a list of item names, or keys, and the associated item. + * + * \see APE::Tag::itemListMap() + */ + typedef Map ItemListMap; + + + //! An APE tag implementation + + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + /*! + * Create an APE tag with default values. + */ + Tag(); + + /*! + * Create an APE tag and parse the data in \a file with APE footer at + * \a tagOffset. + */ + Tag(TagLib::File *file, long footerLocation); + + /*! + * Destroys this Tag instance. + */ + virtual ~Tag(); + + /*! + * Renders the in memory values to a ByteVector suitable for writing to + * the file. + */ + ByteVector render() const; + + /*! + * Returns the string "APETAGEX" suitable for usage in locating the tag in a + * file. + */ + static ByteVector fileIdentifier(); + + // Reimplementations. + + virtual String title() const; + virtual String artist() const; + virtual String album() const; + virtual String comment() const; + virtual String genre() const; + virtual unsigned int year() const; + virtual unsigned int track() const; + + virtual void setTitle(const String &s); + virtual void setArtist(const String &s); + virtual void setAlbum(const String &s); + virtual void setComment(const String &s); + virtual void setGenre(const String &s); + virtual void setYear(unsigned int i); + virtual void setTrack(unsigned int i); + + /*! + * Implements the unified tag dictionary interface -- export function. + * APE tags are perfectly compatible with the dictionary interface because they + * support both arbitrary tag names and multiple values. Currently only + * APE items of type *Text* are handled by the dictionary interface; all *Binary* + * and *Locator* items will be put into the unsupportedData list and can be + * deleted on request using removeUnsupportedProperties(). The same happens + * to Text items if their key is invalid for PropertyMap (which should actually + * never happen). + * + * The only conversion done by this export function is to rename the APE tags + * TRACK to TRACKNUMBER, YEAR to DATE, and ALBUM ARTIST to ALBUMARTIST, respectively, + * in order to be compliant with the names used in other formats. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified tag dictionary interface -- import function. The same + * comments as for the export function apply; additionally note that the APE tag + * specification requires keys to have between 2 and 16 printable ASCII characters + * with the exception of the fixed strings "ID3", "TAG", "OGGS", and "MP+". + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Check if the given String is a valid APE tag key. + */ + static bool checkKey(const String&); + + /*! + * Returns a pointer to the tag's footer. + */ + Footer *footer() const; + + /*! + * Returns a reference to the item list map. This is an ItemListMap of + * all of the items in the tag. + * + * This is the most powerful structure for accessing the items of the tag. + * + * APE tags are case-insensitive, all keys in this map have been converted + * to upper case. + * + * \warning You should not modify this data structure directly, instead + * use setItem() and removeItem(). + */ + const ItemListMap &itemListMap() const; + + /*! + * Removes the \a key item from the tag + */ + void removeItem(const String &key); + + /*! + * Adds to the text item specified by \a key the data \a value. If \a replace + * is true, then all of the other values on the same key will be removed + * first. If a binary item exists for \a key it will be removed first. + */ + void addValue(const String &key, const String &value, bool replace = true); + + /*! + * Set the binary data for the key specified by \a item to \a value + * This will convert the item to type \a Binary if it isn't already and + * all of the other values on the same key will be removed. + */ + void setData(const String &key, const ByteVector &value); + + /*! + * Sets the \a key item to the value of \a item. If an item with the \a key is already + * present, it will be replaced. + */ + void setItem(const String &key, const Item &item); + + /*! + * Returns true if the tag does not contain any data. + */ + bool isEmpty() const; + + protected: + + /*! + * Reads from the file specified in the constructor. + */ + void read(); + + /*! + * Parses the body of the tag in \a data. + */ + void parse(const ByteVector &data); + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/asfattribute.h b/taglib/include/taglib/asfattribute.h new file mode 100644 index 0000000..1738eb4 --- /dev/null +++ b/taglib/include/taglib/asfattribute.h @@ -0,0 +1,208 @@ +/************************************************************************** + copyright : (C) 2005-2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_ASFATTRIBUTE_H +#define TAGLIB_ASFATTRIBUTE_H + +#include "tstring.h" +#include "tbytevector.h" +#include "taglib_export.h" +#include "asfpicture.h" + +namespace TagLib +{ + + namespace ASF + { + + class File; + class Picture; + + class TAGLIB_EXPORT Attribute + { + public: + + /*! + * Enum of types an Attribute can have. + */ + enum AttributeTypes { + UnicodeType = 0, + BytesType = 1, + BoolType = 2, + DWordType = 3, + QWordType = 4, + WordType = 5, + GuidType = 6 + }; + + /*! + * Constructs an empty attribute. + */ + Attribute(); + + /*! + * Constructs an attribute with \a key and a UnicodeType \a value. + */ + Attribute(const String &value); + + /*! + * Constructs an attribute with \a key and a BytesType \a value. + */ + Attribute(const ByteVector &value); + + /*! + * Constructs an attribute with \a key and a Picture \a value. + * + * This attribute is compatible with the ID3 frame, APIC. The ID3 specification for the APIC frame stipulates that, + * while there may be any number of APIC frames associated with a file, + * only one may be of type 1 and only one may be of type 2. + * + * The specification also states that the description of the picture can be no longer than 64 characters, but can be empty. + * WM/Picture attributes added with TagLib::ASF are not automatically validated to conform to ID3 specifications. + * You must add code in your application to perform validations if you want to maintain complete compatibility with ID3. + */ + Attribute(const Picture &value); + + /*! + * Constructs an attribute with \a key and a DWordType \a value. + */ + Attribute(unsigned int value); + + /*! + * Constructs an attribute with \a key and a QWordType \a value. + */ + Attribute(unsigned long long value); + + /*! + * Constructs an attribute with \a key and a WordType \a value. + */ + Attribute(unsigned short value); + + /*! + * Constructs an attribute with \a key and a BoolType \a value. + */ + Attribute(bool value); + + /*! + * Construct an attribute as a copy of \a other. + */ + Attribute(const Attribute &item); + + /*! + * Copies the contents of \a other into this item. + */ + Attribute &operator=(const Attribute &other); + + /*! + * Exchanges the content of the Attribute by the content of \a other. + */ + void swap(Attribute &other); + + /*! + * Destroys the attribute. + */ + virtual ~Attribute(); + + /*! + * Returns type of the value. + */ + AttributeTypes type() const; + + /*! + * Returns the BoolType \a value. + */ + unsigned short toBool() const; + + /*! + * Returns the WordType \a value. + */ + unsigned short toUShort() const; + + /*! + * Returns the DWordType \a value. + */ + unsigned int toUInt() const; + + /*! + * Returns the QWordType \a value. + */ + unsigned long long toULongLong() const; + + /*! + * Returns the UnicodeType \a value. + */ + String toString() const; + + /*! + * Returns the BytesType \a value. + */ + ByteVector toByteVector() const; + + /*! + * Returns the Picture \a value. + */ + Picture toPicture() const; + + /*! + * Returns the language number, or 0 is no stream number was set. + */ + int language() const; + + /*! + * Sets the language number. + */ + void setLanguage(int value); + + /*! + * Returns the stream number, or 0 is no stream number was set. + */ + int stream() const; + + /*! + * Sets the stream number. + */ + void setStream(int value); + +#ifndef DO_NOT_DOCUMENT + /* THIS IS PRIVATE, DON'T TOUCH IT! */ + String parse(ASF::File &file, int kind = 0); +#endif + + //! Returns the size of the stored data + int dataSize() const; + + private: + friend class File; + + ByteVector render(const String &name, int kind = 0) const; + + class AttributePrivate; + AttributePrivate *d; + }; + } + +} + +#endif diff --git a/taglib/include/taglib/asffile.h b/taglib/include/taglib/asffile.h new file mode 100644 index 0000000..05cf4ee --- /dev/null +++ b/taglib/include/taglib/asffile.h @@ -0,0 +1,138 @@ +/************************************************************************** + copyright : (C) 2005-2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_ASFFILE_H +#define TAGLIB_ASFFILE_H + +#include "tag.h" +#include "tfile.h" +#include "taglib_export.h" +#include "asfproperties.h" +#include "asftag.h" + +namespace TagLib { + + //! An implementation of ASF (WMA) metadata + namespace ASF { + + /*! + * This implements and provides an interface for ASF files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to ASF files. + */ + class TAGLIB_EXPORT File : public TagLib::File + { + public: + + /*! + * Constructs an ASF 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, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an ASF 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, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns a pointer to the ASF tag of the file. + * + * ASF::Tag implements the tag interface, so this serves as the + * reimplementation of TagLib::File::tag(). + * + * \note The Tag is still owned by the ASF::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + */ + virtual Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties. Forwards to the actual Tag's + * removeUnsupportedProperties() function. + */ + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the ASF audio properties for this file. + */ + virtual Properties *audioProperties() const; + + /*! + * Save the file. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Returns whether or not the given \a stream can be opened as an ASF + * 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(); + + class FilePrivate; + FilePrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/asfpicture.h b/taglib/include/taglib/asfpicture.h new file mode 100644 index 0000000..17233ba --- /dev/null +++ b/taglib/include/taglib/asfpicture.h @@ -0,0 +1,222 @@ +/************************************************************************** + copyright : (C) 2010 by Anton Sergunov + email : setosha@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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 ASFPICTURE_H +#define ASFPICTURE_H + +#include "tstring.h" +#include "tbytevector.h" +#include "taglib_export.h" +#include "attachedpictureframe.h" + +namespace TagLib +{ + namespace ASF + { + + //! An ASF attached picture interface implementation + + /*! + * This is an implementation of ASF attached pictures interface. Pictures may be + * included in attributes, one per WM/Picture attribute (but there may be multiple WM/Picture + * attribute in a single tag). These pictures are usually in either JPEG or + * PNG format. + * \see Attribute::toPicture() + * \see Attribute::Attribute(const Picture& picture) + */ + class TAGLIB_EXPORT Picture { + public: + + /*! + * This describes the function or content of the picture. + */ + enum Type { + //! A type not enumerated below + Other = 0x00, + //! 32x32 PNG image that should be used as the file icon + FileIcon = 0x01, + //! File icon of a different size or format + OtherFileIcon = 0x02, + //! Front cover image of the album + FrontCover = 0x03, + //! Back cover image of the album + BackCover = 0x04, + //! Inside leaflet page of the album + LeafletPage = 0x05, + //! Image from the album itself + Media = 0x06, + //! Picture of the lead artist or soloist + LeadArtist = 0x07, + //! Picture of the artist or performer + Artist = 0x08, + //! Picture of the conductor + Conductor = 0x09, + //! Picture of the band or orchestra + Band = 0x0A, + //! Picture of the composer + Composer = 0x0B, + //! Picture of the lyricist or text writer + Lyricist = 0x0C, + //! Picture of the recording location or studio + RecordingLocation = 0x0D, + //! Picture of the artists during recording + DuringRecording = 0x0E, + //! Picture of the artists during performance + DuringPerformance = 0x0F, + //! Picture from a movie or video related to the track + MovieScreenCapture = 0x10, + //! Picture of a large, coloured fish + ColouredFish = 0x11, + //! Illustration related to the track + Illustration = 0x12, + //! Logo of the band or performer + BandLogo = 0x13, + //! Logo of the publisher (record company) + PublisherLogo = 0x14 + }; + + /*! + * Constructs an empty picture. + */ + Picture(); + + /*! + * Construct an picture as a copy of \a other. + */ + Picture(const Picture& other); + + /*! + * Destroys the picture. + */ + virtual ~Picture(); + + /*! + * Copies the contents of \a other into this picture. + */ + Picture& operator=(const Picture& other); + + /*! + * Exchanges the content of the Picture by the content of \a other. + */ + void swap(Picture &other); + + /*! + * Returns true if Picture stores valid picture + */ + bool isValid() const; + + /*! + * Returns the mime type of the image. This should in most cases be + * "image/png" or "image/jpeg". + * \see setMimeType(const String &) + * \see picture() + * \see setPicture(const ByteArray&) + */ + String mimeType() const; + + /*! + * Sets the mime type of the image. This should in most cases be + * "image/png" or "image/jpeg". + * \see setMimeType(const String &) + * \see picture() + * \see setPicture(const ByteArray&) + */ + void setMimeType(const String &value); + + /*! + * Returns the type of the image. + * + * \see Type + * \see setType() + */ + Type type() const; + + /*! + * Sets the type for the image. + * + * \see Type + * \see type() + */ + void setType(const ASF::Picture::Type& t); + + /*! + * Returns a text description of the image. + * + * \see setDescription() + */ + String description() const; + + /*! + * Sets a textual description of the image to \a desc. + * + * \see description() + */ + void setDescription(const String &desc); + + /*! + * Returns the image data as a ByteVector. + * + * \note ByteVector has a data() method that returns a const char * which + * should make it easy to export this data to external programs. + * + * \see setPicture() + * \see mimeType() + */ + ByteVector picture() const; + + /*! + * Sets the image data to \a p. \a p should be of the type specified in + * this frame's mime-type specification. + * + * \see picture() + * \see mimeType() + * \see setMimeType() + */ + void setPicture(const ByteVector &p); + + /*! + * Returns picture as binary raw data \a value + */ + ByteVector render() const; + + /*! + * Returns picture as binary raw data \a value + */ + int dataSize() const; + +#ifndef DO_NOT_DOCUMENT + /* THIS IS PRIVATE, DON'T TOUCH IT! */ + void parse(const ByteVector& ); + static Picture fromInvalid(); +#endif + + private: + class PicturePrivate; + PicturePrivate *d; + }; + } +} + +#endif // ASFPICTURE_H diff --git a/taglib/include/taglib/asfproperties.h b/taglib/include/taglib/asfproperties.h new file mode 100644 index 0000000..317bf10 --- /dev/null +++ b/taglib/include/taglib/asfproperties.h @@ -0,0 +1,186 @@ +/************************************************************************** + copyright : (C) 2005-2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_ASFPROPERTIES_H +#define TAGLIB_ASFPROPERTIES_H + +#include "audioproperties.h" +#include "tstring.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ASF { + + //! An implementation of ASF audio properties + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + + /*! + * Audio codec types can be used in ASF file. + */ + enum Codec + { + /*! + * Couldn't detect the codec. + */ + Unknown = 0, + + /*! + * Windows Media Audio 1 + */ + WMA1, + + /*! + * Windows Media Audio 2 or above + */ + WMA2, + + /*! + * Windows Media Audio 9 Professional + */ + WMA9Pro, + + /*! + * Windows Media Audio 9 Lossless + */ + WMA9Lossless, + }; + + /*! + * Creates an instance of ASF::Properties. + */ + Properties(); + + /*! + * Destroys this ASF::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns the codec used in the file. + * + * \see codecName() + * \see codecDescription() + */ + Codec codec() const; + + /*! + * Returns the concrete codec name, for example "Windows Media Audio 9.1" + * used in the file if available, otherwise an empty string. + * + * \see codec() + * \see codecDescription() + */ + String codecName() const; + + /*! + * Returns the codec description, typically contains the encoder settings, + * for example "VBR Quality 50, 44kHz, stereo 1-pass VBR" if available, + * otherwise an empty string. + * + * \see codec() + * \see codecName() + */ + String codecDescription() const; + + /*! + * Returns whether or not the file is encrypted. + */ + bool isEncrypted() const; + +#ifndef DO_NOT_DOCUMENT + // deprecated + void setLength(int value); + + void setLengthInMilliseconds(int value); + void setBitrate(int value); + void setSampleRate(int value); + void setChannels(int value); + void setBitsPerSample(int value); + void setCodec(int value); + void setCodecName(const String &value); + void setCodecDescription(const String &value); + void setEncrypted(bool value); +#endif + + private: + class PropertiesPrivate; + PropertiesPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/asftag.h b/taglib/include/taglib/asftag.h new file mode 100644 index 0000000..bbd9821 --- /dev/null +++ b/taglib/include/taglib/asftag.h @@ -0,0 +1,210 @@ +/************************************************************************** + copyright : (C) 2005-2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_ASFTAG_H +#define TAGLIB_ASFTAG_H + +#include "tag.h" +#include "tlist.h" +#include "tmap.h" +#include "taglib_export.h" +#include "asfattribute.h" + +namespace TagLib { + + namespace ASF { + + typedef List AttributeList; + typedef Map AttributeListMap; + + class TAGLIB_EXPORT Tag : public TagLib::Tag { + + friend class File; + + public: + + Tag(); + + virtual ~Tag(); + + /*! + * Returns the track name. + */ + virtual String title() const; + + /*! + * Returns the artist name. + */ + virtual String artist() const; + + /*! + * Returns the album name; if no album name is present in the tag + * String::null will be returned. + */ + virtual String album() const; + + /*! + * Returns the track comment. + */ + virtual String comment() const; + + /*! + * Returns the genre name; if no genre is present in the tag String::null + * will be returned. + */ + virtual String genre() const; + + /*! + * Returns the rating. + */ + virtual String rating() const; + + /*! + * Returns the genre name; if no genre is present in the tag String::null + * will be returned. + */ + virtual String copyright() const; + + /*! + * Returns the year; if there is no year set, this will return 0. + */ + virtual unsigned int year() const; + + /*! + * Returns the track number; if there is no track number set, this will + * return 0. + */ + virtual unsigned int track() const; + + /*! + * Sets the title to \a s. + */ + virtual void setTitle(const String &s); + + /*! + * Sets the artist to \a s. + */ + virtual void setArtist(const String &s); + + /*! + * Sets the album to \a s. If \a s is String::null then this value will be + * cleared. + */ + virtual void setAlbum(const String &s); + + /*! + * Sets the comment to \a s. + */ + virtual void setComment(const String &s); + + /*! + * Sets the rating to \a s. + */ + virtual void setRating(const String &s); + + /*! + * Sets the copyright to \a s. + */ + virtual void setCopyright(const String &s); + + /*! + * Sets the genre to \a s. + */ + virtual void setGenre(const String &s); + + /*! + * Sets the year to \a i. If \a s is 0 then this value will be cleared. + */ + virtual void setYear(unsigned int i); + + /*! + * Sets the track to \a i. If \a s is 0 then this value will be cleared. + */ + virtual void setTrack(unsigned int i); + + /*! + * Returns true if the tag does not contain any data. This should be + * reimplemented in subclasses that provide more than the basic tagging + * abilities in this class. + */ + virtual bool isEmpty() const; + + /*! + * \deprecated + */ + AttributeListMap &attributeListMap(); + + /*! + * Returns a reference to the item list map. This is an AttributeListMap of + * all of the items in the tag. + */ + // BIC: return by value + const AttributeListMap &attributeListMap() const; + + /*! + * \return True if a value for \a attribute is currently set. + */ + bool contains(const String &name) const; + + /*! + * Removes the \a key attribute from the tag + */ + void removeItem(const String &name); + + /*! + * \return The list of values for the key \a name, or an empty list if no + * values have been set. + */ + AttributeList attribute(const String &name) const; + + /*! + * Sets the \a key attribute to the value of \a attribute. If an attribute + * with the \a key is already present, it will be replaced. + */ + void setAttribute(const String &name, const Attribute &attribute); + + /*! + * Sets multiple \a values to the key \a name. + */ + void setAttribute(const String &name, const AttributeList &values); + + /*! + * Sets the \a key attribute to the value of \a attribute. If an attribute + * with the \a key is already present, it will be added to the list. + */ + void addAttribute(const String &name, const Attribute &attribute); + + PropertyMap properties() const; + void removeUnsupportedProperties(const StringList& properties); + PropertyMap setProperties(const PropertyMap &properties); + + private: + + class TagPrivate; + TagPrivate *d; + }; + } +} +#endif diff --git a/taglib/include/taglib/attachedpictureframe.h b/taglib/include/taglib/attachedpictureframe.h new file mode 100644 index 0000000..55067bd --- /dev/null +++ b/taglib/include/taglib/attachedpictureframe.h @@ -0,0 +1,230 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ATTACHEDPICTUREFRAME_H +#define TAGLIB_ATTACHEDPICTUREFRAME_H + +#include "id3v2frame.h" +#include "id3v2header.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An ID3v2 attached picture frame implementation + + /*! + * This is an implementation of ID3v2 attached pictures. Pictures may be + * included in tags, one per APIC frame (but there may be multiple APIC + * frames in a single tag). These pictures are usually in either JPEG or + * PNG format. + */ + + class TAGLIB_EXPORT AttachedPictureFrame : public Frame + { + friend class FrameFactory; + + public: + + /*! + * This describes the function or content of the picture. + */ + enum Type { + //! A type not enumerated below + Other = 0x00, + //! 32x32 PNG image that should be used as the file icon + FileIcon = 0x01, + //! File icon of a different size or format + OtherFileIcon = 0x02, + //! Front cover image of the album + FrontCover = 0x03, + //! Back cover image of the album + BackCover = 0x04, + //! Inside leaflet page of the album + LeafletPage = 0x05, + //! Image from the album itself + Media = 0x06, + //! Picture of the lead artist or soloist + LeadArtist = 0x07, + //! Picture of the artist or performer + Artist = 0x08, + //! Picture of the conductor + Conductor = 0x09, + //! Picture of the band or orchestra + Band = 0x0A, + //! Picture of the composer + Composer = 0x0B, + //! Picture of the lyricist or text writer + Lyricist = 0x0C, + //! Picture of the recording location or studio + RecordingLocation = 0x0D, + //! Picture of the artists during recording + DuringRecording = 0x0E, + //! Picture of the artists during performance + DuringPerformance = 0x0F, + //! Picture from a movie or video related to the track + MovieScreenCapture = 0x10, + //! Picture of a large, coloured fish + ColouredFish = 0x11, + //! Illustration related to the track + Illustration = 0x12, + //! Logo of the band or performer + BandLogo = 0x13, + //! Logo of the publisher (record company) + PublisherLogo = 0x14 + }; + + /*! + * Constructs an empty picture frame. The description, content and text + * encoding should be set manually. + */ + AttachedPictureFrame(); + + /*! + * Constructs an AttachedPicture frame based on \a data. + */ + explicit AttachedPictureFrame(const ByteVector &data); + + /*! + * Destroys the AttahcedPictureFrame instance. + */ + virtual ~AttachedPictureFrame(); + + /*! + * Returns a string containing the description and mime-type + */ + virtual String toString() const; + + /*! + * Returns the text encoding used for the description. + * + * \see setTextEncoding() + * \see description() + */ + String::Type textEncoding() const; + + /*! + * Set the text encoding used for the description. + * + * \see description() + */ + void setTextEncoding(String::Type t); + + /*! + * Returns the mime type of the image. This should in most cases be + * "image/png" or "image/jpeg". + */ + String mimeType() const; + + /*! + * Sets the mime type of the image. This should in most cases be + * "image/png" or "image/jpeg". + */ + void setMimeType(const String &m); + + /*! + * Returns the type of the image. + * + * \see Type + * \see setType() + */ + Type type() const; + + /*! + * Sets the type for the image. + * + * \see Type + * \see type() + */ + void setType(Type t); + + /*! + * Returns a text description of the image. + * + * \see setDescription() + * \see textEncoding() + * \see setTextEncoding() + */ + + String description() const; + + /*! + * Sets a textual description of the image to \a desc. + * + * \see description() + * \see textEncoding() + * \see setTextEncoding() + */ + + void setDescription(const String &desc); + + /*! + * Returns the image data as a ByteVector. + * + * \note ByteVector has a data() method that returns a const char * which + * should make it easy to export this data to external programs. + * + * \see setPicture() + * \see mimeType() + */ + ByteVector picture() const; + + /*! + * Sets the image data to \a p. \a p should be of the type specified in + * this frame's mime-type specification. + * + * \see picture() + * \see mimeType() + * \see setMimeType() + */ + void setPicture(const ByteVector &p); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + class AttachedPictureFramePrivate; + AttachedPictureFramePrivate *d; + + private: + AttachedPictureFrame(const AttachedPictureFrame &); + AttachedPictureFrame &operator=(const AttachedPictureFrame &); + AttachedPictureFrame(const ByteVector &data, Header *h); + + }; + + //! support for ID3v2.2 PIC frames + class TAGLIB_EXPORT AttachedPictureFrameV22 : public AttachedPictureFrame + { + protected: + virtual void parseFields(const ByteVector &data); + private: + AttachedPictureFrameV22(const ByteVector &data, Header *h); + friend class FrameFactory; + }; + } +} + +#endif diff --git a/taglib/include/taglib/audioproperties.h b/taglib/include/taglib/audioproperties.h new file mode 100644 index 0000000..f27aefc --- /dev/null +++ b/taglib/include/taglib/audioproperties.h @@ -0,0 +1,127 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_AUDIOPROPERTIES_H +#define TAGLIB_AUDIOPROPERTIES_H + +#include "taglib_export.h" + +namespace TagLib { + + //! A simple, abstract interface to common audio properties + + /*! + * The values here are common to most audio formats. For more specific, codec + * dependent values, please see see the subclasses APIs. This is meant to + * compliment the TagLib::File and TagLib::Tag APIs in providing a simple + * interface that is sufficient for most applications. + */ + + class TAGLIB_EXPORT AudioProperties + { + public: + + /*! + * Reading audio properties from a file can sometimes be very time consuming + * and for the most accurate results can often involve reading the entire + * file. Because in many situations speed is critical or the accuracy of the + * values is not particularly important this allows the level of desired + * accuracy to be set. + */ + enum ReadStyle { + //! Read as little of the file as possible + Fast, + //! Read more of the file and make better values guesses + Average, + //! Read as much of the file as needed to report accurate values + Accurate + }; + + /*! + * Destroys this AudioProperties instance. + */ + virtual ~AudioProperties(); + + /*! + * Returns the length of the file in seconds. + */ + virtual int length() const = 0; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the most appropriate bit rate for the file in kb/s. For constant + * bitrate formats this is simply the bitrate of the file. For variable + * bitrate formats this is either the average or nominal bitrate. + */ + virtual int bitrate() const = 0; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const = 0; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const = 0; + + protected: + + /*! + * Construct an audio properties instance. This is protected as this class + * should not be instantiated directly, but should be instantiated via its + * subclasses and can be fetched from the FileRef or File APIs. + * + * \see ReadStyle + */ + AudioProperties(ReadStyle style); + + private: + AudioProperties(const AudioProperties &); + AudioProperties &operator=(const AudioProperties &); + + class AudioPropertiesPrivate; + AudioPropertiesPrivate *d; + }; + +} + +#endif diff --git a/taglib/include/taglib/chapterframe.h b/taglib/include/taglib/chapterframe.h new file mode 100644 index 0000000..0eaa140 --- /dev/null +++ b/taglib/include/taglib/chapterframe.h @@ -0,0 +1,249 @@ +/*************************************************************************** + copyright : (C) 2013 by Lukas Krejci + email : krejclu6@fel.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * 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_CHAPTERFRAME +#define TAGLIB_CHAPTERFRAME + +#include "id3v2tag.h" +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + /*! + * This is an implementation of ID3v2 chapter frames. The purpose of this + * frame is to describe a single chapter within an audio file. + */ + + //! An implementation of ID3v2 chapter frames + + class TAGLIB_EXPORT ChapterFrame : public ID3v2::Frame + { + friend class FrameFactory; + + public: + /*! + * Creates a chapter frame based on \a data. \a tagHeader is required as + * the internal frames are parsed based on the tag version. + */ + ChapterFrame(const ID3v2::Header *tagHeader, const ByteVector &data); + + /*! + * Creates a chapter frame with the element ID \a elementID, start time + * \a startTime, end time \a endTime, start offset \a startOffset, + * end offset \a endOffset and optionally a list of embedded frames, + * whose ownership will then be taken over by this Frame, in + * \a embeddedFrames; + * + * All times are in milliseconds. + */ + ChapterFrame(const ByteVector &elementID, + unsigned int startTime, unsigned int endTime, + unsigned int startOffset, unsigned int endOffset, + const FrameList &embeddedFrames = FrameList()); + + /*! + * Destroys the frame. + */ + virtual ~ChapterFrame(); + + /*! + * Returns the element ID of the frame. Element ID + * is a null terminated string, however it's not human-readable. + * + * \see setElementID() + */ + ByteVector elementID() const; + + /*! + * Returns time of chapter's start (in milliseconds). + * + * \see setStartTime() + */ + unsigned int startTime() const; + + /*! + * Returns time of chapter's end (in milliseconds). + * + * \see setEndTime() + */ + unsigned int endTime() const; + + /*! + * Returns zero based byte offset (count of bytes from the beginning + * of the audio file) of chapter's start. + * + * \note If returned value is 0xFFFFFFFF, start time should be used instead. + * \see setStartOffset() + */ + unsigned int startOffset() const; + + /*! + * Returns zero based byte offset (count of bytes from the beginning + * of the audio file) of chapter's end. + * + * \note If returned value is 0xFFFFFFFF, end time should be used instead. + * \see setEndOffset() + */ + unsigned int endOffset() const; + + /*! + * Sets the element ID of the frame to \a eID. If \a eID isn't + * null terminated, a null char is appended automatically. + * + * \see elementID() + */ + void setElementID(const ByteVector &eID); + + /*! + * Sets time of chapter's start (in milliseconds) to \a sT. + * + * \see startTime() + */ + void setStartTime(const unsigned int &sT); + + /*! + * Sets time of chapter's end (in milliseconds) to \a eT. + * + * \see endTime() + */ + void setEndTime(const unsigned int &eT); + + /*! + * Sets zero based byte offset (count of bytes from the beginning + * of the audio file) of chapter's start to \a sO. + * + * \see startOffset() + */ + void setStartOffset(const unsigned int &sO); + + /*! + * Sets zero based byte offset (count of bytes from the beginning + * of the audio file) of chapter's end to \a eO. + * + * \see endOffset() + */ + void setEndOffset(const unsigned int &eO); + + /*! + * Returns a reference to the frame list map. This is an FrameListMap of + * all of the frames embedded in the CHAP frame. + * + * This is the most convenient structure for accessing the CHAP frame's + * embedded frames. Many frame types allow multiple instances of the same + * frame type so this is a map of lists. In most cases however there will + * only be a single frame of a certain type. + * + * \warning You should not modify this data structure directly, instead + * use addEmbeddedFrame() and removeEmbeddedFrame(). + * + * \see embeddedFrameList() + */ + const FrameListMap &embeddedFrameListMap() const; + + /*! + * Returns a reference to the embedded frame list. This is an FrameList + * of all of the frames embedded in the CHAP frame in the order that they + * were parsed. + * + * This can be useful if for example you want iterate over the CHAP frame's + * embedded frames in the order that they occur in the CHAP frame. + * + * \warning You should not modify this data structure directly, instead + * use addEmbeddedFrame() and removeEmbeddedFrame(). + */ + const FrameList &embeddedFrameList() const; + + /*! + * Returns the embedded frame list for frames with the id \a frameID + * or an empty list if there are no embedded frames of that type. This + * is just a convenience and is equivalent to: + * + * \code + * embeddedFrameListMap()[frameID]; + * \endcode + * + * \see embeddedFrameListMap() + */ + const FrameList &embeddedFrameList(const ByteVector &frameID) const; + + /*! + * Add an embedded frame to the CHAP frame. At this point the CHAP frame + * takes ownership of the embedded frame and will handle freeing its memory. + * + * \note Using this method will invalidate any pointers on the list + * returned by embeddedFrameList() + */ + void addEmbeddedFrame(Frame *frame); + + /*! + * Remove an embedded frame from the CHAP frame. If \a del is true the frame's + * memory will be freed; if it is false, it must be deleted by the user. + * + * \note Using this method will invalidate any pointers on the list + * returned by embeddedFrameList() + */ + void removeEmbeddedFrame(Frame *frame, bool del = true); + + /*! + * Remove all embedded frames of type \a id from the CHAP frame and free their + * memory. + * + * \note Using this method will invalidate any pointers on the list + * returned by embeddedFrameList() + */ + void removeEmbeddedFrames(const ByteVector &id); + + virtual String toString() const; + + PropertyMap asProperties() const; + + /*! + * CHAP frames each have a unique element ID. This searches for a CHAP + * frame with the element ID \a eID and returns a pointer to it. This + * can be used to link CTOC and CHAP frames together. + * + * \see elementID() + */ + static ChapterFrame *findByElementID(const Tag *tag, const ByteVector &eID); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + ChapterFrame(const ID3v2::Header *tagHeader, const ByteVector &data, Header *h); + ChapterFrame(const ChapterFrame &); + ChapterFrame &operator=(const ChapterFrame &); + + class ChapterFramePrivate; + ChapterFramePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/commentsframe.h b/taglib/include/taglib/commentsframe.h new file mode 100644 index 0000000..4da9d53 --- /dev/null +++ b/taglib/include/taglib/commentsframe.h @@ -0,0 +1,179 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_COMMENTSFRAME_H +#define TAGLIB_COMMENTSFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An implementation of ID3v2 comments + + /*! + * This implements the ID3v2 comment format. An ID3v2 comment consists of + * a language encoding, a description and a single text field. + */ + + class TAGLIB_EXPORT CommentsFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty comment frame that will use the text encoding + * \a encoding. + */ + explicit CommentsFrame(String::Type encoding = String::Latin1); + + /*! + * Construct a comment based on the data in \a data. + */ + explicit CommentsFrame(const ByteVector &data); + + /*! + * Destroys this CommentFrame instance. + */ + virtual ~CommentsFrame(); + + /*! + * Returns the text of this comment. + * + * \see text() + */ + virtual String toString() const; + + /*! + * Returns the language encoding as a 3 byte encoding as specified by + * ISO-639-2. + * + * \note Most taggers simply ignore this value. + * + * \see setLanguage() + */ + ByteVector language() const; + + /*! + * Returns the description of this comment. + * + * \note Most taggers simply ignore this value. + * + * \see setDescription() + */ + String description() const; + + /*! + * Returns the text of this comment. + * + * \see setText() + */ + String text() const; + + /*! + * Set the language using the 3 byte language code from + * ISO-639-2 to + * \a languageCode. + * + * \see language() + */ + void setLanguage(const ByteVector &languageCode); + + /*! + * Sets the description of the comment to \a s. + * + * \see description() + */ + void setDescription(const String &s); + + /*! + * Sets the text portion of the comment to \a s. + * + * \see text() + */ + virtual void setText(const String &s); + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + /*! + * Parses this frame as PropertyMap with a single key. + * - if description() is empty or "COMMENT", the key will be "COMMENT" + * - if description() is not a valid PropertyMap key, the frame will be + * marked unsupported by an entry "COMM/" in the unsupportedData() + * attribute of the returned map. + * - otherwise, the key will be "COMMENT:" + * - The single value will be the frame's text(). + */ + PropertyMap asProperties() const; + + /*! + * Comments each have a unique description. This searches for a comment + * frame with the description \a d and returns a pointer to it. If no + * frame is found that matches the given description null is returned. + * + * \see description() + */ + static CommentsFrame *findByDescription(const Tag *tag, const String &d); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + CommentsFrame(const ByteVector &data, Header *h); + CommentsFrame(const CommentsFrame &); + CommentsFrame &operator=(const CommentsFrame &); + + class CommentsFramePrivate; + CommentsFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/eventtimingcodesframe.h b/taglib/include/taglib/eventtimingcodesframe.h new file mode 100644 index 0000000..3dcedb9 --- /dev/null +++ b/taglib/include/taglib/eventtimingcodesframe.h @@ -0,0 +1,185 @@ +/*************************************************************************** + copyright : (C) 2014 by Urs Fleisch + email : ufleisch@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * 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_EVENTTIMINGCODESFRAME_H +#define TAGLIB_EVENTTIMINGCODESFRAME_H + +#include "id3v2frame.h" +#include "tlist.h" + +namespace TagLib { + + namespace ID3v2 { + + //! ID3v2 event timing codes frame + /*! + * An implementation of ID3v2 event timing codes. + */ + class TAGLIB_EXPORT EventTimingCodesFrame : public Frame + { + friend class FrameFactory; + + public: + + /*! + * Specifies the timestamp format used. + */ + enum TimestampFormat { + //! The timestamp is of unknown format. + Unknown = 0x00, + //! The timestamp represents the number of MPEG frames since + //! the beginning of the audio stream. + AbsoluteMpegFrames = 0x01, + //! The timestamp represents the number of milliseconds since + //! the beginning of the audio stream. + AbsoluteMilliseconds = 0x02 + }; + + /*! + * Event types defined in id3v2.4.0-frames.txt 4.5. Event timing codes. + */ + enum EventType { + Padding = 0x00, + EndOfInitialSilence = 0x01, + IntroStart = 0x02, + MainPartStart = 0x03, + OutroStart = 0x04, + OutroEnd = 0x05, + VerseStart = 0x06, + RefrainStart = 0x07, + InterludeStart = 0x08, + ThemeStart = 0x09, + VariationStart = 0x0a, + KeyChange = 0x0b, + TimeChange = 0x0c, + MomentaryUnwantedNoise = 0x0d, + SustainedNoise = 0x0e, + SustainedNoiseEnd = 0x0f, + IntroEnd = 0x10, + MainPartEnd = 0x11, + VerseEnd = 0x12, + RefrainEnd = 0x13, + ThemeEnd = 0x14, + Profanity = 0x15, + ProfanityEnd = 0x16, + NotPredefinedSynch0 = 0xe0, + NotPredefinedSynch1 = 0xe1, + NotPredefinedSynch2 = 0xe2, + NotPredefinedSynch3 = 0xe3, + NotPredefinedSynch4 = 0xe4, + NotPredefinedSynch5 = 0xe5, + NotPredefinedSynch6 = 0xe6, + NotPredefinedSynch7 = 0xe7, + NotPredefinedSynch8 = 0xe8, + NotPredefinedSynch9 = 0xe9, + NotPredefinedSynchA = 0xea, + NotPredefinedSynchB = 0xeb, + NotPredefinedSynchC = 0xec, + NotPredefinedSynchD = 0xed, + NotPredefinedSynchE = 0xee, + NotPredefinedSynchF = 0xef, + AudioEnd = 0xfd, + AudioFileEnds = 0xfe + }; + + /*! + * Single entry of time stamp and event. + */ + struct SynchedEvent { + SynchedEvent(unsigned int ms, EventType t) : time(ms), type(t) {} + unsigned int time; + EventType type; + }; + + /*! + * List of synchronized events. + */ + typedef TagLib::List SynchedEventList; + + /*! + * Construct an empty event timing codes frame. + */ + explicit EventTimingCodesFrame(); + + /*! + * Construct a event timing codes frame based on the data in \a data. + */ + explicit EventTimingCodesFrame(const ByteVector &data); + + /*! + * Destroys this EventTimingCodesFrame instance. + */ + virtual ~EventTimingCodesFrame(); + + /*! + * Returns a null string. + */ + virtual String toString() const; + + /*! + * Returns the timestamp format. + */ + TimestampFormat timestampFormat() const; + + /*! + * Returns the events with the time stamps. + */ + SynchedEventList synchedEvents() const; + + /*! + * Set the timestamp format. + * + * \see timestampFormat() + */ + void setTimestampFormat(TimestampFormat f); + + /*! + * Sets the text with the time stamps. + * + * \see text() + */ + void setSynchedEvents(const SynchedEventList &e); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + EventTimingCodesFrame(const ByteVector &data, Header *h); + EventTimingCodesFrame(const EventTimingCodesFrame &); + EventTimingCodesFrame &operator=(const EventTimingCodesFrame &); + + class EventTimingCodesFramePrivate; + EventTimingCodesFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/fileref.h b/taglib/include/taglib/fileref.h new file mode 100644 index 0000000..76e694e --- /dev/null +++ b/taglib/include/taglib/fileref.h @@ -0,0 +1,287 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_FILEREF_H +#define TAGLIB_FILEREF_H + +#include "tfile.h" +#include "tstringlist.h" + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + + class Tag; + + //! This class provides a simple abstraction for creating and handling files + + /*! + * FileRef exists to provide a minimal, generic and value-based wrapper around + * a File. It is lightweight and implicitly shared, and as such suitable for + * pass-by-value use. This hides some of the uglier details of TagLib::File + * and the non-generic portions of the concrete file implementations. + * + * This class is useful in a "simple usage" situation where it is desirable + * to be able to get and set some of the tag information that is similar + * across file types. + * + * Also note that it is probably a good idea to plug this into your mime + * type system rather than using the constructor that accepts a file name using + * the FileTypeResolver. + * + * \see FileTypeResolver + * \see addFileTypeResolver() + */ + + class TAGLIB_EXPORT FileRef + { + public: + + //! A class for pluggable file type resolution. + + /*! + * This class is used to add extend TagLib's very basic file name based file + * type resolution. + * + * This can be accomplished with: + * + * \code + * + * class MyFileTypeResolver : FileTypeResolver + * { + * TagLib::File *createFile(TagLib::FileName *fileName, bool, AudioProperties::ReadStyle) const + * { + * if(someCheckForAnMP3File(fileName)) + * return new TagLib::MPEG::File(fileName); + * return 0; + * } + * } + * + * FileRef::addFileTypeResolver(new MyFileTypeResolver); + * + * \endcode + * + * Naturally a less contrived example would be slightly more complex. This + * can be used to plug in mime-type detection systems or to add new file types + * to TagLib. + */ + + class TAGLIB_EXPORT FileTypeResolver + { + TAGLIB_IGNORE_MISSING_DESTRUCTOR + public: + /*! + * This method must be overridden to provide an additional file type + * resolver. If the resolver is able to determine the file type it should + * return a valid File object; if not it should return 0. + * + * \note The created file is then owned by the FileRef and should not be + * deleted. Deletion will happen automatically when the FileRef passes + * out of scope. + */ + virtual File *createFile(FileName fileName, + bool readAudioProperties = true, + AudioProperties::ReadStyle + audioPropertiesStyle = AudioProperties::Average) const = 0; + }; + + /*! + * Creates a null FileRef. + */ + FileRef(); + + /*! + * Create a FileRef from \a fileName. If \a readAudioProperties is true then + * the audio properties will be read using \a audioPropertiesStyle. If + * \a readAudioProperties is false then \a audioPropertiesStyle will be + * ignored. + * + * Also see the note in the class documentation about why you may not want to + * use this method in your application. + */ + explicit FileRef(FileName fileName, + bool readAudioProperties = true, + AudioProperties::ReadStyle + audioPropertiesStyle = AudioProperties::Average); + + /*! + * Construct a FileRef from an opened \a IOStream. If \a readAudioProperties + * is true then the audio properties will be read using \a audioPropertiesStyle. + * If \a readAudioProperties is false then \a audioPropertiesStyle will be + * ignored. + * + * Also see the note in the class documentation about why you may not want to + * use this method in your application. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + explicit FileRef(IOStream* stream, + bool readAudioProperties = true, + AudioProperties::ReadStyle + audioPropertiesStyle = AudioProperties::Average); + + /*! + * Construct a FileRef using \a file. The FileRef now takes ownership of the + * pointer and will delete the File when it passes out of scope. + */ + explicit FileRef(File *file); + + /*! + * Make a copy of \a ref. + */ + FileRef(const FileRef &ref); + + /*! + * Destroys this FileRef instance. + */ + virtual ~FileRef(); + + /*! + * Returns a pointer to represented file's tag. + * + * \warning This pointer will become invalid when this FileRef and all + * copies pass out of scope. + * + * \warning Do not cast it to any subclasses of Tag. + * Use tag returning methods of appropriate subclasses of File instead. + * + * \see File::tag() + */ + Tag *tag() const; + + /*! + * Returns the audio properties for this FileRef. If no audio properties + * were read then this will returns a null pointer. + */ + AudioProperties *audioProperties() const; + + /*! + * Returns a pointer to the file represented by this handler class. + * + * As a general rule this call should be avoided since if you need to work + * with file objects directly, you are probably better served instantiating + * the File subclasses (i.e. MPEG::File) manually and working with their APIs. + * + * This handle exists to provide a minimal, generic and value-based + * wrapper around a File. Accessing the file directly generally indicates + * a moving away from this simplicity (and into things beyond the scope of + * FileRef). + * + * \warning This pointer will become invalid when this FileRef and all + * copies pass out of scope. + */ + File *file() const; + + /*! + * Saves the file. Returns true on success. + */ + bool save(); + + /*! + * Adds a FileTypeResolver to the list of those used by TagLib. Each + * additional FileTypeResolver is added to the front of a list of resolvers + * that are tried. If the FileTypeResolver returns zero the next resolver + * is tried. + * + * Returns a pointer to the added resolver (the same one that's passed in -- + * this is mostly so that static initializers have something to use for + * assignment). + * + * \see FileTypeResolver + */ + static const FileTypeResolver *addFileTypeResolver(const FileTypeResolver *resolver); + + /*! + * As is mentioned elsewhere in this class's documentation, the default file + * type resolution code provided by TagLib only works by comparing file + * extensions. + * + * This method returns the list of file extensions that are used by default. + * + * The extensions are all returned in lowercase, though the comparison used + * by TagLib for resolution is case-insensitive. + * + * \note This does not account for any additional file type resolvers that + * are plugged in. Also note that this is not intended to replace a proper + * mime-type resolution system, but is just here for reference. + * + * \see FileTypeResolver + */ + static StringList defaultFileExtensions(); + + /*! + * Returns true if the file (and as such other pointers) are null. + */ + bool isNull() const; + + /*! + * Assign the file pointed to by \a ref to this FileRef. + */ + FileRef &operator=(const FileRef &ref); + + /*! + * Exchanges the content of the FileRef by the content of \a ref. + */ + void swap(FileRef &ref); + + /*! + * Returns true if this FileRef and \a ref point to the same File object. + */ + bool operator==(const FileRef &ref) const; + + /*! + * Returns true if this FileRef and \a ref do not point to the same File + * object. + */ + bool operator!=(const FileRef &ref) const; + + /*! + * A simple implementation of file type guessing. If \a readAudioProperties + * is true then the audio properties will be read using + * \a audioPropertiesStyle. If \a readAudioProperties is false then + * \a audioPropertiesStyle will be ignored. + * + * \note You generally shouldn't use this method, but instead the constructor + * directly. + * + * \deprecated + */ + static File *create(FileName fileName, + bool readAudioProperties = true, + AudioProperties::ReadStyle audioPropertiesStyle = AudioProperties::Average); + + private: + void parse(FileName fileName, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle); + void parse(IOStream *stream, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle); + + class FileRefPrivate; + FileRefPrivate *d; + }; + +} // namespace TagLib + +#endif diff --git a/taglib/include/taglib/flacfile.h b/taglib/include/taglib/flacfile.h new file mode 100644 index 0000000..1b8654e --- /dev/null +++ b/taglib/include/taglib/flacfile.h @@ -0,0 +1,343 @@ +/*************************************************************************** + copyright : (C) 2003 by Allan Sandfeld Jensen + email : kde@carewolf.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_FLACFILE_H +#define TAGLIB_FLACFILE_H + +#include "taglib_export.h" +#include "tfile.h" +#include "tlist.h" +#include "tag.h" + +#include "flacpicture.h" +#include "flacproperties.h" + +namespace TagLib { + + class Tag; + namespace ID3v2 { class FrameFactory; class Tag; } + namespace ID3v1 { class Tag; } + namespace Ogg { class XiphComment; } + + //! An implementation of FLAC metadata + + /*! + * This is implementation of FLAC metadata for non-Ogg FLAC files. At some + * point when Ogg / FLAC is more common there will be a similar implementation + * under the Ogg hierarchy. + * + * This supports ID3v1, ID3v2 and Xiph style comments as well as reading stream + * properties from the file. + */ + + namespace FLAC { + + //! An implementation of TagLib::File with FLAC specific methods + + /*! + * This implements and provides an interface for FLAC files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to FLAC files. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches Vorbis comments. + XiphComment = 0x0001, + //! Matches ID3v1 tags. + ID3v1 = 0x0002, + //! Matches ID3v2 tags. + ID3v2 = 0x0004, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs a FLAC file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + * + * \deprecated This constructor will be dropped in favor of the one below + * in a future version. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an FLAC file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + // BIC: merge with the above constructor + File(FileName file, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a FLAC file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + // BIC: merge with the above constructor + File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. This will be a union of XiphComment, + * ID3v1 and ID3v2 tags. + * + * \see ID3v2Tag() + * \see ID3v1Tag() + * \see XiphComment() + */ + virtual TagLib::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * If the file contains more than one tag (e.g. XiphComment and ID3v1), + * only the first one (in the order XiphComment, ID3v2, ID3v1) will be + * converted to the PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &); + + /*! + * Implements the unified property interface -- import function. + * This always creates a Xiph comment, if none exists. The return value + * relates to the Xiph comment only. + * Ignores any changes to ID3v1 or ID3v2 comments since they are not allowed + * in the FLAC specification. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the FLAC::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Save the file. This will primarily save the XiphComment, but + * will also keep any old ID3-tags up to date. If the file + * has no XiphComment, one will be constructed from the ID3-tags. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Returns a pointer to the ID3v2 tag of the file. + * + * If \a create is false (the default) this returns a null pointer + * if there is no valid ID3v2 tag. If \a create is true it will create + * an ID3v2 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v2 tag. Use hasID3v2Tag() to check if the file + * on disk actually has an ID3v2 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v2Tag() + */ + ID3v2::Tag *ID3v2Tag(bool create = false); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this returns a null pointer + * if there is no valid APE tag. If \a create is true it will create + * an APE tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file + * on disk actually has an ID3v1 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v1Tag() + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the XiphComment for the file. + * + * If \a create is false (the default) this returns a null pointer + * if there is no valid XiphComment. If \a create is true it will create + * a XiphComment if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has a XiphComment. Use hasXiphComment() to check if the + * file on disk actually has a XiphComment. + * + * \note The Tag is still owned by the FLAC::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasXiphComment() + */ + Ogg::XiphComment *xiphComment(bool create = false); + + /*! + * Set the ID3v2::FrameFactory to something other than the default. This + * can be used to specify the way that ID3v2 frames will be interpreted + * when + * + * \see ID3v2FrameFactory + * \deprecated This value should be passed in via the constructor + */ + TAGLIB_DEPRECATED void setID3v2FrameFactory(const ID3v2::FrameFactory *factory); + + /*! + * Returns the block of data used by FLAC::Properties for parsing the + * stream properties. + * + * \deprecated Always returns an empty vector. + */ + TAGLIB_DEPRECATED ByteVector streamInfoData(); // BIC: remove + + /*! + * Returns the length of the audio-stream, used by FLAC::Properties for + * calculating the bitrate. + * + * \deprecated Always returns zero. + */ + TAGLIB_DEPRECATED long streamLength(); // BIC: remove + + /*! + * Returns a list of pictures attached to the FLAC file. + */ + List pictureList(); + + /*! + * Removes an attached picture. If \a del is true the picture's memory + * will be freed; if it is false, it must be deleted by the user. + */ + void removePicture(Picture *picture, bool del = true); + + /*! + * Remove all attached images. + */ + void removePictures(); + + /*! + * Add a new picture to the file. The file takes ownership of the + * picture and will handle freeing its memory. + * + * \note The file will be saved only after calling save(). + */ + void addPicture(Picture *picture); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from + * the file. By default it removes all tags. + * + * \warning This will also invalidate pointers to the tags as their memory + * will be freed. + * + * \note In order to make the removal permanent save() still needs to be + * called. + * + * \note This won't remove the Vorbis comment block completely. The + * vendor ID will be preserved. + */ + void strip(int tags = AllTags); + + /*! + * Returns whether or not the file on disk actually has a XiphComment. + * + * \see xiphComment() + */ + bool hasXiphComment() const; + + /*! + * Returns whether or not the file on disk actually has an ID3v1 tag. + * + * \see ID3v1Tag() + */ + bool hasID3v1Tag() const; + + /*! + * Returns whether or not the file on disk actually has an ID3v2 tag. + * + * \see ID3v2Tag() + */ + bool hasID3v2Tag() const; + + /*! + * Returns whether or not the given \a stream can be opened as a FLAC + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + void scan(); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/flacmetadatablock.h b/taglib/include/taglib/flacmetadatablock.h new file mode 100644 index 0000000..41bca31 --- /dev/null +++ b/taglib/include/taglib/flacmetadatablock.h @@ -0,0 +1,75 @@ +/************************************************************************** + copyright : (C) 2010 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_FLACMETADATABLOCK_H +#define TAGLIB_FLACMETADATABLOCK_H + +#include "tlist.h" +#include "tbytevector.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace FLAC { + + class TAGLIB_EXPORT MetadataBlock + { + public: + MetadataBlock(); + virtual ~MetadataBlock(); + + enum BlockType { + StreamInfo = 0, + Padding, + Application, + SeekTable, + VorbisComment, + CueSheet, + Picture + }; + + /*! + * Returns the FLAC metadata block type. + */ + virtual int code() const = 0; + + /*! + * Render the content of the block. + */ + virtual ByteVector render() const = 0; + + private: + MetadataBlock(const MetadataBlock &item); + MetadataBlock &operator=(const MetadataBlock &item); + + class MetadataBlockPrivate; + MetadataBlockPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/flacpicture.h b/taglib/include/taglib/flacpicture.h new file mode 100644 index 0000000..b6def57 --- /dev/null +++ b/taglib/include/taglib/flacpicture.h @@ -0,0 +1,208 @@ +/************************************************************************** + copyright : (C) 2010 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_FLACPICTURE_H +#define TAGLIB_FLACPICTURE_H + +#include "tlist.h" +#include "tstring.h" +#include "tbytevector.h" +#include "taglib_export.h" +#include "flacmetadatablock.h" + +namespace TagLib { + + namespace FLAC { + + class TAGLIB_EXPORT Picture : public MetadataBlock + { + public: + + /*! + * This describes the function or content of the picture. + */ + enum Type { + //! A type not enumerated below + Other = 0x00, + //! 32x32 PNG image that should be used as the file icon + FileIcon = 0x01, + //! File icon of a different size or format + OtherFileIcon = 0x02, + //! Front cover image of the album + FrontCover = 0x03, + //! Back cover image of the album + BackCover = 0x04, + //! Inside leaflet page of the album + LeafletPage = 0x05, + //! Image from the album itself + Media = 0x06, + //! Picture of the lead artist or soloist + LeadArtist = 0x07, + //! Picture of the artist or performer + Artist = 0x08, + //! Picture of the conductor + Conductor = 0x09, + //! Picture of the band or orchestra + Band = 0x0A, + //! Picture of the composer + Composer = 0x0B, + //! Picture of the lyricist or text writer + Lyricist = 0x0C, + //! Picture of the recording location or studio + RecordingLocation = 0x0D, + //! Picture of the artists during recording + DuringRecording = 0x0E, + //! Picture of the artists during performance + DuringPerformance = 0x0F, + //! Picture from a movie or video related to the track + MovieScreenCapture = 0x10, + //! Picture of a large, coloured fish + ColouredFish = 0x11, + //! Illustration related to the track + Illustration = 0x12, + //! Logo of the band or performer + BandLogo = 0x13, + //! Logo of the publisher (record company) + PublisherLogo = 0x14 + }; + + Picture(); + Picture(const ByteVector &data); + ~Picture(); + + /*! + * Returns the type of the image. + */ + Type type() const; + + /*! + * Sets the type of the image. + */ + void setType(Type type); + + /*! + * Returns the mime type of the image. This should in most cases be + * "image/png" or "image/jpeg". + */ + String mimeType() const; + + /*! + * Sets the mime type of the image. This should in most cases be + * "image/png" or "image/jpeg". + */ + void setMimeType(const String &m); + + /*! + * Returns a text description of the image. + */ + + String description() const; + + /*! + * Sets a textual description of the image to \a desc. + */ + + void setDescription(const String &desc); + + /*! + * Returns the width of the image. + */ + int width() const; + + /*! + * Sets the width of the image. + */ + void setWidth(int w); + + /*! + * Returns the height of the image. + */ + int height() const; + + /*! + * Sets the height of the image. + */ + void setHeight(int h); + + /*! + * Returns the color depth (in bits-per-pixel) of the image. + */ + int colorDepth() const; + + /*! + * Sets the color depth (in bits-per-pixel) of the image. + */ + void setColorDepth(int depth); + + /*! + * Returns the number of colors used on the image.. + */ + int numColors() const; + + /*! + * Sets the number of colors used on the image (for indexed images). + */ + void setNumColors(int numColors); + + /*! + * Returns the image data. + */ + ByteVector data() const; + + /*! + * Sets the image data. + */ + void setData(const ByteVector &data); + + /*! + * Returns the FLAC metadata block type. + */ + int code() const; + + /*! + * Render the content to the FLAC picture block format. + */ + ByteVector render() const; + + /*! + * Parse the picture data in the FLAC picture block format. + */ + bool parse(const ByteVector &rawData); + + private: + Picture(const Picture &item); + Picture &operator=(const Picture &item); + + class PicturePrivate; + PicturePrivate *d; + }; + + typedef List PictureList; + + } + +} + +#endif diff --git a/taglib/include/taglib/flacproperties.h b/taglib/include/taglib/flacproperties.h new file mode 100644 index 0000000..743e587 --- /dev/null +++ b/taglib/include/taglib/flacproperties.h @@ -0,0 +1,148 @@ +/*************************************************************************** + copyright : (C) 2003 by Allan Sandfeld Jensen + email : kde@carewolf.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_FLACPROPERTIES_H +#define TAGLIB_FLACPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace FLAC { + + class File; + + //! An implementation of audio property reading for FLAC + + /*! + * This reads the data from an FLAC stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of FLAC::Properties with the data read from the + * ByteVector \a data. + */ + // BIC: switch to const reference + Properties(ByteVector data, long streamLength, ReadStyle style = Average); + + /*! + * Create an instance of FLAC::Properties with the data read from the + * FLAC::File \a file. + */ + // BIC: remove + Properties(File *file, ReadStyle style = Average); + + /*! + * Destroys this FLAC::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample as read from the FLAC + * identification header. + */ + int bitsPerSample() const; + + /*! + * Returns the sample width as read from the FLAC identification + * header. + * + * \note This method is just an alias of bitsPerSample(). + * + * \deprecated + */ + TAGLIB_DEPRECATED int sampleWidth() const; + + /*! + * Return the number of sample frames. + */ + unsigned long long sampleFrames() const; + + /*! + * Returns the MD5 signature of the uncompressed audio stream as read + * from the stream info header. + */ + ByteVector signature() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(const ByteVector &data, long streamLength); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/generalencapsulatedobjectframe.h b/taglib/include/taglib/generalencapsulatedobjectframe.h new file mode 100644 index 0000000..769dfb0 --- /dev/null +++ b/taglib/include/taglib/generalencapsulatedobjectframe.h @@ -0,0 +1,179 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + + copyright : (C) 2006 by Aaron VonderHaar + email : avh4@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * 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_GENERALENCAPSULATEDOBJECT_H +#define TAGLIB_GENERALENCAPSULATEDOBJECT_H + +#include "id3v2frame.h" +#include "id3v2header.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An ID3v2 general encapsulated object frame implementation + + /*! + * This is an implementation of ID3v2 general encapsulated objects. + * Arbitrary binary data may be included in tags, stored in GEOB frames. + * There may be multiple GEOB frames in a single tag. Each GEOB it + * labelled with a content description (which may be blank), a required + * mime-type, and a file name (may be blank). The content description + * uniquely identifies the GEOB frame in the tag. + */ + + class TAGLIB_EXPORT GeneralEncapsulatedObjectFrame : public Frame + { + friend class FrameFactory; + + public: + + /*! + * Constructs an empty object frame. The description, file name and text + * encoding should be set manually. + */ + GeneralEncapsulatedObjectFrame(); + + /*! + * Constructs a GeneralEncapsulatedObjectFrame frame based on \a data. + * + * \warning This is \em not data for the encapsulated object, for that use + * setObject(). This constructor is used when reading the frame from the + * disk. + */ + explicit GeneralEncapsulatedObjectFrame(const ByteVector &data); + + /*! + * Destroys the GeneralEncapsulatedObjectFrame instance. + */ + virtual ~GeneralEncapsulatedObjectFrame(); + + /*! + * Returns a string containing the description, file name and mime-type + */ + virtual String toString() const; + + /*! + * Returns the text encoding used for the description and file name. + * + * \see setTextEncoding() + * \see description() + * \see fileName() + */ + String::Type textEncoding() const; + + /*! + * Set the text encoding used for the description and file name. + * + * \see description() + * \see fileName() + */ + void setTextEncoding(String::Type encoding); + + /*! + * Returns the mime type of the object. + */ + String mimeType() const; + + /*! + * Sets the mime type of the object. + */ + void setMimeType(const String &type); + + /*! + * Returns the file name of the object. + * + * \see setFileName() + */ + String fileName() const; + + /*! + * Sets the file name for the object. + * + * \see fileName() + */ + void setFileName(const String &name); + + /*! + * Returns the content description of the object. + * + * \see setDescription() + * \see textEncoding() + * \see setTextEncoding() + */ + + String description() const; + + /*! + * Sets the content description of the object to \a desc. + * + * \see description() + * \see textEncoding() + * \see setTextEncoding() + */ + + void setDescription(const String &desc); + + /*! + * Returns the object data as a ByteVector. + * + * \note ByteVector has a data() method that returns a const char * which + * should make it easy to export this data to external programs. + * + * \see setObject() + * \see mimeType() + */ + ByteVector object() const; + + /*! + * Sets the object data to \a data. \a data should be of the type specified in + * this frame's mime-type specification. + * + * \see object() + * \see mimeType() + * \see setMimeType() + */ + void setObject(const ByteVector &object); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + GeneralEncapsulatedObjectFrame(const ByteVector &data, Header *h); + GeneralEncapsulatedObjectFrame(const GeneralEncapsulatedObjectFrame &); + GeneralEncapsulatedObjectFrame &operator=(const GeneralEncapsulatedObjectFrame &); + + class GeneralEncapsulatedObjectFramePrivate; + GeneralEncapsulatedObjectFramePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/id3v1genres.h b/taglib/include/taglib/id3v1genres.h new file mode 100644 index 0000000..0a0dd97 --- /dev/null +++ b/taglib/include/taglib/id3v1genres.h @@ -0,0 +1,66 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V1GENRE_H +#define TAGLIB_ID3V1GENRE_H + +#include "tmap.h" +#include "tstringlist.h" +#include "taglib_export.h" + +namespace TagLib { + namespace ID3v1 { + + typedef Map GenreMap; + + /*! + * Returns the list of canonical ID3v1 genre names in the order that they + * are listed in the standard. + */ + StringList TAGLIB_EXPORT genreList(); + + /*! + * A "reverse mapping" that goes from the canonical ID3v1 genre name to the + * respective genre number. genreMap()["Rock"] == + */ + GenreMap TAGLIB_EXPORT genreMap(); + + /*! + * Returns the name of the genre at \a index in the ID3v1 genre list. If + * \a index is out of range -- less than zero or greater than 191 -- a null + * string will be returned. + */ + String TAGLIB_EXPORT genre(int index); + + /*! + * Returns the genre index for the (case sensitive) genre \a name. If the + * genre is not in the list 255 (which signifies an unknown genre in ID3v1) + * will be returned. + */ + int TAGLIB_EXPORT genreIndex(const String &name); + } +} + +#endif diff --git a/taglib/include/taglib/id3v1tag.h b/taglib/include/taglib/id3v1tag.h new file mode 100644 index 0000000..b61f06a --- /dev/null +++ b/taglib/include/taglib/id3v1tag.h @@ -0,0 +1,202 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V1TAG_H +#define TAGLIB_ID3V1TAG_H + +#include "tag.h" +#include "tbytevector.h" +#include "taglib_export.h" + +namespace TagLib { + + class File; + + //! An ID3v1 implementation + + namespace ID3v1 { + + //! A abstraction for the string to data encoding in ID3v1 tags. + + /*! + * ID3v1 should in theory always contain ISO-8859-1 (Latin1) data. In + * practice it does not. TagLib by default only supports ISO-8859-1 data + * in ID3v1 tags. + * + * However by subclassing this class and reimplementing parse() and render() + * and setting your reimplementation as the default with + * ID3v1::Tag::setStringHandler() you can define how you would like these + * transformations to be done. + * + * \warning It is advisable not to write non-ISO-8859-1 data to ID3v1 + * tags. Please consider disabling the writing of ID3v1 tags in the case + * that the data is not ISO-8859-1. + * + * \see ID3v1::Tag::setStringHandler() + */ + + class TAGLIB_EXPORT StringHandler + { + TAGLIB_IGNORE_MISSING_DESTRUCTOR + public: + // BIC: Add virtual destructor. + StringHandler(); + + /*! + * Decode a string from \a data. The default implementation assumes that + * \a data is an ISO-8859-1 (Latin1) character array. + */ + virtual String parse(const ByteVector &data) const; + + /*! + * Encode a ByteVector with the data from \a s. The default implementation + * assumes that \a s is an ISO-8859-1 (Latin1) string. If the string is + * does not conform to ISO-8859-1, no value is written. + * + * \warning It is recommended that you not override this method, but + * instead do not write an ID3v1 tag in the case that the data is not + * ISO-8859-1. + */ + virtual ByteVector render(const String &s) const; + }; + + //! The main class in the ID3v1 implementation + + /*! + * This is an implementation of the ID3v1 format. ID3v1 is both the simplest + * and most common of tag formats but is rather limited. Because of its + * pervasiveness and the way that applications have been written around the + * fields that it provides, the generic TagLib::Tag API is a mirror of what is + * provided by ID3v1. + * + * ID3v1 tags should generally only contain Latin1 information. However because + * many applications do not follow this rule there is now support for overriding + * the ID3v1 string handling using the ID3v1::StringHandler class. Please see + * the documentation for that class for more information. + * + * \see StringHandler + * + * \note Most fields are truncated to a maximum of 28-30 bytes. The + * truncation happens automatically when the tag is rendered. + */ + + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + /*! + * Create an ID3v1 tag with default values. + */ + Tag(); + + /*! + * Create an ID3v1 tag and parse the data in \a file starting at + * \a tagOffset. + */ + Tag(File *file, long tagOffset); + + /*! + * Destroys this Tag instance. + */ + virtual ~Tag(); + + /*! + * Renders the in memory values to a ByteVector suitable for writing to + * the file. + */ + ByteVector render() const; + + /*! + * Returns the string "TAG" suitable for usage in locating the tag in a + * file. + */ + static ByteVector fileIdentifier(); + + // Reimplementations. + + virtual String title() const; + virtual String artist() const; + virtual String album() const; + virtual String comment() const; + virtual String genre() const; + virtual unsigned int year() const; + virtual unsigned int track() const; + + virtual void setTitle(const String &s); + virtual void setArtist(const String &s); + virtual void setAlbum(const String &s); + virtual void setComment(const String &s); + virtual void setGenre(const String &s); + virtual void setYear(unsigned int i); + virtual void setTrack(unsigned int i); + + /*! + * Returns the genre in number. + * + * \note Normally 255 indicates that this tag contains no genre. + */ + unsigned int genreNumber() const; + + /*! + * Sets the genre in number to \a i. + * + * \note Valid value is from 0 up to 255. Normally 255 indicates that + * this tag contains no genre. + */ + void setGenreNumber(unsigned int i); + + /*! + * Sets the string handler that decides how the ID3v1 data will be + * converted to and from binary data. + * If the parameter \a handler is null, the previous handler is + * released and default ISO-8859-1 handler is restored. + * + * \note The caller is responsible for deleting the previous handler + * as needed after it is released. + * + * \see StringHandler + */ + static void setStringHandler(const StringHandler *handler); + + protected: + /*! + * Reads from the file specified in the constructor. + */ + void read(); + /*! + * Pareses the body of the tag in \a data. + */ + void parse(const ByteVector &data); + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/id3v2.h b/taglib/include/taglib/id3v2.h new file mode 100644 index 0000000..bef8251 --- /dev/null +++ b/taglib/include/taglib/id3v2.h @@ -0,0 +1,24 @@ +#ifndef TAGLIB_ID3V2_H +#define TAGLIB_ID3V2_H + +namespace TagLib { + //! An ID3v2 implementation + + /*! + * This is a relatively complete and flexible framework for working with ID3v2 + * tags. + * + * \see ID3v2::Tag + */ + namespace ID3v2 { + /*! + * Used to specify which version of the ID3 standard to use when saving tags. + */ + enum Version { + v3 = 3, //3.2) + */ + + class TAGLIB_EXPORT ExtendedHeader + { + public: + /*! + * Constructs an empty ID3v2 extended header. + */ + ExtendedHeader(); + + /*! + * Destroys the extended header. + */ + virtual ~ExtendedHeader(); + + /*! + * Returns the size of the extended header. This is variable for the + * extended header. + */ + unsigned int size() const; + + /*! + * Sets the data that will be used as the extended header. Since the + * length is not known before the extended header has been parsed, this + * should just be a pointer to the first byte of the extended header. It + * will determine the length internally and make that available through + * size(). + */ + void setData(const ByteVector &data); + + protected: + /*! + * Called by setData() to parse the extended header data. It makes this + * information available through the public API. + */ + void parse(const ByteVector &data); + + private: + ExtendedHeader(const ExtendedHeader &); + ExtendedHeader &operator=(const ExtendedHeader &); + + class ExtendedHeaderPrivate; + ExtendedHeaderPrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/id3v2footer.h b/taglib/include/taglib/id3v2footer.h new file mode 100644 index 0000000..5eb3800 --- /dev/null +++ b/taglib/include/taglib/id3v2footer.h @@ -0,0 +1,82 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V2FOOTER_H +#define TAGLIB_ID3V2FOOTER_H + +#include "taglib_export.h" +#include "tbytevector.h" + +namespace TagLib { + + namespace ID3v2 { + + class Header; + + //! ID3v2 footer implementation + + /*! + * Per the ID3v2 specification, the tag's footer is just a copy of the + * information in the header. As such there is no API for reading the + * data from the header, it can just as easily be done from the header. + * + * In fact, at this point, TagLib does not even parse the footer since + * it is not useful internally. However, if the flag to include a footer + * has been set in the ID3v2::Tag, TagLib will render a footer. + */ + + class TAGLIB_EXPORT Footer + { + public: + /*! + * Constructs an empty ID3v2 footer. + */ + Footer(); + /*! + * Destroys the footer. + */ + virtual ~Footer(); + + /*! + * Returns the size of the footer. Presently this is always 10 bytes. + */ + static unsigned int size(); + + /*! + * Renders the footer based on the data in \a header. + */ + ByteVector render(const Header *header) const; + + private: + Footer(const Footer &); + Footer &operator=(const Footer &); + + class FooterPrivate; + FooterPrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/id3v2frame.h b/taglib/include/taglib/id3v2frame.h new file mode 100644 index 0000000..b14f6f4 --- /dev/null +++ b/taglib/include/taglib/id3v2frame.h @@ -0,0 +1,521 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V2FRAME_H +#define TAGLIB_ID3V2FRAME_H + +#include "tstring.h" +#include "tbytevector.h" +#include "taglib_export.h" + +namespace TagLib { + + class StringList; + class PropertyMap; + + namespace ID3v2 { + + class Tag; + class FrameFactory; + + //! ID3v2 frame implementation + + /*! + * This class is the main ID3v2 frame implementation. In ID3v2, a tag is + * split between a collection of frames (which are in turn split into fields + * (Structure, 4) + * (Frames). This class provides an API for + * gathering information about and modifying ID3v2 frames. Functionality + * specific to a given frame type is handed in one of the many subclasses. + */ + + class TAGLIB_EXPORT Frame + { + friend class Tag; + friend class FrameFactory; + + public: + + /*! + * Creates a textual frame which corresponds to a single key in the PropertyMap + * interface. These are all (User)TextIdentificationFrames except TIPL and TMCL, + * all (User)URLLinkFrames, CommentsFrames, and UnsynchronizedLyricsFrame. + */ + static Frame *createTextualFrame(const String &key, const StringList &values); + + /*! + * Destroys this Frame instance. + */ + virtual ~Frame(); + + /*! + * Returns the Frame ID (Structure, 4) + * (Frames, 4) + */ + ByteVector frameID() const; + + /*! + * Returns the size of the frame. + */ + unsigned int size() const; + + /*! + * Returns the size of the frame header + * + * \deprecated This is only accurate for ID3v2.3 or ID3v2.4. Please use + * the call below which accepts an ID3v2 version number. In the next + * non-binary compatible release this will be made into a non-static + * member that checks the internal ID3v2 version. + */ + static unsigned int headerSize(); // BIC: make non-static + + /*! + * Returns the size of the frame header for the given ID3v2 version. + * + * \deprecated Please see the explanation above. + */ + // BIC: remove + static unsigned int headerSize(unsigned int version); + + /*! + * Sets the data that will be used as the frame. Since the length is not + * known before the frame has been parsed, this should just be a pointer to + * the first byte of the frame. It will determine the length internally + * and make that available through size(). + */ + void setData(const ByteVector &data); + + /*! + * Set the text of frame in the sanest way possible. This should only be + * reimplemented in frames where there is some logical mapping to text. + * + * \note If the frame type supports multiple text encodings, this will not + * change the text encoding of the frame; the string will be converted to + * that frame's encoding. Please use the specific APIs of the frame types + * to set the encoding if that is desired. + */ + virtual void setText(const String &text); + + /*! + * This returns the textual representation of the data in the frame. + * Subclasses must reimplement this method to provide a string + * representation of the frame's data. + */ + virtual String toString() const = 0; + + /*! + * Render the frame back to its binary format in a ByteVector. + */ + ByteVector render() const; + + /*! + * Returns the text delimiter that is used between fields for the string + * type \a t. + */ + static ByteVector textDelimiter(String::Type t); + + /*! + * The string with which an instrument name is prefixed to build a key in a PropertyMap; + * used to translate PropertyMaps to TMCL frames. In the current implementation, this + * is "PERFORMER:". + */ + static const String instrumentPrefix; + /*! + * The PropertyMap key prefix which triggers the use of a COMM frame instead of a TXXX + * frame for a non-standard key. In the current implementation, this is "COMMENT:". + */ + static const String commentPrefix; + /*! + * The PropertyMap key prefix which triggers the use of a USLT frame instead of a TXXX + * frame for a non-standard key. In the current implementation, this is "LYRICS:". + */ + static const String lyricsPrefix; + /*! + * The PropertyMap key prefix which triggers the use of a WXXX frame instead of a TXX + * frame for a non-standard key. In the current implementation, this is "URL:". + */ + static const String urlPrefix; + + protected: + class Header; + + /*! + * Constructs an ID3v2 frame using \a data to read the header information. + * All other processing of \a data should be handled in a subclass. + * + * \note This need not contain anything more than a frame ID, but + * \e must contain at least that. + */ + explicit Frame(const ByteVector &data); + + /*! + * This creates an Frame using the header \a h. + * + * The ownership of this header will be assigned to the frame and the + * header will be deleted when the frame is destroyed. + */ + Frame(Header *h); + + /*! + * Returns a pointer to the frame header. + */ + Header *header() const; + + /*! + * Sets the header to \a h. If \a deleteCurrent is true, this will free + * the memory of the current header. + * + * The ownership of this header will be assigned to the frame and the + * header will be deleted when the frame is destroyed. + */ + void setHeader(Header *h, bool deleteCurrent = true); + + /*! + * Called by setData() to parse the frame data. It makes this information + * available through the public API. + */ + void parse(const ByteVector &data); + + /*! + * Called by parse() to parse the field data. It makes this information + * available through the public API. This must be overridden by the + * subclasses. + */ + virtual void parseFields(const ByteVector &data) = 0; + + /*! + * Render the field data back to a binary format in a ByteVector. This + * must be overridden by subclasses. + */ + virtual ByteVector renderFields() const = 0; + + /*! + * Returns a ByteVector containing the field data given the frame data. + * This correctly adjusts for the header size plus any additional frame + * data that's specified in the frame header flags. + */ + ByteVector fieldData(const ByteVector &frameData) const; + + /*! + * Reads a String of type \a encoding from the ByteVector \a data. If \a + * position is passed in it is used both as the starting point and is + * updated to return the position just after the string that has been read. + * This is useful for reading strings sequentially. + */ + String readStringField(const ByteVector &data, String::Type encoding, + int *position = 0); + + /*! + * Checks a the list of string values to see if they can be used with the + * specified encoding and returns the recommended encoding. + */ + // BIC: remove and make non-static + static String::Type checkEncoding(const StringList &fields, + String::Type encoding); + + /*! + * Checks a the list of string values to see if they can be used with the + * specified encoding and returns the recommended encoding. This method + * also checks the ID3v2 version and makes sure the encoding can be used + * in the specified version. + */ + // BIC: remove and make non-static + static String::Type checkEncoding(const StringList &fields, + String::Type encoding, unsigned int version); + + /*! + * Checks a the list of string values to see if they can be used with the + * specified encoding and returns the recommended encoding. This method + * also checks the ID3v2 version and makes sure the encoding can be used + * in the version specified by the frame's header. + */ + String::Type checkTextEncoding(const StringList &fields, + String::Type encoding) const; + + + /*! + * Parses the contents of this frame as PropertyMap. If that fails, the returned + * PropertyMap will be empty, and its unsupportedData() will contain this frame's + * ID. + * BIC: Will be a virtual function in future releases. + */ + PropertyMap asProperties() const; + + /*! + * Returns an appropriate ID3 frame ID for the given free-form tag key. This method + * will return an empty ByteVector if no specialized translation is found. + */ + static ByteVector keyToFrameID(const String &); + + /*! + * Returns a free-form tag name for the given ID3 frame ID. Note that this does not work + * for general frame IDs such as TXXX or WXXX; in such a case an empty string is returned. + */ + static String frameIDToKey(const ByteVector &); + + /*! + * Returns an appropriate TXXX frame description for the given free-form tag key. + */ + static String keyToTXXX(const String &); + + /*! + * Returns a free-form tag name for the given ID3 frame description. + */ + static String txxxToKey(const String &); + + /*! + * This helper function splits the PropertyMap \a original into three ProperytMaps + * \a singleFrameProperties, \a tiplProperties, and \a tmclProperties, such that: + * - \a singleFrameProperties contains only of keys which can be represented with + * exactly one ID3 frame per key. In the current implementation + * this is everything except for the fixed "involved people" keys and keys of the + * form "TextIdentificationFrame::instrumentPrefix" + "instrument", which are + * mapped to a TMCL frame. + * - \a tiplProperties will consist of those keys that are present in + * TextIdentificationFrame::involvedPeopleMap() + * - \a tmclProperties contains the "musician credits" keys which should be mapped + * to a TMCL frame + */ + static void splitProperties(const PropertyMap &original, PropertyMap &singleFrameProperties, + PropertyMap &tiplProperties, PropertyMap &tmclProperties); + + private: + Frame(const Frame &); + Frame &operator=(const Frame &); + + class FramePrivate; + friend class FramePrivate; + FramePrivate *d; + }; + + //! ID3v2 frame header implementation + + /*! + * The ID3v2 Frame Header (Structure, 4) + * + * Every ID3v2::Frame has an associated header that gives some general + * properties of the frame and also makes it possible to identify the frame + * type. + * + * As such when reading an ID3v2 tag ID3v2::FrameFactory first creates the + * frame headers and then creates the appropriate Frame subclass based on + * the type and attaches the header. + */ + + class TAGLIB_EXPORT Frame::Header + { + public: + /*! + * Construct a Frame Header based on \a data. \a data must at least + * contain a 4 byte frame ID, and optionally can contain flag data and the + * frame size. i.e. Just the frame id -- "TALB" -- is a valid value. + * + * \deprecated Please use the constructor below that accepts a version + * number. + */ + TAGLIB_DEPRECATED Header(const ByteVector &data, bool synchSafeInts); + + /*! + * Construct a Frame Header based on \a data. \a data must at least + * contain a 4 byte frame ID, and optionally can contain flag data and the + * frame size. i.e. Just the frame id -- "TALB" -- is a valid value. + * + * \a version should be the ID3v2 version of the tag. + */ + explicit Header(const ByteVector &data, unsigned int version = 4); + + /*! + * Destroys this Header instance. + */ + virtual ~Header(); + + /*! + * Sets the data for the Header. + * + * \deprecated Please use the version below that accepts an ID3v2 version + * number. + */ + TAGLIB_DEPRECATED void setData(const ByteVector &data, bool synchSafeInts); + + /*! + * Sets the data for the Header. \a version should indicate the ID3v2 + * version number of the tag that this frame is contained in. + */ + void setData(const ByteVector &data, unsigned int version = 4); + + /*! + * Returns the Frame ID (Structure, 4) + * (Frames, 4) + */ + ByteVector frameID() const; + + /*! + * Sets the frame's ID to \a id. Only the first four bytes of \a id will + * be used. + * + * \warning This method should in general be avoided. It exists simply to + * provide a mechanism for transforming frames from a deprecated frame type + * to a newer one -- i.e. TYER to TDRC from ID3v2.3 to ID3v2.4. + */ + void setFrameID(const ByteVector &id); + + /*! + * Returns the size of the frame data portion, as set when setData() was + * called or set explicitly via setFrameSize(). + */ + unsigned int frameSize() const; + + /*! + * Sets the size of the frame data portion. + */ + void setFrameSize(unsigned int size); + + /*! + * Returns the ID3v2 version of the header, as passed in from the + * construction of the header or set via setVersion(). + */ + unsigned int version() const; + + /*! + * Sets the ID3v2 version of the header, changing has impact on the + * correct parsing/rendering of frame data. + */ + void setVersion(unsigned int version); + + /*! + * Returns the size of the frame header in bytes. + * + * \deprecated Please use the version of this method that accepts a + * version. This is only accurate for ID3v2.3 and ID3v2.4. This will be + * removed in the next binary incompatible release (2.0) and will be + * replaced with a non-static method that checks the frame version. + */ + // BIC: make non-static + static unsigned int size(); + + /*! + * Returns the size of the frame header in bytes for the ID3v2 version + * that's given. + * + * \deprecated Please see the explanation in the version above. + */ + // BIC: remove + static unsigned int size(unsigned int version); + + /*! + * Returns true if the flag for tag alter preservation is set. + * + * The semantics are a little backwards from what would seem natural + * (setting the preservation flag to throw away the frame), but this + * follows the ID3v2 standard. + * + * \see setTagAlterPreservation() + */ + bool tagAlterPreservation() const; + + /*! + * Sets the flag for preservation of this frame if the tag is set. If + * this is set to true the frame will not be written when the tag is + * saved. + * + * The semantics are a little backwards from what would seem natural + * (setting the preservation flag to throw away the frame), but this + * follows the ID3v2 standard. + * + * \see tagAlterPreservation() + */ + void setTagAlterPreservation(bool discard); + + /*! + * Returns true if the flag for file alter preservation is set. + * + * \note This flag is currently ignored internally in TagLib. + */ + bool fileAlterPreservation() const; + + /*! + * Returns true if the frame is meant to be read only. + * + * \note This flag is currently ignored internally in TagLib. + */ + bool readOnly() const; + + /*! + * Returns true if the flag for the grouping identity is set. + * + * \note This flag is currently ignored internally in TagLib. + */ + bool groupingIdentity() const; + + /*! + * Returns true if compression is enabled for this frame. + * + * \note This flag is currently ignored internally in TagLib. + */ + bool compression() const; + + /*! + * Returns true if encryption is enabled for this frame. + * + * \note This flag is currently ignored internally in TagLib. + */ + bool encryption() const; + +#ifndef DO_NOT_DOCUMENT + bool unsycronisation() const; +#endif + + /*! + * Returns true if unsynchronisation is enabled for this frame. + */ + bool unsynchronisation() const; + + /*! + * Returns true if the flag for a data length indicator is set. + */ + bool dataLengthIndicator() const; + + /*! + * Render the Header back to binary format in a ByteVector. + */ + ByteVector render() const; + + /*! + * \deprecated + */ + TAGLIB_DEPRECATED bool frameAlterPreservation() const; + + private: + Header(const Header &); + Header &operator=(const Header &); + + class HeaderPrivate; + HeaderPrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/id3v2framefactory.h b/taglib/include/taglib/id3v2framefactory.h new file mode 100644 index 0000000..9605c78 --- /dev/null +++ b/taglib/include/taglib/id3v2framefactory.h @@ -0,0 +1,169 @@ + /*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V2FRAMEFACTORY_H +#define TAGLIB_ID3V2FRAMEFACTORY_H + +#include "taglib_export.h" +#include "tbytevector.h" +#include "id3v2frame.h" +#include "id3v2header.h" + +namespace TagLib { + + namespace ID3v2 { + + class TextIdentificationFrame; + + //! A factory for creating ID3v2 frames during parsing + + /*! + * This factory abstracts away the frame creation process and instantiates + * the appropriate ID3v2::Frame subclasses based on the contents of the + * data. + * + * Reimplementing this factory is the key to adding support for frame types + * not directly supported by TagLib to your application. To do so you would + * subclass this factory and reimplement createFrame(). Then by setting your + * factory to be the default factory in ID3v2::Tag constructor you can + * implement behavior that will allow for new ID3v2::Frame subclasses (also + * provided by you) to be used. + * + * This implements both abstract factory and singleton patterns + * of which more information is available on the web and in software design + * textbooks (Notably Design Patters). + * + * \note You do not need to use this factory to create new frames to add to + * an ID3v2::Tag. You can instantiate frame subclasses directly (with new) + * and add them to a tag using ID3v2::Tag::addFrame() + * + * \see ID3v2::Tag::addFrame() + */ + + class TAGLIB_EXPORT FrameFactory + { + public: + static FrameFactory *instance(); + /*! + * Create a frame based on \a data. \a synchSafeInts should only be set + * false if we are parsing an old tag (v2.3 or older) that does not support + * synchsafe ints. + * + * \deprecated Please use the method below that accepts a ID3v2::Header + * instance in new code. + */ + TAGLIB_DEPRECATED Frame *createFrame(const ByteVector &data, bool synchSafeInts) const; + + /*! + * Create a frame based on \a data. \a version should indicate the ID3v2 + * version of the tag. As ID3v2.4 is the most current version of the + * standard 4 is the default. + * + * \deprecated Please use the method below that accepts a ID3v2::Header + * instance in new code. + */ + TAGLIB_DEPRECATED Frame *createFrame(const ByteVector &data, unsigned int version = 4) const; + + /*! + * \deprecated + */ + // BIC: remove + Frame *createFrame(const ByteVector &data, Header *tagHeader) const; + /*! + * Create a frame based on \a data. \a tagHeader should be a valid + * ID3v2::Header instance. + */ + // BIC: make virtual + Frame *createFrame(const ByteVector &data, const Header *tagHeader) const; + + /*! + * After a tag has been read, this tries to rebuild some of them + * information, most notably the recording date, from frames that + * have been deprecated and can't be upgraded directly. + */ + // BIC: Make virtual + void rebuildAggregateFrames(ID3v2::Tag *tag) const; + + /*! + * Returns the default text encoding for text frames. If setTextEncoding() + * has not been explicitly called this will only be used for new text + * frames. However, if this value has been set explicitly all frames will be + * converted to this type (unless it's explicitly set differently for the + * individual frame) when being rendered. + * + * \see setDefaultTextEncoding() + */ + String::Type defaultTextEncoding() const; + + /*! + * Set the default text encoding for all text frames that are created to + * \a encoding. If no value is set the frames with either default to the + * encoding type that was parsed and new frames default to Latin1. + * + * Valid string types for ID3v2 tags are Latin1, UTF8, UTF16 and UTF16BE. + * + * \see defaultTextEncoding() + */ + void setDefaultTextEncoding(String::Type encoding); + + protected: + /*! + * Constructs a frame factory. Because this is a singleton this method is + * protected, but may be used for subclasses. + */ + FrameFactory(); + + /*! + * Destroys the frame factory. + */ + virtual ~FrameFactory(); + + /*! + * This method checks for compliance to the current ID3v2 standard (2.4) + * and does nothing in the common case. However if a frame is found that + * is not compatible with the current standard, this method either updates + * the frame or indicates that it should be discarded. + * + * This method with return true (with or without changes to the frame) if + * this frame should be kept or false if it should be discarded. + * + * See the id3v2.4.0-changes.txt document for further information. + */ + virtual bool updateFrame(Frame::Header *header) const; + + private: + FrameFactory(const FrameFactory &); + FrameFactory &operator=(const FrameFactory &); + + static FrameFactory factory; + + class FrameFactoryPrivate; + FrameFactoryPrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/id3v2header.h b/taglib/include/taglib/id3v2header.h new file mode 100644 index 0000000..a1f2985 --- /dev/null +++ b/taglib/include/taglib/id3v2header.h @@ -0,0 +1,176 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V2HEADER_H +#define TAGLIB_ID3V2HEADER_H + +#include "tbytevector.h" +#include "taglib_export.h" +#include "id3v2.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An implementation of ID3v2 headers + + /*! + * This class implements ID3v2 headers. It attempts to follow, both + * semantically and programmatically, the structure specified in + * the ID3v2 standard. The API is based on the properties of ID3v2 headers + * specified there. If any of the terms used in this documentation are + * unclear please check the specification in the linked section. + * (Structure, 3.1) + */ + + class TAGLIB_EXPORT Header + { + public: + /*! + * Constructs an empty ID3v2 header. + */ + Header(); + + /*! + * Constructs an ID3v2 header based on \a data. parse() is called + * immediately. + */ + Header(const ByteVector &data); + + /*! + * Destroys the header. + */ + virtual ~Header(); + + /*! + * Returns the major version number. (Note: This is the 4, not the 2 in + * ID3v2.4.0. The 2 is implied.) + */ + unsigned int majorVersion() const; + + /*! + * Set the the major version number to \a version. (Note: This is + * the 4, not the 2 in ID3v2.4.0. The 2 is implied.) + * \see majorVersion() + * + * \note This is used by the internal parser; this will not change the + * version which is written and in general should not be called by API + * users. + */ + void setMajorVersion(unsigned int version); + + /*! + * Returns the revision number. (Note: This is the 0, not the 4 in + * ID3v2.4.0. The 2 is implied.) + */ + unsigned int revisionNumber() const; + + /*! + * Returns true if unsynchronisation has been applied to all frames. + */ + bool unsynchronisation() const; + + /*! + * Returns true if an extended header is present in the tag. + */ + bool extendedHeader() const; + + /*! + * Returns true if the experimental indicator flag is set. + */ + bool experimentalIndicator() const; + + /*! + * Returns true if a footer is present in the tag. + */ + bool footerPresent() const; + /*! + * Returns the tag size in bytes. This is the size of the frame content. + * The size of the \e entire tag will be this plus the header size (10 + * bytes) and, if present, the footer size (potentially another 10 bytes). + * + * \note This is the value as read from the header to which TagLib attempts + * to provide an API to; it was not a design decision on the part of TagLib + * to not include the mentioned portions of the tag in the \e size. + * + * \see completeTagSize() + */ + unsigned int tagSize() const; + + /*! + * Returns the tag size, including the header and, if present, the footer + * size. + * + * \see tagSize() + */ + unsigned int completeTagSize() const; + + /*! + * Set the tag size to \a s. + * \see tagSize() + */ + void setTagSize(unsigned int s); + + /*! + * Returns the size of the header. Presently this is always 10 bytes. + */ + static unsigned int size(); + + /*! + * Returns the string used to identify and ID3v2 tag inside of a file. + * Presently this is always "ID3". + */ + static ByteVector fileIdentifier(); + + /*! + * Sets the data that will be used as the header. 10 bytes, starting from + * the beginning of \a data are used. + */ + void setData(const ByteVector &data); + + /*! + * Renders the Header back to binary format. + */ + ByteVector render() const; + + protected: + /*! + * Called by setData() to parse the header data. It makes this information + * available through the public API. + */ + void parse(const ByteVector &data); + + private: + Header(const Header &); + Header &operator=(const Header &); + + class HeaderPrivate; + HeaderPrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/id3v2synchdata.h b/taglib/include/taglib/id3v2synchdata.h new file mode 100644 index 0000000..13e0716 --- /dev/null +++ b/taglib/include/taglib/id3v2synchdata.h @@ -0,0 +1,70 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V2SYNCHDATA_H +#define TAGLIB_ID3V2SYNCHDATA_H + +#include "tbytevector.h" +#include "taglib.h" + +namespace TagLib { + + namespace ID3v2 { + + //! A few functions for ID3v2 synch safe integer conversion + + /*! + * In the ID3v2.4 standard most integer values are encoded as "synch safe" + * integers which are encoded in such a way that they will not give false + * MPEG syncs and confuse MPEG decoders. This namespace provides some + * methods for converting to and from these values to ByteVectors for + * things rendering and parsing ID3v2 data. + */ + + namespace SynchData + { + /*! + * This returns the unsigned integer value of \a data where \a data is a + * ByteVector that contains a \e synchsafe integer (Structure, + * 6.2). The default \a length of + * 4 is used if another value is not specified. + */ + TAGLIB_EXPORT unsigned int toUInt(const ByteVector &data); + + /*! + * Returns a 4 byte (32 bit) synchsafe integer based on \a value. + */ + TAGLIB_EXPORT ByteVector fromUInt(unsigned int value); + + /*! + * Convert the data from unsynchronized data to its original format. + */ + TAGLIB_EXPORT ByteVector decode(const ByteVector &input); + } + + } +} + +#endif diff --git a/taglib/include/taglib/id3v2tag.h b/taglib/include/taglib/id3v2tag.h new file mode 100644 index 0000000..74d1df1 --- /dev/null +++ b/taglib/include/taglib/id3v2tag.h @@ -0,0 +1,411 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_ID3V2TAG_H +#define TAGLIB_ID3V2TAG_H + +#include "tag.h" +#include "tbytevector.h" +#include "tstring.h" +#include "tlist.h" +#include "tmap.h" +#include "taglib_export.h" + +#include "id3v2.h" +#include "id3v2framefactory.h" + +namespace TagLib { + + class File; + + namespace ID3v2 { + + class Header; + class ExtendedHeader; + class Footer; + + typedef List FrameList; + typedef Map FrameListMap; + + //! An abstraction for the ISO-8859-1 string to data encoding in ID3v2 tags. + + /*! + * ID3v2 tag can store strings in ISO-8859-1 (Latin1), and TagLib only + * supports genuine ISO-8859-1 by default. However, in practice, non + * ISO-8859-1 encodings are often used instead of ISO-8859-1, such as + * Windows-1252 for western languages, Shift_JIS for Japanese and so on. + * + * Here is an option to read such tags by subclassing this class, + * reimplementing parse() and setting your reimplementation as the default + * with ID3v2::Tag::setStringHandler(). + * + * \note Writing non-ISO-8859-1 tags is not implemented intentionally. + * Use UTF-16 or UTF-8 instead. + * + * \see ID3v2::Tag::setStringHandler() + */ + class TAGLIB_EXPORT Latin1StringHandler + { + public: + Latin1StringHandler(); + virtual ~Latin1StringHandler(); + + /*! + * Decode a string from \a data. The default implementation assumes that + * \a data is an ISO-8859-1 (Latin1) character array. + */ + virtual String parse(const ByteVector &data) const; + }; + + //! The main class in the ID3v2 implementation + + /*! + * This is the main class in the ID3v2 implementation. It serves two + * functions. This first, as is obvious from the public API, is to provide a + * container for the other ID3v2 related classes. In addition, through the + * read() and parse() protected methods, it provides the most basic level of + * parsing. In these methods the ID3v2 tag is extracted from the file and + * split into data components. + * + * ID3v2 tags have several parts, TagLib attempts to provide an interface + * for them all. header(), footer() and extendedHeader() correspond to those + * data structures in the ID3v2 standard and the APIs for the classes that + * they return attempt to reflect this. + * + * Also ID3v2 tags are built up from a list of frames, which are in turn + * have a header and a list of fields. TagLib provides two ways of accessing + * the list of frames that are in a given ID3v2 tag. The first is simply + * via the frameList() method. This is just a list of pointers to the frames. + * The second is a map from the frame type -- i.e. "COMM" for comments -- and + * a list of frames of that type. (In some cases ID3v2 allows for multiple + * frames of the same type, hence this being a map to a list rather than just + * a map to an individual frame.) + * + * More information on the structure of frames can be found in the ID3v2::Frame + * class. + * + * read() and parse() pass binary data to the other ID3v2 class structures, + * they do not handle parsing of flags or fields, for instance. Those are + * handled by similar functions within those classes. + * + * \note All pointers to data structures within the tag will become invalid + * when the tag is destroyed. + * + * \warning Dealing with the nasty details of ID3v2 is not for the faint of + * heart and should not be done without much meditation on the spec. It's + * rather long, but if you're planning on messing with this class and others + * that deal with the details of ID3v2 (rather than the nice, safe, abstract + * TagLib::Tag and friends), it's worth your time to familiarize yourself + * with said spec (which is distributed with the TagLib sources). TagLib + * tries to do most of the work, but with a little luck, you can still + * convince it to generate invalid ID3v2 tags. The APIs for ID3v2 assume a + * working knowledge of ID3v2 structure. You're been warned. + */ + + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + /*! + * Constructs an empty ID3v2 tag. + * + * \note You must create at least one frame for this tag to be valid. + */ + Tag(); + + /*! + * Constructs an ID3v2 tag read from \a file starting at \a tagOffset. + * \a factory specifies which FrameFactory will be used for the + * construction of new frames. + * + * \note You should be able to ignore the \a factory parameter in almost + * all situations. You would want to specify your own FrameFactory + * subclass in the case that you are extending TagLib to support additional + * frame types, which would be incorporated into your factory. + * + * \see FrameFactory + */ + Tag(File *file, long tagOffset, + const FrameFactory *factory = FrameFactory::instance()); + + /*! + * Destroys this Tag instance. + */ + virtual ~Tag(); + + // Reimplementations. + + virtual String title() const; + virtual String artist() const; + virtual String album() const; + virtual String comment() const; + virtual String genre() const; + virtual unsigned int year() const; + virtual unsigned int track() const; + + virtual void setTitle(const String &s); + virtual void setArtist(const String &s); + virtual void setAlbum(const String &s); + virtual void setComment(const String &s); + virtual void setGenre(const String &s); + virtual void setYear(unsigned int i); + virtual void setTrack(unsigned int i); + + virtual bool isEmpty() const; + + /*! + * Returns a pointer to the tag's header. + */ + Header *header() const; + + /*! + * Returns a pointer to the tag's extended header or null if there is no + * extended header. + */ + ExtendedHeader *extendedHeader() const; + + /*! + * Returns a pointer to the tag's footer or null if there is no footer. + * + * \deprecated I don't see any reason to keep this around since there's + * nothing useful to be retrieved from the footer, but well, again, I'm + * prone to change my mind, so this gets to stay around until near a + * release. + */ + TAGLIB_DEPRECATED Footer *footer() const; + + /*! + * Returns a reference to the frame list map. This is an FrameListMap of + * all of the frames in the tag. + * + * This is the most convenient structure for accessing the tag's frames. + * Many frame types allow multiple instances of the same frame type so this + * is a map of lists. In most cases however there will only be a single + * frame of a certain type. + * + * Let's say for instance that you wanted to access the frame for total + * beats per minute -- the TBPM frame. + * + * \code + * TagLib::MPEG::File f("foo.mp3"); + * + * // Check to make sure that it has an ID3v2 tag + * + * if(f.ID3v2Tag()) { + * + * // Get the list of frames for a specific frame type + * + * TagLib::ID3v2::FrameList l = f.ID3v2Tag()->frameListMap()["TBPM"]; + * + * if(!l.isEmpty()) + * std::cout << l.front()->toString() << std::endl; + * } + * + * \endcode + * + * \warning You should not modify this data structure directly, instead + * use addFrame() and removeFrame(). + * + * \see frameList() + */ + const FrameListMap &frameListMap() const; + + /*! + * Returns a reference to the frame list. This is an FrameList of all of + * the frames in the tag in the order that they were parsed. + * + * This can be useful if for example you want iterate over the tag's frames + * in the order that they occur in the tag. + * + * \warning You should not modify this data structure directly, instead + * use addFrame() and removeFrame(). + */ + const FrameList &frameList() const; + + /*! + * Returns the frame list for frames with the id \a frameID or an empty + * list if there are no frames of that type. This is just a convenience + * and is equivalent to: + * + * \code + * frameListMap()[frameID]; + * \endcode + * + * \see frameListMap() + */ + const FrameList &frameList(const ByteVector &frameID) const; + + /*! + * Add a frame to the tag. At this point the tag takes ownership of + * the frame and will handle freeing its memory. + * + * \note Using this method will invalidate any pointers on the list + * returned by frameList() + */ + void addFrame(Frame *frame); + + /*! + * Remove a frame from the tag. If \a del is true the frame's memory + * will be freed; if it is false, it must be deleted by the user. + * + * \note Using this method will invalidate any pointers on the list + * returned by frameList() + */ + void removeFrame(Frame *frame, bool del = true); + + /*! + * Remove all frames of type \a id from the tag and free their memory. + * + * \note Using this method will invalidate any pointers on the list + * returned by frameList() + */ + void removeFrames(const ByteVector &id); + + /*! + * Implements the unified property interface -- export function. + * This function does some work to translate the hard-specified ID3v2 + * frame types into a free-form string-to-stringlist PropertyMap: + * - if ID3v2 frame ID is known by Frame::frameIDToKey(), the returned + * key is used + * - if the frame ID is "TXXX" (user text frame), the description() is + * used as key + * - if the frame ID is "WXXX" (user url frame), + * - if the description is empty or "URL", the key "URL" is used + * - otherwise, the key "URL:" is used; + * - if the frame ID is "COMM" (comments frame), + * - if the description is empty or "COMMENT", the key "COMMENT" + * is used + * - otherwise, the key "COMMENT:" is used; + * - if the frame ID is "USLT" (unsynchronized lyrics), + * - if the description is empty or "LYRICS", the key "LYRICS" is used + * - otherwise, the key "LYRICS:" is used; + * - if the frame ID is "TIPL" (involved peoples list), and if all the + * roles defined in the frame are known in TextIdentificationFrame::involvedPeopleMap(), + * then "=" will be contained in the returned object for each + * - if the frame ID is "TMCL" (musician credit list), then + * "PERFORMER:=" will be contained in the returned + * PropertyMap for each defined musician + * In any other case, the unsupportedData() of the returned object will contain + * the frame's ID and, in case of a frame ID which is allowed to appear more than + * once, the description, separated by a "/". + * + */ + PropertyMap properties() const; + + /*! + * Removes unsupported frames given by \a properties. The elements of + * \a properties must be taken from properties().unsupportedData(); they + * are of one of the following forms: + * - a four-character frame ID, if the ID3 specification allows only one + * frame with that ID (thus, the frame is uniquely determined) + * - frameID + "/" + description(), when the ID is one of "TXXX", "WXXX", + * "COMM", or "USLT", + * - "UNKNOWN/" + frameID, for frames that could not be parsed by TagLib. + * In that case, *all* unknown frames with the given ID will be removed. + */ + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * See the comments in properties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Render the tag back to binary data, suitable to be written to disk. + */ + ByteVector render() const; + + /*! + * \deprecated + */ + TAGLIB_DEPRECATED ByteVector render(int version) const; + + /*! + * Render the tag back to binary data, suitable to be written to disk. + * + * The \a version parameter specifies whether ID3v2.4 (default) or ID3v2.3 + * should be used. + */ + ByteVector render(Version version) const; + + /*! + * Gets the current string handler that decides how the "Latin-1" data + * will be converted to and from binary data. + * + * \see Latin1StringHandler + */ + static Latin1StringHandler const *latin1StringHandler(); + + /*! + * Sets the string handler that decides how the "Latin-1" data will be + * converted to and from binary data. + * If the parameter \a handler is null, the previous handler is + * released and default ISO-8859-1 handler is restored. + * + * \note The caller is responsible for deleting the previous handler + * as needed after it is released. + * + * \see Latin1StringHandler + */ + static void setLatin1StringHandler(const Latin1StringHandler *handler); + + protected: + /*! + * Reads data from the file specified in the constructor. It does basic + * parsing of the data in the largest chunks. It partitions the tag into + * the Header, the body of the tag (which contains the ExtendedHeader and + * frames) and Footer. + */ + void read(); + + /*! + * This is called by read to parse the body of the tag. It determines if an + * extended header exists and adds frames to the FrameListMap. + */ + void parse(const ByteVector &data); + + /*! + * Sets the value of the text frame with the Frame ID \a id to \a value. + * If the frame does not exist, it is created. + */ + void setTextFrame(const ByteVector &id, const String &value); + + /*! + * Downgrade frames from ID3v2.4 (used internally and by default) to ID3v2.3. + */ + void downgradeFrames(FrameList *existingFrames, FrameList *newFrames) const; + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/infotag.h b/taglib/include/taglib/infotag.h new file mode 100644 index 0000000..d1f0297 --- /dev/null +++ b/taglib/include/taglib/infotag.h @@ -0,0 +1,192 @@ +/*************************************************************************** + copyright : (C) 2012 by Tsuda Kageyu + email : tsuda.kageyu@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * 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_INFOTAG_H +#define TAGLIB_INFOTAG_H + +#include "tag.h" +#include "tmap.h" +#include "tstring.h" +#include "tstringlist.h" +#include "tbytevector.h" +#include "taglib_export.h" + +namespace TagLib { + + class File; + + //! A RIFF INFO tag implementation. + namespace RIFF { + namespace Info { + + typedef Map FieldListMap; + + //! A abstraction for the string to data encoding in Info tags. + + /*! + * RIFF INFO tag has no clear definitions about character encodings. + * In practice, local encoding of each system is largely used and UTF-8 is + * popular too. + * + * Here is an option to read and write tags in your preferred encoding + * by subclassing this class, reimplementing parse() and render() and setting + * your reimplementation as the default with Info::Tag::setStringHandler(). + * + * \see ID3v1::Tag::setStringHandler() + */ + + class TAGLIB_EXPORT StringHandler + { + public: + StringHandler(); + ~StringHandler(); + + /*! + * Decode a string from \a data. The default implementation assumes that + * \a data is an UTF-8 character array. + */ + virtual String parse(const ByteVector &data) const; + + /*! + * Encode a ByteVector with the data from \a s. The default implementation + * assumes that \a s is an UTF-8 string. + */ + virtual ByteVector render(const String &s) const; + }; + + //! The main class in the ID3v2 implementation + + /*! + * This is the main class in the INFO tag implementation. RIFF INFO tag is a + * metadata format found in WAV audio and AVI video files. Though it is a part + * of Microsoft/IBM's RIFF specification, the author could not find the official + * documents about it. So, this implementation is referring to unofficial documents + * online and some applications' behaviors especially Windows Explorer. + */ + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + /*! + * Constructs an empty INFO tag. + */ + Tag(); + + /*! + * Constructs an INFO tag read from \a data which is contents of "LIST" chunk. + */ + Tag(const ByteVector &data); + + virtual ~Tag(); + + // Reimplementations + + virtual String title() const; + virtual String artist() const; + virtual String album() const; + virtual String comment() const; + virtual String genre() const; + virtual unsigned int year() const; + virtual unsigned int track() const; + + virtual void setTitle(const String &s); + virtual void setArtist(const String &s); + virtual void setAlbum(const String &s); + virtual void setComment(const String &s); + virtual void setGenre(const String &s); + virtual void setYear(unsigned int i); + virtual void setTrack(unsigned int i); + + virtual bool isEmpty() const; + + /*! + * Returns a copy of the internal fields of the tag. The returned map directly + * reflects the contents of the "INFO" chunk. + * + * \note Modifying this map does not affect the tag's internal data. + * Use setFieldText() and removeField() instead. + * + * \see setFieldText() + * \see removeField() + */ + FieldListMap fieldListMap() const; + + /* + * Gets the value of the field with the ID \a id. + */ + String fieldText(const ByteVector &id) const; + + /* + * Sets the value of the field with the ID \a id to \a s. + * If the field does not exist, it is created. + * If \s is empty, the field is removed. + * + * \note fieldId must be four-byte long pure ASCII string. This function + * performs nothing if fieldId is invalid. + */ + void setFieldText(const ByteVector &id, const String &s); + + /* + * Removes the field with the ID \a id. + */ + void removeField(const ByteVector &id); + + /*! + * Render the tag back to binary data, suitable to be written to disk. + * + * \note Returns empty ByteVector is the tag contains no fields. + */ + ByteVector render() const; + + /*! + * Sets the string handler that decides how the text data will be + * converted to and from binary data. + * If the parameter \a handler is null, the previous handler is + * released and default UTF-8 handler is restored. + * + * \note The caller is responsible for deleting the previous handler + * as needed after it is released. + * + * \see StringHandler + */ + static void setStringHandler(const StringHandler *handler); + + protected: + /*! + * Pareses the body of the tag in \a data. + */ + void parse(const ByteVector &data); + + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; + }} +} + +#endif diff --git a/taglib/include/taglib/itfile.h b/taglib/include/taglib/itfile.h new file mode 100644 index 0000000..19327dc --- /dev/null +++ b/taglib/include/taglib/itfile.h @@ -0,0 +1,109 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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 * + ***************************************************************************/ + +#ifndef TAGLIB_ITFILE_H +#define TAGLIB_ITFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "itproperties.h" + +namespace TagLib { + + namespace IT { + + class TAGLIB_EXPORT File : public Mod::FileBase { + public: + /*! + * Constructs a Impulse Tracker 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 Impulse Tracker 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. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Forwards to Mod::Tag::properties(). + * BIC: will be removed once File::toDict() is made virtual + */ + PropertyMap properties() const; + + /*! + * Forwards to Mod::Tag::setProperties(). + * BIC: will be removed once File::setProperties() is made virtual + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the IT::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + IT::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving Impulse Tracker tags is not supported. + */ + bool save(); + + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/itproperties.h b/taglib/include/taglib/itproperties.h new file mode 100644 index 0000000..be1c9d2 --- /dev/null +++ b/taglib/include/taglib/itproperties.h @@ -0,0 +1,107 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_ITPROPERTIES_H +#define TAGLIB_ITPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + namespace IT { + class TAGLIB_EXPORT Properties : public AudioProperties { + friend class File; + public: + /*! Flag bits. */ + enum { + Stereo = 1, + Vol0MixOptimizations = 2, + UseInstruments = 4, + LinearSlides = 8, + OldEffects = 16, + LinkEffects = 32, + UseMidiPitchController = 64, + RequestEmbeddedMidiConf = 128 + }; + + /*! Special bits. */ + enum { + MessageAttached = 1, + MidiConfEmbedded = 8 + }; + + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int lengthInSeconds() const; + int lengthInMilliseconds() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + unsigned short lengthInPatterns() const; + bool stereo() const; + unsigned short instrumentCount() const; + unsigned short sampleCount() const; + unsigned short patternCount() const; + unsigned short version() const; + unsigned short compatibleVersion() const; + unsigned short flags() const; + unsigned short special() const; + unsigned char globalVolume() const; + unsigned char mixVolume() const; + unsigned char tempo() const; + unsigned char bpmSpeed() const; + unsigned char panningSeparation() const; + unsigned char pitchWheelDepth() const; + + void setChannels(int channels); + void setLengthInPatterns(unsigned short lengthInPatterns); + void setInstrumentCount(unsigned short instrumentCount); + void setSampleCount (unsigned short sampleCount); + void setPatternCount(unsigned short patternCount); + void setVersion (unsigned short version); + void setCompatibleVersion(unsigned short compatibleVersion); + void setFlags (unsigned short flags); + void setSpecial (unsigned short special); + void setGlobalVolume(unsigned char globalVolume); + void setMixVolume (unsigned char mixVolume); + void setTempo (unsigned char tempo); + void setBpmSpeed (unsigned char bpmSpeed); + void setPanningSeparation(unsigned char panningSeparation); + void setPitchWheelDepth (unsigned char pitchWheelDepth); + + private: + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/modfile.h b/taglib/include/taglib/modfile.h new file mode 100644 index 0000000..b66452d --- /dev/null +++ b/taglib/include/taglib/modfile.h @@ -0,0 +1,114 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_MODFILE_H +#define TAGLIB_MODFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "modproperties.h" + +namespace TagLib { + + namespace Mod { + + class TAGLIB_EXPORT File : public TagLib::Mod::FileBase + { + public: + /*! + * Constructs a Protracker 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 Protracker 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. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * Forwards to Mod::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Forwards to Mod::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + /*! + * Returns the Mod::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + Mod::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving Protracker tags is not supported. + */ + bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/modfilebase.h b/taglib/include/taglib/modfilebase.h new file mode 100644 index 0000000..bae9716 --- /dev/null +++ b/taglib/include/taglib/modfilebase.h @@ -0,0 +1,66 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_MODFILEBASE_H +#define TAGLIB_MODFILEBASE_H + +#include "taglib.h" +#include "tfile.h" +#include "tstring.h" +#include "tlist.h" +#include "taglib_export.h" + +#include + +namespace TagLib { + + namespace Mod { + + class TAGLIB_EXPORT FileBase : public TagLib::File + { + protected: + FileBase(FileName file); + FileBase(IOStream *stream); + + void writeString(const String &s, unsigned long size, char padding = 0); + void writeByte(unsigned char byte); + void writeU16L(unsigned short number); + void writeU32L(unsigned long number); + void writeU16B(unsigned short number); + void writeU32B(unsigned long number); + + bool readString(String &s, unsigned long size); + bool readByte(unsigned char &byte); + bool readU16L(unsigned short &number); + bool readU32L(unsigned long &number); + bool readU16B(unsigned short &number); + bool readU32B(unsigned long &number); + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/modproperties.h b/taglib/include/taglib/modproperties.h new file mode 100644 index 0000000..4712294 --- /dev/null +++ b/taglib/include/taglib/modproperties.h @@ -0,0 +1,71 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_MODPROPERTIES_H +#define TAGLIB_MODPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace Mod { + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int lengthInSeconds() const; + int lengthInMilliseconds() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + unsigned int instrumentCount() const; + unsigned char lengthInPatterns() const; + + void setChannels(int channels); + + void setInstrumentCount(unsigned int sampleCount); + void setLengthInPatterns(unsigned char lengthInPatterns); + + private: + friend class File; + + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/modtag.h b/taglib/include/taglib/modtag.h new file mode 100644 index 0000000..dee0661 --- /dev/null +++ b/taglib/include/taglib/modtag.h @@ -0,0 +1,194 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_MODTAG_H +#define TAGLIB_MODTAG_H + +#include "tag.h" + +namespace TagLib { + + namespace Mod { + + /*! + * Tags for module files (Mod, S3M, IT, XM). + * + * Note that only the \a title is supported as such by most + * module file formats. Except for XM files the \a trackerName + * is derived from the file format or the flavour of the file + * format. For XM files it is stored in the file. + * + * The \a comment tag is not strictly supported by module files, + * but it is common practice to abuse instrument/sample/pattern + * names as multiline comments. TagLib does so as well. + */ + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + Tag(); + virtual ~Tag(); + + /*! + * Returns the track name; if no track name is present in the tag + * String::null will be returned. + */ + virtual String title() const; + + /*! + * Not supported by module files. Therefore always returns String::null. + */ + virtual String artist() const; + + /*! + * Not supported by module files. Therefore always returns String::null. + */ + virtual String album() const; + + /*! + * Returns the track comment derived from the instrument/sample/pattern + * names; if no comment is present in the tag String::null will be + * returned. + */ + virtual String comment() const; + + /*! + * Not supported by module files. Therefore always returns String::null. + */ + virtual String genre() const; + + /*! + * Not supported by module files. Therefore always returns 0. + */ + virtual unsigned int year() const; + + /*! + * Not supported by module files. Therefore always returns 0. + */ + virtual unsigned int track() const; + + /*! + * Returns the name of the tracker used to create/edit the module file. + * Only XM files store this tag to the file as such, for other formats + * (Mod, S3M, IT) this is derived from the file type or the flavour of + * the file type. Therefore only XM files might have an empty + * (String::null) tracker name. + */ + String trackerName() const; + + /*! + * Sets the title to \a title. If \a title is String::null then this + * value will be cleared. + * + * The length limits per file type are (1 character = 1 byte): + * Mod 20 characters, S3M 27 characters, IT 25 characters and XM 20 + * characters. + */ + virtual void setTitle(const String &title); + + /*! + * Not supported by module files and therefore ignored. + */ + virtual void setArtist(const String &artist); + + /*! + * Not supported by module files and therefore ignored. + */ + virtual void setAlbum(const String &album); + + /*! + * Sets the comment to \a comment. If \a comment is String::null then + * this value will be cleared. + * + * Note that module file formats don't actually support a comment tag. + * Instead the names of instruments/patterns/samples are abused as + * a multiline comment. Because of this the number of lines in a + * module file is fixed to the number of instruments/patterns/samples. + * + * Also note that the instrument/pattern/sample name length is limited + * an thus the line length in comments are limited. Too big comments + * will be truncated. + * + * The line length limits per file type are (1 character = 1 byte): + * Mod 22 characters, S3M 27 characters, IT 25 characters and XM 22 + * characters. + */ + virtual void setComment(const String &comment); + + /*! + * Not supported by module files and therefore ignored. + */ + virtual void setGenre(const String &genre); + + /*! + * Not supported by module files and therefore ignored. + */ + virtual void setYear(unsigned int year); + + /*! + * Not supported by module files and therefore ignored. + */ + virtual void setTrack(unsigned int track); + + /*! + * Sets the tracker name to \a trackerName. If \a trackerName is + * String::null then this value will be cleared. + * + * Note that only XM files support this tag. Setting the + * tracker name for other module file formats will be ignored. + * + * The length of this tag is limited to 20 characters (1 character + * = 1 byte). + */ + void setTrackerName(const String &trackerName); + + /*! + * Implements the unified property interface -- export function. + * Since the module tag is very limited, the exported map is as well. + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Because of the limitations of the module file tag, any tags besides + * COMMENT, TITLE and, if it is an XM file, TRACKERNAME, will be + * returned. Additionally, if the map contains tags with multiple values, + * all but the first will be contained in the returned map of unsupported + * properties. + */ + PropertyMap setProperties(const PropertyMap &); + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/mp4atom.h b/taglib/include/taglib/mp4atom.h new file mode 100644 index 0000000..cbb0d10 --- /dev/null +++ b/taglib/include/taglib/mp4atom.h @@ -0,0 +1,111 @@ +/************************************************************************** + copyright : (C) 2007,2011 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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/ * + ***************************************************************************/ + +// This file is not part of the public API! + +#ifndef DO_NOT_DOCUMENT + +#ifndef TAGLIB_MP4ATOM_H +#define TAGLIB_MP4ATOM_H + +#include "tfile.h" +#include "tlist.h" + +namespace TagLib { + + namespace MP4 { + + class Atom; + typedef TagLib::List AtomList; + + enum AtomDataType + { + TypeImplicit = 0, // for use with tags for which no type needs to be indicated because only one type is allowed + TypeUTF8 = 1, // without any count or null terminator + TypeUTF16 = 2, // also known as UTF-16BE + TypeSJIS = 3, // deprecated unless it is needed for special Japanese characters + TypeHTML = 6, // the HTML file header specifies which HTML version + TypeXML = 7, // the XML header must identify the DTD or schemas + TypeUUID = 8, // also known as GUID; stored as 16 bytes in binary (valid as an ID) + TypeISRC = 9, // stored as UTF-8 text (valid as an ID) + TypeMI3P = 10, // stored as UTF-8 text (valid as an ID) + TypeGIF = 12, // (deprecated) a GIF image + TypeJPEG = 13, // a JPEG image + TypePNG = 14, // a PNG image + TypeURL = 15, // absolute, in UTF-8 characters + TypeDuration = 16, // in milliseconds, 32-bit integer + TypeDateTime = 17, // in UTC, counting seconds since midnight, January 1, 1904; 32 or 64-bits + TypeGenred = 18, // a list of enumerated values + TypeInteger = 21, // a signed big-endian integer with length one of { 1,2,3,4,8 } bytes + TypeRIAAPA = 24, // RIAA parental advisory; { -1=no, 1=yes, 0=unspecified }, 8-bit integer + TypeUPC = 25, // Universal Product Code, in text UTF-8 format (valid as an ID) + TypeBMP = 27, // Windows bitmap image + TypeUndefined = 255 // undefined + }; + + struct AtomData { + AtomData(AtomDataType type, ByteVector data) : type(type), locale(0), data(data) {} + AtomDataType type; + int locale; + ByteVector data; + }; + + typedef TagLib::List AtomDataList; + + class Atom + { + public: + Atom(File *file); + ~Atom(); + Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0); + bool path(AtomList &path, const char *name1, const char *name2 = 0, const char *name3 = 0); + AtomList findall(const char *name, bool recursive = false); + long offset; + long length; + TagLib::ByteVector name; + AtomList children; + private: + static const int numContainers = 11; + static const char *containers[11]; + }; + + //! Root-level atoms + class Atoms + { + public: + Atoms(File *file); + ~Atoms(); + Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0); + AtomList path(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0); + AtomList atoms; + }; + + } + +} + +#endif + +#endif diff --git a/taglib/include/taglib/mp4coverart.h b/taglib/include/taglib/mp4coverart.h new file mode 100644 index 0000000..ebfb3f9 --- /dev/null +++ b/taglib/include/taglib/mp4coverart.h @@ -0,0 +1,84 @@ +/************************************************************************** + copyright : (C) 2009 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_MP4COVERART_H +#define TAGLIB_MP4COVERART_H + +#include "tlist.h" +#include "tbytevector.h" +#include "taglib_export.h" +#include "mp4atom.h" + +namespace TagLib { + + namespace MP4 { + + class TAGLIB_EXPORT CoverArt + { + public: + /*! + * This describes the image type. + */ + enum Format { + JPEG = TypeJPEG, + PNG = TypePNG, + BMP = TypeBMP, + GIF = TypeGIF, + Unknown = TypeImplicit, + }; + + CoverArt(Format format, const ByteVector &data); + ~CoverArt(); + + CoverArt(const CoverArt &item); + + /*! + * Copies the contents of \a item into this CoverArt. + */ + CoverArt &operator=(const CoverArt &item); + + /*! + * Exchanges the content of the CoverArt by the content of \a item. + */ + void swap(CoverArt &item); + + //! Format of the image + Format format() const; + + //! The image data + ByteVector data() const; + + private: + class CoverArtPrivate; + CoverArtPrivate *d; + }; + + typedef List CoverArtList; + + } + +} + +#endif diff --git a/taglib/include/taglib/mp4file.h b/taglib/include/taglib/mp4file.h new file mode 100644 index 0000000..8a46d17 --- /dev/null +++ b/taglib/include/taglib/mp4file.h @@ -0,0 +1,143 @@ +/************************************************************************** + copyright : (C) 2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_MP4FILE_H +#define TAGLIB_MP4FILE_H + +#include "tag.h" +#include "tfile.h" +#include "taglib_export.h" +#include "mp4properties.h" +#include "mp4tag.h" + +namespace TagLib { + + //! An implementation of MP4 (AAC, ALAC, ...) metadata + namespace MP4 { + + class Atoms; + + /*! + * This implements and provides an interface for MP4 files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to MP4 files. + */ + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * Constructs an MP4 file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle audioPropertiesStyle = Properties::Average); + + /*! + * Constructs an MP4 file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle audioPropertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns a pointer to the MP4 tag of the file. + * + * MP4::Tag implements the tag interface, so this serves as the + * reimplementation of TagLib::File::tag(). + * + * \note The Tag is still owned by the MP4::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + */ + Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties. Forwards to the actual Tag's + * removeUnsupportedProperties() function. + */ + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the MP4 audio properties for this file. + */ + Properties *audioProperties() const; + + /*! + * Save the file. + * + * This returns true if the save was successful. + */ + bool save(); + + /*! + * Returns whether or not the file on disk actually has an MP4 tag, or the + * file has a Metadata Item List (ilst) atom. + */ + bool hasMP4Tag() const; + + /*! + * Returns whether or not the given \a stream can be opened as an ASF + * 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(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/mp4item.h b/taglib/include/taglib/mp4item.h new file mode 100644 index 0000000..3821135 --- /dev/null +++ b/taglib/include/taglib/mp4item.h @@ -0,0 +1,93 @@ +/************************************************************************** + copyright : (C) 2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_MP4ITEM_H +#define TAGLIB_MP4ITEM_H + +#include "tstringlist.h" +#include "mp4coverart.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace MP4 { + + class TAGLIB_EXPORT Item + { + public: + struct IntPair { + int first, second; + }; + + Item(); + Item(const Item &item); + + /*! + * Copies the contents of \a item into this Item. + */ + Item &operator=(const Item &item); + + /*! + * Exchanges the content of the Item by the content of \a item. + */ + void swap(Item &item); + + ~Item(); + + Item(int value); + Item(unsigned char value); + Item(unsigned int value); + Item(long long value); + Item(bool value); + Item(int first, int second); + Item(const StringList &value); + Item(const ByteVectorList &value); + Item(const CoverArtList &value); + + void setAtomDataType(AtomDataType type); + AtomDataType atomDataType() const; + + int toInt() const; + unsigned char toByte() const; + unsigned int toUInt() const; + long long toLongLong() const; + bool toBool() const; + IntPair toIntPair() const; + StringList toStringList() const; + ByteVectorList toByteVectorList() const; + CoverArtList toCoverArtList() const; + + bool isValid() const; + + private: + class ItemPrivate; + ItemPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/mp4properties.h b/taglib/include/taglib/mp4properties.h new file mode 100644 index 0000000..492a48c --- /dev/null +++ b/taglib/include/taglib/mp4properties.h @@ -0,0 +1,120 @@ +/************************************************************************** + copyright : (C) 2007 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_MP4PROPERTIES_H +#define TAGLIB_MP4PROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace MP4 { + + class Atoms; + class File; + + //! An implementation of MP4 audio properties + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + enum Codec { + Unknown = 0, + AAC, + ALAC + }; + + Properties(File *file, Atoms *atoms, ReadStyle style = Average); + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + virtual int bitsPerSample() const; + + /*! + * Returns whether or not the file is encrypted. + */ + bool isEncrypted() const; + + /*! + * Returns the codec used in the file. + */ + Codec codec() const; + + private: + void read(File *file, Atoms *atoms); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/mp4tag.h b/taglib/include/taglib/mp4tag.h new file mode 100644 index 0000000..ccee8e0 --- /dev/null +++ b/taglib/include/taglib/mp4tag.h @@ -0,0 +1,164 @@ +/************************************************************************** + copyright : (C) 2007,2011 by Lukáš Lalinský + email : lalinsky@gmail.com + **************************************************************************/ + +/*************************************************************************** + * 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_MP4TAG_H +#define TAGLIB_MP4TAG_H + +#include "tag.h" +#include "tbytevectorlist.h" +#include "tfile.h" +#include "tmap.h" +#include "tstringlist.h" +#include "taglib_export.h" +#include "mp4atom.h" +#include "mp4item.h" + +namespace TagLib { + + namespace MP4 { + + /*! + * \deprecated + */ + TAGLIB_DEPRECATED typedef TagLib::Map ItemListMap; + typedef TagLib::Map ItemMap; + + class TAGLIB_EXPORT Tag: public TagLib::Tag + { + public: + Tag(); + Tag(TagLib::File *file, Atoms *atoms); + virtual ~Tag(); + bool save(); + + virtual String title() const; + virtual String artist() const; + virtual String album() const; + virtual String comment() const; + virtual String genre() const; + virtual unsigned int year() const; + virtual unsigned int track() const; + + virtual void setTitle(const String &value); + virtual void setArtist(const String &value); + virtual void setAlbum(const String &value); + virtual void setComment(const String &value); + virtual void setGenre(const String &value); + virtual void setYear(unsigned int value); + virtual void setTrack(unsigned int value); + + virtual bool isEmpty() const; + + /*! + * \deprecated Use the item() and setItem() API instead + */ + TAGLIB_DEPRECATED ItemMap &itemListMap(); + + /*! + * Returns a string-keyed map of the MP4::Items for this tag. + */ + const ItemMap &itemMap() const; + + /*! + * \return The item, if any, corresponding to \a key. + */ + Item item(const String &key) const; + + /*! + * Sets the value of \a key to \a value, overwriting any previous value. + */ + void setItem(const String &key, const Item &value); + + /*! + * Removes the entry with \a key from the tag, or does nothing if it does + * not exist. + */ + void removeItem(const String &key); + + /*! + * \return True if the tag contains an entry for \a key. + */ + bool contains(const String &key) const; + + PropertyMap properties() const; + void removeUnsupportedProperties(const StringList& properties); + PropertyMap setProperties(const PropertyMap &properties); + + protected: + /*! + * Sets the value of \a key to \a value, overwriting any previous value. + * If \a value is empty, the item is removed. + */ + void setTextItem(const String &key, const String &value); + + private: + AtomDataList parseData2(const Atom *atom, int expectedFlags = -1, + bool freeForm = false); + ByteVectorList parseData(const Atom *atom, int expectedFlags = -1, + bool freeForm = false); + void parseText(const Atom *atom, int expectedFlags = 1); + void parseFreeForm(const Atom *atom); + void parseInt(const Atom *atom); + void parseByte(const Atom *atom); + void parseUInt(const Atom *atom); + void parseLongLong(const Atom *atom); + void parseGnre(const Atom *atom); + void parseIntPair(const Atom *atom); + void parseBool(const Atom *atom); + void parseCovr(const Atom *atom); + + ByteVector padIlst(const ByteVector &data, int length = -1) const; + ByteVector renderAtom(const ByteVector &name, const ByteVector &data) const; + ByteVector renderData(const ByteVector &name, int flags, + const ByteVectorList &data) const; + ByteVector renderText(const ByteVector &name, const Item &item, + int flags = TypeUTF8) const; + ByteVector renderFreeForm(const String &name, const Item &item) const; + ByteVector renderBool(const ByteVector &name, const Item &item) const; + ByteVector renderInt(const ByteVector &name, const Item &item) const; + ByteVector renderByte(const ByteVector &name, const Item &item) const; + ByteVector renderUInt(const ByteVector &name, const Item &item) const; + ByteVector renderLongLong(const ByteVector &name, const Item &item) const; + ByteVector renderIntPair(const ByteVector &name, const Item &item) const; + ByteVector renderIntPairNoTrailing(const ByteVector &name, const Item &item) const; + ByteVector renderCovr(const ByteVector &name, const Item &item) const; + + void updateParents(const AtomList &path, long delta, int ignore = 0); + void updateOffsets(long delta, long offset); + + void saveNew(ByteVector data); + void saveExisting(ByteVector data, const AtomList &path); + + void addItem(const String &name, const Item &value); + + class TagPrivate; + TagPrivate *d; + }; + + } + +} + +#endif diff --git a/taglib/include/taglib/mpcfile.h b/taglib/include/taglib/mpcfile.h new file mode 100644 index 0000000..eb3ec54 --- /dev/null +++ b/taglib/include/taglib/mpcfile.h @@ -0,0 +1,238 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.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_MPCFILE_H +#define TAGLIB_MPCFILE_H + +#include "taglib_export.h" +#include "tfile.h" +#include "tag.h" + +#include "mpcproperties.h" + +#include "tlist.h" + +namespace TagLib { + + class Tag; + + namespace ID3v1 { class Tag; } + namespace APE { class Tag; } + + //! An implementation of MPC metadata + + /*! + * This is implementation of MPC metadata. + * + * This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream + * properties from the file. ID3v2 tags are invalid in MPC-files, but will be skipped + * and ignored. + */ + + namespace MPC { + + //! An implementation of TagLib::File with MPC specific methods + + /*! + * This implements and provides an interface for MPC files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to MPC files. + * The only invalid tag combination supported is an ID3v1 tag after an APE tag. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v1 tags. + ID3v1 = 0x0001, + //! Matches ID3v2 tags. + ID3v2 = 0x0002, + //! Matches APE tags. + APE = 0x0004, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs an MPC file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an MPC file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag + * or a combination of the two. + */ + virtual TagLib::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only the APE + * tag will be converted to the PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * Affects only the APEv2 tag which will be created if necessary. + * If an ID3v1 tag exists, it will be updated as well. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the MPC::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Saves the file. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this returns a null pointer + * if there is no valid APE tag. If \a create is true it will create + * an APE tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file + * on disk actually has an ID3v1 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v1Tag() + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the APE tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid APE tag. If \a create is true it will create + * an APE tag if one does not exist and returns a valid pointer. If + * there already be an ID3v1 tag, the new APE tag will be placed before it. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an APE tag. Use hasAPETag() to check if the file + * on disk actually has an APE tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasAPETag() + */ + APE::Tag *APETag(bool create = false); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from the + * file. By default it removes all tags. + * + * \warning This will also invalidate pointers to the tags + * as their memory will be freed. + * + * \note In order to make the removal permanent save() still needs to be called. + */ + void strip(int tags = AllTags); + + /*! + * \deprecated + * \see strip + */ + TAGLIB_DEPRECATED void remove(int tags = AllTags); + + /*! + * Returns whether or not the file on disk actually has an ID3v1 tag. + * + * \see ID3v1Tag() + */ + bool hasID3v1Tag() const; + + /*! + * Returns whether or not the file on disk actually has an APE tag. + * + * \see APETag() + */ + bool hasAPETag() const; + + /*! + * Returns whether or not the given \a stream can be opened as an MPC + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/mpcproperties.h b/taglib/include/taglib/mpcproperties.h new file mode 100644 index 0000000..9a902dc --- /dev/null +++ b/taglib/include/taglib/mpcproperties.h @@ -0,0 +1,158 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.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_MPCPROPERTIES_H +#define TAGLIB_MPCPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace MPC { + + class File; + + static const unsigned int HeaderSize = 8 * 7; + + //! An implementation of audio property reading for MPC + + /*! + * This reads the data from an MPC stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of MPC::Properties with the data read from the + * ByteVector \a data. + * + * This constructor is deprecated. It only works for MPC version up to 7. + */ + Properties(const ByteVector &data, long streamLength, ReadStyle style = Average); + + /*! + * Create an instance of MPC::Properties with the data read directly + * from a MPC::File. + */ + Properties(File *file, long streamLength, ReadStyle style = Average); + + /*! + * Destroys this MPC::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the version of the bitstream (SV4-SV8) + */ + int mpcVersion() const; + + unsigned int totalFrames() const; + unsigned int sampleFrames() const; + + /*! + * Returns the track gain as an integer value, + * to convert to dB: trackGain in dB = 64.82 - (trackGain / 256) + */ + int trackGain() const; + + /*! + * Returns the track peak as an integer value, + * to convert to dB: trackPeak in dB = trackPeak / 256 + * to convert to floating [-1..1]: trackPeak = 10^(trackPeak / 256 / 20)/32768 + */ + int trackPeak() const; + + /*! + * Returns the album gain as an integer value, + * to convert to dB: albumGain in dB = 64.82 - (albumGain / 256) + */ + int albumGain() const; + + /*! + * Returns the album peak as an integer value, + * to convert to dB: albumPeak in dB = albumPeak / 256 + * to convert to floating [-1..1]: albumPeak = 10^(albumPeak / 256 / 20)/32768 + */ + int albumPeak() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void readSV7(const ByteVector &data, long streamLength); + void readSV8(File *file, long streamLength); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/mpegfile.h b/taglib/include/taglib/mpegfile.h new file mode 100644 index 0000000..3fcb727 --- /dev/null +++ b/taglib/include/taglib/mpegfile.h @@ -0,0 +1,387 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_MPEGFILE_H +#define TAGLIB_MPEGFILE_H + +#include "taglib_export.h" +#include "tfile.h" +#include "tag.h" + +#include "mpegproperties.h" + +#include "id3v2.h" + +namespace TagLib { + + namespace ID3v2 { class Tag; class FrameFactory; } + namespace ID3v1 { class Tag; } + namespace APE { class Tag; } + + //! An implementation of TagLib::File with MPEG (MP3) specific methods + + namespace MPEG { + + //! An MPEG file class with some useful methods specific to MPEG + + /*! + * This implements the generic TagLib::File API and additionally provides + * access to properties that are distinct to MPEG files, notably access + * to the different ID3 tags. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v1 tags. + ID3v1 = 0x0001, + //! Matches ID3v2 tags. + ID3v2 = 0x0002, + //! Matches APE tags. + APE = 0x0004, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs an MPEG file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + * + * \deprecated This constructor will be dropped in favor of the one below + * in a future version. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an MPEG file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + // BIC: merge with the above constructor + File(FileName file, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an MPEG file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns a pointer to a tag that is the union of the ID3v2 and ID3v1 + * tags. The ID3v2 tag is given priority in reading the information -- if + * requested information exists in both the ID3v2 tag and the ID3v1 tag, + * the information from the ID3v2 tag will be returned. + * + * If you would like more granular control over the content of the tags, + * with the concession of generality, use the tag-type specific calls. + * + * \note As this tag is not implemented as an ID3v2 tag or an ID3v1 tag, + * but a union of the two this pointer may not be cast to the specific + * tag types. + * + * \see ID3v1Tag() + * \see ID3v2Tag() + * \see APETag() + */ + virtual Tag *tag() const; + + /*! + * Implements the reading part of the unified property interface. + * If the file contains more than one tag, only the + * first one (in the order ID3v2, APE, ID3v1) will be converted to the + * PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the writing part of the unified tag dictionary interface. + * In order to avoid problems with deprecated tag formats, this method + * always creates an ID3v2 tag if necessary. + * If an ID3v1 tag exists, it will be updated as well, within the + * limitations of that format. + * The returned PropertyMap refers to the ID3v2 tag only. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the MPEG::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Save the file. If at least one tag -- ID3v1 or ID3v2 -- exists this + * will duplicate its content into the other tag. This returns true + * if saving was successful. + * + * If neither exists or if both tags are empty, this will strip the tags + * from the file. + * + * This is the same as calling save(AllTags); + * + * If you would like more granular control over the content of the tags, + * with the concession of generality, use parameterized save call below. + * + * \see save(int tags) + */ + virtual bool save(); + + /*! + * Save the file. This will attempt to save all of the tag types that are + * specified by OR-ing together TagTypes values. The save() method above + * uses AllTags. This returns true if saving was successful. + * + * This strips all tags not included in the mask, but does not modify them + * in memory, so later calls to save() which make use of these tags will + * remain valid. This also strips empty tags. + */ + bool save(int tags); + + /*! + * \deprecated + */ + // BIC: combine with the above method + TAGLIB_DEPRECATED bool save(int tags, bool stripOthers); + + /*! + * \deprecated + */ + // BIC: combine with the above method + TAGLIB_DEPRECATED bool save(int tags, bool stripOthers, int id3v2Version); + + /*! + * \deprecated + */ + // BIC: combine with the above method + TAGLIB_DEPRECATED bool save(int tags, bool stripOthers, int id3v2Version, bool duplicateTags); + + /*! + * Save the file. This will attempt to save all of the tag types that are + * specified by OR-ing together TagTypes values. + * + * \a strip can be set to strip all tags except those in \a tags. Those + * tags will not be modified in memory, and thus remain valid. + * + * \a version specifies the ID3v2 version to be used for writing tags. By + * default, the latest standard, ID3v2.4 is used. + * + * If \a duplicate is set to DuplicateTags and at least one tag -- ID3v1 + * or ID3v2 -- exists this will duplicate its content into the other tag. + */ + bool save(int tags, StripTags strip, + ID3v2::Version version = ID3v2::v4, + DuplicateTags duplicate = Duplicate); + + /*! + * Returns a pointer to the ID3v2 tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid ID3v2 tag. If \a create is true it will create + * an ID3v2 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v2 tag. Use hasID3v2Tag() to check if the file + * on disk actually has an ID3v2 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v2Tag() + */ + ID3v2::Tag *ID3v2Tag(bool create = false); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid ID3v1 tag. If \a create is true it will create + * an ID3v1 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file + * on disk actually has an ID3v1 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v1Tag() + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the APE tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid APE tag. If \a create is true it will create + * an APE tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an APE tag. Use hasAPETag() to check if the file + * on disk actually has an APE tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasAPETag() + */ + APE::Tag *APETag(bool create = false); + + /*! + * This will strip the tags that match the OR-ed together TagTypes from the + * file. By default it strips all tags. It returns true if the tags are + * successfully stripped. + * + * This is equivalent to strip(tags, true) + * + * \note This will also invalidate pointers to the ID3 and APE tags + * as their memory will be freed. + * + * \note This will update the file immediately. + */ + bool strip(int tags = AllTags); + + /*! + * This will strip the tags that match the OR-ed together TagTypes from the + * file. By default it strips all tags. It returns true if the tags are + * successfully stripped. + * + * If \a freeMemory is true the ID3 and APE tags will be deleted and + * pointers to them will be invalidated. + * + * \note This will update the file immediately. + */ + // BIC: merge with the method above + bool strip(int tags, bool freeMemory); + + /*! + * Set the ID3v2::FrameFactory to something other than the default. + * + * \see ID3v2FrameFactory + * \deprecated This value should be passed in via the constructor + */ + TAGLIB_DEPRECATED void setID3v2FrameFactory(const ID3v2::FrameFactory *factory); + + /*! + * Returns the position in the file of the first MPEG frame. + */ + long firstFrameOffset(); + + /*! + * Returns the position in the file of the next MPEG frame, + * using the current position as start + */ + long nextFrameOffset(long position); + + /*! + * Returns the position in the file of the previous MPEG frame, + * using the current position as start + */ + long previousFrameOffset(long position); + + /*! + * Returns the position in the file of the last MPEG frame. + */ + long lastFrameOffset(); + + /*! + * Returns whether or not the file on disk actually has an ID3v1 tag. + * + * \see ID3v1Tag() + */ + bool hasID3v1Tag() const; + + /*! + * Returns whether or not the file on disk actually has an ID3v2 tag. + * + * \see ID3v2Tag() + */ + bool hasID3v2Tag() const; + + /*! + * Returns whether or not the file on disk actually has an APE tag. + * + * \see APETag() + */ + bool hasAPETag() const; + + /*! + * Returns whether or not the given \a stream can be opened as an MPEG + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + long findID3v2(); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/mpegheader.h b/taglib/include/taglib/mpegheader.h new file mode 100644 index 0000000..ca51184 --- /dev/null +++ b/taglib/include/taglib/mpegheader.h @@ -0,0 +1,178 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_MPEGHEADER_H +#define TAGLIB_MPEGHEADER_H + +#include "taglib_export.h" + +namespace TagLib { + + class ByteVector; + class File; + + namespace MPEG { + + //! An implementation of MP3 frame headers + + /*! + * This is an implementation of MPEG Layer III headers. The API follows more + * or less the binary format of these headers. I've used + * this + * document as a reference. + */ + + class TAGLIB_EXPORT Header + { + public: + /*! + * Parses an MPEG header based on \a data. + * + * \deprecated + */ + TAGLIB_DEPRECATED Header(const ByteVector &data); + + /*! + * Parses an MPEG header based on \a file and \a offset. + * + * \note If \a checkLength is true, this requires the next MPEG frame to + * check if the frame length is parsed and calculated correctly. So it's + * suitable for seeking for the first valid frame. + */ + Header(File *file, long offset, bool checkLength = true); + + /*! + * Does a shallow copy of \a h. + */ + Header(const Header &h); + + /*! + * Destroys this Header instance. + */ + virtual ~Header(); + + /*! + * Returns true if the frame is at least an appropriate size and has + * legal values. + */ + bool isValid() const; + + /*! + * The MPEG Version. + */ + enum Version { + //! MPEG Version 1 + Version1 = 0, + //! MPEG Version 2 + Version2 = 1, + //! MPEG Version 2.5 + Version2_5 = 2 + }; + + /*! + * Returns the MPEG Version of the header. + */ + Version version() const; + + /*! + * Returns the layer version. This will be between the values 1-3. + */ + int layer() const; + + /*! + * Returns true if the MPEG protection bit is enabled. + */ + bool protectionEnabled() const; + + /*! + * Returns the bitrate encoded in the header. + */ + int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + int sampleRate() const; + + /*! + * Returns true if the frame is padded. + */ + bool isPadded() const; + + /*! + * There are a few combinations or one or two channel audio that are + * possible: + */ + enum ChannelMode { + //! Stereo + Stereo = 0, + //! Stereo + JointStereo = 1, + //! Dual Mono + DualChannel = 2, + //! Mono + SingleChannel = 3 + }; + + /*! + * Returns the channel mode for this frame. + */ + ChannelMode channelMode() const; + + /*! + * Returns true if the copyrighted bit is set. + */ + bool isCopyrighted() const; + + /*! + * Returns true if the "original" bit is set. + */ + bool isOriginal() const; + + /*! + * Returns the frame length in bytes. + */ + int frameLength() const; + + /*! + * Returns the number of frames per sample. + */ + int samplesPerFrame() const; + + /*! + * Makes a shallow copy of the header. + */ + Header &operator=(const Header &h); + + private: + void parse(File *file, long offset, bool checkLength); + + class HeaderPrivate; + HeaderPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/mpegproperties.h b/taglib/include/taglib/mpegproperties.h new file mode 100644 index 0000000..a1a1af4 --- /dev/null +++ b/taglib/include/taglib/mpegproperties.h @@ -0,0 +1,152 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_MPEGPROPERTIES_H +#define TAGLIB_MPEGPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +#include "mpegheader.h" + +namespace TagLib { + + namespace MPEG { + + class File; + class XingHeader; + + //! An implementation of audio property reading for MP3 + + /*! + * This reads the data from an MPEG Layer III stream found in the + * AudioProperties API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of MPEG::Properties with the data read from the + * MPEG::File \a file. + */ + Properties(File *file, ReadStyle style = Average); + + /*! + * Destroys this MPEG Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns a pointer to the Xing/VBRI header if one exists or null if no + * Xing/VBRI header was found. + */ + const XingHeader *xingHeader() const; + + /*! + * Returns the MPEG Version of the file. + */ + Header::Version version() const; + + /*! + * Returns the layer version. This will be between the values 1-3. + */ + int layer() const; + + /*! + * Returns true if the MPEG protection bit is enabled. + */ + bool protectionEnabled() const; + + /*! + * Returns the channel mode for this frame. + */ + Header::ChannelMode channelMode() const; + + /*! + * Returns true if the copyrighted bit is set. + */ + bool isCopyrighted() const; + + /*! + * Returns true if the "original" bit is set. + */ + bool isOriginal() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/oggfile.h b/taglib/include/taglib/oggfile.h new file mode 100644 index 0000000..7d889c2 --- /dev/null +++ b/taglib/include/taglib/oggfile.h @@ -0,0 +1,127 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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 "taglib_export.h" +#include "tfile.h" +#include "tbytevectorlist.h" + +#ifndef TAGLIB_OGGFILE_H +#define TAGLIB_OGGFILE_H + +namespace TagLib { + + //! A namespace for the classes used by Ogg-based metadata files + + namespace Ogg { + + class PageHeader; + + //! An implementation of TagLib::File with some helpers for Ogg based formats + + /*! + * This is an implementation of Ogg file page and packet rendering and is of + * use to Ogg based formats. While the API is small this handles the + * non-trivial details of breaking up an Ogg stream into packets and makes + * these available (via subclassing) to the codec meta data implementations. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + virtual ~File(); + + /*! + * Returns the packet contents for the i-th packet (starting from zero) + * in the Ogg bitstream. + * + * \warning This requires reading at least the packet header for every page + * up to the requested page. + */ + ByteVector packet(unsigned int i); + + /*! + * Sets the packet with index \a i to the value \a p. + */ + void setPacket(unsigned int i, const ByteVector &p); + + /*! + * Returns a pointer to the PageHeader for the first page in the stream or + * null if the page could not be found. + */ + const PageHeader *firstPageHeader(); + + /*! + * Returns a pointer to the PageHeader for the last page in the stream or + * null if the page could not be found. + */ + const PageHeader *lastPageHeader(); + + virtual bool save(); + + protected: + /*! + * Constructs an Ogg file from \a file. + * + * \note This constructor is protected since Ogg::File shouldn't be + * instantiated directly but rather should be used through the codec + * specific subclasses. + */ + File(FileName file); + + /*! + * Constructs an Ogg file from \a stream. + * + * \note This constructor is protected since Ogg::File shouldn't be + * instantiated directly but rather should be used through the codec + * specific subclasses. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + */ + File(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + /*! + * Reads the pages from the beginning of the file until enough to compose + * the requested packet. + */ + bool readPages(unsigned int i); + + /*! + * Writes the requested packet to the file. + */ + void writePacket(unsigned int i, const ByteVector &packet); + + class FilePrivate; + FilePrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/oggflacfile.h b/taglib/include/taglib/oggflacfile.h new file mode 100644 index 0000000..b2686e4 --- /dev/null +++ b/taglib/include/taglib/oggflacfile.h @@ -0,0 +1,170 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.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_OGGFLACFILE_H +#define TAGLIB_OGGFLACFILE_H + +#include "taglib_export.h" +#include "oggfile.h" +#include "xiphcomment.h" + +#include "flacproperties.h" + +namespace TagLib { + + class Tag; + + namespace Ogg { + + //! An implementation of Ogg FLAC metadata + + /*! + * This is implementation of FLAC metadata for Ogg FLAC files. For "pure" + * FLAC files look under the FLAC hierarchy. + * + * Unlike "pure" FLAC-files, Ogg FLAC only supports Xiph-comments, + * while the audio-properties are the same. + */ + namespace FLAC { + + using TagLib::FLAC::Properties; + + //! An implementation of TagLib::File with Ogg/FLAC specific methods + + /*! + * This implements and provides an interface for Ogg/FLAC files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to Ogg FLAC files. + */ + + class TAGLIB_EXPORT File : public Ogg::File + { + public: + /*! + * Constructs an Ogg/FLAC file from \a file. If \a readProperties is true + * the file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an Ogg/FLAC file from \a stream. If \a readProperties is true + * the file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. This will always be a XiphComment. + * + * \note This always returns a valid pointer regardless of whether or not + * the file on disk has a XiphComment. Use hasXiphComment() to check if + * the file on disk actually has a XiphComment. + * + * \note The Tag is still owned by the FLAC::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasXiphComment() + */ + virtual XiphComment *tag() const; + + /*! + * Returns the FLAC::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + + /*! + * Implements the unified property interface -- export function. + * This forwards directly to XiphComment::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Like properties(), this is a forwarder to the file's XiphComment. + */ + PropertyMap setProperties(const PropertyMap &); + + + /*! + * Save the file. This will primarily save and update the XiphComment. + * Returns true if the save is successful. + */ + virtual bool save(); + + /*! + * Returns the length of the audio-stream, used by FLAC::Properties for + * calculating the bitrate. + */ + long streamLength(); + + /*! + * Returns whether or not the file on disk actually has a XiphComment. + * + * \see tag() + */ + bool hasXiphComment() const; + + /*! + * Check if the given \a stream can be opened as an Ogg FLAC file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties, Properties::ReadStyle propertiesStyle); + void scan(); + ByteVector streamInfoData(); + ByteVector xiphCommentData(); + + class FilePrivate; + FilePrivate *d; + }; + } // namespace FLAC + } // namespace Ogg +} // namespace TagLib + +#endif diff --git a/taglib/include/taglib/oggpage.h b/taglib/include/taglib/oggpage.h new file mode 100644 index 0000000..af3fe2c --- /dev/null +++ b/taglib/include/taglib/oggpage.h @@ -0,0 +1,228 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_OGGPAGE_H +#define TAGLIB_OGGPAGE_H + +#include "taglib_export.h" +#include "tbytevectorlist.h" + +namespace TagLib { + + namespace Ogg { + + class File; + class PageHeader; + + //! An implementation of Ogg pages + + /*! + * This is an implementation of the pages that make up an Ogg stream. + * This handles parsing pages and breaking them down into packets and handles + * the details of packets spanning multiple pages and pages that contain + * multiple packets. + * + * In most Xiph.org formats the comments are found in the first few packets, + * this however is a reasonably complete implementation of Ogg pages that + * could potentially be useful for non-meta data purposes. + */ + + class TAGLIB_EXPORT Page + { + public: + /*! + * Read an Ogg page from the \a file at the position \a pageOffset. + */ + Page(File *file, long pageOffset); + + virtual ~Page(); + + /*! + * Returns the page's position within the file (in bytes). + */ + long fileOffset() const; + + /*! + * Returns a pointer to the header for this page. This pointer will become + * invalid when the page is deleted. + */ + const PageHeader *header() const; + + /*! + * Returns the index of the page within the Ogg stream. This helps make it + * possible to determine if pages have been lost. + * + * \see setPageSequenceNumber() + */ + int pageSequenceNumber() const; + + /*! + * Sets the page's position in the stream to \a sequenceNumber. + * + * \see pageSequenceNumber() + */ + void setPageSequenceNumber(int sequenceNumber); + + /*! + * Returns a copy of the page with \a sequenceNumber set as sequence number. + * + * \see header() + * \see PageHeader::setPageSequenceNumber() + * + * \deprecated Always returns null. + */ + TAGLIB_DEPRECATED Page *getCopyWithNewPageSequenceNumber(int sequenceNumber); + + /*! + * Returns the index of the first packet wholly or partially contained in + * this page. + * + * \see setFirstPacketIndex() + */ + int firstPacketIndex() const; + + /*! + * Sets the index of the first packet in the page. + * + * \see firstPacketIndex() + */ + void setFirstPacketIndex(int index); + + /*! + * When checking to see if a page contains a given packet this set of flags + * represents the possible values for that packets status in the page. + * + * \see containsPacket() + */ + enum ContainsPacketFlags { + //! No part of the packet is contained in the page + DoesNotContainPacket = 0x0000, + //! The packet is wholly contained in the page + CompletePacket = 0x0001, + //! The page starts with the given packet + BeginsWithPacket = 0x0002, + //! The page ends with the given packet + EndsWithPacket = 0x0004 + }; + + /*! + * Checks to see if the specified \a packet is contained in the current + * page. + * + * \see ContainsPacketFlags + */ + ContainsPacketFlags containsPacket(int index) const; + + /*! + * Returns the number of packets (whole or partial) in this page. + */ + unsigned int packetCount() const; + + /*! + * Returns a list of the packets in this page. + * + * \note Either or both the first and last packets may be only partial. + * \see PageHeader::firstPacketContinued() + */ + ByteVectorList packets() const; + + /*! + * Returns the size of the page in bytes. + */ + int size() const; + + ByteVector render() const; + + /*! + * Defines a strategy for pagination, or grouping pages into Ogg packets, + * for use with pagination methods. + * + * \note Yes, I'm aware that this is not a canonical "Strategy Pattern", + * the term was simply convenient. + */ + enum PaginationStrategy { + /*! + * Attempt to put the specified set of packets into a single Ogg packet. + * If the sum of the packet data is greater than will fit into a single + * Ogg page -- 65280 bytes -- this will fall back to repagination using + * the recommended page sizes. + */ + SinglePagePerGroup, + /*! + * Split the packet or group of packets into pages that conform to the + * sizes recommended in the Ogg standard. + */ + Repaginate + }; + + /*! + * Pack \a packets into Ogg pages using the \a strategy for pagination. + * The page number indicator inside of the rendered packets will start + * with \a firstPage and be incremented for each page rendered. + * \a containsLastPacket should be set to true if \a packets contains the + * last page in the stream and will set the appropriate flag in the last + * rendered Ogg page's header. \a streamSerialNumber should be set to + * the serial number for this stream. + * + * \note The "absolute granule position" is currently always zeroed using + * this method as this suffices for the comment headers. + * + * \warning The pages returned by this method must be deleted by the user. + * You can use List::setAutoDelete(true) to set these pages to be + * automatically deleted when this list passes out of scope. + * + * \see PaginationStrategy + * \see List::setAutoDelete() + */ + static List paginate(const ByteVectorList &packets, + PaginationStrategy strategy, + unsigned int streamSerialNumber, + int firstPage, + bool firstPacketContinued = false, + bool lastPacketCompleted = true, + bool containsLastPacket = false); + + protected: + /*! + * Creates an Ogg packet based on the data in \a packets. The page number + * for each page will be set to \a pageNumber. + */ + Page(const ByteVectorList &packets, + unsigned int streamSerialNumber, + int pageNumber, + bool firstPacketContinued = false, + bool lastPacketCompleted = true, + bool containsLastPacket = false); + + private: + Page(const Page &); + Page &operator=(const Page &); + + class PagePrivate; + PagePrivate *d; + }; + } +} +#endif diff --git a/taglib/include/taglib/oggpageheader.h b/taglib/include/taglib/oggpageheader.h new file mode 100644 index 0000000..571155f --- /dev/null +++ b/taglib/include/taglib/oggpageheader.h @@ -0,0 +1,232 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_OGGPAGEHEADER_H +#define TAGLIB_OGGPAGEHEADER_H + +#include "tlist.h" +#include "tbytevector.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace Ogg { + + class File; + + //! An implementation of the page headers associated with each Ogg::Page + + /*! + * This class implements Ogg page headers which contain the information + * about Ogg pages needed to break them into packets which can be passed on + * to the codecs. + */ + + class TAGLIB_EXPORT PageHeader + { + public: + /*! + * Reads a PageHeader from \a file starting at \a pageOffset. The defaults + * create a page with no (and as such, invalid) data that must be set + * later. + */ + PageHeader(File *file = 0, long pageOffset = -1); + + /*! + * Deletes this instance of the PageHeader. + */ + virtual ~PageHeader(); + + /*! + * Returns true if the header parsed properly and is valid. + */ + bool isValid() const; + + /*! + * Ogg pages contain a list of packets (which are used by the contained + * codecs). The sizes of these pages is encoded in the page header. This + * returns a list of the packet sizes in bytes. + * + * \see setPacketSizes() + */ + List packetSizes() const; + + /*! + * Sets the sizes of the packets in this page to \a sizes. Internally this + * updates the lacing values in the header. + * + * \see packetSizes() + */ + void setPacketSizes(const List &sizes); + + /*! + * Some packets can be continued across multiple pages. If the + * first packet in the current page is a continuation this will return + * true. If this is page starts with a new packet this will return false. + * + * \see lastPacketCompleted() + * \see setFirstPacketContinued() + */ + bool firstPacketContinued() const; + + /*! + * Sets the internal flag indicating if the first packet in this page is + * continued to \a continued. + * + * \see firstPacketContinued() + */ + void setFirstPacketContinued(bool continued); + + /*! + * Returns true if the last packet of this page is completely contained in + * this page. + * + * \see firstPacketContinued() + * \see setLastPacketCompleted() + */ + bool lastPacketCompleted() const; + + /*! + * Sets the internal flag indicating if the last packet in this page is + * complete to \a completed. + * + * \see lastPacketCompleted() + */ + void setLastPacketCompleted(bool completed); + + /*! + * This returns true if this is the first page of the Ogg (logical) stream. + * + * \see setFirstPageOfStream() + */ + bool firstPageOfStream() const; + + /*! + * Marks this page as the first page of the Ogg stream. + * + * \see firstPageOfStream() + */ + void setFirstPageOfStream(bool first); + + /*! + * This returns true if this is the last page of the Ogg (logical) stream. + * + * \see setLastPageOfStream() + */ + bool lastPageOfStream() const; + + /*! + * Marks this page as the last page of the Ogg stream. + * + * \see lastPageOfStream() + */ + void setLastPageOfStream(bool last); + + /*! + * A special value of containing the position of the packet to be + * interpreted by the codec. In the case of Vorbis this contains the PCM + * value and is used to calculate the length of the stream. + * + * \see setAbsoluteGranularPosition() + */ + long long absoluteGranularPosition() const; + + /*! + * A special value of containing the position of the packet to be + * interpreted by the codec. It is only supported here so that it may be + * copied from one page to another. + * + * \see absoluteGranularPosition() + */ + void setAbsoluteGranularPosition(long long agp); + + /*! + * Every Ogg logical stream is given a random serial number which is common + * to every page in that logical stream. This returns the serial number of + * the stream associated with this packet. + * + * \see setStreamSerialNumber() + */ + unsigned int streamSerialNumber() const; + + /*! + * Every Ogg logical stream is given a random serial number which is common + * to every page in that logical stream. This sets this pages serial + * number. This method should be used when adding new pages to a logical + * stream. + * + * \see streamSerialNumber() + */ + void setStreamSerialNumber(unsigned int n); + + /*! + * Returns the index of the page within the Ogg stream. This helps make it + * possible to determine if pages have been lost. + * + * \see setPageSequenceNumber() + */ + int pageSequenceNumber() const; + + /*! + * Sets the page's position in the stream to \a sequenceNumber. + * + * \see pageSequenceNumber() + */ + void setPageSequenceNumber(int sequenceNumber); + + /*! + * Returns the complete header size. + */ + int size() const; + + /*! + * Returns the size of the data portion of the page -- i.e. the size of the + * page less the header size. + */ + int dataSize() const; + + /*! + * Render the page header to binary data. + * + * \note The checksum -- bytes 22 - 25 -- will be left empty and must be + * filled in when rendering the entire page. + */ + ByteVector render() const; + + private: + PageHeader(const PageHeader &); + PageHeader &operator=(const PageHeader &); + + void read(Ogg::File *file, long pageOffset); + ByteVector lacingValues() const; + + class PageHeaderPrivate; + PageHeaderPrivate *d; + }; + + } +} + +#endif diff --git a/taglib/include/taglib/opusfile.h b/taglib/include/taglib/opusfile.h new file mode 100644 index 0000000..0e094ea --- /dev/null +++ b/taglib/include/taglib/opusfile.h @@ -0,0 +1,138 @@ +/*************************************************************************** + copyright : (C) 2012 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + (original Vorbis implementation) +***************************************************************************/ + +/*************************************************************************** + * 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_OPUSFILE_H +#define TAGLIB_OPUSFILE_H + +#include "oggfile.h" +#include "xiphcomment.h" + +#include "opusproperties.h" + +namespace TagLib { + + namespace Ogg { + + //! A namespace containing classes for Opus metadata + + namespace Opus { + + //! An implementation of Ogg::File with Opus specific methods + + /*! + * This is the central class in the Ogg Opus metadata processing collection + * of classes. It's built upon Ogg::File which handles processing of the Ogg + * logical bitstream and breaking it down into pages which are handled by + * the codec implementations, in this case Opus specifically. + */ + + class TAGLIB_EXPORT File : public Ogg::File + { + public: + /*! + * Constructs an Opus file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an Opus file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the XiphComment for this file. XiphComment implements the tag + * interface, so this serves as the reimplementation of + * TagLib::File::tag(). + */ + virtual Ogg::XiphComment *tag() const; + + /*! + * Implements the unified property interface -- export function. + * This forwards directly to XiphComment::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Like properties(), this is a forwarder to the file's XiphComment. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the Opus::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Save the file. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Returns whether or not the given \a stream can be opened as an Opus + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/opusproperties.h b/taglib/include/taglib/opusproperties.h new file mode 100644 index 0000000..2e44dea --- /dev/null +++ b/taglib/include/taglib/opusproperties.h @@ -0,0 +1,134 @@ +/*************************************************************************** + copyright : (C) 2012 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + (original Vorbis implementation) +***************************************************************************/ + +/*************************************************************************** + * 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_OPUSPROPERTIES_H +#define TAGLIB_OPUSPROPERTIES_H + +#include "audioproperties.h" + +namespace TagLib { + + namespace Ogg { + + namespace Opus { + + class File; + + //! An implementation of audio property reading for Ogg Opus + + /*! + * This reads the data from an Ogg Opus stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of Opus::Properties with the data read from the + * Opus::File \a file. + */ + Properties(File *file, ReadStyle style = Average); + + /*! + * Destroys this Opus::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + * + * \note Always returns 48000, because Opus can decode any stream at a + * sample rate of 8, 12, 16, 24, or 48 kHz, + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * The Opus codec supports decoding at multiple sample rates, there is no + * single sample rate of the encoded stream. This returns the sample rate + * of the original audio stream. + */ + int inputSampleRate() const; + + /*! + * Returns the Opus version, in the range 0...255. + */ + int opusVersion() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/ownershipframe.h b/taglib/include/taglib/ownershipframe.h new file mode 100644 index 0000000..06a1e23 --- /dev/null +++ b/taglib/include/taglib/ownershipframe.h @@ -0,0 +1,151 @@ +/*************************************************************************** + copyright : (C) 2012 by Rupert Daniel + email : rupert@cancelmonday.com + ***************************************************************************/ + +/*************************************************************************** + * 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_OWNERSHIPFRAME_H +#define TAGLIB_OWNERSHIPFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An implementation of ID3v2 "ownership" + + /*! + * This implements the ID3v2 ownership (OWNE frame). It consists of + * a price paid, a date purchased (YYYYMMDD) and the name of the seller. + */ + + class TAGLIB_EXPORT OwnershipFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty ownership frame. + */ + explicit OwnershipFrame(String::Type encoding = String::Latin1); + + /*! + * Construct a ownership based on the data in \a data. + */ + explicit OwnershipFrame(const ByteVector &data); + + /*! + * Destroys this OwnershipFrame instance. + */ + virtual ~OwnershipFrame(); + + /*! + * Returns the text of this popularimeter. + * + * \see text() + */ + virtual String toString() const; + + /*! + * Returns the date purchased. + * + * \see setDatePurchased() + */ + String datePurchased() const; + + /*! + * Set the date purchased. + * + * \see datePurchased() + */ + void setDatePurchased(const String &datePurchased); + + /*! + * Returns the price paid. + * + * \see setPricePaid() + */ + String pricePaid() const; + + /*! + * Set the price paid. + * + * \see pricePaid() + */ + void setPricePaid(const String &pricePaid); + + /*! + * Returns the seller. + * + * \see setSeller() + */ + String seller() const; + + /*! + * Set the seller. + * + * \see seller() + */ + void setSeller(const String &seller); + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + OwnershipFrame(const ByteVector &data, Header *h); + OwnershipFrame(const OwnershipFrame &); + OwnershipFrame &operator=(const OwnershipFrame &); + + class OwnershipFramePrivate; + OwnershipFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/podcastframe.h b/taglib/include/taglib/podcastframe.h new file mode 100644 index 0000000..a71278c --- /dev/null +++ b/taglib/include/taglib/podcastframe.h @@ -0,0 +1,82 @@ +/*************************************************************************** + copyright : (C) 2015 by Urs Fleisch + email : ufleisch@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * 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_PODCASTFRAME_H +#define TAGLIB_PODCASTFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! ID3v2 podcast frame + /*! + * An implementation of ID3v2 podcast flag, a frame with four zero bytes. + */ + class TAGLIB_EXPORT PodcastFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct a podcast frame. + */ + PodcastFrame(); + + /*! + * Destroys this PodcastFrame instance. + */ + virtual ~PodcastFrame(); + + /*! + * Returns a null string. + */ + virtual String toString() const; + + PropertyMap asProperties() const; + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + PodcastFrame(const ByteVector &data, Header *h); + PodcastFrame(const PodcastFrame &); + PodcastFrame &operator=(const PodcastFrame &); + + class PodcastFramePrivate; + PodcastFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/popularimeterframe.h b/taglib/include/taglib/popularimeterframe.h new file mode 100644 index 0000000..405ca69 --- /dev/null +++ b/taglib/include/taglib/popularimeterframe.h @@ -0,0 +1,132 @@ +/*************************************************************************** + copyright : (C) 2008 by Lukas Lalinsky + email : lalinsky@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * 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_POPULARIMETERFRAME_H +#define TAGLIB_POPULARIMETERFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An implementation of ID3v2 "popularimeter" + + /*! + * This implements the ID3v2 popularimeter (POPM frame). It consists of + * an email, a rating and an optional counter. + */ + + class TAGLIB_EXPORT PopularimeterFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty popularimeter frame. + */ + explicit PopularimeterFrame(); + + /*! + * Construct a popularimeter based on the data in \a data. + */ + explicit PopularimeterFrame(const ByteVector &data); + + /*! + * Destroys this PopularimeterFrame instance. + */ + virtual ~PopularimeterFrame(); + + /*! + * Returns the text of this popularimeter. + * + * \see text() + */ + virtual String toString() const; + + /*! + * Returns the email. + * + * \see setEmail() + */ + String email() const; + + /*! + * Set the email. + * + * \see email() + */ + void setEmail(const String &email); + + /*! + * Returns the rating. + * + * \see setRating() + */ + int rating() const; + + /*! + * Set the rating. + * + * \see rating() + */ + void setRating(int rating); + + /*! + * Returns the counter. + * + * \see setCounter() + */ + unsigned int counter() const; + + /*! + * Set the counter. + * + * \see counter() + */ + void setCounter(unsigned int counter); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + PopularimeterFrame(const ByteVector &data, Header *h); + PopularimeterFrame(const PopularimeterFrame &); + PopularimeterFrame &operator=(const PopularimeterFrame &); + + class PopularimeterFramePrivate; + PopularimeterFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/privateframe.h b/taglib/include/taglib/privateframe.h new file mode 100644 index 0000000..06f82f3 --- /dev/null +++ b/taglib/include/taglib/privateframe.h @@ -0,0 +1,111 @@ +/*************************************************************************** + copyright : (C) 2008 by Serkan Kalyoncu + copyright : (C) 2008 by Scott Wheeler + email : wheeler@kde.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_PRIVATEFRAME_H +#define TAGLIB_PRIVATEFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An implementation of ID3v2 privateframe + + class TAGLIB_EXPORT PrivateFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty private frame. + */ + PrivateFrame(); + + /*! + * Construct a private frame based on the data in \a data. + * + * \note This is the constructor used when parsing the frame from a file. + */ + explicit PrivateFrame(const ByteVector &data); + + /*! + * Destroys this private frame instance. + */ + virtual ~PrivateFrame(); + + /*! + * Returns the text of this private frame, currently just the owner. + * + * \see text() + */ + virtual String toString() const; + + /*! + * \return The owner of the private frame. + * \note This should contain an email address or link to a website. + */ + String owner() const; + + /*! + * + */ + ByteVector data() const; + + /*! + * Sets the owner of the frame to \a s. + * \note This should contain an email address or link to a website. + */ + void setOwner(const String &s); + + /*! + * + */ + void setData(const ByteVector &v); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + PrivateFrame(const ByteVector &data, Header *h); + + PrivateFrame(const PrivateFrame &); + PrivateFrame &operator=(const PrivateFrame &); + + class PrivateFramePrivate; + PrivateFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/relativevolumeframe.h b/taglib/include/taglib/relativevolumeframe.h new file mode 100644 index 0000000..55f13fc --- /dev/null +++ b/taglib/include/taglib/relativevolumeframe.h @@ -0,0 +1,274 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_RELATIVEVOLUMEFRAME_H +#define TAGLIB_RELATIVEVOLUMEFRAME_H + +#include "tlist.h" +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! An ID3v2 relative volume adjustment frame implementation + + /*! + * This is an implementation of ID3v2 relative volume adjustment. The + * presence of this frame makes it possible to specify an increase in volume + * for an audio file or specific audio tracks in that file. + * + * Multiple relative volume adjustment frames may be present in the tag + * each with a unique identification and describing volume adjustment for + * different channel types. + */ + + class TAGLIB_EXPORT RelativeVolumeFrame : public Frame + { + friend class FrameFactory; + + public: + + /*! + * This indicates the type of volume adjustment that should be applied. + */ + enum ChannelType { + //! A type not enumerated below + Other = 0x00, + //! The master volume for the track + MasterVolume = 0x01, + //! The front right audio channel + FrontRight = 0x02, + //! The front left audio channel + FrontLeft = 0x03, + //! The back right audio channel + BackRight = 0x04, + //! The back left audio channel + BackLeft = 0x05, + //! The front center audio channel + FrontCentre = 0x06, + //! The back center audio channel + BackCentre = 0x07, + //! The subwoofer audio channel + Subwoofer = 0x08 + }; + + //! Struct that stores the relevant values for ID3v2 peak volume + + /*! + * The peak volume is described as a series of bits that is padded to fill + * a block of bytes. These two values should always be updated in tandem. + */ + struct PeakVolume + { + /*! + * Constructs an empty peak volume description. + */ + PeakVolume() : bitsRepresentingPeak(0) {} + /*! + * The number of bits (in the range of 0 to 255) used to describe the + * peak volume. + */ + unsigned char bitsRepresentingPeak; + /*! + * The array of bits (represented as a series of bytes) used to describe + * the peak volume. + */ + ByteVector peakVolume; + }; + + /*! + * Constructs a RelativeVolumeFrame. The relevant data should be set + * manually. + */ + RelativeVolumeFrame(); + + /*! + * Constructs a RelativeVolumeFrame based on the contents of \a data. + */ + RelativeVolumeFrame(const ByteVector &data); + + /*! + * Destroys the RelativeVolumeFrame instance. + */ + virtual ~RelativeVolumeFrame(); + + /*! + * Returns the frame's identification. + * + * \see identification() + */ + virtual String toString() const; + + /*! + * Returns a list of channels with information currently in the frame. + */ + List channels() const; + + /*! + * \deprecated Always returns master volume. + */ + TAGLIB_DEPRECATED ChannelType channelType() const; + + /*! + * \deprecated This method no longer has any effect. + */ + TAGLIB_DEPRECATED void setChannelType(ChannelType t); + + /* + * There was a terrible API goof here, and while this can't be changed to + * the way it appears below for binary compatibility reasons, let's at + * least pretend that it looks clean. + */ + +#ifdef DOXYGEN + + /*! + * Returns the relative volume adjustment "index". As indicated by the + * ID3v2 standard this is a 16-bit signed integer that reflects the + * decibels of adjustment when divided by 512. + * + * This defaults to returning the value for the master volume channel if + * available and returns 0 if the specified channel does not exist. + * + * \see setVolumeAdjustmentIndex() + * \see volumeAdjustment() + */ + short volumeAdjustmentIndex(ChannelType type = MasterVolume) const; + + /*! + * Set the volume adjustment to \a index. As indicated by the ID3v2 + * standard this is a 16-bit signed integer that reflects the decibels of + * adjustment when divided by 512. + * + * By default this sets the value for the master volume. + * + * \see volumeAdjustmentIndex() + * \see setVolumeAdjustment() + */ + void setVolumeAdjustmentIndex(short index, ChannelType type = MasterVolume); + + /*! + * Returns the relative volume adjustment in decibels. + * + * \note Because this is actually stored internally as an "index" to this + * value the value returned by this method may not be identical to the + * value set using setVolumeAdjustment(). + * + * This defaults to returning the value for the master volume channel if + * available and returns 0 if the specified channel does not exist. + * + * \see setVolumeAdjustment() + * \see volumeAdjustmentIndex() + */ + float volumeAdjustment(ChannelType type = MasterVolume) const; + + /*! + * Set the relative volume adjustment in decibels to \a adjustment. + * + * By default this sets the value for the master volume. + * + * \note Because this is actually stored internally as an "index" to this + * value the value set by this method may not be identical to the one + * returned by volumeAdjustment(). + * + * \see setVolumeAdjustment() + * \see volumeAdjustmentIndex() + */ + void setVolumeAdjustment(float adjustment, ChannelType type = MasterVolume); + + /*! + * Returns the peak volume (represented as a length and a string of bits). + * + * This defaults to returning the value for the master volume channel if + * available and returns 0 if the specified channel does not exist. + * + * \see setPeakVolume() + */ + PeakVolume peakVolume(ChannelType type = MasterVolume) const; + + /*! + * Sets the peak volume to \a peak. + * + * By default this sets the value for the master volume. + * + * \see peakVolume() + */ + void setPeakVolume(const PeakVolume &peak, ChannelType type = MasterVolume); + +#else + + // BIC: Combine each of the following pairs of functions (or maybe just + // rework this junk altogether). + + short volumeAdjustmentIndex(ChannelType type) const; + short volumeAdjustmentIndex() const; + + void setVolumeAdjustmentIndex(short index, ChannelType type); + void setVolumeAdjustmentIndex(short index); + + float volumeAdjustment(ChannelType type) const; + float volumeAdjustment() const; + + void setVolumeAdjustment(float adjustment, ChannelType type); + void setVolumeAdjustment(float adjustment); + + PeakVolume peakVolume(ChannelType type) const; + PeakVolume peakVolume() const; + + void setPeakVolume(const PeakVolume &peak, ChannelType type); + void setPeakVolume(const PeakVolume &peak); + +#endif + + /*! + * Returns the identification for this frame. + */ + String identification() const; + + /*! + * Sets the identification of the frame to \a s. The string + * is used to identify the situation and/or device where this + * adjustment should apply. + */ + void setIdentification(const String &s); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + RelativeVolumeFrame(const ByteVector &data, Header *h); + RelativeVolumeFrame(const RelativeVolumeFrame &); + RelativeVolumeFrame &operator=(const RelativeVolumeFrame &); + + class RelativeVolumeFramePrivate; + RelativeVolumeFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/rifffile.h b/taglib/include/taglib/rifffile.h new file mode 100644 index 0000000..5c606b4 --- /dev/null +++ b/taglib/include/taglib/rifffile.h @@ -0,0 +1,161 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_RIFFFILE_H +#define TAGLIB_RIFFFILE_H + +#include "taglib_export.h" +#include "tfile.h" + +namespace TagLib { + + //! An implementation of TagLib::File with RIFF specific methods + + namespace RIFF { + + //! An RIFF file class with some useful methods specific to RIFF + + /*! + * This implements the generic TagLib::File API and additionally provides + * access to properties that are distinct to RIFF files, notably access + * to the different ID3 tags. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + protected: + + enum Endianness { BigEndian, LittleEndian }; + + File(FileName file, Endianness endianness); + File(IOStream *stream, Endianness endianness); + + /*! + * \return The size of the main RIFF chunk. + */ + unsigned int riffSize() const; + + /*! + * \return The number of chunks in the file. + */ + unsigned int chunkCount() const; + + /*! + * \return The offset within the file for the selected chunk number. + */ + unsigned int chunkOffset(unsigned int i) const; + + /*! + * \return The size of the chunk data. + */ + unsigned int chunkDataSize(unsigned int i) const; + + /*! + * \return The size of the padding after the chunk (can be either 0 or 1). + */ + unsigned int chunkPadding(unsigned int i) const; + + /*! + * \return The name of the specified chunk, for instance, "COMM" or "ID3 " + */ + ByteVector chunkName(unsigned int i) const; + + /*! + * Reads the chunk data from the file and returns it. + * + * \note This \e will move the read pointer for the file. + */ + ByteVector chunkData(unsigned int i); + + /*! + * Sets the data for the specified chunk to \a data. + * + * \warning This will update the file immediately. + */ + void setChunkData(unsigned int i, const ByteVector &data); + + /*! + * Sets the data for the chunk \a name to \a data. If a chunk with the + * given name already exists it will be overwritten, otherwise it will be + * created after the existing chunks. + * + * \warning This will update the file immediately. + */ + void setChunkData(const ByteVector &name, const ByteVector &data); + + /*! + * Sets the data for the chunk \a name to \a data. If a chunk with the + * given name already exists it will be overwritten, otherwise it will be + * created after the existing chunks. + * + * \note If \a alwaysCreate is true, a new chunk is created regardless of + * whether or not the chunk \a name exists. It should only be used for + * "LIST" chunks. + * + * \warning This will update the file immediately. + */ + void setChunkData(const ByteVector &name, const ByteVector &data, bool alwaysCreate); + + /*! + * Removes the specified chunk. + * + * \warning This will update the file immediately. + */ + void removeChunk(unsigned int i); + + /*! + * Removes the chunk \a name. + * + * \warning This will update the file immediately. + * \warning This removes all the chunks with the given name. + */ + void removeChunk(const ByteVector &name); + + private: + File(const File &); + File &operator=(const File &); + + void read(); + void writeChunk(const ByteVector &name, const ByteVector &data, + unsigned long offset, unsigned long replace = 0); + + /*! + * Update the global RIFF size based on the current internal structure. + */ + void updateGlobalSize(); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/s3mfile.h b/taglib/include/taglib/s3mfile.h new file mode 100644 index 0000000..4011bd1 --- /dev/null +++ b/taglib/include/taglib/s3mfile.h @@ -0,0 +1,112 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_S3MFILE_H +#define TAGLIB_S3MFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "s3mproperties.h" + +namespace TagLib { + + namespace S3M { + + class TAGLIB_EXPORT File : public Mod::FileBase { + public: + /*! + * Constructs a ScreamTracker III 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 ScreamTracker III 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. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * Forwards to Mod::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Forwards to Mod::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the S3M::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + S3M::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving ScreamTracker III tags is not supported. + */ + bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/s3mproperties.h b/taglib/include/taglib/s3mproperties.h new file mode 100644 index 0000000..92b2a27 --- /dev/null +++ b/taglib/include/taglib/s3mproperties.h @@ -0,0 +1,94 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_S3MPROPERTIES_H +#define TAGLIB_S3MPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + namespace S3M { + class TAGLIB_EXPORT Properties : public AudioProperties { + friend class File; + public: + /*! Flag bits. */ + enum { + ST2Vibrato = 1, + ST2Tempo = 2, + AmigaSlides = 4, + Vol0MixOptimizations = 8, + AmigaLimits = 16, + EnableFilter = 32, + CustomData = 128 + }; + + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int lengthInSeconds() const; + int lengthInMilliseconds() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + unsigned short lengthInPatterns() const; + bool stereo() const; + unsigned short sampleCount() const; + unsigned short patternCount() const; + unsigned short flags() const; + unsigned short trackerVersion() const; + unsigned short fileFormatVersion() const; + unsigned char globalVolume() const; + unsigned char masterVolume() const; + unsigned char tempo() const; + unsigned char bpmSpeed() const; + + void setChannels(int channels); + + void setLengthInPatterns (unsigned short lengthInPatterns); + void setStereo (bool stereo); + void setSampleCount (unsigned short sampleCount); + void setPatternCount (unsigned short patternCount); + void setFlags (unsigned short flags); + void setTrackerVersion (unsigned short trackerVersion); + void setFileFormatVersion(unsigned short fileFormatVersion); + void setGlobalVolume (unsigned char globalVolume); + void setMasterVolume (unsigned char masterVolume); + void setTempo (unsigned char tempo); + void setBpmSpeed (unsigned char bpmSpeed); + + private: + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/speexfile.h b/taglib/include/taglib/speexfile.h new file mode 100644 index 0000000..1be7113 --- /dev/null +++ b/taglib/include/taglib/speexfile.h @@ -0,0 +1,138 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + (original Vorbis implementation) +***************************************************************************/ + +/*************************************************************************** + * 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_SPEEXFILE_H +#define TAGLIB_SPEEXFILE_H + +#include "oggfile.h" +#include "xiphcomment.h" + +#include "speexproperties.h" + +namespace TagLib { + + namespace Ogg { + + //! A namespace containing classes for Speex metadata + + namespace Speex { + + //! An implementation of Ogg::File with Speex specific methods + + /*! + * This is the central class in the Ogg Speex metadata processing collection + * of classes. It's built upon Ogg::File which handles processing of the Ogg + * logical bitstream and breaking it down into pages which are handled by + * the codec implementations, in this case Speex specifically. + */ + + class TAGLIB_EXPORT File : public Ogg::File + { + public: + /*! + * Constructs a Speex file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a Speex file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the XiphComment for this file. XiphComment implements the tag + * interface, so this serves as the reimplementation of + * TagLib::File::tag(). + */ + virtual Ogg::XiphComment *tag() const; + + /*! + * Implements the unified property interface -- export function. + * This forwards directly to XiphComment::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Like properties(), this is a forwarder to the file's XiphComment. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the Speex::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Save the file. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Returns whether or not the given \a stream can be opened as a Speex + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/speexproperties.h b/taglib/include/taglib/speexproperties.h new file mode 100644 index 0000000..3f5a20f --- /dev/null +++ b/taglib/include/taglib/speexproperties.h @@ -0,0 +1,129 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + (original Vorbis implementation) +***************************************************************************/ + +/*************************************************************************** + * 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_SPEEXPROPERTIES_H +#define TAGLIB_SPEEXPROPERTIES_H + +#include "audioproperties.h" + +namespace TagLib { + + namespace Ogg { + + namespace Speex { + + class File; + + //! An implementation of audio property reading for Ogg Speex + + /*! + * This reads the data from an Ogg Speex stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of Speex::Properties with the data read from the + * Speex::File \a file. + */ + Properties(File *file, ReadStyle style = Average); + + /*! + * Destroys this Speex::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the nominal bit rate as read from the Speex header in kb/s. + */ + int bitrateNominal() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the Speex version, currently "0" (as specified by the spec). + */ + int speexVersion() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/synchronizedlyricsframe.h b/taglib/include/taglib/synchronizedlyricsframe.h new file mode 100644 index 0000000..f520c59 --- /dev/null +++ b/taglib/include/taglib/synchronizedlyricsframe.h @@ -0,0 +1,231 @@ +/*************************************************************************** + copyright : (C) 2014 by Urs Fleisch + email : ufleisch@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * 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_SYNCHRONIZEDLYRICSFRAME_H +#define TAGLIB_SYNCHRONIZEDLYRICSFRAME_H + +#include "id3v2frame.h" +#include "tlist.h" + +namespace TagLib { + + namespace ID3v2 { + + //! ID3v2 synchronized lyrics frame + /*! + * An implementation of ID3v2 synchronized lyrics. + */ + class TAGLIB_EXPORT SynchronizedLyricsFrame : public Frame + { + friend class FrameFactory; + + public: + + /*! + * Specifies the timestamp format used. + */ + enum TimestampFormat { + //! The timestamp is of unknown format. + Unknown = 0x00, + //! The timestamp represents the number of MPEG frames since + //! the beginning of the audio stream. + AbsoluteMpegFrames = 0x01, + //! The timestamp represents the number of milliseconds since + //! the beginning of the audio stream. + AbsoluteMilliseconds = 0x02 + }; + + /*! + * Specifies the type of text contained. + */ + enum Type { + //! The text is some other type of text. + Other = 0x00, + //! The text contains lyrical data. + Lyrics = 0x01, + //! The text contains a transcription. + TextTranscription = 0x02, + //! The text lists the movements in the piece. + Movement = 0x03, + //! The text describes events that occur. + Events = 0x04, + //! The text contains chord changes that occur in the music. + Chord = 0x05, + //! The text contains trivia or "pop up" information about the media. + Trivia = 0x06, + //! The text contains URLs for relevant webpages. + WebpageUrls = 0x07, + //! The text contains URLs for relevant images. + ImageUrls = 0x08 + }; + + /*! + * Single entry of time stamp and lyrics text. + */ + struct SynchedText { + SynchedText(unsigned int ms, String str) : time(ms), text(str) {} + unsigned int time; + String text; + }; + + /*! + * List of synchronized lyrics. + */ + typedef TagLib::List SynchedTextList; + + /*! + * Construct an empty synchronized lyrics frame that will use the text + * encoding \a encoding. + */ + explicit SynchronizedLyricsFrame(String::Type encoding = String::Latin1); + + /*! + * Construct a synchronized lyrics frame based on the data in \a data. + */ + explicit SynchronizedLyricsFrame(const ByteVector &data); + + /*! + * Destroys this SynchronizedLyricsFrame instance. + */ + virtual ~SynchronizedLyricsFrame(); + + /*! + * Returns the description of this synchronized lyrics frame. + * + * \see description() + */ + virtual String toString() const; + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Returns the language encoding as a 3 byte encoding as specified by + * ISO-639-2. + * + * \note Most taggers simply ignore this value. + * + * \see setLanguage() + */ + ByteVector language() const; + + /*! + * Returns the timestamp format. + */ + TimestampFormat timestampFormat() const; + + /*! + * Returns the type of text contained. + */ + Type type() const; + + /*! + * Returns the description of this synchronized lyrics frame. + * + * \note Most taggers simply ignore this value. + * + * \see setDescription() + */ + String description() const; + + /*! + * Returns the text with the time stamps. + */ + SynchedTextList synchedText() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + /*! + * Set the language using the 3 byte language code from + * ISO-639-2 to + * \a languageCode. + * + * \see language() + */ + void setLanguage(const ByteVector &languageCode); + + /*! + * Set the timestamp format. + * + * \see timestampFormat() + */ + void setTimestampFormat(TimestampFormat f); + + /*! + * Set the type of text contained. + * + * \see type() + */ + void setType(Type t); + + /*! + * Sets the description of the synchronized lyrics frame to \a s. + * + * \see description() + */ + void setDescription(const String &s); + + /*! + * Sets the text with the time stamps. + * + * \see text() + */ + void setSynchedText(const SynchedTextList &t); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + SynchronizedLyricsFrame(const ByteVector &data, Header *h); + SynchronizedLyricsFrame(const SynchronizedLyricsFrame &); + SynchronizedLyricsFrame &operator=(const SynchronizedLyricsFrame &); + + class SynchronizedLyricsFramePrivate; + SynchronizedLyricsFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/tableofcontentsframe.h b/taglib/include/taglib/tableofcontentsframe.h new file mode 100644 index 0000000..2e5401e --- /dev/null +++ b/taglib/include/taglib/tableofcontentsframe.h @@ -0,0 +1,260 @@ +/*************************************************************************** + copyright : (C) 2013 by Lukas Krejci + email : krejclu6@fel.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * 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_TABLEOFCONTENTSFRAME +#define TAGLIB_TABLEOFCONTENTSFRAME + +#include "id3v2tag.h" +#include "id3v2frame.h" + +#include "tbytevectorlist.h" + +namespace TagLib { + + namespace ID3v2 { + + /*! + * This is an implementation of ID3v2 table of contents frames. Purpose + * of this frame is to allow a table of contents to be defined. + */ + + //! An implementation of ID3v2 table of contents frames + + class TAGLIB_EXPORT TableOfContentsFrame : public ID3v2::Frame + { + friend class FrameFactory; + + public: + /*! + * Creates a table of contents frame based on \a data. \a tagHeader is + * required as the internal frames are parsed based on the tag version. + */ + TableOfContentsFrame(const ID3v2::Header *tagHeader, const ByteVector &data); + + /*! + * Creates a table of contents frame with the element ID \a elementID, + * the child elements \a children and embedded frames, which become owned + * by this frame, in \a embeddedFrames. + */ + TableOfContentsFrame(const ByteVector &elementID, + const ByteVectorList &children = ByteVectorList(), + const FrameList &embeddedFrames = FrameList()); + + /*! + * Destroys the frame. + */ + ~TableOfContentsFrame(); + + /*! + * Returns the elementID of the frame. Element ID + * is a null terminated string, however it's not human-readable. + * + * \see setElementID() + */ + ByteVector elementID() const; + + /*! + * Returns true, if the frame is top-level (doesn't have + * any parent CTOC frame). + * + * \see setIsTopLevel() + */ + bool isTopLevel() const; + + /*! + * Returns true, if the child elements list entries + * are ordered. + * + * \see setIsOrdered() + */ + bool isOrdered() const; + + /*! + * Returns count of child elements of the frame. It always + * corresponds to size of child elements list. + * + * \see childElements() + */ + unsigned int entryCount() const; + + /*! + * Returns list of child elements of the frame. + * + * \see setChildElements() + */ + ByteVectorList childElements() const; + + /*! + * Sets the elementID of the frame to \a eID. If \a eID isn't + * null terminated, a null char is appended automatically. + * + * \see elementID() + */ + void setElementID(const ByteVector &eID); + + /*! + * Sets, if the frame is top-level (doesn't have + * any parent CTOC frame). + * + * \see isTopLevel() + */ + void setIsTopLevel(const bool &t); + + /*! + * Sets, if the child elements list entries + * are ordered. + * + * \see isOrdered() + */ + void setIsOrdered(const bool &o); + + /*! + * Sets list of child elements of the frame to \a l. + * + * \see childElements() + */ + void setChildElements(const ByteVectorList &l); + + /*! + * Adds \a cE to list of child elements of the frame. + * + * \see childElements() + */ + void addChildElement(const ByteVector &cE); + + /*! + * Removes \a cE to list of child elements of the frame. + * + * \see childElements() + */ + void removeChildElement(const ByteVector &cE); + + /*! + * Returns a reference to the frame list map. This is an FrameListMap of + * all of the frames embedded in the CTOC frame. + * + * This is the most convenient structure for accessing the CTOC frame's + * embedded frames. Many frame types allow multiple instances of the same + * frame type so this is a map of lists. In most cases however there will + * only be a single frame of a certain type. + * + * \warning You should not modify this data structure directly, instead + * use addEmbeddedFrame() and removeEmbeddedFrame(). + * + * \see embeddedFrameList() + */ + const FrameListMap &embeddedFrameListMap() const; + + /*! + * Returns a reference to the embedded frame list. This is an FrameList + * of all of the frames embedded in the CTOC frame in the order that they + * were parsed. + * + * This can be useful if for example you want iterate over the CTOC frame's + * embedded frames in the order that they occur in the CTOC frame. + * + * \warning You should not modify this data structure directly, instead + * use addEmbeddedFrame() and removeEmbeddedFrame(). + */ + const FrameList &embeddedFrameList() const; + + /*! + * Returns the embedded frame list for frames with the id \a frameID + * or an empty list if there are no embedded frames of that type. This + * is just a convenience and is equivalent to: + * + * \code + * embeddedFrameListMap()[frameID]; + * \endcode + * + * \see embeddedFrameListMap() + */ + const FrameList &embeddedFrameList(const ByteVector &frameID) const; + + /*! + * Add an embedded frame to the CTOC frame. At this point the CTOC frame + * takes ownership of the embedded frame and will handle freeing its memory. + * + * \note Using this method will invalidate any pointers on the list + * returned by embeddedFrameList() + */ + void addEmbeddedFrame(Frame *frame); + + /*! + * Remove an embedded frame from the CTOC frame. If \a del is true the frame's + * memory will be freed; if it is false, it must be deleted by the user. + * + * \note Using this method will invalidate any pointers on the list + * returned by embeddedFrameList() + */ + void removeEmbeddedFrame(Frame *frame, bool del = true); + + /*! + * Remove all embedded frames of type \a id from the CTOC frame and free their + * memory. + * + * \note Using this method will invalidate any pointers on the list + * returned by embeddedFrameList() + */ + void removeEmbeddedFrames(const ByteVector &id); + + virtual String toString() const; + + PropertyMap asProperties() const; + + /*! + * CTOC frames each have a unique element ID. This searches for a CTOC + * frame with the element ID \a eID and returns a pointer to it. This + * can be used to link together parent and child CTOC frames. + * + * \see elementID() + */ + static TableOfContentsFrame *findByElementID(const Tag *tag, const ByteVector &eID); + + /*! + * CTOC frames each contain a flag that indicates, if CTOC frame is top-level (there isn't + * any frame, which contains this frame in its child elements list). Only a single frame + * within tag can be top-level. This searches for a top-level CTOC frame. + * + * \see isTopLevel() + */ + static TableOfContentsFrame *findTopLevel(const Tag *tag); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + TableOfContentsFrame(const ID3v2::Header *tagHeader, const ByteVector &data, Header *h); + TableOfContentsFrame(const TableOfContentsFrame &); + TableOfContentsFrame &operator=(const TableOfContentsFrame &); + + class TableOfContentsFramePrivate; + TableOfContentsFramePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/tag.h b/taglib/include/taglib/tag.h new file mode 100644 index 0000000..be9628c --- /dev/null +++ b/taglib/include/taglib/tag.h @@ -0,0 +1,201 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_TAG_H +#define TAGLIB_TAG_H + +#include "taglib_export.h" +#include "tstring.h" + +namespace TagLib { + + //! A simple, generic interface to common audio meta data fields + + /*! + * This is an attempt to abstract away the difference in the meta data formats + * of various audio codecs and tagging schemes. As such it is generally a + * subset of what is available in the specific formats but should be suitable + * for most applications. This is meant to compliment the generic APIs found + * in TagLib::AudioProperties, TagLib::File and TagLib::FileRef. + */ + + class PropertyMap; + + class TAGLIB_EXPORT Tag + { + public: + + /*! + * Destroys this Tag instance. + */ + virtual ~Tag(); + + /*! + * Exports the tags of the file as dictionary mapping (human readable) tag + * names (Strings) to StringLists of tag values. + * The default implementation in this class considers only the usual built-in + * tags (artist, album, ...) and only one value per key. + */ + PropertyMap properties() const; + + /*! + * Removes unsupported properties, or a subset of them, from the tag. + * The parameter \a properties must contain only entries from + * properties().unsupportedData(). + * BIC: Will become virtual in future releases. Currently the non-virtual + * standard implementation of TagLib::Tag does nothing, since there are + * no unsupported elements. + */ + void removeUnsupportedProperties(const StringList& properties); + + /*! + * Sets the tags of this File to those specified in \a properties. This default + * implementation sets only the tags for which setter methods exist in this class + * (artist, album, ...), and only one value per key; the rest will be contained + * in the returned PropertyMap. + */ + PropertyMap setProperties(const PropertyMap &properties); + + /*! + * Returns the track name; if no track name is present in the tag + * String::null will be returned. + */ + virtual String title() const = 0; + + /*! + * Returns the artist name; if no artist name is present in the tag + * String::null will be returned. + */ + virtual String artist() const = 0; + + /*! + * Returns the album name; if no album name is present in the tag + * String::null will be returned. + */ + virtual String album() const = 0; + + /*! + * Returns the track comment; if no comment is present in the tag + * String::null will be returned. + */ + virtual String comment() const = 0; + + /*! + * Returns the genre name; if no genre is present in the tag String::null + * will be returned. + */ + virtual String genre() const = 0; + + /*! + * Returns the year; if there is no year set, this will return 0. + */ + virtual unsigned int year() const = 0; + + /*! + * Returns the track number; if there is no track number set, this will + * return 0. + */ + virtual unsigned int track() const = 0; + + /*! + * Sets the title to \a s. If \a s is String::null then this value will be + * cleared. + */ + virtual void setTitle(const String &s) = 0; + + /*! + * Sets the artist to \a s. If \a s is String::null then this value will be + * cleared. + */ + virtual void setArtist(const String &s) = 0; + + /*! + * Sets the album to \a s. If \a s is String::null then this value will be + * cleared. + */ + virtual void setAlbum(const String &s) = 0; + + /*! + * Sets the comment to \a s. If \a s is String::null then this value will be + * cleared. + */ + virtual void setComment(const String &s) = 0; + + /*! + * Sets the genre to \a s. If \a s is String::null then this value will be + * cleared. For tag formats that use a fixed set of genres, the appropriate + * value will be selected based on a string comparison. A list of available + * genres for those formats should be available in that type's + * implementation. + */ + virtual void setGenre(const String &s) = 0; + + /*! + * Sets the year to \a i. If \a s is 0 then this value will be cleared. + */ + virtual void setYear(unsigned int i) = 0; + + /*! + * Sets the track to \a i. If \a s is 0 then this value will be cleared. + */ + virtual void setTrack(unsigned int i) = 0; + + /*! + * Returns true if the tag does not contain any data. This should be + * reimplemented in subclasses that provide more than the basic tagging + * abilities in this class. + */ + virtual bool isEmpty() const; + + /*! + * Copies the generic data from one tag to another. + * + * \note This will no affect any of the lower level details of the tag. For + * instance if any of the tag type specific data (maybe a URL for a band) is + * set, this will not modify or copy that. This just copies using the API + * in this class. + * + * If \a overwrite is true then the values will be unconditionally copied. + * If false only empty values will be overwritten. + */ + static void duplicate(const Tag *source, Tag *target, bool overwrite = true); + + protected: + /*! + * Construct a Tag. This is protected since tags should only be instantiated + * through subclasses. + */ + Tag(); + + private: + Tag(const Tag &); + Tag &operator=(const Tag &); + + class TagPrivate; + TagPrivate *d; + }; +} + +#endif diff --git a/taglib/include/taglib/tag_c.h b/taglib/include/taglib/tag_c.h new file mode 100644 index 0000000..8d5f85f --- /dev/null +++ b/taglib/include/taglib/tag_c.h @@ -0,0 +1,299 @@ +/*************************************************************************** + copyright : (C) 2003 by Scott Wheeler + email : wheeler@kde.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * + * USA * + ***************************************************************************/ + +#ifndef TAGLIB_TAG_C +#define TAGLIB_TAG_C + +/* Do not include this in the main TagLib documentation. */ +#ifndef DO_NOT_DOCUMENT + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(TAGLIB_STATIC) +#define TAGLIB_C_EXPORT +#elif defined(_WIN32) || defined(_WIN64) +#ifdef MAKE_TAGLIB_C_LIB +#define TAGLIB_C_EXPORT __declspec(dllexport) +#else +#define TAGLIB_C_EXPORT __declspec(dllimport) +#endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1) +#define TAGLIB_C_EXPORT __attribute__ ((visibility("default"))) +#else +#define TAGLIB_C_EXPORT +#endif + +#ifndef BOOL +#define BOOL int +#endif + +/******************************************************************************* + * [ TagLib C Binding ] + * + * This is an interface to TagLib's "simple" API, meaning that you can read and + * modify media files in a generic, but not specialized way. This is a rough + * representation of TagLib::File and TagLib::Tag, for which the documentation + * is somewhat more complete and worth consulting. + *******************************************************************************/ + +/* + * These are used for type provide some type safety to the C API (as opposed to + * using void *, but pointers to them are simply cast to the corresponding C++ + * types in the implementation. + */ + +typedef struct { int dummy; } TagLib_File; +typedef struct { int dummy; } TagLib_Tag; +typedef struct { int dummy; } TagLib_AudioProperties; + +/*! + * By default all strings coming into or out of TagLib's C API are in UTF8. + * However, it may be desirable for TagLib to operate on Latin1 (ISO-8859-1) + * strings in which case this should be set to FALSE. + */ +TAGLIB_C_EXPORT void taglib_set_strings_unicode(BOOL unicode); + +/*! + * TagLib can keep track of strings that are created when outputting tag values + * and clear them using taglib_tag_clear_strings(). This is enabled by default. + * However if you wish to do more fine grained management of strings, you can do + * so by setting \a management to FALSE. + */ +TAGLIB_C_EXPORT void taglib_set_string_management_enabled(BOOL management); + +/*! + * Explicitly free a string returned from TagLib + */ +TAGLIB_C_EXPORT void taglib_free(void* pointer); + +/******************************************************************************* + * File API + ******************************************************************************/ + +typedef enum { + TagLib_File_MPEG, + TagLib_File_OggVorbis, + TagLib_File_FLAC, + TagLib_File_MPC, + TagLib_File_OggFlac, + TagLib_File_WavPack, + TagLib_File_Speex, + TagLib_File_TrueAudio, + TagLib_File_MP4, + TagLib_File_ASF +} TagLib_File_Type; + +/*! + * Creates a TagLib file based on \a filename. TagLib will try to guess the file + * type. + * + * \returns NULL if the file type cannot be determined or the file cannot + * be opened. + */ +TAGLIB_C_EXPORT TagLib_File *taglib_file_new(const char *filename); + +/*! + * 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); + +/*! + * Frees and closes the file. + */ +TAGLIB_C_EXPORT void taglib_file_free(TagLib_File *file); + +/*! + * Returns true if the file is open and readable and valid information for + * the Tag and / or AudioProperties was found. + */ + +TAGLIB_C_EXPORT BOOL taglib_file_is_valid(const TagLib_File *file); + +/*! + * Returns a pointer to the tag associated with this file. This will be freed + * automatically when the file is freed. + */ +TAGLIB_C_EXPORT TagLib_Tag *taglib_file_tag(const TagLib_File *file); + +/*! + * Returns a pointer to the audio properties associated with this file. This + * will be freed automatically when the file is freed. + */ +TAGLIB_C_EXPORT const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file); + +/*! + * Saves the \a file to disk. + */ +TAGLIB_C_EXPORT BOOL taglib_file_save(TagLib_File *file); + +/****************************************************************************** + * Tag API + ******************************************************************************/ + +/*! + * Returns a string with this tag's title. + * + * \note By default this string should be UTF8 encoded and its memory should be + * freed using taglib_tag_free_strings(). + */ +TAGLIB_C_EXPORT char *taglib_tag_title(const TagLib_Tag *tag); + +/*! + * Returns a string with this tag's artist. + * + * \note By default this string should be UTF8 encoded and its memory should be + * freed using taglib_tag_free_strings(). + */ +TAGLIB_C_EXPORT char *taglib_tag_artist(const TagLib_Tag *tag); + +/*! + * Returns a string with this tag's album name. + * + * \note By default this string should be UTF8 encoded and its memory should be + * freed using taglib_tag_free_strings(). + */ +TAGLIB_C_EXPORT char *taglib_tag_album(const TagLib_Tag *tag); + +/*! + * Returns a string with this tag's comment. + * + * \note By default this string should be UTF8 encoded and its memory should be + * freed using taglib_tag_free_strings(). + */ +TAGLIB_C_EXPORT char *taglib_tag_comment(const TagLib_Tag *tag); + +/*! + * Returns a string with this tag's genre. + * + * \note By default this string should be UTF8 encoded and its memory should be + * freed using taglib_tag_free_strings(). + */ +TAGLIB_C_EXPORT char *taglib_tag_genre(const TagLib_Tag *tag); + +/*! + * Returns the tag's year or 0 if year is not set. + */ +TAGLIB_C_EXPORT unsigned int taglib_tag_year(const TagLib_Tag *tag); + +/*! + * Returns the tag's track number or 0 if track number is not set. + */ +TAGLIB_C_EXPORT unsigned int taglib_tag_track(const TagLib_Tag *tag); + +/*! + * Sets the tag's title. + * + * \note By default this string should be UTF8 encoded. + */ +TAGLIB_C_EXPORT void taglib_tag_set_title(TagLib_Tag *tag, const char *title); + +/*! + * Sets the tag's artist. + * + * \note By default this string should be UTF8 encoded. + */ +TAGLIB_C_EXPORT void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist); + +/*! + * Sets the tag's album. + * + * \note By default this string should be UTF8 encoded. + */ +TAGLIB_C_EXPORT void taglib_tag_set_album(TagLib_Tag *tag, const char *album); + +/*! + * Sets the tag's comment. + * + * \note By default this string should be UTF8 encoded. + */ +TAGLIB_C_EXPORT void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment); + +/*! + * Sets the tag's genre. + * + * \note By default this string should be UTF8 encoded. + */ +TAGLIB_C_EXPORT void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre); + +/*! + * Sets the tag's year. 0 indicates that this field should be cleared. + */ +TAGLIB_C_EXPORT void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year); + +/*! + * Sets the tag's track number. 0 indicates that this field should be cleared. + */ +TAGLIB_C_EXPORT void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track); + +/*! + * Frees all of the strings that have been created by the tag. + */ +TAGLIB_C_EXPORT void taglib_tag_free_strings(void); + +/****************************************************************************** + * Audio Properties API + ******************************************************************************/ + +/*! + * Returns the length of the file in seconds. + */ +TAGLIB_C_EXPORT int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties); + +/*! + * Returns the bitrate of the file in kb/s. + */ +TAGLIB_C_EXPORT int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties); + +/*! + * Returns the sample rate of the file in Hz. + */ +TAGLIB_C_EXPORT int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties); + +/*! + * Returns the number of channels in the audio stream. + */ +TAGLIB_C_EXPORT int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties); + +/******************************************************************************* + * Special convenience ID3v2 functions + *******************************************************************************/ + +typedef enum { + TagLib_ID3v2_Latin1, + TagLib_ID3v2_UTF16, + TagLib_ID3v2_UTF16BE, + TagLib_ID3v2_UTF8 +} TagLib_ID3v2_Encoding; + +/*! + * This sets the default encoding for ID3v2 frames that are written to tags. + */ + +TAGLIB_C_EXPORT void taglib_id3v2_set_default_text_encoding(TagLib_ID3v2_Encoding encoding); + +#ifdef __cplusplus +} +#endif +#endif /* DO_NOT_DOCUMENT */ +#endif diff --git a/taglib/include/taglib/taglib.h b/taglib/include/taglib/taglib.h new file mode 100644 index 0000000..ffce61f --- /dev/null +++ b/taglib/include/taglib/taglib.h @@ -0,0 +1,179 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_H +#define TAGLIB_H + +#include "taglib_config.h" + +#define TAGLIB_MAJOR_VERSION 1 +#define TAGLIB_MINOR_VERSION 12 +#define TAGLIB_PATCH_VERSION 0 + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)) || defined(__clang__) +#define TAGLIB_IGNORE_MISSING_DESTRUCTOR _Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"") +#else +#define TAGLIB_IGNORE_MISSING_DESTRUCTOR +#endif + +#if (defined(_MSC_VER) && _MSC_VER >= 1600) +#define TAGLIB_CONSTRUCT_BITSET(x) static_cast(x) +#else +#define TAGLIB_CONSTRUCT_BITSET(x) static_cast(x) +#endif + +#if __cplusplus >= 201402 +#define TAGLIB_DEPRECATED [[deprecated]] +#elif defined(__GNUC__) || defined(__clang__) +#define TAGLIB_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define TAGLIB_DEPRECATED __declspec(deprecated) +#else +#define TAGLIB_DEPRECATED +#endif + +#include + +//! A namespace for all TagLib related classes and functions + +/*! + * This namespace contains everything in TagLib. For projects working with + * TagLib extensively it may be convenient to add a + * \code + * using namespace TagLib; + * \endcode + */ + +namespace TagLib { + + class String; + + // These integer types are deprecated. Do not use them. + + typedef wchar_t wchar; // Assumed to be sufficient to store a UTF-16 char. + typedef unsigned char uchar; + typedef unsigned short ushort; + typedef unsigned int uint; + typedef unsigned long ulong; + typedef unsigned long long ulonglong; + + /*! + * Unfortunately std::wstring isn't defined on some systems, (i.e. GCC < 3) + * so I'm providing something here that should be constant. + */ + typedef std::basic_string wstring; +} + +/*! + * \mainpage TagLib + * + * \section intro Introduction + * + * TagLib is a library for reading and editing audio meta data, commonly know as \e tags. + * + * Features: + * - A clean, high level, C++ API to handling audio meta data. + * - Format specific APIs for advanced API users. + * - ID3v1, ID3v2, APE, FLAC, Xiph, iTunes-style MP4 and WMA tag formats. + * - MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio, WavPack, Ogg FLAC, Ogg Vorbis, Speex and Opus file formats. + * - Basic audio file properties such as length, sample rate, etc. + * - Long term binary and source compatibility. + * - Extensible design, notably the ability to add other formats or extend current formats as a library user. + * - Full support for unicode and internationalized tags. + * - Dual MPL and + * LGPL licenses. + * - No external toolkit dependencies. + * + * \section why Why TagLib? + * + * TagLib originally was written to provide an updated and improved ID3v2 implementation in C++ for use + * in a variety of Open Source projects. Since development began in 2002 and the 1.0 release in 2004 + * it has expanded to cover a wide variety of tag and file formats and is used in a wide variety of + * Open Source and proprietary applications. It now supports a variety of UNIXes, including Apple's OS + * X, as well as Microsoft Windows. + * + * \section commercial Usage in Commercial Applications + * + * TagLib's licenses \e do allow usage within propriety (\e closed) applications, however TagLib is \e not + * public domain. Please note the requirements of the LGPL or MPL, and adhere to at least one of them. + * In simple terms, you must at a minimum note your usage of TagLib, note the licensing terms of TagLib and + * if you make changes to TagLib publish them. Please review the licenses above before using TagLib in your + * software. Note that you may choose either the MPL or the LGPL, you do not have to fulfill the + * requirements of both. + * + * \section installing Installing TagLib + * + * Please see the TagLib website for the latest + * downloads. + * + * TagLib can be built using the CMake build system. TagLib installs a taglib-config and pkg-config file to + * make it easier to integrate into various build systems. Note that TagLib's include install directory \e must + * be included in the header include path. Simply adding will \e not work. + * + * \section start Getting Started + * + * TagLib provides both simple, abstract APIs which make it possible to ignore the differences between tagging + * formats and format specific APIs which allow programmers to work with the features of specific tagging + * schemes. There is a similar abstraction mechanism for AudioProperties. + * + * The best place to start is with the Class Hierarchy linked at the top of the page. The File and + * AudioProperties classes and their subclasses are the core of TagLib. The FileRef class is also a convenient + * way for using a value-based handle. + * + * \note When working with FileRef please consider that it has only the most basic (extension-based) file + * type resolution. Please see its documentation on how to plug in more advanced file type resolution. (Such + * resolution may be part of later TagLib releases by default.) + * + * Here's a very simple example with TagLib: + * + * \code + * + * TagLib::FileRef f("Latex Solar Beef.mp3"); + * TagLib::String artist = f.tag()->artist(); // artist == "Frank Zappa" + * + * f.tag()->setAlbum("Fillmore East"); + * f.save(); + * + * TagLib::FileRef g("Free City Rhymes.ogg"); + * TagLib::String album = g.tag()->album(); // album == "NYC Ghosts & Flowers" + * + * g.tag()->setTrack(1); + * g.save(); + * + * \endcode + * + * More examples can be found in the \e examples directory of the source distribution. + * + * \section Contact + * + * Questions about TagLib should be directed to the TagLib mailing list, not directly to the author. + * + * - TagLib Homepage + * - TagLib Mailing List (taglib-devel@kde.org) + * + * \author TagLib authors. + */ + +#endif diff --git a/taglib/include/taglib/taglib_config.h b/taglib/include/taglib/taglib_config.h new file mode 100644 index 0000000..915f130 --- /dev/null +++ b/taglib/include/taglib/taglib_config.h @@ -0,0 +1,11 @@ +/* taglib_config.h. Generated by cmake from taglib_config.h.cmake */ + +#ifndef TAGLIB_TAGLIB_CONFIG_H +#define TAGLIB_TAGLIB_CONFIG_H + +/* These values are no longer used. This file is present only for compatibility reasons. */ + +#define TAGLIB_WITH_ASF 1 +#define TAGLIB_WITH_MP4 1 + +#endif diff --git a/taglib/include/taglib/taglib_export.h b/taglib/include/taglib/taglib_export.h new file mode 100644 index 0000000..737ae64 --- /dev/null +++ b/taglib/include/taglib/taglib_export.h @@ -0,0 +1,43 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_EXPORT_H +#define TAGLIB_EXPORT_H + +#if defined(TAGLIB_STATIC) +#define TAGLIB_EXPORT +#elif (defined(_WIN32) || defined(_WIN64)) +#ifdef MAKE_TAGLIB_LIB +#define TAGLIB_EXPORT __declspec(dllexport) +#else +#define TAGLIB_EXPORT __declspec(dllimport) +#endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1) +#define TAGLIB_EXPORT __attribute__ ((visibility("default"))) +#else +#define TAGLIB_EXPORT +#endif + +#endif diff --git a/taglib/include/taglib/tbytevector.h b/taglib/include/taglib/tbytevector.h new file mode 100644 index 0000000..41373c7 --- /dev/null +++ b/taglib/include/taglib/tbytevector.h @@ -0,0 +1,635 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_BYTEVECTOR_H +#define TAGLIB_BYTEVECTOR_H + +#include "taglib.h" +#include "taglib_export.h" + +#include +#include + +namespace TagLib { + + //! A byte vector + + /*! + * This class provides a byte vector with some methods that are useful for + * tagging purposes. Many of the search functions are tailored to what is + * useful for finding tag related patterns in a data array. + */ + + class TAGLIB_EXPORT ByteVector + { + public: +#ifndef DO_NOT_DOCUMENT + typedef std::vector::iterator Iterator; + typedef std::vector::const_iterator ConstIterator; + typedef std::vector::reverse_iterator ReverseIterator; + typedef std::vector::const_reverse_iterator ConstReverseIterator; +#endif + + /*! + * Constructs an empty byte vector. + */ + ByteVector(); + + /*! + * Construct a vector of size \a size with all values set to \a value by + * default. + */ + ByteVector(unsigned int size, char value = 0); + + /*! + * Constructs a byte vector that is a copy of \a v. + */ + ByteVector(const ByteVector &v); + + /*! + * Constructs a byte vector that is a copy of \a v. + */ + ByteVector(const ByteVector &v, unsigned int offset, unsigned int length); + + /*! + * Constructs a byte vector that contains \a c. + */ + ByteVector(char c); + + /*! + * Constructs a byte vector that copies \a data for up to \a length bytes. + */ + ByteVector(const char *data, unsigned int length); + + /*! + * Constructs a byte vector that copies \a data up to the first null + * byte. This is particularly useful for constructing byte arrays from + * string constants. + * + * \warning The behavior is undefined if \a data is not null terminated. + */ + ByteVector(const char *data); + + /*! + * Destroys this ByteVector instance. + */ + virtual ~ByteVector(); + + /*! + * Sets the data for the byte array using the first \a length bytes of \a data + */ + ByteVector &setData(const char *data, unsigned int length); + + /*! + * Sets the data for the byte array copies \a data up to the first null + * byte. The behavior is undefined if \a data is not null terminated. + */ + ByteVector &setData(const char *data); + + /*! + * Returns a pointer to the internal data structure. + * + * \warning Care should be taken when modifying this data structure as it is + * easy to corrupt the ByteVector when doing so. Specifically, while the + * data may be changed, its length may not be. + */ + char *data(); + + /*! + * Returns a pointer to the internal data structure which may not be modified. + */ + const char *data() const; + + /*! + * Returns a byte vector made up of the bytes starting at \a index and + * for \a length bytes. If \a length is not specified it will return the bytes + * from \a index to the end of the vector. + */ + ByteVector mid(unsigned int index, unsigned int length = 0xffffffff) const; + + /*! + * This essentially performs the same as operator[](), but instead of causing + * a runtime error if the index is out of bounds, it will return a null byte. + */ + char at(unsigned int index) const; + + /*! + * Searches the ByteVector for \a pattern starting at \a offset and returns + * the offset. Returns -1 if the pattern was not found. If \a byteAlign is + * specified the pattern will only be matched if it starts on a byte divisible + * by \a byteAlign (starting from \a offset). + */ + int find(const ByteVector &pattern, unsigned int offset = 0, int byteAlign = 1) const; + + /*! + * Searches the char for \a c starting at \a offset and returns + * the offset. Returns \a -1 if the pattern was not found. If \a byteAlign is + * specified the pattern will only be matched if it starts on a byte divisible + * by \a byteAlign (starting from \a offset). + */ + int find(char c, unsigned int offset = 0, int byteAlign = 1) const; + + /*! + * Searches the ByteVector for \a pattern starting from either the end of the + * vector or \a offset and returns the offset. Returns -1 if the pattern was + * not found. If \a byteAlign is specified the pattern will only be matched + * if it starts on a byte divisible by \a byteAlign (starting from \a offset). + */ + int rfind(const ByteVector &pattern, unsigned int offset = 0, int byteAlign = 1) const; + + /*! + * Checks to see if the vector contains the \a pattern starting at position + * \a offset. Optionally, if you only want to search for part of the pattern + * you can specify an offset within the pattern to start from. Also, you can + * specify to only check for the first \a patternLength bytes of \a pattern with + * the \a patternLength argument. + */ + bool containsAt(const ByteVector &pattern, unsigned int offset, + unsigned int patternOffset = 0, unsigned int patternLength = 0xffffffff) const; + + /*! + * Returns true if the vector starts with \a pattern. + */ + bool startsWith(const ByteVector &pattern) const; + + /*! + * Returns true if the vector ends with \a pattern. + */ + bool endsWith(const ByteVector &pattern) const; + + /*! + * Replaces \a oldByte with \a newByte and returns a reference to the + * ByteVector after the operation. This \e does modify the vector. + */ + ByteVector &replace(char oldByte, char newByte); + + /*! + * Replaces \a pattern with \a with and returns a reference to the ByteVector + * after the operation. This \e does modify the vector. + */ + ByteVector &replace(const ByteVector &pattern, const ByteVector &with); + + /*! + * Checks for a partial match of \a pattern at the end of the vector. It + * returns the offset of the partial match within the vector, or -1 if the + * pattern is not found. This method is particularly useful when searching for + * patterns that start in one vector and end in another. When combined with + * startsWith() it can be used to find a pattern that overlaps two buffers. + * + * \note This will not match the complete pattern at the end of the string; use + * endsWith() for that. + */ + int endsWithPartialMatch(const ByteVector &pattern) const; + + /*! + * Appends \a v to the end of the ByteVector. + */ + ByteVector &append(const ByteVector &v); + + /*! + * Appends \a c to the end of the ByteVector. + */ + ByteVector &append(char c); + + /*! + * Clears the data. + */ + ByteVector &clear(); + + /*! + * Returns the size of the array. + */ + unsigned int size() const; + + /*! + * Resize the vector to \a size. If the vector is currently less than + * \a size, pad the remaining spaces with \a padding. Returns a reference + * to the resized vector. + */ + ByteVector &resize(unsigned int size, char padding = 0); + + /*! + * Returns an Iterator that points to the front of the vector. + */ + Iterator begin(); + + /*! + * Returns a ConstIterator that points to the front of the vector. + */ + ConstIterator begin() const; + + /*! + * Returns an Iterator that points to the back of the vector. + */ + Iterator end(); + + /*! + * Returns a ConstIterator that points to the back of the vector. + */ + ConstIterator end() const; + + /*! + * Returns a ReverseIterator that points to the front of the vector. + */ + ReverseIterator rbegin(); + + /*! + * Returns a ConstReverseIterator that points to the front of the vector. + */ + ConstReverseIterator rbegin() const; + + /*! + * Returns a ReverseIterator that points to the back of the vector. + */ + ReverseIterator rend(); + + /*! + * Returns a ConstReverseIterator that points to the back of the vector. + */ + ConstReverseIterator rend() const; + + /*! + * Returns true if the vector is null. + * + * \note A vector may be empty without being null. So do not use this + * method to check if the vector is empty. + * + * \see isEmpty() + * + * \deprecated + */ + // BIC: remove + TAGLIB_DEPRECATED bool isNull() const; + + /*! + * Returns true if the ByteVector is empty. + * + * \see size() + * \see isNull() + */ + bool isEmpty() const; + + /*! + * Returns a CRC checksum of the byte vector's data. + * + * \note This uses an uncommon variant of CRC32 specializes in Ogg. + */ + // BIC: Remove or make generic. + unsigned int checksum() const; + + /*! + * Converts the first 4 bytes of the vector to an unsigned integer. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 == + * 0x01000000 == 1. + * + * \see fromUInt() + */ + unsigned int toUInt(bool mostSignificantByteFirst = true) const; + + /*! + * Converts the 4 bytes at \a offset of the vector to an unsigned integer. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 == + * 0x01000000 == 1. + * + * \see fromUInt() + */ + unsigned int toUInt(unsigned int offset, bool mostSignificantByteFirst = true) const; + + /*! + * Converts the \a length bytes at \a offset of the vector to an unsigned + * integer. If \a length is larger than 4, the excess is ignored. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 == + * 0x01000000 == 1. + * + * \see fromUInt() + */ + unsigned int toUInt(unsigned int offset, unsigned int length, + bool mostSignificantByteFirst = true) const; + + /*! + * Converts the first 2 bytes of the vector to a (signed) short. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1. + * + * \see fromShort() + */ + short toShort(bool mostSignificantByteFirst = true) const; + + /*! + * Converts the 2 bytes at \a offset of the vector to a (signed) short. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1. + * + * \see fromShort() + */ + short toShort(unsigned int offset, bool mostSignificantByteFirst = true) const; + + /*! + * Converts the first 2 bytes of the vector to a unsigned short. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1. + * + * \see fromShort() + */ + unsigned short toUShort(bool mostSignificantByteFirst = true) const; + + /*! + * Converts the 2 bytes at \a offset of the vector to a unsigned short. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1. + * + * \see fromShort() + */ + unsigned short toUShort(unsigned int offset, bool mostSignificantByteFirst = true) const; + + /*! + * Converts the first 8 bytes of the vector to a (signed) long long. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 00 00 00 00 00 00 01 == 0x0000000000000001 == 1, + * if false, $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1. + * + * \see fromUInt() + */ + long long toLongLong(bool mostSignificantByteFirst = true) const; + + /*! + * Converts the 8 bytes at \a offset of the vector to a (signed) long long. + * + * If \a mostSignificantByteFirst is true this will operate left to right + * evaluating the integer. For example if \a mostSignificantByteFirst is + * true then $00 00 00 00 00 00 00 01 == 0x0000000000000001 == 1, + * if false, $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1. + * + * \see fromUInt() + */ + long long toLongLong(unsigned int offset, bool mostSignificantByteFirst = true) const; + + /* + * Converts the 4 bytes at \a offset of the vector to a float as an IEEE754 + * 32-bit little-endian floating point number. + */ + float toFloat32LE(size_t offset) const; + + /* + * Converts the 4 bytes at \a offset of the vector to a float as an IEEE754 + * 32-bit big-endian floating point number. + */ + float toFloat32BE(size_t offset) const; + + /* + * Converts the 8 bytes at \a offset of the vector to a double as an IEEE754 + * 64-bit little-endian floating point number. + */ + double toFloat64LE(size_t offset) const; + + /* + * Converts the 8 bytes at \a offset of the vector to a double as an IEEE754 + * 64-bit big-endian floating point number. + */ + double toFloat64BE(size_t offset) const; + + /* + * Converts the 10 bytes at \a offset of the vector to a long double as an + * IEEE754 80-bit little-endian floating point number. + * + * \note This may compromise the precision depends on the size of long double. + */ + long double toFloat80LE(size_t offset) const; + + /* + * Converts the 10 bytes at \a offset of the vector to a long double as an + * IEEE754 80-bit big-endian floating point number. + * + * \note This may compromise the precision depends on the size of long double. + */ + long double toFloat80BE(size_t offset) const; + + /*! + * Creates a 4 byte ByteVector based on \a value. If + * \a mostSignificantByteFirst is true, then this will operate left to right + * in building the ByteVector. For example if \a mostSignificantByteFirst is + * true then $00 00 00 01 == 0x00000001 == 1, if false, $01 00 00 00 == + * 0x01000000 == 1. + * + * \see toUInt() + */ + static ByteVector fromUInt(unsigned int value, bool mostSignificantByteFirst = true); + + /*! + * Creates a 2 byte ByteVector based on \a value. If + * \a mostSignificantByteFirst is true, then this will operate left to right + * in building the ByteVector. For example if \a mostSignificantByteFirst is + * true then $00 01 == 0x0001 == 1, if false, $01 00 == 0x0100 == 1. + * + * \see toShort() + */ + static ByteVector fromShort(short value, bool mostSignificantByteFirst = true); + + /*! + * Creates a 8 byte ByteVector based on \a value. If + * \a mostSignificantByteFirst is true, then this will operate left to right + * in building the ByteVector. For example if \a mostSignificantByteFirst is + * true then $00 00 00 01 == 0x0000000000000001 == 1, if false, + * $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1. + * + * \see toLongLong() + */ + static ByteVector fromLongLong(long long value, bool mostSignificantByteFirst = true); + + /*! + * Creates a 4 byte ByteVector based on \a value as an IEEE754 32-bit + * little-endian floating point number. + * + * \see fromFloat32BE() + */ + static ByteVector fromFloat32LE(float value); + + /*! + * Creates a 4 byte ByteVector based on \a value as an IEEE754 32-bit + * big-endian floating point number. + * + * \see fromFloat32LE() + */ + static ByteVector fromFloat32BE(float value); + + /*! + * Creates a 8 byte ByteVector based on \a value as an IEEE754 64-bit + * little-endian floating point number. + * + * \see fromFloat64BE() + */ + static ByteVector fromFloat64LE(double value); + + /*! + * Creates a 8 byte ByteVector based on \a value as an IEEE754 64-bit + * big-endian floating point number. + * + * \see fromFloat64LE() + */ + static ByteVector fromFloat64BE(double value); + + /*! + * Returns a ByteVector based on the CString \a s. + */ + static ByteVector fromCString(const char *s, unsigned int length = 0xffffffff); + + /*! + * Returns a const reference to the byte at \a index. + */ + const char &operator[](int index) const; + + /*! + * Returns a reference to the byte at \a index. + */ + char &operator[](int index); + + /*! + * Returns true if this ByteVector and \a v are equal. + */ + bool operator==(const ByteVector &v) const; + + /*! + * Returns true if this ByteVector and \a v are not equal. + */ + bool operator!=(const ByteVector &v) const; + + /*! + * Returns true if this ByteVector and the null terminated C string \a s + * contain the same data. + */ + bool operator==(const char *s) const; + + /*! + * Returns true if this ByteVector and the null terminated C string \a s + * do not contain the same data. + */ + bool operator!=(const char *s) const; + + /*! + * Returns true if this ByteVector is less than \a v. The value of the + * vectors is determined by evaluating the character from left to right, and + * in the event one vector is a superset of the other, the size is used. + */ + bool operator<(const ByteVector &v) const; + + /*! + * Returns true if this ByteVector is greater than \a v. + */ + bool operator>(const ByteVector &v) const; + + /*! + * Returns a vector that is \a v appended to this vector. + */ + ByteVector operator+(const ByteVector &v) const; + + /*! + * Copies ByteVector \a v. + */ + ByteVector &operator=(const ByteVector &v); + + /*! + * Copies a byte \a c. + */ + ByteVector &operator=(char c); + + /*! + * Copies \a data up to the first null byte. + * + * \warning The behavior is undefined if \a data is not null terminated. + */ + ByteVector &operator=(const char *data); + + /*! + * Exchanges the content of the ByteVector by the content of \a v. + */ + void swap(ByteVector &v); + + /*! + * A static, empty ByteVector which is convenient and fast (since returning + * an empty or "null" value does not require instantiating a new ByteVector). + * + * \warning Do not modify this variable. It will mess up the internal state + * of TagLib. + * + * \deprecated + */ + // BIC: remove + TAGLIB_DEPRECATED static ByteVector null; + + /*! + * Returns a hex-encoded copy of the byte vector. + */ + ByteVector toHex() const; + + /*! + * Returns a base64 encoded copy of the byte vector + */ + ByteVector toBase64() const; + + /*! + * Decodes the base64 encoded byte vector. + */ + static ByteVector fromBase64(const ByteVector &); + + protected: + /* + * If this ByteVector is being shared via implicit sharing, do a deep copy + * of the data and separate from the shared members. This should be called + * by all non-const subclass members. + */ + void detach(); + + private: + class ByteVectorPrivate; + ByteVectorPrivate *d; + }; +} + +/*! + * \relates TagLib::ByteVector + * Streams the ByteVector \a v to the output stream \a s. + */ +TAGLIB_EXPORT std::ostream &operator<<(std::ostream &s, const TagLib::ByteVector &v); + +#endif diff --git a/taglib/include/taglib/tbytevectorlist.h b/taglib/include/taglib/tbytevectorlist.h new file mode 100644 index 0000000..5852583 --- /dev/null +++ b/taglib/include/taglib/tbytevectorlist.h @@ -0,0 +1,91 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_BYTEVECTORLIST_H +#define TAGLIB_BYTEVECTORLIST_H + +#include "taglib_export.h" +#include "tbytevector.h" +#include "tlist.h" + +namespace TagLib { + + //! A list of ByteVectors + + /*! + * A List specialization with some handy features useful for ByteVectors. + */ + + class TAGLIB_EXPORT ByteVectorList : public List + { + public: + + /*! + * Construct an empty ByteVectorList. + */ + ByteVectorList(); + + /*! + * Destroys this ByteVectorList instance. + */ + virtual ~ByteVectorList(); + + /*! + * Make a shallow, implicitly shared, copy of \a l. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + ByteVectorList(const ByteVectorList &l); + + /*! + * Convert the ByteVectorList to a ByteVector separated by \a separator. By + * default a space is used. + */ + ByteVector toByteVector(const ByteVector &separator = " ") const; + + /*! + * Splits the ByteVector \a v into several strings at \a pattern. This will + * not include the pattern in the returned ByteVectors. + */ + static ByteVectorList split(const ByteVector &v, const ByteVector &pattern, + int byteAlign = 1); + /*! + * Splits the ByteVector \a v into several strings at \a pattern. This will + * not include the pattern in the returned ByteVectors. \a max is the + * maximum number of entries that will be separated. If \a max for instance + * is 2 then a maximum of 1 match will be found and the vector will be split + * on that match. + */ + // BIC: merge with the function above + static ByteVectorList split(const ByteVector &v, const ByteVector &pattern, + int byteAlign, int max); + private: + class ByteVectorListPrivate; + ByteVectorListPrivate *d; + }; + +} + +#endif diff --git a/taglib/include/taglib/tbytevectorstream.h b/taglib/include/taglib/tbytevectorstream.h new file mode 100644 index 0000000..84327c4 --- /dev/null +++ b/taglib/include/taglib/tbytevectorstream.h @@ -0,0 +1,145 @@ +/*************************************************************************** + copyright : (C) 2011 by Lukas Lalinsky + email : lalinsky@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * 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_BYTEVECTORSTREAM_H +#define TAGLIB_BYTEVECTORSTREAM_H + +#include "taglib_export.h" +#include "taglib.h" +#include "tbytevector.h" +#include "tiostream.h" + +namespace TagLib { + + class String; + class Tag; + class AudioProperties; + + //! In-memory Stream class using ByteVector for its storage. + + class TAGLIB_EXPORT ByteVectorStream : public IOStream + { + public: + /*! + * Construct a File object and opens the \a file. \a file should be a + * be a C-string in the local file system encoding. + */ + ByteVectorStream(const ByteVector &data); + + /*! + * Destroys this ByteVectorStream instance. + */ + virtual ~ByteVectorStream(); + + /*! + * Returns the file name in the local file system encoding. + */ + FileName name() const; + + /*! + * Reads a block of size \a length at the current get pointer. + */ + ByteVector readBlock(unsigned long length); + + /*! + * Attempts to write the block \a data at the current get pointer. If the + * file is currently only opened read only -- i.e. readOnly() returns true -- + * this attempts to reopen the file in read/write mode. + * + * \note This should be used instead of using the streaming output operator + * for a ByteVector. And even this function is significantly slower than + * doing output with a char[]. + */ + void writeBlock(const ByteVector &data); + + /*! + * Insert \a data at position \a start in the file overwriting \a replace + * bytes of the original content. + * + * \note This method is slow since it requires rewriting all of the file + * after the insertion point. + */ + void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0); + + /*! + * Removes a block of the file starting a \a start and continuing for + * \a length bytes. + * + * \note This method is slow since it involves rewriting all of the file + * after the removed portion. + */ + void removeBlock(unsigned long start = 0, unsigned long length = 0); + + /*! + * Returns true if the file is read only (or if the file can not be opened). + */ + bool readOnly() const; + + /*! + * Since the file can currently only be opened as an argument to the + * constructor (sort-of by design), this returns if that open succeeded. + */ + bool isOpen() const; + + /*! + * Move the I/O pointer to \a offset in the file from position \a p. This + * defaults to seeking from the beginning of the file. + * + * \see Position + */ + void seek(long offset, Position p = Beginning); + + /*! + * Reset the end-of-file and error flags on the file. + */ + void clear(); + + /*! + * Returns the current offset within the file. + */ + long tell() const; + + /*! + * Returns the length of the file. + */ + long length(); + + /*! + * Truncates the file to a \a length. + */ + void truncate(long length); + + ByteVector *data(); + + protected: + + private: + class ByteVectorStreamPrivate; + ByteVectorStreamPrivate *d; + }; + +} + +#endif diff --git a/taglib/include/taglib/tdebuglistener.h b/taglib/include/taglib/tdebuglistener.h new file mode 100644 index 0000000..3c8e118 --- /dev/null +++ b/taglib/include/taglib/tdebuglistener.h @@ -0,0 +1,74 @@ +/*************************************************************************** + copyright : (C) 2013 by Tsuda Kageyu + email : tsuda.kageyu@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * 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_DEBUGLISTENER_H +#define TAGLIB_DEBUGLISTENER_H + +#include "taglib_export.h" +#include "tstring.h" + +namespace TagLib +{ + //! An abstraction for the listener to the debug messages. + + /*! + * This class enables you to handle the debug messages in your preferred + * way by subclassing this class, reimplementing printMessage() and setting + * your reimplementation as the default with setDebugListener(). + * + * \see setDebugListener() + */ + class TAGLIB_EXPORT DebugListener + { + public: + DebugListener(); + virtual ~DebugListener(); + + /*! + * When overridden in a derived class, redirects \a msg to your preferred + * channel such as stderr, Windows debugger or so forth. + */ + virtual void printMessage(const String &msg) = 0; + + private: + // Noncopyable + DebugListener(const DebugListener &); + DebugListener &operator=(const DebugListener &); + }; + + /*! + * Sets the listener that decides how the debug messages are redirected. + * If the parameter \a listener is null, the previous listener is released + * and default stderr listener is restored. + * + * \note The caller is responsible for deleting the previous listener + * as needed after it is released. + * + * \see DebugListener + */ + TAGLIB_EXPORT void setDebugListener(DebugListener *listener); +} + +#endif diff --git a/taglib/include/taglib/textidentificationframe.h b/taglib/include/taglib/textidentificationframe.h new file mode 100644 index 0000000..e49aa89 --- /dev/null +++ b/taglib/include/taglib/textidentificationframe.h @@ -0,0 +1,313 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_TEXTIDENTIFICATIONFRAME_H +#define TAGLIB_TEXTIDENTIFICATIONFRAME_H + +#include "tstringlist.h" +#include "tmap.h" +#include "taglib_export.h" + +#include "id3v2frame.h" + +namespace TagLib { + + namespace ID3v2 { + + class Tag; + typedef Map KeyConversionMap; + + //! An ID3v2 text identification frame implementation + + /*! + * This is an implementation of the most common type of ID3v2 frame -- text + * identification frames. There are a number of variations on this. Those + * enumerated in the ID3v2.4 standard are: + * + *
    + *
  • TALB Album/Movie/Show title
  • + *
  • TBPM BPM (beats per minute)
  • + *
  • TCOM Composer
  • + *
  • TCON Content type
  • + *
  • TCOP Copyright message
  • + *
  • TDEN Encoding time
  • + *
  • TDLY Playlist delay
  • + *
  • TDOR Original release time
  • + *
  • TDRC Recording time
  • + *
  • TDRL Release time
  • + *
  • TDTG Tagging time
  • + *
  • TENC Encoded by
  • + *
  • TEXT Lyricist/Text writer
  • + *
  • TFLT File type
  • + *
  • TIPL Involved people list
  • + *
  • TIT1 Content group description
  • + *
  • TIT2 Title/songname/content description
  • + *
  • TIT3 Subtitle/Description refinement
  • + *
  • TKEY Initial key
  • + *
  • TLAN Language(s)
  • + *
  • TLEN Length
  • + *
  • TMCL Musician credits list
  • + *
  • TMED Media type
  • + *
  • TMOO Mood
  • + *
  • TOAL Original album/movie/show title
  • + *
  • TOFN Original filename
  • + *
  • TOLY Original lyricist(s)/text writer(s)
  • + *
  • TOPE Original artist(s)/performer(s)
  • + *
  • TOWN File owner/licensee
  • + *
  • TPE1 Lead performer(s)/Soloist(s)
  • + *
  • TPE2 Band/orchestra/accompaniment
  • + *
  • TPE3 Conductor/performer refinement
  • + *
  • TPE4 Interpreted, remixed, or otherwise modified by
  • + *
  • TPOS Part of a set
  • + *
  • TPRO Produced notice
  • + *
  • TPUB Publisher
  • + *
  • TRCK Track number/Position in set
  • + *
  • TRSN Internet radio station name
  • + *
  • TRSO Internet radio station owner
  • + *
  • TSOA Album sort order
  • + *
  • TSOP Performer sort order
  • + *
  • TSOT Title sort order
  • + *
  • TSRC ISRC (international standard recording code)
  • + *
  • TSSE Software/Hardware and settings used for encoding
  • + *
  • TSST Set subtitle
  • + *
+ * + * The ID3v2 Frames document gives a description of each of these formats + * and the expected order of strings in each. ID3v2::Header::frameID() can + * be used to determine the frame type. + * + * \note If non-Latin1 compatible strings are used with this class, even if + * the text encoding is set to Latin1, the frame will be written using UTF8 + * (with the encoding flag appropriately set in the output). + */ + + class TAGLIB_EXPORT TextIdentificationFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty frame of type \a type. Uses \a encoding as the + * default text encoding. + * + * \note In this case you must specify the text encoding as it + * resolves the ambiguity between constructors. + * + * \note Please see the note in the class description regarding Latin1. + */ + TextIdentificationFrame(const ByteVector &type, String::Type encoding); + + /*! + * This is a dual purpose constructor. \a data can either be binary data + * that should be parsed or (at a minimum) the frame ID. + */ + explicit TextIdentificationFrame(const ByteVector &data); + + /*! + * This is a special factory method to create a TIPL (involved people list) + * frame from the given \a properties. Will parse key=[list of values] data + * into the TIPL format as specified in the ID3 standard. + */ + static TextIdentificationFrame *createTIPLFrame(const PropertyMap &properties); + + /*! + * This is a special factory method to create a TMCL (musician credits list) + * frame from the given \a properties. Will parse key=[list of values] data + * into the TMCL format as specified in the ID3 standard, where key should be + * of the form instrumentPrefix:instrument. + */ + static TextIdentificationFrame *createTMCLFrame(const PropertyMap &properties); + /*! + * Destroys this TextIdentificationFrame instance. + */ + virtual ~TextIdentificationFrame(); + + /*! + * Text identification frames are a list of string fields. + * + * This function will accept either a StringList or a String (using the + * StringList constructor that accepts a single String). + * + * \note This will not change the text encoding of the frame even if the + * strings passed in are not of the same encoding. Please use + * setEncoding(s.type()) if you wish to change the encoding of the frame. + */ + void setText(const StringList &l); + + // Reimplementations. + + virtual void setText(const String &s); + virtual String toString() const; + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \note Please see the note in the class description regarding Latin1. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \note Please see the note in the class description regarding Latin1. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + /*! + * Returns a list of the strings in this frame. + */ + StringList fieldList() const; + + /*! + * Returns a KeyConversionMap mapping a role as it would be used in a PropertyMap + * to the corresponding key used in a TIPL ID3 frame to describe that role. + */ + static const KeyConversionMap &involvedPeopleMap(); + + PropertyMap asProperties() const; + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + /*! + * The constructor used by the FrameFactory. + */ + TextIdentificationFrame(const ByteVector &data, Header *h); + + private: + TextIdentificationFrame(const TextIdentificationFrame &); + TextIdentificationFrame &operator=(const TextIdentificationFrame &); + + /*! + * Parses the special structure of a TIPL frame + * Only the whitelisted roles "ARRANGER", "ENGINEER", "PRODUCER", + * "DJMIXER" (ID3: "DJ-MIX") and "MIXER" (ID3: "MIX") are allowed. + */ + PropertyMap makeTIPLProperties() const; + /*! + * Parses the special structure of a TMCL frame. + */ + PropertyMap makeTMCLProperties() const; + class TextIdentificationFramePrivate; + TextIdentificationFramePrivate *d; + }; + + /*! + * This is a specialization of text identification frames that allows for + * user defined entries. Each entry has a description in addition to the + * normal list of fields that a text identification frame has. + * + * This description identifies the frame and must be unique. + */ + + //! An ID3v2 custom text identification frame implementation + + class TAGLIB_EXPORT UserTextIdentificationFrame : public TextIdentificationFrame + { + friend class FrameFactory; + + public: + /*! + * Constructs an empty user defined text identification frame. For this to be + * a useful frame both a description and text must be set. + */ + explicit UserTextIdentificationFrame(String::Type encoding = String::Latin1); + + /*! + * Creates a frame based on \a data. + */ + explicit UserTextIdentificationFrame(const ByteVector &data); + + /*! + * Creates a user defined text identification frame with the given \a description + * and \a values. + */ + UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding = String::UTF8); + + virtual String toString() const; + + /*! + * Returns the description for this frame. + */ + String description() const; + + /*! + * Sets the description of the frame to \a s. \a s must be unique. You can + * check for the presence of another user defined text frame of the same type + * using find() and testing for null. + */ + void setDescription(const String &s); + + StringList fieldList() const; + void setText(const String &text); + void setText(const StringList &fields); + + /*! + * A UserTextIdentificationFrame is parsed into a PropertyMap as follows: + * - the key is the frame's description, uppercased + * - if the description contains '::', only the substring after that + * separator is considered as key (compatibility with exfalso) + * - if the above rules don't yield a valid key (e.g. containing non-ASCII + * characters), the returned map will contain an entry "TXXX/" + * in its unsupportedData() list. + * - The values will be copies of the fieldList(). + * - If the description() appears as value in fieldList(), it will be omitted + * in the value list, in order to be compatible with TagLib which copies + * the description() into the fieldList(). + */ + PropertyMap asProperties() const; + + /*! + * Searches for the user defined text frame with the description \a description + * in \a tag. This returns null if no matching frames were found. + */ + static UserTextIdentificationFrame *find(Tag *tag, const String &description); + + private: + UserTextIdentificationFrame(const ByteVector &data, Header *h); + UserTextIdentificationFrame(const TextIdentificationFrame &); + UserTextIdentificationFrame &operator=(const UserTextIdentificationFrame &); + + void checkFields(); + + class UserTextIdentificationFramePrivate; + UserTextIdentificationFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/tfile.h b/taglib/include/taglib/tfile.h new file mode 100644 index 0000000..bdc4f12 --- /dev/null +++ b/taglib/include/taglib/tfile.h @@ -0,0 +1,323 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_FILE_H +#define TAGLIB_FILE_H + +#include "taglib_export.h" +#include "taglib.h" +#include "tag.h" +#include "tbytevector.h" +#include "tiostream.h" + +namespace TagLib { + + class String; + class Tag; + class AudioProperties; + class PropertyMap; + + //! A file class with some useful methods for tag manipulation + + /*! + * This class is a basic file class with some methods that are particularly + * useful for tag editors. It has methods to take advantage of + * ByteVector and a binary search method for finding patterns in a file. + */ + + class TAGLIB_EXPORT File + { + public: + /*! + * Position in the file used for seeking. + */ + enum Position { + //! Seek from the beginning of the file. + Beginning, + //! Seek from the current position in the file. + Current, + //! Seek from the end of the file. + End + }; + + /*! + * Specify which tags to strip either explicitly, or on save. + */ + enum StripTags { + StripNone, // + +namespace TagLib { + + //! A generic, implicitly shared list. + + /*! + * This is basic generic list that's somewhere between a std::list and a + * QValueList. This class is implicitly shared. For example: + * + * \code + * + * TagLib::List l = someOtherIntList; + * + * \endcode + * + * The above example is very cheap. This also makes lists suitable for the + * return types of functions. The above example will just copy a pointer rather + * than copying the data in the list. When your \e shared list's data changes, + * only \e then will the data be copied. + */ + + template class List + { + public: +#ifndef DO_NOT_DOCUMENT + typedef typename std::list::iterator Iterator; + typedef typename std::list::const_iterator ConstIterator; +#endif + + /*! + * Constructs an empty list. + */ + List(); + + /*! + * Make a shallow, implicitly shared, copy of \a l. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + List(const List &l); + + /*! + * Destroys this List instance. If auto deletion is enabled and this list + * contains a pointer type all of the members are also deleted. + */ + virtual ~List(); + + /*! + * Returns an STL style iterator to the beginning of the list. See + * std::list::const_iterator for the semantics. + */ + Iterator begin(); + + /*! + * Returns an STL style constant iterator to the beginning of the list. See + * std::list::iterator for the semantics. + */ + ConstIterator begin() const; + + /*! + * Returns an STL style iterator to the end of the list. See + * std::list::iterator for the semantics. + */ + Iterator end(); + + /*! + * Returns an STL style constant iterator to the end of the list. See + * std::list::const_iterator for the semantics. + */ + ConstIterator end() const; + + /*! + * Inserts a copy of \a value before \a it. + */ + Iterator insert(Iterator it, const T &value); + + /*! + * Inserts the \a value into the list. This assumes that the list is + * currently sorted. If \a unique is true then the value will not + * be inserted if it is already in the list. + */ + List &sortedInsert(const T &value, bool unique = false); + + /*! + * Appends \a item to the end of the list and returns a reference to the + * list. + */ + List &append(const T &item); + + /*! + * Appends all of the values in \a l to the end of the list and returns a + * reference to the list. + */ + List &append(const List &l); + + /*! + * Prepends \a item to the beginning list and returns a reference to the + * list. + */ + List &prepend(const T &item); + + /*! + * Prepends all of the items in \a l to the beginning list and returns a + * reference to the list. + */ + List &prepend(const List &l); + + /*! + * Clears the list. If auto deletion is enabled and this list contains a + * pointer type the members are also deleted. + * + * \see setAutoDelete() + */ + List &clear(); + + /*! + * Returns the number of elements in the list. + * + * \see isEmpty() + */ + unsigned int size() const; + + /*! + * Returns whether or not the list is empty. + * + * \see size() + */ + bool isEmpty() const; + + /*! + * Find the first occurrence of \a value. + */ + Iterator find(const T &value); + + /*! + * Find the first occurrence of \a value. + */ + ConstIterator find(const T &value) const; + + /*! + * Returns true if the list contains \a value. + */ + bool contains(const T &value) const; + + /*! + * Erase the item at \a it from the list. + */ + Iterator erase(Iterator it); + + /*! + * Returns a reference to the first item in the list. + */ + const T &front() const; + + /*! + * Returns a reference to the first item in the list. + */ + T &front(); + + /*! + * Returns a reference to the last item in the list. + */ + const T &back() const; + + /*! + * Returns a reference to the last item in the list. + */ + T &back(); + + /*! + * Auto delete the members of the list when the last reference to the list + * passes out of scope. This will have no effect on lists which do not + * contain a pointer type. + * + * \note This relies on partial template instantiation -- most modern C++ + * compilers should now support this. + */ + void setAutoDelete(bool autoDelete); + + /*! + * Returns a reference to item \a i in the list. + * + * \warning This method is slow. Use iterators to loop through the list. + */ + T &operator[](unsigned int i); + + /*! + * Returns a const reference to item \a i in the list. + * + * \warning This method is slow. Use iterators to loop through the list. + */ + const T &operator[](unsigned int i) const; + + /*! + * Make a shallow, implicitly shared, copy of \a l. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + List &operator=(const List &l); + + /*! + * Exchanges the content of this list by the content of \a l. + */ + void swap(List &l); + + /*! + * Compares this list with \a l and returns true if all of the elements are + * the same. + */ + bool operator==(const List &l) const; + + /*! + * Compares this list with \a l and returns true if the lists differ. + */ + bool operator!=(const List &l) const; + + protected: + /* + * If this List is being shared via implicit sharing, do a deep copy of the + * data and separate from the shared members. This should be called by all + * non-const subclass members. + */ + void detach(); + + private: +#ifndef DO_NOT_DOCUMENT + template class ListPrivate; + ListPrivate *d; +#endif + }; + +} + +// Since GCC doesn't support the "export" keyword, we have to include the +// implementation. + +#include "tlist.tcc" + +#endif diff --git a/taglib/include/taglib/tlist.tcc b/taglib/include/taglib/tlist.tcc new file mode 100644 index 0000000..478f098 --- /dev/null +++ b/taglib/include/taglib/tlist.tcc @@ -0,0 +1,323 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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 +#include "trefcounter.h" + +namespace TagLib { + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +// The functionality of List::setAutoDelete() is implemented here partial +// template specialization. This is implemented in such a way that calling +// setAutoDelete() on non-pointer types will simply have no effect. + +// A base for the generic and specialized private class types. New +// non-templatized members should be added here. + +// BIC change to RefCounter +class ListPrivateBase : public RefCounterOld +{ +public: + ListPrivateBase() : autoDelete(false) {} + bool autoDelete; +}; + +// A generic implementation + +template +template class List::ListPrivate : public ListPrivateBase +{ +public: + ListPrivate() : ListPrivateBase() {} + ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} + void clear() { + list.clear(); + } + std::list list; +}; + +// A partial specialization for all pointer types that implements the +// setAutoDelete() functionality. + +template +template class List::ListPrivate : public ListPrivateBase +{ +public: + ListPrivate() : ListPrivateBase() {} + ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} + ~ListPrivate() { + clear(); + } + void clear() { + if(autoDelete) { + typename std::list::const_iterator it = list.begin(); + for(; it != list.end(); ++it) + delete *it; + } + list.clear(); + } + std::list list; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +template +List::List() : + d(new ListPrivate()) +{ +} + +template +List::List(const List &l) : d(l.d) +{ + d->ref(); +} + +template +List::~List() +{ + if(d->deref()) + delete d; +} + +template +typename List::Iterator List::begin() +{ + detach(); + return d->list.begin(); +} + +template +typename List::ConstIterator List::begin() const +{ + return d->list.begin(); +} + +template +typename List::Iterator List::end() +{ + detach(); + return d->list.end(); +} + +template +typename List::ConstIterator List::end() const +{ + return d->list.end(); +} + +template +typename List::Iterator List::insert(Iterator it, const T &item) +{ + detach(); + return d->list.insert(it, item); +} + +template +List &List::sortedInsert(const T &value, bool unique) +{ + detach(); + Iterator it = begin(); + while(it != end() && *it < value) + ++it; + if(unique && it != end() && *it == value) + return *this; + insert(it, value); + return *this; +} + +template +List &List::append(const T &item) +{ + detach(); + d->list.push_back(item); + return *this; +} + +template +List &List::append(const List &l) +{ + detach(); + d->list.insert(d->list.end(), l.begin(), l.end()); + return *this; +} + +template +List &List::prepend(const T &item) +{ + detach(); + d->list.push_front(item); + return *this; +} + +template +List &List::prepend(const List &l) +{ + detach(); + d->list.insert(d->list.begin(), l.begin(), l.end()); + return *this; +} + +template +List &List::clear() +{ + detach(); + d->clear(); + return *this; +} + +template +unsigned int List::size() const +{ + return static_cast(d->list.size()); +} + +template +bool List::isEmpty() const +{ + return d->list.empty(); +} + +template +typename List::Iterator List::find(const T &value) +{ + detach(); + return std::find(d->list.begin(), d->list.end(), value); +} + +template +typename List::ConstIterator List::find(const T &value) const +{ + return std::find(d->list.begin(), d->list.end(), value); +} + +template +bool List::contains(const T &value) const +{ + return std::find(d->list.begin(), d->list.end(), value) != d->list.end(); +} + +template +typename List::Iterator List::erase(Iterator it) +{ + return d->list.erase(it); +} + +template +const T &List::front() const +{ + return d->list.front(); +} + +template +T &List::front() +{ + detach(); + return d->list.front(); +} + +template +const T &List::back() const +{ + return d->list.back(); +} + +template +void List::setAutoDelete(bool autoDelete) +{ + d->autoDelete = autoDelete; +} + +template +T &List::back() +{ + detach(); + return d->list.back(); +} + +template +T &List::operator[](unsigned int i) +{ + Iterator it = d->list.begin(); + std::advance(it, i); + + return *it; +} + +template +const T &List::operator[](unsigned int i) const +{ + ConstIterator it = d->list.begin(); + std::advance(it, i); + + return *it; +} + +template +List &List::operator=(const List &l) +{ + List(l).swap(*this); + return *this; +} + +template +void List::swap(List &l) +{ + using std::swap; + + swap(d, l.d); +} + +template +bool List::operator==(const List &l) const +{ + return d->list == l.d->list; +} + +template +bool List::operator!=(const List &l) const +{ + return d->list != l.d->list; +} + +//////////////////////////////////////////////////////////////////////////////// +// protected members +//////////////////////////////////////////////////////////////////////////////// + +template +void List::detach() +{ + if(d->count() > 1) { + d->deref(); + d = new ListPrivate(d->list); + } +} + +} // namespace TagLib diff --git a/taglib/include/taglib/tmap.h b/taglib/include/taglib/tmap.h new file mode 100644 index 0000000..f54e5a2 --- /dev/null +++ b/taglib/include/taglib/tmap.h @@ -0,0 +1,204 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_MAP_H +#define TAGLIB_MAP_H + +#include + +#include "taglib.h" + +namespace TagLib { + + //! A generic, implicitly shared map. + + /*! + * This implements a standard map container that associates a key with a value + * and has fast key-based lookups. This map is also implicitly shared making + * it suitable for pass-by-value usage. + */ + + template class Map + { + public: +#ifndef DO_NOT_DOCUMENT +#ifdef WANT_CLASS_INSTANTIATION_OF_MAP + // Some STL implementations get snippy over the use of the + // class keyword to distinguish different templates; Sun Studio + // in particular finds multiple specializations in certain rare + // cases and complains about that. GCC doesn't seem to mind, + // and uses the typedefs further below without the class keyword. + // Not all the specializations of Map can use the class keyword + // (when T is not actually a class type), so don't apply this + // generally. + typedef typename std::map::iterator Iterator; + typedef typename std::map::const_iterator ConstIterator; +#else + typedef typename std::map::iterator Iterator; + typedef typename std::map::const_iterator ConstIterator; +#endif +#endif + + /*! + * Constructs an empty Map. + */ + Map(); + + /*! + * Make a shallow, implicitly shared, copy of \a m. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + Map(const Map &m); + + /*! + * Destroys this instance of the Map. + */ + virtual ~Map(); + + /*! + * Returns an STL style iterator to the beginning of the map. See + * std::map::iterator for the semantics. + */ + Iterator begin(); + + /*! + * Returns an STL style iterator to the beginning of the map. See + * std::map::const_iterator for the semantics. + */ + ConstIterator begin() const; + + /*! + * Returns an STL style iterator to the end of the map. See + * std::map::iterator for the semantics. + */ + Iterator end(); + + /*! + * Returns an STL style iterator to the end of the map. See + * std::map::const_iterator for the semantics. + */ + ConstIterator end() const; + + /*! + * Inserts \a value under \a key in the map. If a value for \a key already + * exists it will be overwritten. + */ + Map &insert(const Key &key, const T &value); + + /*! + * Removes all of the elements from elements from the map. This however + * will not delete pointers if the mapped type is a pointer type. + */ + Map &clear(); + + /*! + * The number of elements in the map. + * + * \see isEmpty() + */ + unsigned int size() const; + + /*! + * Returns true if the map is empty. + * + * \see size() + */ + bool isEmpty() const; + + /*! + * Find the first occurrence of \a key. + */ + Iterator find(const Key &key); + + /*! + * Find the first occurrence of \a key. + */ + ConstIterator find(const Key &key) const; + + /*! + * Returns true if the map contains an instance of \a key. + */ + bool contains(const Key &key) const; + + /*! + * Erase the item at \a it from the list. + */ + Map &erase(Iterator it); + + /*! + * Erase the item with \a key from the list. + */ + Map &erase(const Key &key); + + /*! + * Returns a reference to the value associated with \a key. + * + * \note This has undefined behavior if the key is not present in the map. + */ + const T &operator[](const Key &key) const; + + /*! + * Returns a reference to the value associated with \a key. + * + * \note This has undefined behavior if the key is not present in the map. + */ + T &operator[](const Key &key); + + /*! + * Make a shallow, implicitly shared, copy of \a m. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + Map &operator=(const Map &m); + + /*! + * Exchanges the content of this map by the content of \a m. + */ + void swap(Map &m); + + protected: + /* + * If this List is being shared via implicit sharing, do a deep copy of the + * data and separate from the shared members. This should be called by all + * non-const subclass members. + */ + void detach(); + + private: +#ifndef DO_NOT_DOCUMENT + template class MapPrivate; + MapPrivate *d; +#endif + }; + +} + +// Since GCC doesn't support the "export" keyword, we have to include the +// implementation. + +#include "tmap.tcc" + +#endif diff --git a/taglib/include/taglib/tmap.tcc b/taglib/include/taglib/tmap.tcc new file mode 100644 index 0000000..2e4ed5e --- /dev/null +++ b/taglib/include/taglib/tmap.tcc @@ -0,0 +1,199 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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 "trefcounter.h" + +namespace TagLib { + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +// BIC change to RefCounter +template +template +class Map::MapPrivate : public RefCounterOld +{ +public: + MapPrivate() : RefCounterOld() {} +#ifdef WANT_CLASS_INSTANTIATION_OF_MAP + MapPrivate(const std::map& m) : RefCounterOld(), map(m) {} + std::map map; +#else + MapPrivate(const std::map& m) : RefCounterOld(), map(m) {} + std::map map; +#endif +}; + +template +Map::Map() : + d(new MapPrivate()) +{ +} + +template +Map::Map(const Map &m) : d(m.d) +{ + d->ref(); +} + +template +Map::~Map() +{ + if(d->deref()) + delete(d); +} + +template +typename Map::Iterator Map::begin() +{ + detach(); + return d->map.begin(); +} + +template +typename Map::ConstIterator Map::begin() const +{ + return d->map.begin(); +} + +template +typename Map::Iterator Map::end() +{ + detach(); + return d->map.end(); +} + +template +typename Map::ConstIterator Map::end() const +{ + return d->map.end(); +} + +template +Map &Map::insert(const Key &key, const T &value) +{ + detach(); + d->map[key] = value; + return *this; +} + +template +Map &Map::clear() +{ + detach(); + d->map.clear(); + return *this; +} + +template +bool Map::isEmpty() const +{ + return d->map.empty(); +} + +template +typename Map::Iterator Map::find(const Key &key) +{ + detach(); + return d->map.find(key); +} + +template +typename Map::ConstIterator Map::find(const Key &key) const +{ + return d->map.find(key); +} + +template +bool Map::contains(const Key &key) const +{ + return d->map.find(key) != d->map.end(); +} + +template +Map &Map::erase(Iterator it) +{ + detach(); + d->map.erase(it); + return *this; +} + +template +Map &Map::erase(const Key &key) +{ + detach(); + d->map.erase(key); + return *this; +} + +template +unsigned int Map::size() const +{ + return static_cast(d->map.size()); +} + +template +const T &Map::operator[](const Key &key) const +{ + return d->map[key]; +} + +template +T &Map::operator[](const Key &key) +{ + detach(); + return d->map[key]; +} + +template +Map &Map::operator=(const Map &m) +{ + Map(m).swap(*this); + return *this; +} + +template +void Map::swap(Map &m) +{ + using std::swap; + + swap(d, m.d); +} + +//////////////////////////////////////////////////////////////////////////////// +// protected members +//////////////////////////////////////////////////////////////////////////////// + +template +void Map::detach() +{ + if(d->count() > 1) { + d->deref(); + d = new MapPrivate(d->map); + } +} + +} // namespace TagLib diff --git a/taglib/include/taglib/tpropertymap.h b/taglib/include/taglib/tpropertymap.h new file mode 100644 index 0000000..27731a8 --- /dev/null +++ b/taglib/include/taglib/tpropertymap.h @@ -0,0 +1,242 @@ +/*************************************************************************** + copyright : (C) 2012 by Michael Helmling + email : helmling@mathematik.uni-kl.de + ***************************************************************************/ + +/*************************************************************************** + * 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_PROPERTYMAP_H_ +#define TAGLIB_PROPERTYMAP_H_ + +#include "tmap.h" +#include "tstringlist.h" + +namespace TagLib { + + typedef Map SimplePropertyMap; + + //! A map for format-independent tag representations. + + /*! + * This map implements a generic representation of textual audio metadata + * ("tags") realized as pairs of a case-insensitive key + * and a nonempty list of corresponding values, each value being an arbitrary + * unicode String. + * + * Note that most metadata formats pose additional conditions on the tag keys. The + * most popular ones (Vorbis, APE, ID3v2) should support all ASCII only words of + * length between 2 and 16. + * + * This class can contain any tags, but here is a list of "well-known" tags that + * you might want to use: + * + * Basic tags: + * + * - TITLE + * - ALBUM + * - ARTIST + * - ALBUMARTIST + * - SUBTITLE + * - TRACKNUMBER + * - DISCNUMBER + * - DATE + * - ORIGINALDATE + * - GENRE + * - COMMENT + * + * Sort names: + * + * - TITLESORT + * - ALBUMSORT + * - ARTISTSORT + * - ALBUMARTISTSORT + * - COMPOSERSORT + * + * Credits: + * + * - COMPOSER + * - LYRICIST + * - CONDUCTOR + * - REMIXER + * - PERFORMER:\ + * + * Other tags: + * + * - ISRC + * - ASIN + * - BPM + * - COPYRIGHT + * - ENCODEDBY + * - MOOD + * - COMMENT + * - MEDIA + * - LABEL + * - CATALOGNUMBER + * - BARCODE + * - RELEASECOUNTRY + * - RELEASESTATUS + * - RELEASETYPE + * + * MusicBrainz identifiers: + * + * - MUSICBRAINZ_TRACKID + * - MUSICBRAINZ_ALBUMID + * - MUSICBRAINZ_RELEASEGROUPID + * - MUSICBRAINZ_RELEASETRACKID + * - MUSICBRAINZ_WORKID + * - MUSICBRAINZ_ARTISTID + * - MUSICBRAINZ_ALBUMARTISTID + * - ACOUSTID_ID + * - ACOUSTID_FINGERPRINT + * - MUSICIP_PUID + * + */ + + class TAGLIB_EXPORT PropertyMap: public SimplePropertyMap + { + public: + + typedef SimplePropertyMap::Iterator Iterator; + typedef SimplePropertyMap::ConstIterator ConstIterator; + + PropertyMap(); + + PropertyMap(const PropertyMap &m); + + /*! + * Creates a PropertyMap initialized from a SimplePropertyMap. Copies all + * entries from \a m that have valid keys. + * Invalid keys will be appended to the unsupportedData() list. + */ + PropertyMap(const SimplePropertyMap &m); + + virtual ~PropertyMap(); + + /*! + * Inserts \a values under \a key in the map. If \a key already exists, + * then \a values will be appended to the existing StringList. + * The returned value indicates success, i.e. whether \a key is a + * valid key. + */ + bool insert(const String &key, const StringList &values); + + /*! + * Replaces any existing values for \a key with the given \a values, + * and simply insert them if \a key did not exist before. + * The returned value indicates success, i.e. whether \a key is a + * valid key. + */ + bool replace(const String &key, const StringList &values); + + /*! + * Find the first occurrence of \a key. + */ + Iterator find(const String &key); + + /*! + * Find the first occurrence of \a key. + */ + ConstIterator find(const String &key) const; + + /*! + * Returns true if the map contains values for \a key. + */ + bool contains(const String &key) const; + + /*! + * Returns true if this map contains all keys of \a other + * and the values coincide for that keys. Does not take + * the unsupportedData list into account. + */ + bool contains(const PropertyMap &other) const; + + /*! + * Erase the \a key and its values from the map. + */ + PropertyMap &erase(const String &key); + + /*! + * Erases from this map all keys that appear in \a other. + */ + PropertyMap &erase(const PropertyMap &other); + + /*! + * Merge the contents of \a other into this PropertyMap. + * If a key is contained in both maps, the values of the second + * are appended to that of the first. + * The unsupportedData() lists are concatenated as well. + */ + PropertyMap &merge(const PropertyMap &other); + + /*! + * Returns a reference to the value associated with \a key. + * + * \note: If \a key is not contained in the map, an empty + * StringList is returned without error. + */ + const StringList &operator[](const String &key) const; + + /*! + * Returns a reference to the value associated with \a key. + * + * \note: If \a key is not contained in the map, an empty + * StringList is returned. You can also directly add entries + * by using this function as an lvalue. + */ + StringList &operator[](const String &key); + + /*! + * Returns true if and only if \a other has the same contents as this map. + */ + bool operator==(const PropertyMap &other) const; + + /*! + * Returns false if and only \a other has the same contents as this map. + */ + bool operator!=(const PropertyMap &other) const; + + /*! + * If a PropertyMap is read from a File object using File::properties(), + * the StringList returned from this function will represent metadata + * that could not be parsed into the PropertyMap representation. This could + * be e.g. binary data, unknown ID3 frames, etc. + * You can remove items from the returned list, which tells TagLib to remove + * those unsupported elements if you call File::setProperties() with the + * same PropertyMap as argument. + */ + StringList &unsupportedData(); + const StringList &unsupportedData() const; + + /*! + * Removes all entries which have an empty value list. + */ + void removeEmpty(); + + String toString() const; + + private: + + + StringList unsupported; + }; + +} +#endif /* TAGLIB_PROPERTYMAP_H_ */ diff --git a/taglib/include/taglib/trefcounter.h b/taglib/include/taglib/trefcounter.h new file mode 100644 index 0000000..db97c53 --- /dev/null +++ b/taglib/include/taglib/trefcounter.h @@ -0,0 +1,114 @@ +/*************************************************************************** + copyright : (C) 2013 by Tsuda Kageyu + email : tsuda.kageyu@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * 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_REFCOUNTER_H +#define TAGLIB_REFCOUNTER_H + +#include "taglib_export.h" +#include "taglib.h" + +#ifdef __APPLE__ +# define OSATOMIC_DEPRECATED 0 +# include +# define TAGLIB_ATOMIC_MAC +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +# define TAGLIB_ATOMIC_WIN +#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \ + && (defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__x86_64) || defined(__ia64)) \ + && !defined(__INTEL_COMPILER) +# define TAGLIB_ATOMIC_GCC +#elif defined(__ia64) && defined(__INTEL_COMPILER) +# include +# define TAGLIB_ATOMIC_GCC +#endif + +#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class. +/*! + * \internal + * This is just used as a base class for shared classes in TagLib. + * + * \warning This is not part of the TagLib public API! + */ +namespace TagLib +{ + + class TAGLIB_EXPORT RefCounter + { + public: + RefCounter(); + virtual ~RefCounter(); + + void ref(); + bool deref(); + int count() const; + + private: + class RefCounterPrivate; + RefCounterPrivate *d; + }; + + // BIC this old class is needed by tlist.tcc and tmap.tcc + class RefCounterOld + { + public: + RefCounterOld() : refCount(1) {} + +#ifdef TAGLIB_ATOMIC_MAC + void ref() { OSAtomicIncrement32Barrier(const_cast(&refCount)); } + bool deref() { return ! OSAtomicDecrement32Barrier(const_cast(&refCount)); } + int32_t count() { return refCount; } + private: + volatile int32_t refCount; +#elif defined(TAGLIB_ATOMIC_WIN) + void ref() { InterlockedIncrement(&refCount); } + bool deref() { return ! InterlockedDecrement(&refCount); } + long count() { return refCount; } + private: + volatile long refCount; +#elif defined(TAGLIB_ATOMIC_GCC) + void ref() { __sync_add_and_fetch(&refCount, 1); } + bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); } + int count() { return refCount; } + private: + volatile int refCount; +#else + void ref() { refCount++; } + bool deref() { return ! --refCount; } + int count() { return refCount; } + private: + unsigned int refCount; +#endif + }; + +} + +#endif // DO_NOT_DOCUMENT +#endif + diff --git a/taglib/include/taglib/trueaudiofile.h b/taglib/include/taglib/trueaudiofile.h new file mode 100644 index 0000000..1f664d2 --- /dev/null +++ b/taglib/include/taglib/trueaudiofile.h @@ -0,0 +1,259 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.org + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * 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_TRUEAUDIOFILE_H +#define TAGLIB_TRUEAUDIOFILE_H + +#include "tfile.h" +#include "trueaudioproperties.h" + +namespace TagLib { + + class Tag; + + namespace ID3v2 { class Tag; class FrameFactory; } + namespace ID3v1 { class Tag; } + + //! An implementation of TrueAudio metadata + + /*! + * This is implementation of TrueAudio metadata. + * + * This supports ID3v1 and ID3v2 tags as well as reading stream + * properties from the file. + */ + + namespace TrueAudio { + + //! An implementation of TagLib::File with TrueAudio specific methods + + /*! + * This implements and provides an interface for TrueAudio files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to TrueAudio files. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v1 tags. + ID3v1 = 0x0001, + //! Matches ID3v2 tags. + ID3v2 = 0x0002, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs a TrueAudio file from \a file. If \a readProperties is true + * the file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a TrueAudio file from \a file. If \a readProperties is true + * the file's audio properties will also be read. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a TrueAudio file from \a stream. If \a readProperties is true + * the file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a TrueAudio file from \a stream. If \a readProperties is true + * the file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * If this file contains and ID3v2 tag the frames will be created using + * \a frameFactory. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. + */ + virtual TagLib::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * If the file contains both ID3v1 and v2 tags, only ID3v2 will be + * converted to the PropertyMap. + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Creates in ID3v2 tag if necessary. If an ID3v1 tag exists, it will + * be updated as well, within the limitations of ID3v1. + */ + PropertyMap setProperties(const PropertyMap &); + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Returns the TrueAudio::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Set the ID3v2::FrameFactory to something other than the default. + * + * \see ID3v2FrameFactory + * \deprecated This value should be passed in via the constructor + */ + TAGLIB_DEPRECATED void setID3v2FrameFactory(const ID3v2::FrameFactory *factory); + + /*! + * Saves the file. + */ + virtual bool save(); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid ID3v1 tag. If \a create is true it will create + * an ID3v1 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file + * on disk actually has an ID3v1 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v1Tag() + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the ID3v2 tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid ID3v2 tag. If \a create is true it will create + * an ID3v2 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v2 tag. Use hasID3v2Tag() to check if the file + * on disk actually has an ID3v2 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v2Tag() + */ + ID3v2::Tag *ID3v2Tag(bool create = false); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from the + * file. By default it removes all tags. + * + * \note This will also invalidate pointers to the tags + * as their memory will be freed. + * \note In order to make the removal permanent save() still needs to be called + */ + void strip(int tags = AllTags); + + /*! + * Returns whether or not the file on disk actually has an ID3v1 tag. + * + * \see ID3v1Tag() + */ + bool hasID3v1Tag() const; + + /*! + * Returns whether or not the file on disk actually has an ID3v2 tag. + * + * \see ID3v2Tag() + */ + bool hasID3v2Tag() const; + + /*! + * Returns whether or not the given \a stream can be opened as a TrueAudio + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/trueaudioproperties.h b/taglib/include/taglib/trueaudioproperties.h new file mode 100644 index 0000000..d25c7a7 --- /dev/null +++ b/taglib/include/taglib/trueaudioproperties.h @@ -0,0 +1,133 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.org + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * 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_TRUEAUDIOPROPERTIES_H +#define TAGLIB_TRUEAUDIOPROPERTIES_H + +#include "audioproperties.h" + +namespace TagLib { + + namespace TrueAudio { + + class File; + + static const unsigned int HeaderSize = 18; + + //! An implementation of audio property reading for TrueAudio + + /*! + * This reads the data from an TrueAudio stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of TrueAudio::Properties with the data read from the + * ByteVector \a data. + */ + Properties(const ByteVector &data, long streamLength, ReadStyle style = Average); + + /*! + * Destroys this TrueAudio::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns the total number of sample frames + */ + unsigned int sampleFrames() const; + + /*! + * Returns the major version number. + */ + int ttaVersion() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(const ByteVector &data, long streamLength); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/tstring.h b/taglib/include/taglib/tstring.h new file mode 100644 index 0000000..7028aab --- /dev/null +++ b/taglib/include/taglib/tstring.h @@ -0,0 +1,580 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_STRING_H +#define TAGLIB_STRING_H + +#include "taglib_export.h" +#include "taglib.h" +#include "tbytevector.h" + +#include +#include + +/*! + * \relates TagLib::String + * + * Converts a QString to a TagLib::String without a requirement to link to Qt. + * + * \note consider conversion via usual char-by-char for loop to avoid UTF16->UTF8->UTF16 + * conversion happening in the background + */ + +#if defined(QT_VERSION) && (QT_VERSION >= 0x040000) +#define QStringToTString(s) TagLib::String(s.toUtf8().data(), TagLib::String::UTF8) +#else +#define QStringToTString(s) TagLib::String(s.utf8().data(), TagLib::String::UTF8) +#endif + +/*! + * \relates TagLib::String + * + * Converts a TagLib::String to a QString without a requirement to link to Qt. + * + * \note consider conversion via usual char-by-char for loop to avoid UTF16->UTF8->UTF16 + * conversion happening in the background + * + */ + +#define TStringToQString(s) QString::fromUtf8(s.toCString(true)) + +namespace TagLib { + + class StringList; + + //! A \e wide string class suitable for unicode. + + /*! + * This is an implicitly shared \e wide string. For storage it uses + * TagLib::wstring, but as this is an implementation detail this of + * course could change. Strings are stored internally as UTF-16(without BOM/ + * CPU byte order) + * + * The use of implicit sharing means that copying a string is cheap, the only + * \e cost comes into play when the copy is modified. Prior to that the string + * just has a pointer to the data of the \e parent String. This also makes + * this class suitable as a function return type. + * + * In addition to adding implicit sharing, this class keeps track of four + * possible encodings, which are the four supported by the ID3v2 standard. + */ + + class TAGLIB_EXPORT String + { + public: + +#ifndef DO_NOT_DOCUMENT + typedef TagLib::wstring::iterator Iterator; + typedef TagLib::wstring::const_iterator ConstIterator; +#endif + + /** + * The four types of string encodings supported by the ID3v2 specification. + * ID3v1 is assumed to be Latin1 and Ogg Vorbis comments use UTF8. + */ + enum Type { + /*! + * IS08859-1, or Latin1 encoding. 8 bit characters. + */ + Latin1 = 0, + /*! + * UTF16 with a byte order mark. 16 bit characters. + */ + UTF16 = 1, + /*! + * UTF16 big endian. 16 bit characters. This is the encoding used + * internally by TagLib. + */ + UTF16BE = 2, + /*! + * UTF8 encoding. Characters are usually 8 bits but can be up to 32. + */ + UTF8 = 3, + /*! + * UTF16 little endian. 16 bit characters. + */ + UTF16LE = 4 + }; + + /*! + * Constructs an empty String. + */ + String(); + + /*! + * Make a shallow, implicitly shared, copy of \a s. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + String(const String &s); + + /*! + * Makes a deep copy of the data in \a s. + * + * \note This should only be used with the 8-bit codecs Latin1 and UTF8, when + * used with other codecs it will simply print a warning and exit. + */ + String(const std::string &s, Type t = Latin1); + + /*! + * Makes a deep copy of the data in \a s. + * + * /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless + * of the CPU byte order. If UTF16BE, it will not be swapped. This behavior + * will be changed in TagLib2.0. + */ + String(const wstring &s, Type t = UTF16BE); + + /*! + * Makes a deep copy of the data in \a s. + * + * /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless + * of the CPU byte order. If UTF16BE, it will not be swapped. This behavior + * will be changed in TagLib2.0. + */ + String(const wchar_t *s, Type t = UTF16BE); + + /*! + * Makes a deep copy of the data in \a c. + * + * \note This should only be used with the 8-bit codecs Latin1 and UTF8, when + * used with other codecs it will simply print a warning and exit. + */ + String(char c, Type t = Latin1); + + /*! + * Makes a deep copy of the data in \a c. + */ + String(wchar_t c, Type t = Latin1); + + /*! + * Makes a deep copy of the data in \a s. + * + * \note This should only be used with the 8-bit codecs Latin1 and UTF8, when + * used with other codecs it will simply print a warning and exit. + */ + String(const char *s, Type t = Latin1); + + /*! + * Makes a deep copy of the data in \a v. + */ + String(const ByteVector &v, Type t = Latin1); + + /*! + * Destroys this String instance. + */ + virtual ~String(); + + /*! + * Returns a deep copy of this String as an std::string. The returned string + * is encoded in UTF8 if \a unicode is true, otherwise Latin1. + * + * \see toCString() + */ + std::string to8Bit(bool unicode = false) const; + + /*! + * Returns a deep copy of this String as a wstring. The returned string is + * encoded in UTF-16 (without BOM/CPU byte order), not UTF-32 even if wchar_t + * is 32-bit wide. + * + * \see toCWString() + */ + wstring toWString() const; + + /*! + * Creates and returns a standard C-style (null-terminated) version of this + * String. The returned string is encoded in UTF8 if \a unicode is true, + * otherwise Latin1. + * + * The returned string is still owned by this String and should not be deleted + * by the user. + * + * The returned pointer remains valid until this String instance is destroyed + * or toCString() is called again. + * + * \warning This however has the side effect that the returned string will remain + * in memory in addition to other memory that is consumed by this + * String instance. So, this method should not be used on large strings or + * where memory is critical. Consider using to8Bit() instead to avoid it. + * + * \see to8Bit() + */ + const char *toCString(bool unicode = false) const; + + /*! + * Returns a standard C-style (null-terminated) wide character version of + * this String. The returned string is encoded in UTF-16 (without BOM/CPU byte + * order), not UTF-32 even if wchar_t is 32-bit wide. + * + * The returned string is still owned by this String and should not be deleted + * by the user. + * + * The returned pointer remains valid until this String instance is destroyed + * or any other method of this String is called. + * + * \note This returns a pointer to the String's internal data without any + * conversions. + * + * \see toWString() + */ + const wchar_t *toCWString() const; + + /*! + * Returns an iterator pointing to the beginning of the string. + */ + Iterator begin(); + + /*! + * Returns a const iterator pointing to the beginning of the string. + */ + ConstIterator begin() const; + + /*! + * Returns an iterator pointing to the end of the string (the position + * after the last character). + */ + Iterator end(); + + /*! + * Returns a const iterator pointing to the end of the string (the position + * after the last character). + */ + ConstIterator end() const; + + /*! + * Finds the first occurrence of pattern \a s in this string starting from + * \a offset. If the pattern is not found, -1 is returned. + */ + int find(const String &s, int offset = 0) const; + + /*! + * Finds the last occurrence of pattern \a s in this string, searched backwards, + * either from the end of the string or starting from \a offset. If the pattern + * is not found, -1 is returned. + */ + int rfind(const String &s, int offset = -1) const; + + /*! + * Splits the string on each occurrence of \a separator. + */ + StringList split(const String &separator = " ") const; + + /*! + * Returns true if the strings starts with the substring \a s. + */ + bool startsWith(const String &s) const; + + /*! + * Extract a substring from this string starting at \a position and + * continuing for \a n characters. + */ + String substr(unsigned int position, unsigned int n = 0xffffffff) const; + + /*! + * Append \a s to the current string and return a reference to the current + * string. + */ + String &append(const String &s); + + /*! + * Clears the string. + */ + String &clear(); + + /*! + * Returns an upper case version of the string. + * + * \warning This only works for the characters in US-ASCII, i.e. A-Z. + */ + String upper() const; + + /*! + * Returns the size of the string. + */ + unsigned int size() const; + + /*! + * Returns the length of the string. Equivalent to size(). + */ + unsigned int length() const; + + /*! + * Returns true if the string is empty. + * + * \see isNull() + */ + bool isEmpty() const; + + /*! + * Returns true if this string is null -- i.e. it is a copy of the + * String::null string. + * + * \note A string can be empty and not null. So do not use this method to + * check if the string is empty. + * + * \see isEmpty() + * + * \deprecated + */ + // BIC: remove + TAGLIB_DEPRECATED bool isNull() const; + + /*! + * Returns a ByteVector containing the string's data. If \a t is Latin1 or + * UTF8, this will return a vector of 8 bit characters, otherwise it will use + * 16 bit characters. + * + * \note If \a t is UTF16, the returned data is encoded in little-endian + * format and has a BOM. + * + * \note The returned data is not null terminated. + */ + ByteVector data(Type t) const; + + /*! + * Convert the string to an integer. + * + * Returns the integer if the conversion was successful or 0 if the + * string does not represent a number. + */ + // BIC: merge with the method below + int toInt() const; + + /*! + * Convert the string to an integer. + * + * If the conversion was successful, it sets the value of \a *ok to + * true and returns the integer. Otherwise it sets \a *ok to false + * and the result is undefined. + */ + int toInt(bool *ok) const; + + /*! + * Returns a string with the leading and trailing whitespace stripped. + */ + String stripWhiteSpace() const; + + /*! + * Returns true if the file only uses characters required by Latin1. + */ + bool isLatin1() const; + + /*! + * Returns true if the file only uses characters required by (7-bit) ASCII. + */ + bool isAscii() const; + + /*! + * Converts the base-10 integer \a n to a string. + */ + static String number(int n); + + /*! + * Returns a reference to the character at position \a i. + */ + wchar_t &operator[](int i); + + /*! + * Returns a const reference to the character at position \a i. + */ + const wchar_t &operator[](int i) const; + + /*! + * Compares each character of the String with each character of \a s and + * returns true if the strings match. + */ + bool operator==(const String &s) const; + + /*! + * Compares each character of the String with each character of \a s and + * returns false if the strings match. + */ + bool operator!=(const String &s) const; + + /*! + * Compares each character of the String with each character of \a s and + * returns true if the strings match. + */ + bool operator==(const char *s) const; + + /*! + * Compares each character of the String with each character of \a s and + * returns false if the strings match. + */ + bool operator!=(const char *s) const; + + /*! + * Compares each character of the String with each character of \a s and + * returns true if the strings match. + */ + bool operator==(const wchar_t *s) const; + + /*! + * Compares each character of the String with each character of \a s and + * returns false if the strings match. + */ + bool operator!=(const wchar_t *s) const; + + /*! + * Appends \a s to the end of the String. + */ + String &operator+=(const String &s); + + /*! + * Appends \a s to the end of the String. + */ + String &operator+=(const wchar_t* s); + + /*! + * Appends \a s to the end of the String. + */ + String &operator+=(const char* s); + + /*! + * Appends \a s to the end of the String. + */ + String &operator+=(wchar_t c); + + /*! + * Appends \a c to the end of the String. + */ + String &operator+=(char c); + + /*! + * Performs a shallow, implicitly shared, copy of \a s, overwriting the + * String's current data. + */ + String &operator=(const String &s); + + /*! + * Performs a deep copy of the data in \a s. + */ + String &operator=(const std::string &s); + + /*! + * Performs a deep copy of the data in \a s. + */ + String &operator=(const wstring &s); + + /*! + * Performs a deep copy of the data in \a s. + */ + String &operator=(const wchar_t *s); + + /*! + * Performs a deep copy of the data in \a s. + */ + String &operator=(char c); + + /*! + * Performs a deep copy of the data in \a s. + */ + String &operator=(wchar_t c); + + /*! + * Performs a deep copy of the data in \a s. + */ + String &operator=(const char *s); + + /*! + * Performs a deep copy of the data in \a v. + */ + String &operator=(const ByteVector &v); + + /*! + * Exchanges the content of the String by the content of \a s. + */ + void swap(String &s); + + /*! + * To be able to use this class in a Map, this operator needed to be + * implemented. Returns true if \a s is less than this string in a byte-wise + * comparison. + */ + bool operator<(const String &s) const; + + /*! + * A null string provided for convenience. + * + * \warning Do not modify this variable. It will mess up the internal state + * of TagLib. + * + * \deprecated + */ + // BIC: remove + TAGLIB_DEPRECATED static String null; + + protected: + /*! + * If this String is being shared via implicit sharing, do a deep copy of the + * data and separate from the shared members. This should be called by all + * non-const subclass members. + */ + void detach(); + + private: + /*! + * \deprecated This variable is no longer used, but NEVER remove this. It + * may lead to a linkage error. + */ + // BIC: remove + TAGLIB_DEPRECATED static const Type WCharByteOrder; + + class StringPrivate; + StringPrivate *d; + }; +} + +/*! + * \relates TagLib::String + * + * Concatenates \a s1 and \a s2 and returns the result as a string. + */ +TAGLIB_EXPORT const TagLib::String operator+(const TagLib::String &s1, const TagLib::String &s2); + +/*! + * \relates TagLib::String + * + * Concatenates \a s1 and \a s2 and returns the result as a string. + */ +TAGLIB_EXPORT const TagLib::String operator+(const char *s1, const TagLib::String &s2); + +/*! + * \relates TagLib::String + * + * Concatenates \a s1 and \a s2 and returns the result as a string. + */ +TAGLIB_EXPORT const TagLib::String operator+(const TagLib::String &s1, const char *s2); + + +/*! + * \relates TagLib::String + * + * Send the string to an output stream. + */ +TAGLIB_EXPORT std::ostream &operator<<(std::ostream &s, const TagLib::String &str); + +#endif diff --git a/taglib/include/taglib/tstringlist.h b/taglib/include/taglib/tstringlist.h new file mode 100644 index 0000000..41b7f6e --- /dev/null +++ b/taglib/include/taglib/tstringlist.h @@ -0,0 +1,115 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_STRINGLIST_H +#define TAGLIB_STRINGLIST_H + +#include "tstring.h" +#include "tlist.h" +#include "tbytevectorlist.h" +#include "taglib_export.h" + +#include + +namespace TagLib { + + //! A list of strings + + /*! + * This is a specialization of the List class with some members convention for + * string operations. + */ + + class TAGLIB_EXPORT StringList : public List + { + public: + + /*! + * Constructs an empty StringList. + */ + StringList(); + + /*! + * Make a shallow, implicitly shared, copy of \a l. Because this is + * implicitly shared, this method is lightweight and suitable for + * pass-by-value usage. + */ + StringList(const StringList &l); + + /*! + * Constructs a StringList with \a s as a member. + */ + StringList(const String &s); + + /*! + * Makes a deep copy of the data in \a vl. + * + * \note This should only be used with the 8-bit codecs Latin1 and UTF8, when + * used with other codecs it will simply print a warning and exit. + */ + StringList(const ByteVectorList &vl, String::Type t = String::Latin1); + + /*! + * Destroys this StringList instance. + */ + virtual ~StringList(); + + /*! + * Concatenate the list of strings into one string separated by \a separator. + */ + String toString(const String &separator = " ") const; + + /*! + * Appends \a s to the end of the list and returns a reference to the + * list. + */ + StringList &append(const String &s); + + /*! + * Appends all of the values in \a l to the end of the list and returns a + * reference to the list. + */ + StringList &append(const StringList &l); + + /*! + * Splits the String \a s into several strings at \a pattern. This will not include + * the pattern in the returned strings. + */ + static StringList split(const String &s, const String &pattern); + + private: + class StringListPrivate; + StringListPrivate *d; + }; + +} + +/*! + * \related TagLib::StringList + * Send the StringList to an output stream. + */ +std::ostream &operator<<(std::ostream &s, const TagLib::StringList &l); + +#endif diff --git a/taglib/include/taglib/uniquefileidentifierframe.h b/taglib/include/taglib/uniquefileidentifierframe.h new file mode 100644 index 0000000..decf1b0 --- /dev/null +++ b/taglib/include/taglib/uniquefileidentifierframe.h @@ -0,0 +1,123 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_UNIQUEFILEIDENTIFIERFRAME +#define TAGLIB_UNIQUEFILEIDENTIFIERFRAME + +#include "id3v2frame.h" + +namespace TagLib { + + namespace ID3v2 { + + /*! + * This is an implementation of ID3v2 unique file identifier frames. This + * frame is used to identify the file in an arbitrary database identified + * by the owner field. + */ + + //! An implementation of ID3v2 unique identifier frames + + class TAGLIB_EXPORT UniqueFileIdentifierFrame : public ID3v2::Frame + { + friend class FrameFactory; + + public: + /*! + * Creates a unique file identifier frame based on \a data. + */ + UniqueFileIdentifierFrame(const ByteVector &data); + + /*! + * Creates a unique file identifier frame with the owner \a owner and + * the identification \a id. + */ + UniqueFileIdentifierFrame(const String &owner, const ByteVector &id); + + /*! + * Destroys the frame. + */ + ~UniqueFileIdentifierFrame(); + + /*! + * Returns the owner for the frame; essentially this is the key for + * determining which identification scheme this key belongs to. This + * will usually either be an email address or URL for the person or tool + * used to create the unique identifier. + * + * \see setOwner() + */ + String owner() const; + + /*! + * Returns the unique identifier. Though sometimes this is a text string + * it also may be binary data and as much should be assumed when handling + * it. + */ + ByteVector identifier() const; + + /*! + * Sets the owner of the identification scheme to \a s. + * + * \see owner() + */ + void setOwner(const String &s); + + /*! + * Sets the unique file identifier to \a v. + * + * \see identifier() + */ + void setIdentifier(const ByteVector &v); + + virtual String toString() const; + + PropertyMap asProperties() const; + + /*! + * UFID frames each have a unique owner. This searches for a UFID + * frame with the owner \a o and returns a pointer to it. + * + * \see owner() + */ + static UniqueFileIdentifierFrame *findByOwner(const Tag *tag, const String &o); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + UniqueFileIdentifierFrame(const UniqueFileIdentifierFrame &); + UniqueFileIdentifierFrame &operator=(const UniqueFileIdentifierFrame &); + + UniqueFileIdentifierFrame(const ByteVector &data, Header *h); + + class UniqueFileIdentifierFramePrivate; + UniqueFileIdentifierFramePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/unknownframe.h b/taglib/include/taglib/unknownframe.h new file mode 100644 index 0000000..6559f4e --- /dev/null +++ b/taglib/include/taglib/unknownframe.h @@ -0,0 +1,79 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_UNKNOWNFRAME_H +#define TAGLIB_UNKNOWNFRAME_H + +#include "id3v2frame.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace ID3v2 { + + //! A frame type \e unknown to TagLib. + + /*! + * This class represents a frame type not known (or more often simply + * unimplemented) in TagLib. This is here provide a basic API for + * manipulating the binary data of unknown frames and to provide a means + * of rendering such \e unknown frames. + * + * Please note that a cleaner way of handling frame types that TagLib + * does not understand is to subclass ID3v2::Frame and ID3v2::FrameFactory + * to have your frame type supported through the standard ID3v2 mechanism. + */ + + class TAGLIB_EXPORT UnknownFrame : public Frame + { + friend class FrameFactory; + + public: + UnknownFrame(const ByteVector &data); + virtual ~UnknownFrame(); + + virtual String toString() const; + + /*! + * Returns the field data (everything but the header) for this frame. + */ + ByteVector data() const; + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + UnknownFrame(const ByteVector &data, Header *h); + UnknownFrame(const UnknownFrame &); + UnknownFrame &operator=(const UnknownFrame &); + + class UnknownFramePrivate; + UnknownFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/unsynchronizedlyricsframe.h b/taglib/include/taglib/unsynchronizedlyricsframe.h new file mode 100644 index 0000000..dad67c7 --- /dev/null +++ b/taglib/include/taglib/unsynchronizedlyricsframe.h @@ -0,0 +1,179 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + copyright : (C) 2006 by Urs Fleisch + email : ufleisch@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * 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_UNSYNCHRONIZEDLYRICSFRAME_H +#define TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H + +#include "id3v2frame.h" + +namespace TagLib { + + namespace ID3v2 { + + //! ID3v2 unsynchronized lyrics frame + /*! + * An implementation of ID3v2 unsynchronized lyrics. + */ + class TAGLIB_EXPORT UnsynchronizedLyricsFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * Construct an empty unsynchronized lyrics frame that will use the text encoding + * \a encoding. + */ + explicit UnsynchronizedLyricsFrame(String::Type encoding = String::Latin1); + + /*! + * Construct a unsynchronized lyrics frame based on the data in \a data. + */ + explicit UnsynchronizedLyricsFrame(const ByteVector &data); + + /*! + * Destroys this UnsynchronizedLyricsFrame instance. + */ + virtual ~UnsynchronizedLyricsFrame(); + + /*! + * Returns the text of this unsynchronized lyrics frame. + * + * \see text() + */ + virtual String toString() const; + + /*! + * Returns the language encoding as a 3 byte encoding as specified by + * ISO-639-2. + * + * \note Most taggers simply ignore this value. + * + * \see setLanguage() + */ + ByteVector language() const; + + /*! + * Returns the description of this unsynchronized lyrics frame. + * + * \note Most taggers simply ignore this value. + * + * \see setDescription() + */ + String description() const; + + /*! + * Returns the text of this unsynchronized lyrics frame. + * + * \see setText() + */ + String text() const; + + /*! + * Set the language using the 3 byte language code from + * ISO-639-2 to + * \a languageCode. + * + * \see language() + */ + void setLanguage(const ByteVector &languageCode); + + /*! + * Sets the description of the unsynchronized lyrics frame to \a s. + * + * \see description() + */ + void setDescription(const String &s); + + /*! + * Sets the text portion of the unsynchronized lyrics frame to \a s. + * + * \see text() + */ + virtual void setText(const String &s); + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + + /*! Parses this frame as PropertyMap with a single key. + * - if description() is empty or "LYRICS", the key will be "LYRICS" + * - if description() is not a valid PropertyMap key, the frame will be + * marked unsupported by an entry "USLT/" in the unsupportedData() + * attribute of the returned map. + * - otherwise, the key will be "LYRICS:" + * - The single value will be the frame's text(). + * Note that currently the language() field is not supported by the PropertyMap + * interface. + */ + PropertyMap asProperties() const; + + /*! + * LyricsFrames each have a unique description. This searches for a lyrics + * frame with the description \a d and returns a pointer to it. If no + * frame is found that matches the given description null is returned. + * + * \see description() + */ + static UnsynchronizedLyricsFrame *findByDescription(const Tag *tag, const String &d); + + protected: + // Reimplementations. + + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + private: + /*! + * The constructor used by the FrameFactory. + */ + UnsynchronizedLyricsFrame(const ByteVector &data, Header *h); + UnsynchronizedLyricsFrame(const UnsynchronizedLyricsFrame &); + UnsynchronizedLyricsFrame &operator=(const UnsynchronizedLyricsFrame &); + + class UnsynchronizedLyricsFramePrivate; + UnsynchronizedLyricsFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/urllinkframe.h b/taglib/include/taglib/urllinkframe.h new file mode 100644 index 0000000..d9ac109 --- /dev/null +++ b/taglib/include/taglib/urllinkframe.h @@ -0,0 +1,190 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + + copyright : (C) 2006 by Urs Fleisch + email : ufleisch@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * 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_URLLINKFRAME_H +#define TAGLIB_URLLINKFRAME_H + +#include "id3v2frame.h" + +namespace TagLib { + + namespace ID3v2 { + + //! ID3v2 URL frame + /*! + * An implementation of ID3v2 URL link frames. + */ + class TAGLIB_EXPORT UrlLinkFrame : public Frame + { + friend class FrameFactory; + + public: + /*! + * This is a dual purpose constructor. \a data can either be binary data + * that should be parsed or (at a minimum) the frame ID. + */ + explicit UrlLinkFrame(const ByteVector &data); + + /*! + * Destroys this UrlLinkFrame instance. + */ + virtual ~UrlLinkFrame(); + + /*! + * Returns the URL. + */ + virtual String url() const; + + /*! + * Sets the URL to \a s. + */ + virtual void setUrl(const String &s); + + // Reimplementations. + + virtual void setText(const String &s); + virtual String toString() const; + PropertyMap asProperties() const; + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + /*! + * The constructor used by the FrameFactory. + */ + UrlLinkFrame(const ByteVector &data, Header *h); + + private: + UrlLinkFrame(const UrlLinkFrame &); + UrlLinkFrame &operator=(const UrlLinkFrame &); + + class UrlLinkFramePrivate; + UrlLinkFramePrivate *d; + }; + + //! ID3v2 User defined URL frame + + /*! + * This is a specialization of URL link frames that allows for + * user defined entries. Each entry has a description in addition to the + * normal list of fields that a URL link frame has. + * + * This description identifies the frame and must be unique. + */ + class TAGLIB_EXPORT UserUrlLinkFrame : public UrlLinkFrame + { + friend class FrameFactory; + + public: + /*! + * Constructs an empty user defined URL link frame. For this to be + * a useful frame both a description and text must be set. + */ + explicit UserUrlLinkFrame(String::Type encoding = String::Latin1); + + /*! + * This is a dual purpose constructor. \a data can either be binary data + * that should be parsed or (at a minimum) the frame ID. + */ + explicit UserUrlLinkFrame(const ByteVector &data); + + /*! + * Destroys this UserUrlLinkFrame instance. + */ + virtual ~UserUrlLinkFrame(); + + // Reimplementations. + + virtual String toString() const; + + /*! + * Returns the text encoding that will be used in rendering this frame. + * This defaults to the type that was either specified in the constructor + * or read from the frame when parsed. + * + * \see setTextEncoding() + * \see render() + */ + String::Type textEncoding() const; + + /*! + * Sets the text encoding to be used when rendering this frame to + * \a encoding. + * + * \see textEncoding() + * \see render() + */ + void setTextEncoding(String::Type encoding); + + /*! + * Returns the description for this frame. + */ + String description() const; + + /*! + * Sets the description of the frame to \a s. \a s must be unique. + */ + void setDescription(const String &s); + + /*! + * Parses the UserUrlLinkFrame as PropertyMap. The description() is taken as key, + * and the URL as single value. + * - if description() is empty, the key will be "URL". + * - otherwise, if description() is not a valid key (e.g. containing non-ASCII + * characters), the returned map will contain an entry "WXXX/" + * in its unsupportedData() list. + */ + PropertyMap asProperties() const; + + /*! + * Searches for the user defined url frame with the description \a description + * in \a tag. This returns null if no matching frames were found. + */ + static UserUrlLinkFrame *find(Tag *tag, const String &description); + + protected: + virtual void parseFields(const ByteVector &data); + virtual ByteVector renderFields() const; + + /*! + * The constructor used by the FrameFactory. + */ + UserUrlLinkFrame(const ByteVector &data, Header *h); + + private: + UserUrlLinkFrame(const UserUrlLinkFrame &); + UserUrlLinkFrame &operator=(const UserUrlLinkFrame &); + + class UserUrlLinkFramePrivate; + UserUrlLinkFramePrivate *d; + }; + + } +} +#endif diff --git a/taglib/include/taglib/vorbisfile.h b/taglib/include/taglib/vorbisfile.h new file mode 100644 index 0000000..04c0c04 --- /dev/null +++ b/taglib/include/taglib/vorbisfile.h @@ -0,0 +1,157 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_VORBISFILE_H +#define TAGLIB_VORBISFILE_H + +#include "taglib_export.h" +#include "oggfile.h" +#include "xiphcomment.h" + +#include "vorbisproperties.h" + +namespace TagLib { + +/* + * This is just to make this appear to be in the Ogg namespace in the + * documentation. The typedef below will make this work with the current code. + * In the next BIC version of TagLib this will be really moved into the Ogg + * namespace. + */ + +#ifdef DOXYGEN + namespace Ogg { +#endif + + //! A namespace containing classes for Vorbis metadata + + namespace Vorbis { + + + //! An implementation of Ogg::File with Vorbis specific methods + + /*! + * This is the central class in the Ogg Vorbis metadata processing collection + * of classes. It's built upon Ogg::File which handles processing of the Ogg + * logical bitstream and breaking it down into pages which are handled by + * the codec implementations, in this case Vorbis specifically. + */ + + class TAGLIB_EXPORT File : public Ogg::File + { + public: + /*! + * Constructs a Vorbis file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a Vorbis file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the XiphComment for this file. XiphComment implements the tag + * interface, so this serves as the reimplementation of + * TagLib::File::tag(). + */ + virtual Ogg::XiphComment *tag() const; + + + /*! + * Implements the unified property interface -- export function. + * This forwards directly to XiphComment::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified tag dictionary interface -- import function. + * Like properties(), this is a forwarder to the file's XiphComment. + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the Vorbis::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Save the file. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Check if the given \a stream can be opened as an Ogg Vorbis file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } + +/* + * To keep compatibility with the current version put Vorbis in the Ogg namespace + * only in the docs and provide a typedef to make it work. In the next BIC + * version this will be removed and it will only exist in the Ogg namespace. + */ + +#ifdef DOXYGEN + } +#else + namespace Ogg { namespace Vorbis { typedef TagLib::Vorbis::File File; } } +#endif + +} + +#endif diff --git a/taglib/include/taglib/vorbisproperties.h b/taglib/include/taglib/vorbisproperties.h new file mode 100644 index 0000000..472e039 --- /dev/null +++ b/taglib/include/taglib/vorbisproperties.h @@ -0,0 +1,160 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_VORBISPROPERTIES_H +#define TAGLIB_VORBISPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + +/* + * This is just to make this appear to be in the Ogg namespace in the + * documentation. The typedef below will make this work with the current code. + * In the next BIC version of TagLib this will be really moved into the Ogg + * namespace. + */ + +#ifdef DOXYGEN + namespace Ogg { +#endif + + namespace Vorbis { + + class File; + + //! An implementation of audio property reading for Ogg Vorbis + + /*! + * This reads the data from an Ogg Vorbis stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of Vorbis::Properties with the data read from the + * Vorbis::File \a file. + */ + Properties(File *file, ReadStyle style = Average); + + /*! + * Destroys this VorbisProperties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the Vorbis version, currently "0" (as specified by the spec). + */ + int vorbisVersion() const; + + /*! + * Returns the maximum bitrate as read from the Vorbis identification + * header. + */ + int bitrateMaximum() const; + + /*! + * Returns the nominal bitrate as read from the Vorbis identification + * header. + */ + int bitrateNominal() const; + + /*! + * Returns the minimum bitrate as read from the Vorbis identification + * header. + */ + int bitrateMinimum() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } + +/* + * To keep compatibility with the current version put Vorbis in the Ogg namespace + * only in the docs and provide a typedef to make it work. In the next BIC + * version this will be removed and it will only exist in the Ogg namespace. + */ + +#ifdef DOXYGEN + } +#else + namespace Ogg { namespace Vorbis { typedef TagLib::AudioProperties AudioProperties; } } +#endif + +} + +#endif diff --git a/taglib/include/taglib/wavfile.h b/taglib/include/taglib/wavfile.h new file mode 100644 index 0000000..bc9ce31 --- /dev/null +++ b/taglib/include/taglib/wavfile.h @@ -0,0 +1,215 @@ +/*************************************************************************** + copyright : (C) 2008 by Scott Wheeler + email : wheeler@kde.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_WAVFILE_H +#define TAGLIB_WAVFILE_H + +#include "rifffile.h" +#include "id3v2tag.h" +#include "infotag.h" +#include "wavproperties.h" + +namespace TagLib { + + namespace RIFF { + + //! An implementation of WAV metadata + + /*! + * This is implementation of WAV metadata. + * + * This supports an ID3v2 tag as well as reading stream from the ID3 RIFF + * chunk as well as properties from the file. + */ + + namespace WAV { + + //! An implementation of TagLib::File with WAV specific methods + + /*! + * This implements and provides an interface for WAV files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to WAV files. + */ + + class TAGLIB_EXPORT File : public TagLib::RIFF::File + { + public: + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v2 tags. + ID3v2 = 0x0001, + //! Matches INFO tags. + Info = 0x0002, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs a WAV file from \a file. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs a WAV file from \a stream. If \a readProperties is true the + * file's audio properties will also be read. + * + * \note TagLib will *not* take ownership of the stream, the caller is + * responsible for deleting it after the File object. + * + * \note In the current implementation, \a propertiesStyle is ignored. + */ + File(IOStream *stream, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the ID3v2 Tag for this file. + * + * \note This method does not return all the tags for this file for + * backward compatibility. Will be fixed in TagLib 2.0. + */ + ID3v2::Tag *tag() const; + + /*! + * Returns the ID3v2 Tag for this file. + * + * \note This always returns a valid pointer regardless of whether or not + * the file on disk has an ID3v2 tag. Use hasID3v2Tag() to check if the + * file on disk actually has an ID3v2 tag. + * + * \see hasID3v2Tag() + */ + ID3v2::Tag *ID3v2Tag() const; + + /*! + * Returns the RIFF INFO Tag for this file. + * + * \note This always returns a valid pointer regardless of whether or not + * the file on disk has a RIFF INFO tag. Use hasInfoTag() to check if the + * file on disk actually has a RIFF INFO tag. + * + * \see hasInfoTag() + */ + Info::Tag *InfoTag() const; + + /*! + * This will strip the tags that match the OR-ed together TagTypes from the + * file. By default it strips all tags. It returns true if the tags are + * successfully stripped. + * + * \note This will update the file immediately. + */ + void strip(TagTypes tags = AllTags); + + /*! + * Implements the unified property interface -- export function. + * This method forwards to ID3v2::Tag::properties(). + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * This method forwards to ID3v2::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the WAV::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Saves the file. + */ + virtual bool save(); + + /*! + * \deprecated + */ + TAGLIB_DEPRECATED bool save(TagTypes tags, bool stripOthers, int id3v2Version = 4); + + /*! + * Save the file. If \a strip is specified, it is possible to choose if + * tags not specified in \a tags should be stripped from the file or + * retained. With \a version, it is possible to specify whether ID3v2.4 + * or ID3v2.3 should be used. + */ + bool save(TagTypes tags, StripTags strip = StripOthers, + ID3v2::Version version = ID3v2::v4); + + /*! + * Returns whether or not the file on disk actually has an ID3v2 tag. + * + * \see ID3v2Tag() + */ + bool hasID3v2Tag() const; + + /*! + * Returns whether or not the file on disk actually has a RIFF INFO tag. + * + * \see InfoTag() + */ + bool hasInfoTag() const; + + /*! + * Returns whether or not the given \a stream can be opened as a WAV + * file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + void removeTagChunks(TagTypes tags); + + friend class Properties; + + class FilePrivate; + FilePrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/wavpackfile.h b/taglib/include/taglib/wavpackfile.h new file mode 100644 index 0000000..ccc4ef6 --- /dev/null +++ b/taglib/include/taglib/wavpackfile.h @@ -0,0 +1,223 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.org + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * 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_WVFILE_H +#define TAGLIB_WVFILE_H + +#include "tfile.h" +#include "taglib_export.h" +#include "wavpackproperties.h" + +namespace TagLib { + + class Tag; + + namespace ID3v1 { class Tag; } + namespace APE { class Tag; } + + //! An implementation of WavPack metadata + + /*! + * This is implementation of WavPack metadata. + * + * This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream + * properties from the file. + */ + + namespace WavPack { + + //! An implementation of TagLib::File with WavPack specific methods + + /*! + * This implements and provides an interface for WavPack files to the + * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing + * the abstract TagLib::File API as well as providing some additional + * information specific to WavPack files. + */ + + class TAGLIB_EXPORT File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v1 tags. + ID3v1 = 0x0001, + //! Matches APE tags. + APE = 0x0002, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Constructs a WavPack file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored + */ + File(FileName file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Constructs an WavPack file from \a file. If \a readProperties is true the + * file's audio properties will also be read using \a propertiesStyle. If + * false, \a propertiesStyle is ignored. + * + * \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, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag + * or a combination of the two. + */ + virtual TagLib::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * If the file contains both an APE and an ID3v1 tag, only APE + * will be converted to the PropertyMap. + */ + PropertyMap properties() const; + + void removeUnsupportedProperties(const StringList &properties); + + /*! + * Implements the unified property interface -- import function. + * Creates an APE tag if it does not exists and calls setProperties() on + * that. Any existing ID3v1 tag will be updated as well. + */ + PropertyMap setProperties(const PropertyMap&); + + /*! + * Returns the MPC::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Saves the file. + * + * This returns true if the save was successful. + */ + virtual bool save(); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid ID3v1 tag. If \a create is true it will create + * an ID3v1 tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an ID3v1 tag. Use hasID3v1Tag() to check if the file + * on disk actually has an ID3v1 tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasID3v1Tag() + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the APE tag of the file. + * + * If \a create is false (the default) this may return a null pointer + * if there is no valid APE tag. If \a create is true it will create + * an APE tag if one does not exist and returns a valid pointer. + * + * \note This may return a valid pointer regardless of whether or not the + * file on disk has an APE tag. Use hasAPETag() to check if the file + * on disk actually has an APE tag. + * + * \note The Tag is still owned by the MPEG::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + * + * \see hasAPETag() + */ + APE::Tag *APETag(bool create = false); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from the + * file. By default it removes all tags. + * + * \note This will also invalidate pointers to the tags + * as their memory will be freed. + * \note In order to make the removal permanent save() still needs to be called + */ + void strip(int tags = AllTags); + + /*! + * Returns whether or not the file on disk actually has an ID3v1 tag. + * + * \see ID3v1Tag() + */ + bool hasID3v1Tag() const; + + /*! + * Returns whether or not the file on disk actually has an APE tag. + * + * \see APETag() + */ + bool hasAPETag() const; + + /*! + * Check if the given \a stream can be opened as a WavPack file. + * + * \note This method is designed to do a quick check. The result may + * not necessarily be correct. + */ + static bool isSupported(IOStream *stream); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/wavpackproperties.h b/taglib/include/taglib/wavpackproperties.h new file mode 100644 index 0000000..e6acdcc --- /dev/null +++ b/taglib/include/taglib/wavpackproperties.h @@ -0,0 +1,149 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : lalinsky@gmail.com + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : kde@carewolf.org + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * 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_WVPROPERTIES_H +#define TAGLIB_WVPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + +namespace TagLib { + + namespace WavPack { + + class File; + + static const unsigned int HeaderSize = 32; + + //! An implementation of audio property reading for WavPack + + /*! + * This reads the data from an WavPack stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of WavPack::Properties with the data read from the + * ByteVector \a data. + * + * \deprecated This constructor will be dropped in favor of the one below + * in a future version. + */ + TAGLIB_DEPRECATED Properties(const ByteVector &data, long streamLength, + ReadStyle style = Average); + + /*! + * Create an instance of WavPack::Properties. + */ + Properties(File *file, long streamLength, ReadStyle style = Average); + + /*! + * Destroys this WavPack::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. 0 means unknown or custom. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns whether or not the file is lossless encoded. + */ + bool isLossless() const; + + /*! + * Returns the total number of audio samples in file. + */ + unsigned int sampleFrames() const; + + /*! + * Returns WavPack version. + */ + int version() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file, long streamLength); + unsigned int seekFinalIndex(File *file, long streamLength); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/wavproperties.h b/taglib/include/taglib/wavproperties.h new file mode 100644 index 0000000..1ca7310 --- /dev/null +++ b/taglib/include/taglib/wavproperties.h @@ -0,0 +1,163 @@ +/*************************************************************************** + copyright : (C) 2008 by Scott Wheeler + email : wheeler@kde.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_WAVPROPERTIES_H +#define TAGLIB_WAVPROPERTIES_H + +#include "taglib.h" +#include "audioproperties.h" + +namespace TagLib { + + class ByteVector; + + namespace RIFF { + + namespace WAV { + + class File; + + //! An implementation of audio property reading for WAV + + /*! + * This reads the data from an WAV stream found in the AudioProperties + * API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + /*! + * Create an instance of WAV::Properties with the data read from the + * ByteVector \a data. + * + * \deprecated + */ + TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style); + + /*! + * Create an instance of WAV::Properties with the data read from the + * ByteVector \a data and the length calculated using \a streamLength. + * + * \deprecated + */ + TAGLIB_DEPRECATED Properties(const ByteVector &data, unsigned int streamLength, ReadStyle style); + + /*! + * Create an instance of WAV::Properties with the data read from the + * WAV::File \a file. + */ + Properties(File *file, ReadStyle style); + + /*! + * Destroys this WAV::Properties instance. + */ + virtual ~Properties(); + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \note This method is just an alias of lengthInSeconds(). + * + * \deprecated + */ + TAGLIB_DEPRECATED virtual int length() const; + + /*! + * Returns the length of the file in seconds. The length is rounded down to + * the nearest whole second. + * + * \see lengthInMilliseconds() + */ + // BIC: make virtual + int lengthInSeconds() const; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + // BIC: make virtual + int lengthInMilliseconds() const; + + /*! + * Returns the average bit rate of the file in kb/s. + */ + virtual int bitrate() const; + + /*! + * Returns the sample rate in Hz. + */ + virtual int sampleRate() const; + + /*! + * Returns the number of audio channels. + */ + virtual int channels() const; + + /*! + * Returns the number of bits per audio sample. + */ + int bitsPerSample() const; + + /*! + * Returns the number of bits per audio sample. + * + * \note This method is just an alias of bitsPerSample(). + * + * \deprecated + */ + TAGLIB_DEPRECATED int sampleWidth() const; + + /*! + * Returns the number of sample frames. + */ + unsigned int sampleFrames() const; + + /*! + * Returns the format ID of the file. + * 0 for unknown, 1 for PCM, 2 for ADPCM, 3 for 32/64-bit IEEE754, and + * so forth. + * + * \note For further information, refer to the WAVE Form Registration + * Numbers in RFC 2361. + */ + int format() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(File *file); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } + } +} + +#endif diff --git a/taglib/include/taglib/xingheader.h b/taglib/include/taglib/xingheader.h new file mode 100644 index 0000000..ce75619 --- /dev/null +++ b/taglib/include/taglib/xingheader.h @@ -0,0 +1,129 @@ +/*************************************************************************** + copyright : (C) 2003 by Ismael Orenstein + email : orenstein@kde.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_XINGHEADER_H +#define TAGLIB_XINGHEADER_H + +#include "mpegheader.h" +#include "taglib_export.h" + +namespace TagLib { + + class ByteVector; + + namespace MPEG { + + class File; + + //! An implementation of the Xing/VBRI headers + + /*! + * This is a minimalistic implementation of the Xing/VBRI VBR headers. + * Xing/VBRI headers are often added to VBR (variable bit rate) MP3 streams + * to make it easy to compute the length and quality of a VBR stream. Our + * implementation is only concerned with the total size of the stream (so + * that we can calculate the total playing time and the average bitrate). + * It uses + * this text and the XMMS sources as references. + */ + + class TAGLIB_EXPORT XingHeader + { + public: + /*! + * The type of the VBR header. + */ + enum HeaderType + { + /*! + * Invalid header or no VBR header found. + */ + Invalid = 0, + + /*! + * Xing header. + */ + Xing = 1, + + /*! + * VBRI header. + */ + VBRI = 2, + }; + + /*! + * Parses an Xing/VBRI header based on \a data which contains the entire + * first MPEG frame. + */ + XingHeader(const ByteVector &data); + + /*! + * Destroy this XingHeader instance. + */ + virtual ~XingHeader(); + + /*! + * Returns true if the data was parsed properly and if there is a valid + * Xing/VBRI header present. + */ + bool isValid() const; + + /*! + * Returns the total number of frames. + */ + unsigned int totalFrames() const; + + /*! + * Returns the total size of stream in bytes. + */ + unsigned int totalSize() const; + + /*! + * Returns the type of the VBR header. + */ + HeaderType type() const; + + /*! + * Returns the offset for the start of this Xing header, given the + * version and channels of the frame + * + * \deprecated Always returns 0. + */ + TAGLIB_DEPRECATED static int xingHeaderOffset(TagLib::MPEG::Header::Version v, + TagLib::MPEG::Header::ChannelMode c); + + private: + XingHeader(const XingHeader &); + XingHeader &operator=(const XingHeader &); + + void parse(const ByteVector &data); + + class XingHeaderPrivate; + XingHeaderPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/xiphcomment.h b/taglib/include/taglib/xiphcomment.h new file mode 100644 index 0000000..674d616 --- /dev/null +++ b/taglib/include/taglib/xiphcomment.h @@ -0,0 +1,275 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.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_VORBISCOMMENT_H +#define TAGLIB_VORBISCOMMENT_H + +#include "tag.h" +#include "tlist.h" +#include "tmap.h" +#include "tstring.h" +#include "tstringlist.h" +#include "tbytevector.h" +#include "flacpicture.h" +#include "taglib_export.h" + +namespace TagLib { + + namespace Ogg { + + /*! + * A mapping between a list of field names, or keys, and a list of values + * associated with that field. + * + * \see XiphComment::fieldListMap() + */ + typedef Map FieldListMap; + + //! Ogg Vorbis comment implementation + + /*! + * This class is an implementation of the Ogg Vorbis comment specification, + * to be found in section 5 of the Ogg Vorbis specification. Because this + * format is also used in other (currently unsupported) Xiph.org formats, it + * has been made part of a generic implementation rather than being limited + * to strictly Vorbis. + * + * Vorbis comments are a simple vector of keys and values, called fields. + * Multiple values for a given key are supported. + * + * \see fieldListMap() + */ + + class TAGLIB_EXPORT XiphComment : public TagLib::Tag + { + public: + /*! + * Constructs an empty Vorbis comment. + */ + XiphComment(); + + /*! + * Constructs a Vorbis comment from \a data. + */ + XiphComment(const ByteVector &data); + + /*! + * Destroys this instance of the XiphComment. + */ + virtual ~XiphComment(); + + virtual String title() const; + virtual String artist() const; + virtual String album() const; + virtual String comment() const; + virtual String genre() const; + virtual unsigned int year() const; + virtual unsigned int track() const; + + virtual void setTitle(const String &s); + virtual void setArtist(const String &s); + virtual void setAlbum(const String &s); + virtual void setComment(const String &s); + virtual void setGenre(const String &s); + virtual void setYear(unsigned int i); + virtual void setTrack(unsigned int i); + + virtual bool isEmpty() const; + + /*! + * Returns the number of fields present in the comment. + */ + unsigned int fieldCount() const; + + /*! + * Returns a reference to the map of field lists. Because Xiph comments + * support multiple fields with the same key, a pure Map would not work. + * As such this is a Map of string lists, keyed on the comment field name. + * + * The standard set of Xiph/Vorbis fields (which may or may not be + * contained in any specific comment) is: + * + *
    + *
  • TITLE
  • + *
  • VERSION
  • + *
  • ALBUM
  • + *
  • ARTIST
  • + *
  • PERFORMER
  • + *
  • COPYRIGHT
  • + *
  • ORGANIZATION
  • + *
  • DESCRIPTION
  • + *
  • GENRE
  • + *
  • DATE
  • + *
  • LOCATION
  • + *
  • CONTACT
  • + *
  • ISRC
  • + *
+ * + * For a more detailed description of these fields, please see the Ogg + * Vorbis specification, section 5.2.2.1. + * + * \note The Ogg Vorbis comment specification does allow these key values + * to be either upper or lower case. However, it is conventional for them + * to be upper case. As such, TagLib, when parsing a Xiph/Vorbis comment, + * converts all fields to uppercase. When you are using this data + * structure, you will need to specify the field name in upper case. + * + * \warning You should not modify this data structure directly, instead + * use addField() and removeField(). + */ + const FieldListMap &fieldListMap() const; + + /*! + * Implements the unified property interface -- export function. + * The result is a one-to-one match of the Xiph comment, since it is + * completely compatible with the property interface (in fact, a Xiph + * comment is nothing more than a map from tag names to list of values, + * as is the dict interface). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * The tags from the given map will be stored one-to-one in the file, + * except for invalid keys (less than one character, non-ASCII, or + * containing '=' or '~') in which case the according values will + * be contained in the returned PropertyMap. + */ + PropertyMap setProperties(const PropertyMap&); + + /*! + * Check if the given String is a valid Xiph comment key. + */ + static bool checkKey(const String&); + + /*! + * Returns the vendor ID of the Ogg Vorbis encoder. libvorbis 1.0 as the + * most common case always returns "Xiph.Org libVorbis I 20020717". + */ + String vendorID() const; + + /*! + * Add the field specified by \a key with the data \a value. If \a replace + * is true, then all of the other fields with the same key will be removed + * first. + * + * If the field value is empty, the field will be removed. + */ + void addField(const String &key, const String &value, bool replace = true); + + /*! + * Remove the field specified by \a key with the data \a value. If + * \a value is null, all of the fields with the given key will be removed. + * + * \deprecated Using this method may lead to a linkage error. + */ + // BIC: remove and merge with below + TAGLIB_DEPRECATED void removeField(const String &key, const String &value = String()); + + /*! + * Remove all the fields specified by \a key. + * + * \see removeAllFields() + */ + void removeFields(const String &key); + + /*! + * Remove all the fields specified by \a key with the data \a value. + * + * \see removeAllFields() + */ + void removeFields(const String &key, const String &value); + + /*! + * Remove all the fields in the comment. + * + * \see removeFields() + */ + void removeAllFields(); + + /*! + * Returns true if the field is contained within the comment. + * + * \note This is safer than checking for membership in the FieldListMap. + */ + bool contains(const String &key) const; + + /*! + * Renders the comment to a ByteVector suitable for inserting into a file. + */ + ByteVector render() const; // BIC: remove and merge with below + + /*! + * Renders the comment to a ByteVector suitable for inserting into a file. + * + * If \a addFramingBit is true the standard Vorbis comment framing bit will + * be appended. However some formats (notably FLAC) do not work with this + * in place. + */ + ByteVector render(bool addFramingBit) const; + + + /*! + * Returns a list of pictures attached to the xiph comment. + */ + List pictureList(); + + /*! + * Removes an picture. If \a del is true the picture's memory + * will be freed; if it is false, it must be deleted by the user. + */ + void removePicture(FLAC::Picture *picture, bool del = true); + + /*! + * Remove all pictures. + */ + void removeAllPictures(); + + /*! + * Add a new picture to the comment block. The comment block takes ownership of the + * picture and will handle freeing its memory. + * + * \note The file will be saved only after calling save(). + */ + void addPicture(FLAC::Picture *picture); + + protected: + /*! + * Reads the tag from the file specified in the constructor and fills the + * FieldListMap. + */ + void parse(const ByteVector &data); + + private: + XiphComment(const XiphComment &); + XiphComment &operator=(const XiphComment &); + + class XiphCommentPrivate; + XiphCommentPrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/xmfile.h b/taglib/include/taglib/xmfile.h new file mode 100644 index 0000000..9211078 --- /dev/null +++ b/taglib/include/taglib/xmfile.h @@ -0,0 +1,112 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_XMFILE_H +#define TAGLIB_XMFILE_H + +#include "tfile.h" +#include "audioproperties.h" +#include "taglib_export.h" +#include "modfilebase.h" +#include "modtag.h" +#include "xmproperties.h" + +namespace TagLib { + + namespace XM { + + class TAGLIB_EXPORT File : public Mod::FileBase { + public: + /*! + * Constructs an Extended Module 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 an Extended Module 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. + */ + virtual ~File(); + + Mod::Tag *tag() const; + + /*! + * Implements the unified property interface -- export function. + * Forwards to Mod::Tag::properties(). + */ + PropertyMap properties() const; + + /*! + * Implements the unified property interface -- import function. + * Forwards to Mod::Tag::setProperties(). + */ + PropertyMap setProperties(const PropertyMap &); + + /*! + * Returns the XM::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + XM::Properties *audioProperties() const; + + /*! + * Save the file. + * This is the same as calling save(AllTags); + * + * \note Saving Extended Module tags is not supported. + */ + bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/taglib/include/taglib/xmproperties.h b/taglib/include/taglib/xmproperties.h new file mode 100644 index 0000000..24a5221 --- /dev/null +++ b/taglib/include/taglib/xmproperties.h @@ -0,0 +1,85 @@ +/*************************************************************************** + copyright : (C) 2011 by Mathias Panzenböck + email : grosser.meister.morti@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * 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_XMPROPERTIES_H +#define TAGLIB_XMPROPERTIES_H + +#include "taglib.h" +#include "tstring.h" +#include "audioproperties.h" + +namespace TagLib { + namespace XM { + class TAGLIB_EXPORT Properties : public AudioProperties { + friend class File; + public: + /*! Flag bits. */ + enum { + LinearFreqTable = 1 // otherwise its the amiga freq. table + }; + + Properties(AudioProperties::ReadStyle propertiesStyle); + virtual ~Properties(); + + int length() const; + int lengthInSeconds() const; + int lengthInMilliseconds() const; + int bitrate() const; + int sampleRate() const; + int channels() const; + + unsigned short lengthInPatterns() const; + unsigned short version() const; + unsigned short restartPosition() const; + unsigned short patternCount() const; + unsigned short instrumentCount() const; + unsigned int sampleCount() const; + unsigned short flags() const; + unsigned short tempo() const; + unsigned short bpmSpeed() const; + + void setChannels(int channels); + + void setLengthInPatterns(unsigned short lengthInPatterns); + void setVersion(unsigned short version); + void setRestartPosition(unsigned short restartPosition); + void setPatternCount(unsigned short patternCount); + void setInstrumentCount(unsigned short instrumentCount); + void setSampleCount(unsigned int sampleCount); + void setFlags(unsigned short flags); + void setTempo(unsigned short tempo); + void setBpmSpeed(unsigned short bpmSpeed); + + private: + Properties(const Properties&); + Properties &operator=(const Properties&); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif diff --git a/taglib/lib/libtag.a b/taglib/lib/libtag.a new file mode 100644 index 0000000000000000000000000000000000000000..1c36226ef54ad9e5cc52baf9b5843691fbbe10ee GIT binary patch literal 2316966 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
|1T?6M~D9?Pa#LI2rJz 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
p-D-e>_X3l3zcEk7=6PEk!o7cN2|Z8i_UE|Z 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
NhuUe=aaTXtQEp)Ag1}%h$I?HiOeJT*^ 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⪙xf_9`2AhCH?p7d?+o5Qua-Rf} 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 literal 0 HcmV?d00001 diff --git a/taglib/lib/libtag_c.a b/taglib/lib/libtag_c.a new file mode 100644 index 0000000000000000000000000000000000000000..d06acc983a7f247035ee2ef825cdd23e63c26500 GIT binary patch literal 20496 zcmeHP4Rl<^b)NO^+ACv6!u;9TiI-O7$k>*5^=FAftF49=FQBTr=5!~i}iPO|K-eOe&-RasjRH7tPTdN{r-R! z*{^wE*yf%@ zdo&eKM^owkL~?T~I*?3s^mfMcMbRy>WNdSMOFWs5#*?x3o_MFF)YTu4+kDinO7z6n z#Fs^uO)F_@CTE&Rq@r76J&CM4N(u#ssn|egqPMTVw=dqG zPQ+6VSt_elI!*rRG#B^=XYfs+?|)#^zG2)LkB>N-pB~!wCGUxvji2mX6uehe&VGY4EOTN<9F3-DRva3qidK)R*@;^@dzZh0j-N!sxXb zy=7IL&bp2ReD?yS_AX(@i@;yf+_tRJsYvD6J(qQ?Ykf(eepyYm71bf-=T7K7W$d{T z*Lrm|4!v>2_CfE2(L+_T-(ZD9k?eKO!^L)Jd%^1EHcF9RAN1xfWmfzKYisR#&4}!P zUX9U1b+X@zphM3G{zxIe6;*Y1d*t^S=&jE6TTvUZ>+OZ33Fvhjy-Oja_Oh&^&QXCq zxNk!XaF3U9YO+uFcUfgHXty_p$g60krN&FC(JSwFwgVFHc%M>xOllhX(Eebr!cl(; zejk9|38Ob1dfX0bDgfnJ0`$N_rIr{L$@u$VmoxbRMp@q%^u`;qhF~9jXmv`o{x@nZ@=w{BYWM@`&WB8RQ>p} zs^t#9P*Ht!u^sg#sK4rfL$3t#F+c9Hu}AHS^(q~DP*HnvdDEUhZLh|m*9^UJQnnp* z-@>D_$<;BUix<|bQ0p}<;o(>P;ZZN~;S4>%Dm>z)0-hKya~1Ep2`DmhF%fHa9Ze5} zhIW*CRMW`DQeV?(y406m8LoRVy|Sx#VFRVSvLw9g@pSZn3;HkP1T{Zg_r}0WIt8iD zEnWymKRPg%g{)Nf;=u6(elU^De}sn*`9JjG&_^=kw|HM zQ|3^3w4t;)T=z)2I6OjVv{g+r1&zQ4qydt?hophn0g-jST{6|gvCKFy{_|Ka7 z{U-j9i9c@QKQeLZ0LjmzD z+MYj0zf9tKwDOOJCPSGc!@qJrh}u&P#VaSc&(A#4kohT%p4QkoX2$nG@uGC8f9P^_ zdXs8kPH`Dx&5|Y!nZY1-w1EQWKgonp{;kttZ zFIc>pEac4-7GoNarmFZ~%oDo8#mQfE75Dst(k#r5*O)h8KB1=$oE^+8ju)R@({#9@ zl%7iEEZUfve9%0>vUvPSTbnWC{|4MwJ>K$IJK0>)Q2b3jj|h)ON&^^RP2mxlJdga) zY#?A}1NAcAW5kv5{+Lc;)%p260ob4iRa<#RXOlIps)zN+$Wot0L^5q9G_a3e?b8ZP z!;N!Yc02T-Tx%YXZ3w%@rYg_ecTIVAoATUy((?GrWg3db37Z*9BG_49?2XF4NtiBBZ-~?-QMKW z;BhgJ%ufh{>w@n+@apG{!^SPDpQP23aCppFBq|0{>Ud`U`9Z>U%JgVrc-hd^A z>^@fj!b`o66{%M5Xp#E73(>E-ye}20BQEcci`3XO5Pv((`)rZ=`ZVtkiqw!B#3$X} zZx^Y3ZtpjW)CnTqc6;wFQn!1&cND1!4~SPh-d!`*POta3Me0c}i08fDw~Ex8Uhiu~ zYJ56~?@jl9sYo52?!CK6?VkbSzzpvlGu1OQyrVPKULS}r_`LVdREK=tyJzaMxjZiA zS;6JhWzLP8IN&iPn8S>*kWOI1$) zXP3Igh2=!9(?4ZBy07aT_tm!;^;a|PO1|fRL>aX@T92ZG7H6Kq>A^XH^A()Loxu4v z&U10njiosY&4Wr1j^e~ppc+H?Z7j&u0*@p7Ae*7$~7XuF=T#L#Y2X03A zK1{1#2KFON;VeN%Fof`FoJ)Ww5LUhiHi7FA-iEUicrU^?a1H^}TuQHwmC5QD#)Ocs zDRYEY#s(6Rk%Vu}uGi9Sp`nk_ir6MBhz3PS=Co!lj7OCNbgMDW&>Ia+*+ZL-(LKvs3$yohV`HwFUNv*Y^nkZ5`&@pN(&5Nk z_tPcQ#o7@WiJ@3W)2X}}e27XGvfc+yzRvf?6zhE1vc0o)zMQhz`fMtXRW4r4%zQsQ z(uAeBmDWlefNh!XEJ#Xd&OR?Z(ozy0e$++pOdoR8DG>)zhu&$*Tj2_jkF|8cA@4cX zm=8j~ku+sqFp~nlZCS7FW!37tR@<5@N)3sIC9mNRdMGa*@PY8uA6jtklY&qgv`K1ZhT8Knsw z25dc%o)aDk+E#@!uOB~V^;V89+4h)dIB(VrHEV@0Fr#gHpSL+XPU3kfu0wt8a(N$i zspBrRJbk=wLRx1u-_o>wV3HWDzoqGFG9T0|9U8~6MC3cHsBWmT9{o-|Y7KQ0K3q?I zCl*EZs#@{c^}4irP{KIm;rTjgB>MvW9NM5mi>H3-~ z|6pxRw5Dq5Ku3RiXA4v41{q5WREBfOd-D!VIEZG_FPc8BXgXIMp+)F?=YUIX~!D;=1>VP=KN+3?L31~>CxIy&p6m$;|r}!ce zr+5tLCY|DEqUS-yu(z{;IK_M*PEif?37w)v^wNTE0^$@SK%C-UpkbZjAP`$VD(H0} zPVwJBoZ>w63OjX*N+3?rDkuiTDXs(J6uW?S=@fr2dWQu45QtO!I}oRM3+QH@g5I6k zN0p!u5U02jh*QLYZqX@*MQ@*=uK;n1e*)qZ&jRh%Dc%shbMeTsx0ir2TKXdlBA?V~ z5{O&Ve4o|o{v2qrmR=&<mnC4PIVU2DB;-}(HAkN=D;qC|GI(P_Zk4}MQ0+V*;Ov~GOKZFT;b*cvA0D) zd$e>55U0H!h`sFsVsG~Xv9~V)vA3@Qaf+vbxNOe>vA3hb9Rp%-zXsZ)y;Wie;j|H; zTQ#>4h%MhH(g#HPut?t!=`2kAIPC%;PTK;+mU~3HL!@65=@F5>AW|RlL9-Q)`ZBIu zURp)try>JH^BRx(J3$xWd1G#oprD{SK_Nj+f<7SVgMwm$5`sP|XuF`B1Z4!>D(JI< z?h$mqpsxseNYE?jBSv)Dp28EwC3;@a=g`KP`+}f;v^D0g7qkNRm$}t~=HPBIccGwO zK~D%;hP%LepAz(6g36G$0i15tAgC30fw>)m_6a&7=uJTjFdlJ=T0yOX`ULF}1ZQfM z_KU9FAZjHM&7qKnD-lGiQ!J$^4yRop$S=}T;izn^w?w1?;i?4Hiu5w!>IG4~u-~w7 z6lcrLB5f6JgCMGRPTMA2r=V_;_6XM}C@oTYa@gArK|>ynJBL`v(E%v~m^UZf4eg$2=D8vAV)j-Fb!LbF$vZWOLfP^U<{h3gSSYoeSsE!?0W z>JM0o?#0Z)uL9y8JuT>FL3axRpfv^5q(_hss9AI9>P}+suOVe00192DvBHR~v}z9j z#A);{7X+YJw%PBwh~bM2t{XI>yqu5IqgTm4rqO$GWp5XYbSV%^vz8l0x<;g%fH-Yj zq+3Kv7FfDVq@yCeSEOGO={H3Bm`Hyh(q~2bl1N_@>02VD6@B(Q8;Hw$9uSx4Vv#Nt zX|+fjMY=|$SBo?y(i?!r;L)RoMS71&?-%J;MEZnC|4pPn5$SJ5ise&dc{UK|c`*=| zs8XbVA<_onBEnrQ9KCt5l`i3u!fg}oM&Wh~HzwR2C@Vd09{p}S0OVEyTp3ZTX4E5S zx1fE3#sy6XqP~gKQm?{@`U6JvBr`$+J+gDl-iR2t>F%p5(PjOfbJHsLx2b&HhhnN#!$ zN{e(*xE+FqM7mQrx<_nfk4OQ`o%RUw37RE{>X};v)iWciXGRMI`302HXEJBQ11S866r{*vfHE$D?XX$N%miYj!@@ZbP?0IdIbPwFFwYVDRHnd-KEbre1L-VDqo#%{BF>=W8H3VZ0ooT2JTJ_HAEC4f(8qa*TM8Tn8(2kIhdb=8FMi7 zKNWi&Oc|K{4kip{+`;skW=GGZ+eItI)FSz??!l);$Ex{%1arb+=djT^Uuyn!F!U8X zTVvB;n!Yh)Ykn>m`Z}J~xdhB^hYr1Q(^vDX&N?vkO(JWj8w`C-&+6O&=BPvGHZb&+ zJ*%@141L4M+BpD*zP@L5o&Zzt&^ZQ%zRG8HCc)4*kF1>wQ8)CpKC80~41Ej9>NJ6& zulQM=HZb&!B&)Ln41L|t>f8!ur$gt9VCc9Ir`tvMF?*QDK|OAC=0oImQBMRD<{%yW zFa1zy(4qe)c-T_Wq5W5Wl-f=IOqX-mf8j@V-7b34oQM6_eQ3ncq2Kq>lb=28zwD!i z<#r7rTWwhdgMMzxMFE#9t77GDI(7IsC~&)U52NFBv2^qgg%C$GGdd*Y!_sLmcIeGv zDmxuU2e%$NCX!?46NW|wPif~Kqf@MP=sOvW*Un?V(b40Ii{7Z5bx7LdMu+Z#+ck!3 zDbaG+e>pb?tlL$FE7gMYc+%LRk>Bm2QJPu_A6EUmX>`s5Jyre8r9lY?y%D%wNnG=N zz2E3upmmHx=a4zkHjgb;wRO&!j^~gR%2oV7KcE&E;OMGCDNoa#_0! zLr)wtA2SR+U(DQY7^VD%`JynE4y}G$2dDapFqA5KZD&vOR+@d$L5%*HIY$jckzYDe z5p%XwtL6QJ4kmhSa+_s0n?qVX=fg_%Kpt};b1;vYEsfPm)tblL zmB&ovF_+MzrVqap;g}Aw9(Uuym>&%zDIh z-&$H|Hv`(`fP2HK#rh}CQ;X>r+6ASwi@`~3Yw^^!wK&JNbBBaH+d1M~+c{#gT|SWP zNn982*={mwi|f?3curOdYz~l@pF%phnJT2CbCycuhy4S6R>maC`I4yq-7%`a;E(jV zZzXA=-|A z+aVX)aV0A)*qQ4MOA3y|dW@fP+|e5yO+9q!{+Hi{3K}ms$UA$kywo}3cQ_DFS_^lcz#>>;OJ9^W z73##mulM5#2BOi9!NFL2VrwwC9JnWzO6hJrnn-r_()K)SThg_O-c+6%%-KDMli&JH9Y&QYQ@HG)^i<=($-^%o?vy9Hl~XvvBjKz(3eNoM7w)? zuWM{>2}BEZ0(kcH{Magyv0jtztzD5wuc$_+5)3xB+j;||k<)t^mivyiaAxv1^M3&O C&~~{1 literal 0 HcmV?d00001 diff --git a/taglib/lib/pkgconfig/taglib.pc b/taglib/lib/pkgconfig/taglib.pc new file mode 100644 index 0000000..ce332b3 --- /dev/null +++ b/taglib/lib/pkgconfig/taglib.pc @@ -0,0 +1,11 @@ +prefix=C:/taglib +exec_prefix=C:/taglib +libdir=C:/taglib/lib +includedir=C:/taglib/include + +Name: TagLib +Description: Audio meta-data library +Requires: +Version: 1.12 +Libs: -L${libdir} -ltag +Cflags: -I${includedir} -I${includedir}/taglib diff --git a/taglib/lib/pkgconfig/taglib_c.pc b/taglib/lib/pkgconfig/taglib_c.pc new file mode 100644 index 0000000..b1fc695 --- /dev/null +++ b/taglib/lib/pkgconfig/taglib_c.pc @@ -0,0 +1,12 @@ +prefix=C:/taglib +exec_prefix=C:/taglib +libdir=C:/taglib/lib +includedir=C:/taglib/include + + +Name: TagLib C Bindings +Description: Audio meta-data library (C bindings) +Requires: taglib +Version: 1.12 +Libs: -LC:/taglib/lib -ltag_c +Cflags: -IC:/taglib/include/taglib