44 Commits

Author SHA1 Message Date
Urs Fleisch
0ebb14b855 Version 2.0 2024-01-24 05:10:43 +01:00
Rosen Penev
89af92333c clang-tidy: use dynamic_cast
Found with cppcoreguidelines-pro-type-static-cast-downcast

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-22 18:35:30 +01:00
Rosen Penev
b356fabe12 clang-tidy: avoid else after return
Found with: readability-else-after-return

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-22 18:35:30 +01:00
Rosen Penev
8a65068f3b clang-tidy: fix wrong cast
Found with bugprone-misplaced-widening-cast

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-22 18:35:30 +01:00
Rosen Penev
e1ac724cfe convert const double to const auto
Fixes some Wconversion warnings.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-22 18:35:30 +01:00
Urs Fleisch
a08acdcf23 Remove unused types from taglib.h 2024-01-21 20:46:27 +01:00
Urs Fleisch
1799b98c17 Inspection: Table is not correctly formatted 2024-01-21 20:46:27 +01:00
Urs Fleisch
e49390c7c5 Inspection: Type can be replaced with auto 2024-01-21 20:46:27 +01:00
Urs Fleisch
7bcfb96098 Inspection: Code redundancies 2024-01-21 20:46:27 +01:00
Urs Fleisch
580b0b0c82 Inspection: Possibly unused #include directive 2024-01-21 20:46:27 +01:00
Urs Fleisch
5fc3e5c192 Inspection: Possibly uninitialized class member 2024-01-21 20:46:27 +01:00
Urs Fleisch
570b40bdcd Inspection: Polymorphic class with non-virtual public destructor 2024-01-21 20:46:27 +01:00
Urs Fleisch
c3d73a26ff Inspection: Parameter names do not match 2024-01-21 20:46:27 +01:00
Urs Fleisch
790815bcf4 Inspection: Missing include guard 2024-01-21 20:46:27 +01:00
Urs Fleisch
1a5c417558 Inspection: Function is not implemented 2024-01-21 20:46:27 +01:00
Urs Fleisch
d87b2dad48 Inspection: Expression can be simplified 2024-01-21 20:46:27 +01:00
Urs Fleisch
613355665c Inspection: Variable can be moved to inner scope 2024-01-21 20:46:27 +01:00
Urs Fleisch
dfe2aa5253 Inspection: Variable can be moved to init statement 2024-01-21 20:46:27 +01:00
Urs Fleisch
5d921c6325 Inspection: Variable can be made constexpr 2024-01-21 20:46:27 +01:00
Urs Fleisch
710522e6e1 Inspection: Result of a postfix operator is discarded 2024-01-21 20:46:27 +01:00
Urs Fleisch
6b17aa3694 Inspection: Parameter can be made pointer to const 2024-01-21 20:46:27 +01:00
Urs Fleisch
b4f77a4d52 Inspection: Member function can be made const 2024-01-21 20:46:27 +01:00
Urs Fleisch
c907d8b273 Inspection: Functional-style cast is used instead of a C++ cast 2024-01-21 20:46:27 +01:00
Urs Fleisch
98175168f3 Inspection: Declaration and assignment can be joined 2024-01-21 20:46:27 +01:00
Urs Fleisch
73aff544b3 Inspection: C-style cast is used instead of a C++ cast 2024-01-21 20:46:27 +01:00
Rosen Penev
9cbb6615d5 clang-tidy: use using
Found with modernize-use-using

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
8b7b48cc9b clang-tidy: add ending namespace comments
Found with llvm-namespace
2024-01-19 21:57:55 +01:00
Rosen Penev
be8d71dad8 MSVC: fix signed/unsigned comparison
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
6abbe579a2 clang-tidy: remove virtual from prot destructors
Found with cppcoreguidelines-virtual-class-destructor

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
208fc93aaa cppcheck: match function argument names
Found with funcArgNamesDifferent

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
769feafbe0 cppcheck: include system headers with <>
Found with missingInclude

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
dfef09f134 cppcheck: assign d to a value
Found with operatorEqVarError, missingMemberCopy

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
3a003c1229 cppcheck: add const
Found with constVariablePointer, constParameterPointer

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
8b9a260d18 clang-tidy: fix doubled cases
Found with bugprone-branch-clone

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
c2eb6b59b5 clang-tidy: avoid endl
Found with performance-avoid-endl

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
99ba7635be clang-tidy: remove pointless const
Found with cppcoreguidelines-avoid-const-or-ref-data-members

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Rosen Penev
82b5ded8ee tvariant: fix -Wconversion warning
char -> wchar_t. Just directly use int and remove the cast.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2024-01-19 21:57:55 +01:00
Urs Fleisch
0318201fbd Make classes with destructor as only virtual member non-virtual
These classes are probably not meant to be used polymorphically.
2024-01-17 21:25:44 +01:00
Urs Fleisch
6c1ba88eab Make Frame::Header::size(), Frame::headerSize() const 2024-01-17 21:25:44 +01:00
Urs Fleisch
fb0f7dfa57 More API documentation corrections 2024-01-17 20:54:56 +01:00
Urs Fleisch
c5d798a50d Correct the API documentation 2024-01-04 17:18:23 +01:00
Urs Fleisch
ef013b76db Add checks for the expected sizes of new public classes 2024-01-02 14:16:22 +01:00
Urs Fleisch
a6dbc70644 Fix shadowArgument issue reported by cppcheck 2024-01-02 13:50:11 +01:00
Urs Fleisch
9a026976ae Do not use std::visit() for std::variant
It is not supported for macOS 10.13 and earlier, see
https://stackoverflow.com/questions/53946674/noexcept-visitation-for-stdvariant.
2023-12-29 07:36:03 +01:00
212 changed files with 1667 additions and 1624 deletions

1
.gitignore vendored
View File

@@ -22,7 +22,6 @@ CMakeLists.txt.user*
/tests/test_runner
/tests/Testing
/taglib/libtag.a
/taglib_config.h
/taglib-config
/bindings/c/libtag_c.a
/bindings/c/taglib_c.pc

View File

@@ -74,6 +74,15 @@ TagLib 2.0 (Jan 24, 2024)
- String::null
- TrueAudio::File::setID3v2FrameFactory(): Use constructor
- WavPack::Properties::Properties(const ByteVector &, long, ReadStyle)
* Made methods const: Frame::Header::size(), Frame::headerSize(),
MP4::Atom::findall(), MP4::Atoms::find(), MP4::Atoms::path().
* Made classes non-virtual: APE::Footer, APE::Item, ASF::Attribute,
ASF::Picture, MP4::CoverArt, MP4::Item, ID3v2::ExtendedHeader, ID3v2::Footer,
ID3v2::Header, MPEG::Header, MPEG::XingHeader, Ogg::Page, Ogg::PageHeader.
* Removed type definitions in TagLib namespace: wchar, uchar, ushort, uint,
ulong, ulonglong, wstring: Use the standard types.
* Removed include file taglib_config.h and its defines TAGLIB_WITH_ASF,
TAGLIB_WITH_MP4: They were always 1 since version 1.8.
* Behavioral changes:
- The basic tag methods (e.g. genre()) separate multiple values with " / "
instead of " ".

View File

@@ -148,8 +148,6 @@ if(TRACE_IN_RELEASE)
set(TRACE_IN_RELEASE TRUE)
endif()
configure_file(taglib/taglib_config.h.cmake "${CMAKE_CURRENT_BINARY_DIR}/taglib_config.h")
find_package(utf8cpp QUIET)
if(NOT utf8cpp_FOUND)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/utfcpp/CMakeLists.txt)

View File

@@ -12,7 +12,6 @@ OUTPUT_DIRECTORY = doc
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
OUTPUT_TEXT_DIRECTION = None
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
@@ -239,7 +238,6 @@ PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
@@ -252,7 +250,6 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -273,7 +270,6 @@ XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@@ -309,7 +305,6 @@ EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES

View File

@@ -27,7 +27,7 @@ These are the most important build options. For details, have a look into the
CMakeLists.txt file.
| Option | Description |
| ----------------------- | -------------------------------------------------- |
|-------------------------|----------------------------------------------------|
| `BUILD_SHARED_LIBS` | Build shared libraries |
| `CMAKE_BUILD_TYPE` | Debug, Release, RelWithDebInfo, MinSizeRel |
| `BUILD_EXAMPLES` | Build examples |

View File

@@ -2,5 +2,4 @@ There are a few other people that have done bindings externally that I have
been made aware of. I have not personally reviewed these bindings, but I'm
listing them here so that those who find them useful are able to find them:
http://developer.kde.org/~wheeler/taglib.html#bindings
https://taglib.org/#language-bindings

View File

@@ -30,7 +30,6 @@
# include "config.h"
#endif
#include "tstringlist.h"
#include "tbytevectorlist.h"
#include "tbytevectorstream.h"
#include "tiostream.h"
#include "tfile.h"
@@ -236,7 +235,7 @@ BOOL taglib_file_save(TagLib_File *file)
char *taglib_tag_title(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
char *s = stringToCharArray(t->title());
if(stringManagementEnabled)
strings.append(s);
@@ -245,7 +244,7 @@ char *taglib_tag_title(const TagLib_Tag *tag)
char *taglib_tag_artist(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
char *s = stringToCharArray(t->artist());
if(stringManagementEnabled)
strings.append(s);
@@ -254,7 +253,7 @@ char *taglib_tag_artist(const TagLib_Tag *tag)
char *taglib_tag_album(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
char *s = stringToCharArray(t->album());
if(stringManagementEnabled)
strings.append(s);
@@ -263,7 +262,7 @@ char *taglib_tag_album(const TagLib_Tag *tag)
char *taglib_tag_comment(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
char *s = stringToCharArray(t->comment());
if(stringManagementEnabled)
strings.append(s);
@@ -272,7 +271,7 @@ char *taglib_tag_comment(const TagLib_Tag *tag)
char *taglib_tag_genre(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
char *s = stringToCharArray(t->genre());
if(stringManagementEnabled)
strings.append(s);
@@ -281,55 +280,55 @@ char *taglib_tag_genre(const TagLib_Tag *tag)
unsigned int taglib_tag_year(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
return t->year();
}
unsigned int taglib_tag_track(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
auto t = reinterpret_cast<const Tag *>(tag);
return t->track();
}
void taglib_tag_set_title(TagLib_Tag *tag, const char *title)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setTitle(charArrayToString(title));
}
void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setArtist(charArrayToString(artist));
}
void taglib_tag_set_album(TagLib_Tag *tag, const char *album)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setAlbum(charArrayToString(album));
}
void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setComment(charArrayToString(comment));
}
void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setGenre(charArrayToString(genre));
}
void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setYear(year);
}
void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track)
{
Tag *t = reinterpret_cast<Tag *>(tag);
auto t = reinterpret_cast<Tag *>(tag);
t->setTrack(track);
}
@@ -431,17 +430,17 @@ void _taglib_property_set(TagLib_File *file, const char* prop, const char* value
} // namespace
void taglib_property_set(TagLib_File *f, const char *prop, const char *value)
void taglib_property_set(TagLib_File *file, const char *prop, const char *value)
{
_taglib_property_set(f, prop, value, false);
_taglib_property_set(file, prop, value, false);
}
void taglib_property_set_append(TagLib_File *f, const char *prop, const char *value)
void taglib_property_set_append(TagLib_File *file, const char *prop, const char *value)
{
_taglib_property_set(f, prop, value, true);
_taglib_property_set(file, prop, value, true);
}
char** taglib_property_keys(TagLib_File *file)
char** taglib_property_keys(const TagLib_File *file)
{
if(file == NULL)
return NULL;
@@ -461,7 +460,7 @@ char** taglib_property_keys(TagLib_File *file)
return props;
}
char **taglib_property_get(TagLib_File *file, const char *prop)
char **taglib_property_get(const TagLib_File *file, const char *prop)
{
if(file == NULL || prop == NULL)
return NULL;
@@ -520,8 +519,7 @@ bool _taglib_complex_property_set(
while(*attrPtr) {
const TagLib_Complex_Property_Attribute *attr = *attrPtr;
String attrKey(attr->key);
TagLib_Variant_Type type = attr->value.type;
switch(type) {
switch(attr->value.type) {
case TagLib_Variant_Void:
map.insert(attrKey, Variant());
break;
@@ -585,7 +583,7 @@ BOOL taglib_complex_property_set_append(
return _taglib_complex_property_set(file, key, value, true);
}
char** taglib_complex_property_keys(TagLib_File *file)
char** taglib_complex_property_keys(const TagLib_File *file)
{
if(file == NULL) {
return NULL;
@@ -608,7 +606,7 @@ char** taglib_complex_property_keys(TagLib_File *file)
}
TagLib_Complex_Property_Attribute*** taglib_complex_property_get(
TagLib_File *file, const char *key)
const TagLib_File *file, const char *key)
{
if(file == NULL || key == NULL) {
return NULL;
@@ -619,15 +617,15 @@ TagLib_Complex_Property_Attribute*** taglib_complex_property_get(
return NULL;
}
TagLib_Complex_Property_Attribute ***props = static_cast<TagLib_Complex_Property_Attribute ***>(
auto props = static_cast<TagLib_Complex_Property_Attribute ***>(
malloc(sizeof(TagLib_Complex_Property_Attribute **) * (variantMaps.size() + 1)));
TagLib_Complex_Property_Attribute ***propPtr = props;
for(const auto &variantMap : variantMaps) {
if(!variantMap.isEmpty()) {
TagLib_Complex_Property_Attribute **attrs = static_cast<TagLib_Complex_Property_Attribute **>(
auto attrs = static_cast<TagLib_Complex_Property_Attribute **>(
malloc(sizeof(TagLib_Complex_Property_Attribute *) * (variantMap.size() + 1)));
TagLib_Complex_Property_Attribute *attr = static_cast<TagLib_Complex_Property_Attribute *>(
auto attr = static_cast<TagLib_Complex_Property_Attribute *>(
malloc(sizeof(TagLib_Complex_Property_Attribute) * variantMap.size()));
TagLib_Complex_Property_Attribute **attrPtr = attrs;
// The next assignment is redundant to silence the clang analyzer,
@@ -675,7 +673,7 @@ TagLib_Complex_Property_Attribute*** taglib_complex_property_get(
}
case Variant::StringList: {
attr->value.type = TagLib_Variant_StringList;
StringList strs = v.value<StringList>();
auto strs = v.value<StringList>();
auto strPtr = static_cast<char **>(malloc(sizeof(char *) * (strs.size() + 1)));
attr->value.value.stringListValue = strPtr;
attr->value.size = strs.size();
@@ -727,8 +725,7 @@ void taglib_picture_from_complex_property(
TagLib_Complex_Property_Attribute** attrPtr = *propPtr;
while(*attrPtr) {
TagLib_Complex_Property_Attribute *attr = *attrPtr;
TagLib_Variant_Type type = attr->value.type;
switch(type) {
switch(attr->value.type) {
case TagLib_Variant_String:
if(strcmp("mimeType", attr->key) == 0) {
picture->mimeType = attr->value.value.stringValue;
@@ -779,8 +776,7 @@ void taglib_complex_property_free(
TagLib_Complex_Property_Attribute** attrPtr = *propPtr;
while(*attrPtr) {
TagLib_Complex_Property_Attribute *attr = *attrPtr;
TagLib_Variant_Type type = attr->value.type;
switch(type) {
switch(attr->value.type) {
case TagLib_Variant_String:
free(attr->value.value.stringValue);
break;

View File

@@ -164,7 +164,7 @@ TAGLIB_C_EXPORT TagLib_File *taglib_file_new_iostream(TagLib_IOStream *stream);
TAGLIB_C_EXPORT void taglib_file_free(TagLib_File *file);
/*!
* Returns true if the file is open and readable and valid information for
* Returns \c true if the file is open and readable and valid information for
* the Tag and / or AudioProperties was found.
*/
@@ -232,12 +232,12 @@ TAGLIB_C_EXPORT char *taglib_tag_comment(const TagLib_Tag *tag);
TAGLIB_C_EXPORT char *taglib_tag_genre(const TagLib_Tag *tag);
/*!
* Returns the tag's year or 0 if year is not set.
* Returns the tag's year or 0 if the 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.
* Returns the tag's track number or 0 if the track number is not set.
*/
TAGLIB_C_EXPORT unsigned int taglib_tag_track(const TagLib_Tag *tag);
@@ -354,7 +354,7 @@ TAGLIB_C_EXPORT void taglib_property_set_append(TagLib_File *file, const char *p
* \return NULL terminated array of C-strings (char *), only NULL if empty.
* It must be freed by the client using taglib_property_free().
*/
TAGLIB_C_EXPORT char** taglib_property_keys(TagLib_File *file);
TAGLIB_C_EXPORT char** taglib_property_keys(const TagLib_File *file);
/*!
* Get value(s) of property \a prop.
@@ -362,7 +362,7 @@ TAGLIB_C_EXPORT char** taglib_property_keys(TagLib_File *file);
* \return NULL terminated array of C-strings (char *), only NULL if empty.
* It must be freed by the client using taglib_property_free().
*/
TAGLIB_C_EXPORT char** taglib_property_get(TagLib_File *file, const char *prop);
TAGLIB_C_EXPORT char** taglib_property_get(const TagLib_File *file, const char *prop);
/*!
* Frees the NULL terminated array \a props and the C-strings it contains.
@@ -541,7 +541,7 @@ TAGLIB_C_EXPORT BOOL taglib_complex_property_set_append(
* \return NULL terminated array of C-strings (char *), only NULL if empty.
* It must be freed by the client using taglib_complex_property_free_keys().
*/
TAGLIB_C_EXPORT char** taglib_complex_property_keys(TagLib_File *file);
TAGLIB_C_EXPORT char** taglib_complex_property_keys(const TagLib_File *file);
/*!
* Get value(s) of complex property \a key.
@@ -551,7 +551,7 @@ TAGLIB_C_EXPORT char** taglib_complex_property_keys(TagLib_File *file);
* It must be freed by the client using taglib_complex_property_free().
*/
TAGLIB_C_EXPORT TagLib_Complex_Property_Attribute*** taglib_complex_property_get(
TagLib_File *file, const char *key);
const TagLib_File *file, const char *key);
/*!
* Extract the complex property values of a picture.

View File

@@ -33,7 +33,6 @@ set(tag_HDRS
fileref.h
audioproperties.h
taglib_export.h
${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h
toolkit/taglib.h
toolkit/tstring.h
toolkit/tlist.h

View File

@@ -75,7 +75,7 @@ bool APE::File::isSupported(IOStream *stream)
// An APE file has an ID "MAC " somewhere. An ID3v2 tag may precede.
const ByteVector buffer = Utils::readHeader(stream, bufferSize(), true);
return (buffer.find("MAC ") >= 0);
return buffer.find("MAC ") >= 0;
}
////////////////////////////////////////////////////////////////////////////////
@@ -178,7 +178,7 @@ bool APE::File::save()
insert(data, d->APELocation, d->APESize);
if(d->ID3v1Location >= 0)
d->ID3v1Location += (static_cast<long>(data.size()) - d->APESize);
d->ID3v1Location += static_cast<long>(data.size()) - d->APESize;
d->APESize = data.size();
}
@@ -224,12 +224,12 @@ void APE::File::strip(int tags)
bool APE::File::hasAPETag() const
{
return (d->APELocation >= 0);
return d->APELocation >= 0;
}
bool APE::File::hasID3v1Tag() const
{
return (d->ID3v1Location >= 0);
return d->ID3v1Location >= 0;
}
////////////////////////////////////////////////////////////////////////////////
@@ -283,7 +283,7 @@ void APE::File::read(bool readProperties)
if(d->ID3v2Location >= 0) {
seek(d->ID3v2Location + d->ID3v2Size);
streamLength -= (d->ID3v2Location + d->ID3v2Size);
streamLength -= d->ID3v2Location + d->ID3v2Size;
}
else {
seek(0);

View File

@@ -48,7 +48,7 @@ namespace TagLib {
//! An implementation of APE metadata
/*!
* This is implementation of APE metadata.
* This is an implementation of APE metadata.
*
* This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream
* properties from the file.
@@ -84,7 +84,7 @@ namespace TagLib {
};
/*!
* Constructs an APE file from \a file. If \a readProperties is true the
* Constructs an APE file from \a file. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
@@ -93,7 +93,7 @@ namespace TagLib {
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Constructs an APE file from \a stream. If \a readProperties is true the
* Constructs an APE file from \a stream. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
@@ -155,15 +155,15 @@ namespace TagLib {
/*!
* 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
* If \a create is \c false (the default) this may return a null pointer
* if there is no valid ID3v1 tag. If \a create is \c 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 <b>is still</b> owned by the MPEG::File and should not be
* \note The Tag <b>is still</b> owned by the APE::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*
@@ -174,15 +174,15 @@ namespace TagLib {
/*!
* 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
* If \a create is \c false (the default) this may return a null pointer
* if there is no valid APE tag. If \a create is \c 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 <b>is still</b> owned by the MPEG::File and should not be
* \note The Tag <b>is still</b> owned by the APE::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*

View File

@@ -28,6 +28,8 @@
#include <bitset>
#include "taglib.h"
using namespace TagLib;
using namespace APE;

View File

@@ -59,7 +59,7 @@ namespace TagLib {
/*!
* Destroys the footer.
*/
virtual ~Footer();
~Footer();
Footer(const Footer &) = delete;
Footer &operator=(const Footer &) = delete;
@@ -70,17 +70,17 @@ namespace TagLib {
unsigned int version() const;
/*!
* Returns true if a header is present in the tag.
* Returns \c true if a header is present in the tag.
*/
bool headerPresent() const;
/*!
* Returns true if a footer is present in the tag.
* Returns \c true if a footer is present in the tag.
*/
bool footerPresent() const;
/*!
* Returns true this is actually the header.
* Returns \c true if this is actually the header.
*/
bool isHeader() const;
@@ -145,8 +145,8 @@ namespace TagLib {
ByteVector renderFooter() const;
/*!
* Renders the header corresponding to the footer. If headerPresent is
* set to false, it returns an empty ByteVector.
* Renders the header corresponding to the footer. If headerPresent() is
* \c false, it returns an empty ByteVector.
*/
ByteVector renderHeader() const;

View File

@@ -141,10 +141,10 @@ void APE::Item::setValue(const String &value)
d->value.clear();
}
void APE::Item::setValues(const StringList &value)
void APE::Item::setValues(const StringList &values)
{
d->type = Text;
d->text = value;
d->text = values;
d->value.clear();
}
@@ -241,7 +241,7 @@ void APE::Item::parse(const ByteVector &data)
ByteVector APE::Item::render() const
{
ByteVector data;
unsigned int flags = ((d->readOnly) ? 1 : 0) | (d->type << 1);
unsigned int flags = (d->readOnly ? 1 : 0) | (d->type << 1);
ByteVector val;
if(isEmpty())

View File

@@ -63,7 +63,7 @@ namespace TagLib {
/*!
* 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
* If \a binary is \c true a Binary item will be created, otherwise \a value will be interpreted as text
*/
Item(const String &key, const ByteVector &value, bool binary);
@@ -75,7 +75,7 @@ namespace TagLib {
/*!
* Destroys the item.
*/
virtual ~Item();
~Item();
/*!
* Copies the contents of \a item into this item.
@@ -83,7 +83,7 @@ namespace TagLib {
Item &operator=(const Item &item);
/*!
* Exchanges the content of this item by the content of \a item.
* Exchanges the content of this item with the content of \a item.
*/
void swap(Item &item) noexcept;
@@ -172,7 +172,7 @@ namespace TagLib {
void setReadOnly(bool readOnly);
/*!
* Return true if the item is read-only.
* Return \c true if the item is read-only.
*/
bool isReadOnly() const;
@@ -189,7 +189,7 @@ namespace TagLib {
ItemTypes type() const;
/*!
* Returns if the item has any real content.
* Returns \c false if the item has any real content.
*/
bool isEmpty() const;

View File

@@ -137,7 +137,7 @@ void APE::Properties::read(File *file, offset_t streamLength)
analyzeOld(file);
if(d->sampleFrames > 0 && d->sampleRate > 0) {
const double length = d->sampleFrames * 1000.0 / d->sampleRate;
const auto length = static_cast<double>(d->sampleFrames) * 1000.0 / d->sampleRate;
d->length = static_cast<int>(length + 0.5);
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
}
@@ -153,9 +153,8 @@ void APE::Properties::analyzeCurrent(File *file)
return;
}
const unsigned int descriptorBytes = descriptor.toUInt(0, false);
if((descriptorBytes - 52) > 0)
if(const unsigned int descriptorBytes = descriptor.toUInt(0, false);
descriptorBytes - 52 > 0)
file->seek(descriptorBytes - 52, File::Current);
// Read the header

View File

@@ -97,7 +97,7 @@ namespace TagLib {
unsigned int sampleFrames() const;
/*!
* Returns APE version.
* Returns the APE version.
*/
int version() const;

View File

@@ -47,8 +47,8 @@ using namespace APE;
namespace
{
const unsigned int MinKeyLength = 2;
const unsigned int MaxKeyLength = 255;
constexpr unsigned int MinKeyLength = 2;
constexpr unsigned int MaxKeyLength = 255;
const String FRONT_COVER("COVER ART (FRONT)");
const String BACK_COVER("COVER ART (BACK)");
@@ -203,10 +203,10 @@ PropertyMap APE::Tag::properties() const
{
PropertyMap properties;
for(const auto &[tag, item] : std::as_const(itemListMap())) {
String tagName = tag.upper();
// if the item is Binary or Locator, or if the key is an invalid string,
// add to unsupportedData
if(item.type() != Item::Text || tagName.isEmpty()) {
if(String tagName = tag.upper();
item.type() != Item::Text || tagName.isEmpty()) {
properties.addUnsupportedData(tag);
}
else {
@@ -241,9 +241,9 @@ PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
// first check if tags need to be removed completely
StringList toRemove;
for(const auto &[k, t] : std::as_const(itemListMap())) {
String key = k.upper();
// only remove if a) key is valid, b) type is text, c) key not contained in new properties
if(!key.isEmpty() && t.type() == APE::Item::Text && !props.contains(key))
if(String key = k.upper();
!key.isEmpty() && t.type() == APE::Item::Text && !props.contains(key))
toRemove.append(k);
}
@@ -255,7 +255,7 @@ PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
for(const auto &[tagName, val] : std::as_const(props)) {
if(!checkKey(tagName))
invalid.insert(tagName, val);
else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == val)) {
else if(!itemListMap().contains(tagName) || itemListMap()[tagName].values() != val) {
if(val.isEmpty())
removeItem(tagName);
else {
@@ -281,13 +281,12 @@ StringList APE::Tag::complexPropertyKeys() const
List<VariantMap> APE::Tag::complexProperties(const String &key) const
{
List<VariantMap> props;
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
const StringList itemNames = StringList(FRONT_COVER).append(BACK_COVER);
for(const auto &itemName: itemNames) {
if(d->itemListMap.contains(itemName)) {
Item picture = d->itemListMap.value(itemName);
if(picture.type() == Item::Binary) {
if(Item picture = d->itemListMap.value(itemName);
picture.type() == Item::Binary) {
ByteVector data = picture.binaryData();
// Do not search for a description if the first byte could start JPG or PNG
// data.
@@ -316,8 +315,7 @@ List<VariantMap> APE::Tag::complexProperties(const String &key) const
bool APE::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
{
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
removeItem(FRONT_COVER);
removeItem(BACK_COVER);

View File

@@ -29,6 +29,7 @@
#include "tbytevector.h"
#include "tmap.h"
#include "tstring.h"
#include "taglib.h"
#include "taglib_export.h"
#include "tag.h"
#include "apeitem.h"
@@ -116,6 +117,7 @@ namespace TagLib {
*
* 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,
* (and a few other keys, see \ref p_propertymapping)
* in order to be compliant with the names used in other formats.
*/
PropertyMap properties() const override;
@@ -165,7 +167,7 @@ namespace TagLib {
/*!
* 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
* is \c 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);
@@ -184,7 +186,7 @@ namespace TagLib {
void setItem(const String &key, const Item &item);
/*!
* Returns true if the tag does not contain any data.
* Returns \c true if the tag does not contain any data.
*/
bool isEmpty() const override;

View File

@@ -39,7 +39,7 @@ public:
pictureValue(ASF::Picture::fromInvalid())
{
}
AttributeTypes type;
AttributeTypes type { UnicodeType };
String stringValue;
ByteVector byteVectorValue;
ASF::Picture pictureValue;
@@ -154,7 +154,7 @@ unsigned int ASF::Attribute::toUInt() const
unsigned long long ASF::Attribute::toULongLong() const
{
return static_cast<unsigned long long>(d->numericValue);
return d->numericValue;
}
ASF::Picture ASF::Attribute::toPicture() const
@@ -162,30 +162,30 @@ ASF::Picture ASF::Attribute::toPicture() const
return d->pictureValue;
}
String ASF::Attribute::parse(ASF::File &f, int kind)
String ASF::Attribute::parse(ASF::File &file, int kind)
{
unsigned int size, nameLength;
String name;
d->pictureValue = Picture::fromInvalid();
// extended content descriptor
if(kind == 0) {
nameLength = readWORD(&f);
name = readString(&f, nameLength);
d->type = static_cast<ASF::Attribute::AttributeTypes>(readWORD(&f));
size = readWORD(&f);
nameLength = readWORD(&file);
name = readString(&file, nameLength);
d->type = static_cast<ASF::Attribute::AttributeTypes>(readWORD(&file));
size = readWORD(&file);
}
// metadata & metadata library
else {
int temp = readWORD(&f);
int temp = readWORD(&file);
// metadata library
if(kind == 2) {
d->language = temp;
}
d->stream = readWORD(&f);
nameLength = readWORD(&f);
d->type = static_cast<ASF::Attribute::AttributeTypes>(readWORD(&f));
size = readDWORD(&f);
name = readString(&f, nameLength);
d->stream = readWORD(&file);
nameLength = readWORD(&file);
d->type = static_cast<ASF::Attribute::AttributeTypes>(readWORD(&file));
size = readDWORD(&file);
name = readString(&file, nameLength);
}
if(kind != 2 && size > 65535) {
@@ -194,33 +194,33 @@ String ASF::Attribute::parse(ASF::File &f, int kind)
switch(d->type) {
case WordType:
d->numericValue = readWORD(&f);
d->numericValue = readWORD(&file);
break;
case BoolType:
if(kind == 0) {
d->numericValue = (readDWORD(&f) != 0);
d->numericValue = readDWORD(&file) != 0;
}
else {
d->numericValue = (readWORD(&f) != 0);
d->numericValue = readWORD(&file) != 0;
}
break;
case DWordType:
d->numericValue = readDWORD(&f);
d->numericValue = readDWORD(&file);
break;
case QWordType:
d->numericValue = readQWORD(&f);
d->numericValue = readQWORD(&file);
break;
case UnicodeType:
d->stringValue = readString(&f, size);
d->stringValue = readString(&file, size);
break;
case BytesType:
case GuidType:
d->byteVectorValue = f.readBlock(size);
d->byteVectorValue = file.readBlock(size);
break;
}
@@ -240,7 +240,6 @@ int ASF::Attribute::dataSize() const
case WordType:
return 2;
case BoolType:
return 4;
case DWordType:
return 4;
case QWordType:

View File

@@ -38,6 +38,8 @@ namespace TagLib
class File;
class Picture;
//! Attribute of ASF (WMA) metadata
class TAGLIB_EXPORT Attribute
{
public:
@@ -114,17 +116,17 @@ namespace TagLib
Attribute &operator=(const Attribute &other);
/*!
* Exchanges the content of the Attribute by the content of \a other.
* Exchanges the content of the Attribute with the content of \a other.
*/
void swap(Attribute &other) noexcept;
/*!
* Destroys the attribute.
*/
virtual ~Attribute();
~Attribute();
/*!
* Returns type of the value.
* Returns the type of the value.
*/
AttributeTypes type() const;

View File

@@ -472,7 +472,7 @@ bool ASF::File::isSupported(IOStream *stream)
// An ASF file has to start with the designated GUID.
const ByteVector id = Utils::readHeader(stream, 16, false);
return (id == headerGuid);
return id == headerGuid;
}
////////////////////////////////////////////////////////////////////////////////
@@ -564,8 +564,8 @@ bool ASF::File::save()
bool inMetadataObject = false;
for(const auto &attribute : attributes) {
const bool largeValue = (attribute.dataSize() > 65535);
const bool guid = (attribute.type() == Attribute::GuidType);
const bool largeValue = attribute.dataSize() > 65535;
const bool guid = attribute.type() == Attribute::GuidType;
if(!inExtendedContentDescriptionObject && !guid && !largeValue && attribute.language() == 0 && attribute.stream() == 0) {
d->extendedContentDescriptionObject->attributeData.append(attribute.render(name));
@@ -681,6 +681,5 @@ void ASF::File::read()
if(!filePropertiesObject || !streamPropertiesObject) {
debug("ASF::File::read(): Missing mandatory header objects.");
setValid(false);
return;
}
}

View File

@@ -35,6 +35,8 @@
namespace TagLib {
//! An implementation of ASF (WMA) metadata
namespace ASF {
//! An implementation of TagLib::File with ASF specific methods
/*!
* This implements and provides an interface for ASF files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
@@ -112,7 +114,7 @@ namespace TagLib {
/*!
* Save the file.
*
* This returns true if the save was successful.
* This returns \c true if the save was successful.
*/
bool save() override;

View File

@@ -30,7 +30,6 @@
#include "tbytevector.h"
#include "tpicturetype.h"
#include "taglib_export.h"
#include "attachedpictureframe.h"
namespace TagLib
{
@@ -40,9 +39,9 @@ namespace TagLib
//! An ASF attached picture interface implementation
/*!
* This is an implementation of ASF attached pictures interface. Pictures may be
* This is an implementation of ASF attached pictures. 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
* attributes in a single tag). These pictures are usually in either JPEG or
* PNG format.
* \see Attribute::toPicture()
* \see Attribute::Attribute(const Picture& picture)
@@ -50,7 +49,7 @@ namespace TagLib
class TAGLIB_EXPORT Picture {
public:
/*!
/*
* This describes the function or content of the picture.
*/
DECLARE_PICTURE_TYPE_ENUM(Type)
@@ -61,14 +60,14 @@ namespace TagLib
Picture();
/*!
* Construct an picture as a copy of \a other.
* Construct a picture as a copy of \a other.
*/
Picture(const Picture& other);
/*!
* Destroys the picture.
*/
virtual ~Picture();
~Picture();
/*!
* Copies the contents of \a other into this picture.
@@ -76,12 +75,12 @@ namespace TagLib
Picture& operator=(const Picture& other);
/*!
* Exchanges the content of the Picture by the content of \a other.
* Exchanges the content of the Picture with the content of \a other.
*/
void swap(Picture &other) noexcept;
/*!
* Returns true if Picture stores valid picture
* Returns \c true if Picture stores valid picture
*/
bool isValid() const;
@@ -136,7 +135,7 @@ namespace TagLib
/*!
* Returns the image data as a ByteVector.
*
* \note ByteVector has a data() method that returns a const char * which
* \note ByteVector has a data() method that returns a <tt>const char *</tt> which
* should make it easy to export this data to external programs.
*
* \see setPicture()

View File

@@ -38,7 +38,7 @@ namespace TagLib {
public:
/*!
* Audio codec types can be used in ASF file.
* Audio codec types which can be used in ASF files.
*/
enum Codec
{

View File

@@ -313,8 +313,7 @@ PropertyMap ASF::Tag::properties() const
}
for(const auto &[k, attributes] : std::as_const(d->attributeListMap)) {
const String key = translateKey(k);
if(!key.isEmpty()) {
if(const String key = translateKey(k); !key.isEmpty()) {
for(const auto &attr : attributes) {
if(key == "TRACKNUMBER") {
if(attr.type() == ASF::Attribute::DWordType)
@@ -411,8 +410,7 @@ StringList ASF::Tag::complexPropertyKeys() const
List<VariantMap> ASF::Tag::complexProperties(const String &key) const
{
List<VariantMap> props;
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
const AttributeList pictures = d->attributeListMap.value("WM/Picture");
for(const Attribute &attr : pictures) {
ASF::Picture picture = attr.toPicture();
@@ -430,8 +428,7 @@ List<VariantMap> ASF::Tag::complexProperties(const String &key) const
bool ASF::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
{
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
removeItem("WM/Picture");
for(const auto &property : value) {

View File

@@ -39,6 +39,8 @@ namespace TagLib {
using AttributeList = List<Attribute>;
using AttributeListMap = Map<String, AttributeList>;
//! An implementation of ASF (WMA) tags
class TAGLIB_EXPORT Tag : public TagLib::Tag {
friend class File;
@@ -64,7 +66,7 @@ namespace TagLib {
/*!
* Returns the album name; if no album name is present in the tag
* String::null will be returned.
* an empty string will be returned.
*/
String album() const override;
@@ -74,7 +76,7 @@ namespace TagLib {
String comment() const override;
/*!
* Returns the genre name; if no genre is present in the tag String::null
* Returns the genre name; if no genre is present in the tag an empty string
* will be returned.
*/
String genre() const override;
@@ -85,8 +87,8 @@ namespace TagLib {
virtual String rating() const;
/*!
* Returns the genre name; if no genre is present in the tag String::null
* will be returned.
* Returns the copyright information; if no copyright information is
* present in the tag an empty string will be returned.
*/
virtual String copyright() const;
@@ -112,7 +114,7 @@ namespace TagLib {
void setArtist(const String &value) override;
/*!
* Sets the album to \a value. If \a value is String::null then this value will be
* Sets the album to \a value. If \a value is an empty string then this value will be
* cleared.
*/
void setAlbum(const String &value) override;
@@ -148,7 +150,7 @@ namespace TagLib {
void setTrack(unsigned int value) override;
/*!
* Returns true if the tag does not contain any data. This should be
* Returns \c 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.
*/
@@ -168,7 +170,7 @@ namespace TagLib {
const AttributeListMap &attributeListMap() const;
/*!
* \return True if a value for \a key is currently set.
* \return \c true if a value for \a key is currently set.
*/
bool contains(const String &key) const;

View File

@@ -37,7 +37,7 @@ namespace TagLib {
/*!
* 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
* dependent values, please 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.
*/

View File

@@ -48,7 +48,7 @@ namespace
char padding;
};
typedef std::vector<Chunk64> ChunkList;
using ChunkList = std::vector<Chunk64>;
int chunkIndex(const ChunkList &chunks, const ByteVector &id)
{
@@ -86,7 +86,7 @@ namespace
class DSDIFF::File::FilePrivate
{
public:
FilePrivate(ID3v2::FrameFactory *frameFactory)
FilePrivate(const ID3v2::FrameFactory *frameFactory)
: ID3v2FrameFactory(frameFactory ? frameFactory
: ID3v2::FrameFactory::instance())
{
@@ -130,7 +130,7 @@ bool DSDIFF::File::isSupported(IOStream *stream)
{
// A DSDIFF file has to start with "FRM8????????DSD ".
const ByteVector id = Utils::readHeader(stream, 16, false);
return (id.startsWith("FRM8") && id.containsAt("DSD ", 12));
return id.startsWith("FRM8") && id.containsAt("DSD ", 12);
}
////////////////////////////////////////////////////////////////////////////////
@@ -189,9 +189,9 @@ PropertyMap DSDIFF::File::properties() const
return d->tag.properties();
}
void DSDIFF::File::removeUnsupportedProperties(const StringList &unsupported)
void DSDIFF::File::removeUnsupportedProperties(const StringList &properties)
{
d->tag.removeUnsupportedProperties(unsupported);
d->tag.removeUnsupportedProperties(properties);
}
PropertyMap DSDIFF::File::setProperties(const PropertyMap &properties)
@@ -226,9 +226,7 @@ bool DSDIFF::File::save(int tags, StripTags strip, ID3v2::Version version)
// First: save ID3V2 chunk
ID3v2::Tag *id3v2Tag = ID3v2Tag();
if((tags & ID3v2) && id3v2Tag) {
if(const ID3v2::Tag *id3v2Tag = ID3v2Tag(); (tags & ID3v2) && id3v2Tag) {
if(d->isID3InPropChunk) {
if(!id3v2Tag->isEmpty()) {
setChildChunkData(d->id3v2TagChunkID, id3v2Tag->render(version), PROPChunk);
@@ -255,9 +253,7 @@ bool DSDIFF::File::save(int tags, StripTags strip, ID3v2::Version version)
// Second: save the DIIN chunk
DSDIFF::DIIN::Tag *diinTag = DIINTag();
if((tags & DIIN) && diinTag) {
if(const DSDIFF::DIIN::Tag *diinTag = DIINTag(); (tags & DIIN) && diinTag) {
if(!diinTag->title().isEmpty()) {
ByteVector diinTitle;
diinTitle.append(ByteVector::fromUInt(diinTag->title().size(), d->endianness == BigEndian));
@@ -433,7 +429,7 @@ void DSDIFF::File::removeChildChunk(unsigned int i, unsigned int childChunkNum)
// Update the internal offsets
// For child chunks
if((i + 1) < childChunks.size()) {
if(i + 1 < childChunks.size()) {
childChunks[i + 1].offset = childChunks[i].offset;
for(unsigned int c = i + 2; c < childChunks.size(); ++c)
childChunks[c].offset = childChunks[c - 1].offset + 12
@@ -527,8 +523,8 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name,
int i = d->childChunkIndex[DIINChunk];
if(i < 0) {
setRootChunkData("DIIN", ByteVector());
const int lastChunkIndex = static_cast<int>(d->chunks.size()) - 1;
if(lastChunkIndex >= 0 && d->chunks[lastChunkIndex].name == "DIIN") {
if(const int lastChunkIndex = static_cast<int>(d->chunks.size()) - 1;
lastChunkIndex >= 0 && d->chunks[lastChunkIndex].name == "DIIN") {
i = lastChunkIndex;
d->childChunkIndex[DIINChunk] = lastChunkIndex;
d->hasDiin = true;
@@ -559,13 +555,13 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name,
// Now add the chunk to the file
unsigned long long nextRootChunkIdx = length();
if((d->childChunkIndex[childChunkNum] + 1) < static_cast<int>(d->chunks.size()))
if(d->childChunkIndex[childChunkNum] + 1 < static_cast<int>(d->chunks.size()))
nextRootChunkIdx = d->chunks[d->childChunkIndex[childChunkNum] + 1].offset - 12;
writeChunk(name, data, offset,
static_cast<unsigned long>(
nextRootChunkIdx > offset ? nextRootChunkIdx - offset : 0),
(offset & 1) ? 1 : 0);
offset & 1 ? 1 : 0);
// For root chunks
@@ -575,7 +571,7 @@ void DSDIFF::File::setChildChunkData(const ByteVector &name,
chunk.name = name;
chunk.size = data.size();
chunk.offset = offset + 12;
chunk.padding = (data.size() & 0x01) ? 1 : 0;
chunk.padding = data.size() & 0x01 ? 1 : 0;
childChunks.push_back(chunk);
}
@@ -589,8 +585,8 @@ void DSDIFF::File::updateRootChunksStructure(unsigned int startingChunk)
// Update child chunks structure as well
if(d->childChunkIndex[PROPChunk] >= static_cast<int>(startingChunk)) {
ChunkList &childChunksToUpdate = d->childChunks[PROPChunk];
if(!childChunksToUpdate.empty()) {
if(ChunkList &childChunksToUpdate = d->childChunks[PROPChunk];
!childChunksToUpdate.empty()) {
childChunksToUpdate[0].offset = d->chunks[d->childChunkIndex[PROPChunk]].offset + 12;
for(unsigned int i = 1; i < childChunksToUpdate.size(); i++)
childChunksToUpdate[i].offset = childChunksToUpdate[i - 1].offset + 12
@@ -599,8 +595,8 @@ void DSDIFF::File::updateRootChunksStructure(unsigned int startingChunk)
}
if(d->childChunkIndex[DIINChunk] >= static_cast<int>(startingChunk)) {
ChunkList &childChunksToUpdate = d->childChunks[DIINChunk];
if(!childChunksToUpdate.empty()) {
if(ChunkList &childChunksToUpdate = d->childChunks[DIINChunk];
!childChunksToUpdate.empty()) {
childChunksToUpdate[0].offset = d->chunks[d->childChunkIndex[DIINChunk]].offset + 12;
for(unsigned int i = 1; i < childChunksToUpdate.size(); i++)
childChunksToUpdate[i].offset = childChunksToUpdate[i - 1].offset + 12
@@ -647,10 +643,9 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty
// Check padding
chunk.padding = 0;
offset_t uPosNotPadded = tell();
if((uPosNotPadded & 0x01) != 0) {
ByteVector iByte = readBlock(1);
if((iByte.size() != 1) || (iByte[0] != 0))
if(offset_t uPosNotPadded = tell(); (uPosNotPadded & 0x01) != 0) {
if(ByteVector iByte = readBlock(1);
iByte.size() != 1 || iByte[0] != 0)
// Not well formed, re-seek
seek(uPosNotPadded, Beginning);
else
@@ -708,10 +703,9 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty
seek(dstChunkSize, Current);
// Check padding
offset_t uPosNotPadded = tell();
if((uPosNotPadded & 0x01) != 0) {
ByteVector iByte = readBlock(1);
if((iByte.size() != 1) || (iByte[0] != 0))
if(offset_t uPosNotPadded = tell(); (uPosNotPadded & 0x01) != 0) {
if(ByteVector iByte = readBlock(1);
iByte.size() != 1 || iByte[0] != 0)
// Not well formed, re-seek
seek(uPosNotPadded, Beginning);
}
@@ -749,10 +743,9 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty
// Check padding
chunk.padding = 0;
offset_t uPosNotPadded = tell();
if((uPosNotPadded & 0x01) != 0) {
ByteVector iByte = readBlock(1);
if((iByte.size() != 1) || (iByte[0] != 0))
if(offset_t uPosNotPadded = tell(); (uPosNotPadded & 0x01) != 0) {
if(ByteVector iByte = readBlock(1);
iByte.size() != 1 || iByte[0] != 0)
// Not well formed, re-seek
seek(uPosNotPadded, Beginning);
else
@@ -797,11 +790,10 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty
// Check padding
chunk.padding = 0;
offset_t uPosNotPadded = tell();
if((uPosNotPadded & 0x01) != 0) {
ByteVector iByte = readBlock(1);
if((iByte.size() != 1) || (iByte[0] != 0))
if(offset_t uPosNotPadded = tell(); (uPosNotPadded & 0x01) != 0) {
if(ByteVector iByte = readBlock(1);
iByte.size() != 1 || iByte[0] != 0)
// Not well formed, re-seek
seek(uPosNotPadded, Beginning);
else
@@ -867,16 +859,16 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty
for(unsigned int i = 0; i < d->childChunks[DIINChunk].size(); i++) {
if(d->childChunks[DIINChunk][i].name == "DITI") {
seek(d->childChunks[DIINChunk][i].offset);
unsigned int titleStrLength = readBlock(4).toUInt(0, 4, bigEndian);
if(titleStrLength <= d->childChunks[DIINChunk][i].size) {
if(unsigned int titleStrLength = readBlock(4).toUInt(0, 4, bigEndian);
titleStrLength <= d->childChunks[DIINChunk][i].size) {
ByteVector titleStr = readBlock(titleStrLength);
d->tag.access<DSDIFF::DIIN::Tag>(DIINIndex, false)->setTitle(titleStr);
}
}
else if(d->childChunks[DIINChunk][i].name == "DIAR") {
seek(d->childChunks[DIINChunk][i].offset);
unsigned int artistStrLength = readBlock(4).toUInt(0, 4, bigEndian);
if(artistStrLength <= d->childChunks[DIINChunk][i].size) {
if(unsigned int artistStrLength = readBlock(4).toUInt(0, 4, bigEndian);
artistStrLength <= d->childChunks[DIINChunk][i].size) {
ByteVector artistStr = readBlock(artistStrLength);
d->tag.access<DSDIFF::DIIN::Tag>(DIINIndex, false)->setArtist(artistStr);
}
@@ -902,7 +894,7 @@ void DSDIFF::File::read(bool readProperties, Properties::ReadStyle propertiesSty
int bitrate = 0;
if(lengthDSDSamplesTimeChannels > 0)
bitrate = static_cast<int>(
(audioDataSizeinBytes * 8 * sampleRate) / lengthDSDSamplesTimeChannels / 1000);
audioDataSizeinBytes * 8 * sampleRate / lengthDSDSamplesTimeChannels / 1000);
d->properties = std::make_unique<Properties>(sampleRate, channels,
lengthDSDSamplesTimeChannels, bitrate, propertiesStyle);

View File

@@ -36,20 +36,21 @@ namespace TagLib {
//! An implementation of DSDIFF metadata
/*!
* This is implementation of DSDIFF metadata.
* This is an implementation of DSDIFF metadata.
*
* This supports an ID3v2 tag as well as reading stream from the ID3 RIFF
* chunk as well as properties from the file.
* Description of the DSDIFF format is available
* at http://dsd-guide.com/sites/default/files/white-papers/DSDIFF_1.5_Spec.pdf
* DSDIFF standard does not explicitly specify the ID3V2 chunk
* It can be found at the root level, but also sometimes inside the PROP chunk
* In addition, title and artist info are stored as part of the standard
* Description of the DSDIFF format is available at
* <a href="https://dsd-guide.com/sites/default/files/white-papers/DSDIFF_1.5_Spec.pdf">
* DSDIFF_1.5_Spec.pdf</a>.
* The DSDIFF standard does not explicitly specify the ID3 chunk.
* It can be found at the root level, but also sometimes inside the PROP chunk.
* In addition, title and artist info are stored as part of the standard.
*/
namespace DSDIFF {
//! An implementation of TagLib::File with DSDIFF specific methods
//! An implementation of TagLib::File with DSDIFF specific methods.
/*!
* This implements and provides an interface for DSDIFF files to the
@@ -78,7 +79,7 @@ namespace TagLib {
};
/*!
* Constructs a DSDIFF file from \a file. If \a readProperties is true
* Constructs a DSDIFF file from \a file. If \a readProperties is \c true
* the file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
@@ -91,7 +92,7 @@ namespace TagLib {
ID3v2::FrameFactory *frameFactory = nullptr);
/*!
* Constructs an DSDIFF file from \a stream. If \a readProperties is true
* Constructs a DSDIFF file from \a stream. If \a readProperties is \c true
* the file's audio properties will also be read.
*
* If this file contains an ID3v2 tag, the frames will be created using
@@ -168,7 +169,7 @@ namespace TagLib {
/*!
* Save the file. If at least one tag -- ID3v1 or DIIN -- exists this
* will duplicate its content into the other tag. This returns true
* will duplicate its content into the other tag. This returns \c true
* if saving was successful.
*
* If neither exists or if both tags are empty, this will strip the tags
@@ -177,7 +178,7 @@ namespace TagLib {
* 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 paramaterized save call below.
* with the concession of generality, use parameterized save call below.
*
* \see save(int tags)
*/
@@ -193,7 +194,7 @@ namespace TagLib {
/*!
* 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
* file. By default it strips all tags. It returns \c true if the tags are
* successfully stripped.
*
* \note This will update the file immediately.
@@ -227,9 +228,6 @@ namespace TagLib {
protected:
enum Endianness { BigEndian, LittleEndian };
File(FileName file, Endianness endianness);
File(IOStream *stream, Endianness endianness);
private:
void removeRootChunk(const ByteVector &id);
void removeRootChunk(unsigned int i);
@@ -237,7 +235,7 @@ namespace TagLib {
void removeChildChunk(unsigned int i, unsigned int childChunkNum);
/*!
* Sets the data for the the specified chunk at root level to \a data.
* Sets the data for the specified chunk at root level to \a data.
*
* \warning This will update the file immediately.
*/
@@ -254,7 +252,7 @@ namespace TagLib {
void setRootChunkData(const ByteVector &name, const ByteVector &data);
/*!
* Sets the data for the the specified child chunk to \a data.
* Sets the data for the specified child chunk to \a data.
*
* If data is null, then remove the chunk
*
@@ -266,7 +264,7 @@ namespace TagLib {
/*!
* Sets the data for the child 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 inside child chunk.
* be created after the existing chunks inside the child chunk.
*
* If data is null, then remove the chunks with \a name name
*

View File

@@ -26,7 +26,6 @@
#include "dsdiffproperties.h"
#include "tstring.h"
#include "tdebug.h"
using namespace TagLib;
@@ -45,10 +44,10 @@ public:
// public members
////////////////////////////////////////////////////////////////////////////////
DSDIFF::Properties::Properties(const unsigned int sampleRate,
const unsigned short channels,
const unsigned long long samplesCount,
const int bitrate,
DSDIFF::Properties::Properties(unsigned int sampleRate,
unsigned short channels,
unsigned long long samplesCount,
int bitrate,
ReadStyle style) :
AudioProperties(style),
d(std::make_unique<PropertiesPrivate>())
@@ -59,7 +58,7 @@ DSDIFF::Properties::Properties(const unsigned int sampleRate,
d->sampleRate = sampleRate;
d->bitrate = bitrate;
d->length = d->sampleRate > 0
? static_cast<int>((d->sampleCount * 1000.0) / d->sampleRate + 0.5)
? static_cast<int>(d->sampleCount * 1000.0 / d->sampleRate + 0.5)
: 0;
}

View File

@@ -37,7 +37,7 @@ namespace TagLib {
//! An implementation of audio property reading for DSDIFF
/*!
* This reads the data from an DSDIFF stream found in the AudioProperties
* This reads the data from a DSDIFF stream found in the AudioProperties
* API.
*/
@@ -48,8 +48,8 @@ namespace TagLib {
* Create an instance of DSDIFF::Properties with the data read from the
* ByteVector \a data.
*/
Properties(const unsigned int sampleRate, const unsigned short channels,
const unsigned long long samplesCount, const int bitrate,
Properties(unsigned int sampleRate, unsigned short channels,
unsigned long long samplesCount, int bitrate,
ReadStyle style);
/*!

View File

@@ -31,12 +31,10 @@
using namespace TagLib;
// The DSF specification is located at http://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
class DSF::File::FilePrivate
{
public:
FilePrivate(ID3v2::FrameFactory *frameFactory)
FilePrivate(const ID3v2::FrameFactory *frameFactory)
: ID3v2FrameFactory(frameFactory ? frameFactory
: ID3v2::FrameFactory::instance())
{

View File

@@ -36,7 +36,27 @@
#include "id3v2tag.h"
namespace TagLib {
//! An implementation of DSF metadata
/*!
* This is an implementation of DSF metadata using an ID3v2 tag inside the
* metadata chunk.
* The DSF specification is located at
* http://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
*/
namespace DSF {
//! An implementation of TagLib::File with DSF specific methods
/*!
* This implements and provides an interface for DSF 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 DSF files.
*/
class TAGLIB_EXPORT File : public TagLib::File {
public:
/*!
@@ -103,7 +123,7 @@ namespace TagLib {
/*!
* Save the file.
*
* This returns true if the save was successful.
* This returns \c true if the save was successful.
*/
bool save() override;

View File

@@ -127,7 +127,7 @@ void DSF::Properties::read(const ByteVector &data)
d->blockSizePerChannel = data.toUInt(32U,false);
d->bitrate = static_cast<unsigned int>(
(d->samplingFrequency * d->bitsPerSample * d->channelNum) / 1000.0 + 0.5);
d->samplingFrequency * d->bitsPerSample * d->channelNum / 1000.0 + 0.5);
d->length = d->samplingFrequency > 0
? static_cast<unsigned int>(d->sampleCount * 1000.0 / d->samplingFrequency + 0.5)
: 0;

View File

@@ -34,6 +34,7 @@
namespace TagLib {
namespace DSF {
//! An implementation of audio properties for DSF
class TAGLIB_EXPORT Properties : public AudioProperties {
public:
Properties(const ByteVector &data, ReadStyle style);

View File

@@ -119,8 +119,7 @@ namespace
#endif
String ext;
const int pos = s.rfind(".");
if(pos != -1)
if(const int pos = s.rfind("."); pos != -1)
ext = s.substr(pos + 1).upper();
// If this list is updated, the method defaultFileExtensions() should also be
@@ -457,12 +456,12 @@ void FileRef::swap(FileRef &ref) noexcept
bool FileRef::operator==(const FileRef &ref) const
{
return (ref.d->file == d->file);
return ref.d->file == d->file;
}
bool FileRef::operator!=(const FileRef &ref) const
{
return (ref.d->file != d->file);
return ref.d->file != d->file;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -60,34 +60,12 @@ namespace TagLib {
{
public:
//! A class for pluggable file type resolution.
//! A class for pluggable file type resolution.
/*!
* This class is used to 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.
*/
/*!
* %File type resolver, better implement StreamTypeResolver in order to
* support both file and stream resolution.
*/
class TAGLIB_EXPORT FileTypeResolver
{
@@ -120,6 +98,44 @@ namespace TagLib {
std::unique_ptr<FileTypeResolverPrivate> d;
};
//! A class for pluggable stream type resolution.
/*!
* This class is used to extend TagLib's very basic file name based file
* type resolution.
*
* This can be accomplished with:
*
* \code
*
* class MyStreamTypeResolver : StreamTypeResolver
* {
* TagLib::File *createFile(TagLib::FileName *fileName, bool readProps,
* AudioProperties::ReadStyle readStyle) const override
* {
* if(someCheckForAnMP3File(fileName))
* return new TagLib::MPEG::File(fileName, readProps, readStyle);
* return nullptr;
* }
*
* TagLib::File *createFileFromStream(TagLib::IOStream *s, bool readProps,
* AudioProperties::ReadStyle readStyle) const override
* {
* if(someCheckForAnMP3Stream(s))
* return new TagLib::MPEG::File(s, readProps, readStyle);
* return nullptr;
* }
* }
*
* FileRef::addFileTypeResolver(new MyStreamTypeResolver);
*
* \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 StreamTypeResolver : public FileTypeResolver
{
public:
@@ -132,6 +148,17 @@ namespace TagLib {
StreamTypeResolver(const StreamTypeResolver &) = delete;
StreamTypeResolver &operator=(const StreamTypeResolver &) = delete;
/*!
* This method must be overridden to provide an additional stream type
* resolver. If the resolver is able to determine the file type it should
* return a valid File object; if not it should return nullptr.
*
* \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.
*
* \see createFile()
*/
virtual File *createFileFromStream(IOStream *stream,
bool readAudioProperties = true,
AudioProperties::ReadStyle
@@ -148,9 +175,9 @@ namespace TagLib {
FileRef();
/*!
* Create a FileRef from \a fileName. If \a readAudioProperties is true then
* Create a FileRef from \a fileName. If \a readAudioProperties is \c true then
* the audio properties will be read using \a audioPropertiesStyle. If
* \a readAudioProperties is false then \a audioPropertiesStyle will be
* \a readAudioProperties is \c false then \a audioPropertiesStyle will be
* ignored.
*
* Also see the note in the class documentation about why you may not want to
@@ -163,8 +190,8 @@ namespace TagLib {
/*!
* 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
* is \c true then the audio properties will be read using \a audioPropertiesStyle.
* If \a readAudioProperties is \c false then \a audioPropertiesStyle will be
* ignored.
*
* Also see the note in the class documentation about why you may not want to
@@ -195,7 +222,7 @@ namespace TagLib {
~FileRef();
/*!
* Returns a pointer to represented file's tag.
* Returns a pointer to the represented file's tag.
*
* \warning This pointer will become invalid when this FileRef and all
* copies pass out of scope.
@@ -287,7 +314,7 @@ namespace TagLib {
/*!
* Returns the audio properties for this FileRef. If no audio properties
* were read then this will returns a null pointer.
* were read then this will return a null pointer.
*/
AudioProperties *audioProperties() const;
@@ -309,7 +336,7 @@ namespace TagLib {
File *file() const;
/*!
* Saves the file. Returns true on success.
* Saves the file. Returns \c true on success.
*/
bool save();
@@ -351,7 +378,7 @@ namespace TagLib {
static StringList defaultFileExtensions();
/*!
* Returns true if the file (and as such other pointers) are null.
* Returns \c true if the file (and as such other pointers) are null.
*/
bool isNull() const;
@@ -361,17 +388,17 @@ namespace TagLib {
FileRef &operator=(const FileRef &ref);
/*!
* Exchanges the content of the FileRef by the content of \a ref.
* Exchanges the content of the FileRef with the content of \a ref.
*/
void swap(FileRef &ref) noexcept;
/*!
* Returns true if this FileRef and \a ref point to the same File object.
* Returns \c 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
* Returns \c true if this FileRef and \a ref do not point to the same File
* object.
*/
bool operator!=(const FileRef &ref) const;

View File

@@ -45,10 +45,10 @@ namespace
{
enum { FlacXiphIndex = 0, FlacID3v2Index = 1, FlacID3v1Index = 2 };
const long MinPaddingLength = 4096;
const long MaxPaddingLegnth = 1024 * 1024;
constexpr long MinPaddingLength = 4096;
constexpr long MaxPaddingLegnth = 1024 * 1024;
const char LastBlockFlag = '\x80';
constexpr char LastBlockFlag = '\x80';
} // namespace
class FLAC::File::FilePrivate
@@ -86,7 +86,7 @@ bool FLAC::File::isSupported(IOStream *stream)
// A FLAC file has an ID "fLaC" somewhere. An ID3v2 tag may precede.
const ByteVector buffer = Utils::readHeader(stream, bufferSize(), true);
return (buffer.find("fLaC") >= 0);
return buffer.find("fLaC") >= 0;
}
////////////////////////////////////////////////////////////////////////////////
@@ -171,8 +171,7 @@ StringList FLAC::File::complexPropertyKeys() const
List<VariantMap> FLAC::File::complexProperties(const String &key) const
{
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
List<VariantMap> props;
for(const auto &block : std::as_const(d->blocks)) {
if(auto picture = dynamic_cast<Picture *>(block)) {
@@ -196,8 +195,7 @@ List<VariantMap> FLAC::File::complexProperties(const String &key) const
bool FLAC::File::setComplexProperties(const String &key, const List<VariantMap> &value)
{
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
removePictures();
for(const auto &property : value) {
@@ -303,10 +301,10 @@ bool FLAC::File::save()
insert(data, d->flacStart, originalLength);
d->streamStart += (static_cast<long>(data.size()) - originalLength);
d->streamStart += static_cast<long>(data.size()) - originalLength;
if(d->ID3v1Location >= 0)
d->ID3v1Location += (static_cast<long>(data.size()) - originalLength);
d->ID3v1Location += static_cast<long>(data.size()) - originalLength;
// Update ID3 tags
@@ -320,11 +318,11 @@ bool FLAC::File::save()
data = ID3v2Tag()->render();
insert(data, d->ID3v2Location, d->ID3v2OriginalSize);
d->flacStart += (static_cast<long>(data.size()) - d->ID3v2OriginalSize);
d->streamStart += (static_cast<long>(data.size()) - d->ID3v2OriginalSize);
d->flacStart += static_cast<long>(data.size()) - d->ID3v2OriginalSize;
d->streamStart += static_cast<long>(data.size()) - d->ID3v2OriginalSize;
if(d->ID3v1Location >= 0)
d->ID3v1Location += (static_cast<long>(data.size()) - d->ID3v2OriginalSize);
d->ID3v1Location += static_cast<long>(data.size()) - d->ID3v2OriginalSize;
d->ID3v2OriginalSize = data.size();
}
@@ -449,12 +447,12 @@ bool FLAC::File::hasXiphComment() const
bool FLAC::File::hasID3v1Tag() const
{
return (d->ID3v1Location >= 0);
return d->ID3v1Location >= 0;
}
bool FLAC::File::hasID3v2Tag() const
{
return (d->ID3v2Location >= 0);
return d->ID3v2Location >= 0;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -43,7 +43,7 @@ namespace TagLib {
//! An implementation of FLAC metadata
/*!
* This is implementation of FLAC metadata for non-Ogg FLAC files. At some
* This is an 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.
*
@@ -83,7 +83,7 @@ namespace TagLib {
};
/*!
* Constructs a FLAC file from \a file. If \a readProperties is true the
* Constructs a FLAC file from \a file. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
@@ -96,13 +96,15 @@ namespace TagLib {
ID3v2::FrameFactory *frameFactory = nullptr);
/*!
* Constructs an FLAC file from \a file. If \a readProperties is true the
* Constructs a FLAC file from \a file. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* If this file contains an ID3v2 tag, the frames will be created using
* \a frameFactory.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*
* \deprecated Use the constructor above.
*/
TAGLIB_DEPRECATED
File(FileName file, ID3v2::FrameFactory *frameFactory,
@@ -110,7 +112,7 @@ namespace TagLib {
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Constructs a FLAC file from \a stream. If \a readProperties is true the
* Constructs a FLAC file from \a stream. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
@@ -126,7 +128,7 @@ namespace TagLib {
ID3v2::FrameFactory *frameFactory = nullptr);
/*!
* Constructs a FLAC file from \a stream. If \a readProperties is true the
* Constructs a FLAC file from \a stream. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
@@ -136,6 +138,8 @@ namespace TagLib {
* \a frameFactory.
*
* \note In the current implementation, \a propertiesStyle is ignored.
*
* \deprecated Use the constructor above.
*/
TAGLIB_DEPRECATED
File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
@@ -207,22 +211,22 @@ namespace TagLib {
* 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.
* This returns \c true if the save was successful.
*/
bool save() override;
/*!
* 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
* If \a create is \c false (the default) this returns a null pointer
* if there is no valid ID3v2 tag. If \a create is \c 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 <b>is still</b> owned by the MPEG::File and should not be
* \note The Tag <b>is still</b> owned by the FLAC::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*
@@ -233,15 +237,15 @@ namespace TagLib {
/*!
* 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
* If \a create is \c false (the default) this returns a null pointer
* if there is no valid APE tag. If \a create is \c 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 <b>is still</b> owned by the MPEG::File and should not be
* \note The Tag <b>is still</b> owned by the FLAC::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*
@@ -252,8 +256,8 @@ namespace TagLib {
/*!
* 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
* If \a create is \c false (the default) this returns a null pointer
* if there is no valid XiphComment. If \a create is \c 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
@@ -274,8 +278,8 @@ namespace TagLib {
List<Picture *> 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.
* Removes an attached picture. If \a del is \c true the picture's memory
* will be freed; if it is \c false, it must be deleted by the user.
*/
void removePicture(Picture *picture, bool del = true);

View File

@@ -26,12 +26,12 @@
#ifndef TAGLIB_FLACMETADATABLOCK_H
#define TAGLIB_FLACMETADATABLOCK_H
#include "tlist.h"
#include "tbytevector.h"
#include "taglib_export.h"
namespace TagLib {
namespace FLAC {
//! FLAC metadata block
class TAGLIB_EXPORT MetadataBlock
{
public:

View File

@@ -35,11 +35,12 @@
namespace TagLib {
namespace FLAC {
//! FLAC picture
class TAGLIB_EXPORT Picture : public MetadataBlock
{
public:
/*!
/*
* This describes the function or content of the picture.
*/
DECLARE_PICTURE_TYPE_ENUM(Type)
@@ -71,7 +72,7 @@ namespace TagLib {
* Sets the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
*/
void setMimeType(const String &m);
void setMimeType(const String &mimeType);
/*!
* Returns a text description of the image.
@@ -80,10 +81,10 @@ namespace TagLib {
String description() const;
/*!
* Sets a textual description of the image to \a desc.
* Sets a textual description of the image to \a description.
*/
void setDescription(const String &desc);
void setDescription(const String &description);
/*!
* Returns the width of the image.
@@ -93,7 +94,7 @@ namespace TagLib {
/*!
* Sets the width of the image.
*/
void setWidth(int w);
void setWidth(int width);
/*!
* Returns the height of the image.
@@ -103,7 +104,7 @@ namespace TagLib {
/*!
* Sets the height of the image.
*/
void setHeight(int h);
void setHeight(int height);
/*!
* Returns the color depth (in bits-per-pixel) of the image.
@@ -113,7 +114,7 @@ namespace TagLib {
/*!
* Sets the color depth (in bits-per-pixel) of the image.
*/
void setColorDepth(int depth);
void setColorDepth(int colorDepth);
/*!
* Returns the number of colors used on the image..
@@ -148,7 +149,7 @@ namespace TagLib {
/*!
* Parse the picture data in the FLAC picture block format.
*/
bool parse(const ByteVector &rawData);
bool parse(const ByteVector &data);
private:
class PicturePrivate;

View File

@@ -28,8 +28,6 @@
#include "tstring.h"
#include "tdebug.h"
#include "flacfile.h"
using namespace TagLib;
class FLAC::Properties::PropertiesPrivate
@@ -134,7 +132,7 @@ void FLAC::Properties::read(const ByteVector &data, offset_t streamLength)
d->sampleFrames = (hi << 32) | lo;
if(d->sampleFrames > 0 && d->sampleRate > 0) {
const double length = d->sampleFrames * 1000.0 / d->sampleRate;
const auto length = static_cast<double>(d->sampleFrames) * 1000.0 / d->sampleRate;
d->length = static_cast<int>(length + 0.5);
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
}

View File

@@ -37,7 +37,7 @@ namespace TagLib {
//! An implementation of audio property reading for FLAC
/*!
* This reads the data from an FLAC stream found in the AudioProperties
* This reads the data from a FLAC stream found in the AudioProperties
* API.
*/

View File

@@ -33,6 +33,7 @@
namespace TagLib {
namespace FLAC {
//! Unknown FLAC metadata block
class TAGLIB_EXPORT UnknownMetadataBlock : public MetadataBlock
{
public:

View File

@@ -27,7 +27,6 @@
#include "tstringlist.h"
#include "tdebug.h"
#include "tpropertymap.h"
#include "modfileprivate.h"
using namespace TagLib;

View File

@@ -31,12 +31,27 @@
namespace TagLib {
//! An implementation of Impulse Tracker metadata
/*!
* This is an implementation of Impulse Tracker metadata.
*/
namespace IT {
//! An implementation of TagLib::File with IT specific methods
/*!
* This implements and provides an interface for IT 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 IT files.
*/
class TAGLIB_EXPORT File : public Mod::FileBase {
public:
/*!
* Constructs a Impulse Tracker file from \a file.
* Constructs an Impulse Tracker file from \a file.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored. The audio properties are always
@@ -47,7 +62,7 @@ namespace TagLib {
AudioProperties::Average);
/*!
* Constructs a Impulse Tracker file from \a stream.
* Constructs an Impulse Tracker file from \a stream.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored. The audio properties are always

View File

@@ -26,11 +26,11 @@
#ifndef TAGLIB_ITPROPERTIES_H
#define TAGLIB_ITPROPERTIES_H
#include "taglib.h"
#include "audioproperties.h"
namespace TagLib {
namespace IT {
//! An implementation of audio property reading for IT
class TAGLIB_EXPORT Properties : public AudioProperties {
public:
/*! Flag bits. */

View File

@@ -34,7 +34,24 @@
#include "modproperties.h"
namespace TagLib {
//! An implementation of Protracker metadata
/*!
* This is an implementation of Protracker metadata.
*/
namespace Mod {
//! An implementation of TagLib::File with Mod specific methods
/*!
* This implements and provides an interface for Mod 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 Mod files.
*/
class TAGLIB_EXPORT File : public TagLib::Mod::FileBase
{
public:

View File

@@ -28,14 +28,12 @@
#include "taglib.h"
#include "tfile.h"
#include "tstring.h"
#include "tlist.h"
#include "taglib_export.h"
#include <algorithm>
namespace TagLib {
namespace Mod {
//! Base class for module files
class TAGLIB_EXPORT FileBase : public TagLib::File
{
public:

View File

@@ -26,11 +26,11 @@
#ifndef TAGLIB_MODPROPERTIES_H
#define TAGLIB_MODPROPERTIES_H
#include "taglib.h"
#include "audioproperties.h"
namespace TagLib {
namespace Mod {
//! An implementation of audio property reading for Mod
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:

View File

@@ -128,7 +128,7 @@ PropertyMap Mod::Tag::properties() const
PropertyMap properties;
properties["TITLE"] = d->title;
properties["COMMENT"] = d->comment;
if(!(d->trackerName.isEmpty()))
if(!d->trackerName.isEmpty())
properties["TRACKERNAME"] = d->trackerName;
return properties;
}

View File

@@ -30,6 +30,9 @@
namespace TagLib {
namespace Mod {
//! A module file tag implementation
/*!
* Tags for module files (Mod, S3M, IT, XM).
*
@@ -53,29 +56,29 @@ namespace TagLib {
/*!
* Returns the track name; if no track name is present in the tag
* String::null will be returned.
* an empty string will be returned.
*/
String title() const override;
/*!
* Not supported by module files. Therefore always returns String::null.
* Not supported by module files. Therefore always returns an empty string.
*/
String artist() const override;
/*!
* Not supported by module files. Therefore always returns String::null.
* Not supported by module files. Therefore always returns an empty string.
*/
String album() const override;
/*!
* Returns the track comment derived from the instrument/sample/pattern
* names; if no comment is present in the tag String::null will be
* names; if no comment is present in the tag an empty string will be
* returned.
*/
String comment() const override;
/*!
* Not supported by module files. Therefore always returns String::null.
* Not supported by module files. Therefore always returns an empty string.
*/
String genre() const override;
@@ -94,12 +97,12 @@ namespace TagLib {
* 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.
* tracker name.
*/
String trackerName() const;
/*!
* Sets the title to \a title. If \a title is String::null then this
* Sets the title to \a title. If \a title is an empty string then this
* value will be cleared.
*
* The length limits per file type are (1 character = 1 byte):
@@ -119,7 +122,7 @@ namespace TagLib {
void setAlbum(const String &album) override;
/*!
* Sets the comment to \a comment. If \a comment is String::null then
* Sets the comment to \a comment. If \a comment is an empty string then
* this value will be cleared.
*
* Note that module file formats don't actually support a comment tag.
@@ -128,7 +131,7 @@ namespace TagLib {
* 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
* and 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):
@@ -154,7 +157,7 @@ namespace TagLib {
/*!
* Sets the tracker name to \a trackerName. If \a trackerName is
* String::null then this value will be cleared.
* an empty string 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.

View File

@@ -25,6 +25,7 @@
#include "mp4atom.h"
#include <array>
#include <climits>
#include <utility>
@@ -73,8 +74,8 @@ MP4::Atom::Atom(File *file)
}
else if(d->length == 1) {
// The atom has a 64-bit length.
const long long longLength = file->readBlock(8).toLongLong();
if(longLength <= LONG_MAX) {
if(const long long longLength = file->readBlock(8).toLongLong();
longLength <= LONG_MAX) {
// The actual length fits in long. That's always the case if long is 64-bit.
d->length = static_cast<long>(longLength);
}
@@ -95,8 +96,7 @@ MP4::Atom::Atom(File *file)
d->name = header.mid(4, 4);
for(int i = 0; i < 4; ++i) {
const char ch = d->name.at(i);
if((ch < ' ' || ch > '~') && ch != '\251') {
if(const char ch = d->name.at(i); (ch < ' ' || ch > '~') && ch != '\251') {
debug("MP4: Invalid atom type");
d->length = 0;
file->seek(0, File::End);
@@ -143,12 +143,12 @@ MP4::Atom::find(const char *name1, const char *name2, const char *name3, const c
return this;
}
auto it = std::find_if(d->children.cbegin(), d->children.cend(),
[&name1](Atom *child) { return child->d->name == name1; });
[&name1](const Atom *child) { return child->d->name == name1; });
return it != d->children.cend() ? (*it)->find(name2, name3, name4) : nullptr;
}
MP4::AtomList
MP4::Atom::findall(const char *name, bool recursive)
MP4::Atom::findall(const char *name, bool recursive) const
{
MP4::AtomList result;
for(const auto &child : std::as_const(d->children)) {
@@ -170,7 +170,7 @@ MP4::Atom::path(MP4::AtomList &path, const char *name1, const char *name2, const
return true;
}
auto it = std::find_if(d->children.cbegin(), d->children.cend(),
[&name1](Atom *child) { return child->d->name == name1; });
[&name1](const Atom *child) { return child->d->name == name1; });
return it != d->children.cend() ? (*it)->path(path, name2, name3) : false;
}
@@ -240,19 +240,19 @@ MP4::Atoms::Atoms(File *file) :
MP4::Atoms::~Atoms() = default;
MP4::Atom *
MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4)
MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4) const
{
auto it = std::find_if(d->atoms.cbegin(), d->atoms.cend(),
[&name1](Atom *atom) { return atom->name() == name1; });
[&name1](const Atom *atom) { return atom->name() == name1; });
return it != d->atoms.cend() ? (*it)->find(name2, name3, name4) : nullptr;
}
MP4::AtomList
MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4)
MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4) const
{
MP4::AtomList path;
auto it = std::find_if(d->atoms.cbegin(), d->atoms.cend(),
[&name1](Atom *atom) { return atom->name() == name1; });
[&name1](const Atom *atom) { return atom->name() == name1; });
if(it != d->atoms.cend()) {
if(!(*it)->path(path, name2, name3, name4)) {
path.clear();
@@ -271,28 +271,25 @@ namespace
}
} // namespace
bool MP4::Atoms::checkRootLevelAtoms()
{
bool MP4::Atoms::checkRootLevelAtoms() {
bool moovValid = false;
for(auto it = d->atoms.begin(); it != d->atoms.end(); ++it) {
bool invalid = (*it)->length() == 0 || !checkValid((*it)->children());
if(!moovValid && !invalid && (*it)->name() == "moov") {
bool invalid = (*it)->length() == 0 || !checkValid((*it)->children());
if(!moovValid && !invalid && (*it)->name() == "moov") {
moovValid = true;
}
if(invalid) {
if(!moovValid || (*it)->name() == "moof")
return false;
// Only the root level atoms "moov" and (if present) "moof" are
// modified. If they are valid, ignore following invalid root level
// atoms as trailing garbage.
while(it != d->atoms.end()) {
delete *it;
it = d->atoms.erase(it);
}
if(invalid) {
if(moovValid && (*it)->name() != "moof") {
// Only the root level atoms "moov" and (if present) "moof" are
// modified. If they are valid, ignore following invalid root level
// atoms as trailing garbage.
while(it != d->atoms.end()) {
delete *it;
it = d->atoms.erase(it);
}
return true;
}
else {
return false;
}
return true;
}
}

View File

@@ -28,17 +28,11 @@
#ifndef TAGLIB_MP4ATOM_H
#define TAGLIB_MP4ATOM_H
#include <array>
#include "tfile.h"
#include "tlist.h"
#ifndef DO_NOT_DOCUMENT
namespace TagLib {
namespace MP4 {
class Atom;
using AtomList = TagLib::List<Atom *>;
enum AtomDataType {
TypeImplicit = 0, // for use with tags for which no type needs to be indicated because only one type is allowed
@@ -64,6 +58,7 @@ namespace TagLib {
TypeUndefined = 255 // undefined
};
#ifndef DO_NOT_DOCUMENT
struct AtomData {
AtomData(AtomDataType type, const ByteVector &data) :
type(type), data(data) { }
@@ -72,6 +67,8 @@ namespace TagLib {
ByteVector data;
};
class Atom;
using AtomList = TagLib::List<Atom *>;
using AtomDataList = TagLib::List<AtomData>;
class TAGLIB_EXPORT Atom
@@ -83,7 +80,7 @@ namespace TagLib {
Atom &operator=(const Atom &) = delete;
Atom *find(const char *name1, const char *name2 = nullptr, const char *name3 = nullptr, const char *name4 = nullptr);
bool path(AtomList &path, const char *name1, const char *name2 = nullptr, const char *name3 = nullptr);
AtomList findall(const char *name, bool recursive = false);
AtomList findall(const char *name, bool recursive = false) const;
void addToOffset(offset_t delta);
void prependChild(Atom *atom);
bool removeChild(Atom *meta);
@@ -106,8 +103,8 @@ namespace TagLib {
~Atoms();
Atoms(const Atoms &) = delete;
Atoms &operator=(const Atoms &) = delete;
Atom *find(const char *name1, const char *name2 = nullptr, const char *name3 = nullptr, const char *name4 = nullptr);
AtomList path(const char *name1, const char *name2 = nullptr, const char *name3 = nullptr, const char *name4 = nullptr);
Atom *find(const char *name1, const char *name2 = nullptr, const char *name3 = nullptr, const char *name4 = nullptr) const;
AtomList path(const char *name1, const char *name2 = nullptr, const char *name3 = nullptr, const char *name4 = nullptr) const;
bool checkRootLevelAtoms();
const AtomList &atoms() const;
@@ -116,9 +113,8 @@ namespace TagLib {
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
std::unique_ptr<AtomsPrivate> d;
};
#endif // DO_NOT_DOCUMENT
} // namespace MP4
} // namespace TagLib
#endif
#endif

View File

@@ -33,6 +33,7 @@
namespace TagLib {
namespace MP4 {
//! MP4 picture
class TAGLIB_EXPORT CoverArt
{
public:
@@ -48,7 +49,7 @@ namespace TagLib {
};
CoverArt(Format format, const ByteVector &data);
virtual ~CoverArt();
~CoverArt();
CoverArt(const CoverArt &item);
@@ -58,7 +59,7 @@ namespace TagLib {
CoverArt &operator=(const CoverArt &item);
/*!
* Exchanges the content of the CoverArt by the content of \a item.
* Exchanges the content of the CoverArt with the content of \a item.
*/
void swap(CoverArt &item) noexcept;

View File

@@ -36,7 +36,7 @@ using namespace TagLib;
class MP4::File::FilePrivate
{
public:
FilePrivate(MP4::ItemFactory *mp4ItemFactory)
FilePrivate(const MP4::ItemFactory *mp4ItemFactory)
: itemFactory(mp4ItemFactory ? mp4ItemFactory
: MP4::ItemFactory::instance())
{
@@ -174,5 +174,5 @@ MP4::File::strip(int tags)
bool
MP4::File::hasMP4Tag() const
{
return (d->atoms->find("moov", "udta", "meta", "ilst") != nullptr);
return d->atoms->find("moov", "udta", "meta", "ilst") != nullptr;
}

View File

@@ -38,6 +38,7 @@ namespace TagLib {
class Atoms;
class ItemFactory;
//! An implementation of TagLib::File with MP4 specific methods
/*!
* This implements and provides an interface for MP4 files to the
@@ -62,7 +63,7 @@ namespace TagLib {
};
/*!
* Constructs an MP4 file from \a file. If \a readProperties is true the
* Constructs an MP4 file from \a file. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
@@ -74,7 +75,7 @@ namespace TagLib {
ItemFactory *itemFactory = nullptr);
/*!
* Constructs an MP4 file from \a stream. If \a readProperties is true the
* Constructs an MP4 file from \a stream. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
@@ -132,13 +133,13 @@ namespace TagLib {
/*!
* Save the file.
*
* This returns true if the save was successful.
* This returns \c true if the save was successful.
*/
bool save() override;
/*!
* 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
* file. By default it strips all tags. It returns \c true if the tags are
* successfully stripped.
*
* \note This will update the file immediately.

View File

@@ -32,6 +32,7 @@
namespace TagLib {
namespace MP4 {
//! MP4 item
class TAGLIB_EXPORT Item
{
public:
@@ -48,11 +49,11 @@ namespace TagLib {
Item &operator=(const Item &item);
/*!
* Exchanges the content of the Item by the content of \a item.
* Exchanges the content of the Item with the content of \a item.
*/
void swap(Item &item) noexcept;
virtual ~Item();
~Item();
Item(int value);
Item(unsigned char value);

View File

@@ -57,8 +57,7 @@ ItemFactory *ItemFactory::instance()
std::pair<String, Item> ItemFactory::parseItem(
const Atom *atom, const ByteVector &data) const
{
auto handlerType = handlerTypeForName(atom->name());
switch(handlerType) {
switch(handlerTypeForName(atom->name())) {
case ItemHandlerType::Unknown:
break;
case ItemHandlerType::FreeForm:
@@ -96,40 +95,37 @@ ByteVector ItemFactory::renderItem(
if(itemName.startsWith("----")) {
return renderFreeForm(itemName, item);
}
else {
const ByteVector name = itemName.data(String::Latin1);
auto handlerType = handlerTypeForName(name);
switch(handlerType) {
case ItemHandlerType::Unknown:
debug("MP4: Unknown item name \"" + name + "\"");
break;
case ItemHandlerType::FreeForm:
return renderFreeForm(name, item);
case ItemHandlerType::IntPair:
return renderIntPair(name, item);
case ItemHandlerType::IntPairNoTrailing:
return renderIntPairNoTrailing(name, item);
case ItemHandlerType::Bool:
return renderBool(name, item);
case ItemHandlerType::Int:
return renderInt(name, item);
case ItemHandlerType::TextOrInt:
return renderTextOrInt(name, item);
case ItemHandlerType::UInt:
return renderUInt(name, item);
case ItemHandlerType::LongLong:
return renderLongLong(name, item);
case ItemHandlerType::Byte:
return renderByte(name, item);
case ItemHandlerType::Gnre:
return renderInt(name, item);
case ItemHandlerType::Covr:
return renderCovr(name, item);
case ItemHandlerType::TextImplicit:
return renderText(name, item, TypeImplicit);
case ItemHandlerType::Text:
return renderText(name, item);
}
const ByteVector name = itemName.data(String::Latin1);
switch(handlerTypeForName(name)) {
case ItemHandlerType::Unknown:
debug("MP4: Unknown item name \"" + name + "\"");
break;
case ItemHandlerType::FreeForm:
return renderFreeForm(name, item);
case ItemHandlerType::IntPair:
return renderIntPair(name, item);
case ItemHandlerType::IntPairNoTrailing:
return renderIntPairNoTrailing(name, item);
case ItemHandlerType::Bool:
return renderBool(name, item);
case ItemHandlerType::Int:
return renderInt(name, item);
case ItemHandlerType::TextOrInt:
return renderTextOrInt(name, item);
case ItemHandlerType::UInt:
return renderUInt(name, item);
case ItemHandlerType::LongLong:
return renderLongLong(name, item);
case ItemHandlerType::Byte:
return renderByte(name, item);
case ItemHandlerType::Gnre:
return renderInt(name, item);
case ItemHandlerType::Covr:
return renderCovr(name, item);
case ItemHandlerType::TextImplicit:
return renderText(name, item, TypeImplicit);
case ItemHandlerType::Text:
return renderText(name, item);
}
return ByteVector();
}
@@ -142,10 +138,9 @@ std::pair<ByteVector, Item> ItemFactory::itemFromProperty(
if(values.isEmpty()) {
return {name, values};
}
auto handlerType = name.startsWith("----")
? ItemHandlerType::FreeForm
: handlerTypeForName(name);
switch(handlerType) {
switch(name.startsWith("----")
? ItemHandlerType::FreeForm
: handlerTypeForName(name)) {
case ItemHandlerType::IntPair:
case ItemHandlerType::IntPairNoTrailing:
if(StringList parts = StringList::split(values.front(), "/");
@@ -189,12 +184,10 @@ std::pair<ByteVector, Item> ItemFactory::itemFromProperty(
std::pair<String, StringList> ItemFactory::itemToProperty(
const ByteVector &itemName, const Item &item) const
{
const String key = propertyKeyForName(itemName);
if(!key.isEmpty()) {
auto handlerType = itemName.startsWith("----")
? ItemHandlerType::FreeForm
: handlerTypeForName(itemName);
switch(handlerType) {
if(const String key = propertyKeyForName(itemName); !key.isEmpty()) {
switch(itemName.startsWith("----")
? ItemHandlerType::FreeForm
: handlerTypeForName(itemName)) {
case ItemHandlerType::IntPair:
case ItemHandlerType::IntPairNoTrailing:
{
@@ -458,8 +451,7 @@ std::pair<String, Item> ItemFactory::parseInt(
std::pair<String, Item> ItemFactory::parseTextOrInt(
const MP4::Atom *atom, const ByteVector &bytes)
{
AtomDataList data = parseData2(atom, bytes);
if(!data.isEmpty()) {
if(AtomDataList data = parseData2(atom, bytes); !data.isEmpty()) {
AtomData val = data[0];
return {
atom->name(),
@@ -503,8 +495,7 @@ std::pair<String, Item> ItemFactory::parseByte(
std::pair<String, Item> ItemFactory::parseGnre(
const MP4::Atom *atom, const ByteVector &bytes)
{
ByteVectorList data = parseData(atom, bytes);
if(!data.isEmpty()) {
if(ByteVectorList data = parseData(atom, bytes); !data.isEmpty()) {
int idx = static_cast<int>(data[0].toShort());
if(idx > 0) {
return {
@@ -519,8 +510,7 @@ std::pair<String, Item> ItemFactory::parseGnre(
std::pair<String, Item> ItemFactory::parseIntPair(
const MP4::Atom *atom, const ByteVector &bytes)
{
ByteVectorList data = parseData(atom, bytes);
if(!data.isEmpty()) {
if(ByteVectorList data = parseData(atom, bytes); !data.isEmpty()) {
const int a = data[0].toShort(2U);
const int b = data[0].toShort(4U);
return {atom->name(), Item(a, b)};
@@ -531,8 +521,7 @@ std::pair<String, Item> ItemFactory::parseIntPair(
std::pair<String, Item> ItemFactory::parseBool(
const MP4::Atom *atom, const ByteVector &bytes)
{
ByteVectorList data = parseData(atom, bytes);
if(!data.isEmpty()) {
if(ByteVectorList data = parseData(atom, bytes); !data.isEmpty()) {
bool value = !data[0].isEmpty() && data[0][0] != '\0';
return {atom->name(), Item(value)};
}
@@ -542,8 +531,8 @@ std::pair<String, Item> ItemFactory::parseBool(
std::pair<String, Item> ItemFactory::parseText(
const MP4::Atom *atom, const ByteVector &bytes, int expectedFlags)
{
const ByteVectorList data = parseData(atom, bytes, expectedFlags);
if(!data.isEmpty()) {
if(const ByteVectorList data = parseData(atom, bytes, expectedFlags);
!data.isEmpty()) {
StringList value;
for(const auto &byte : data) {
value.append(String(byte, String::UTF8));
@@ -556,8 +545,8 @@ std::pair<String, Item> ItemFactory::parseText(
std::pair<String, Item> ItemFactory::parseFreeForm(
const MP4::Atom *atom, const ByteVector &bytes)
{
const AtomDataList data = parseData2(atom, bytes, -1, true);
if(data.size() > 2) {
if(const AtomDataList data = parseData2(atom, bytes, -1, true);
data.size() > 2) {
auto itBegin = data.begin();
String name = "----:";
@@ -582,15 +571,13 @@ std::pair<String, Item> ItemFactory::parseFreeForm(
item.setAtomDataType(type);
return {name, item};
}
else {
ByteVectorList value;
for(auto it = itBegin; it != data.end(); ++it) {
value.append(it->data);
}
Item item(value);
item.setAtomDataType(type);
return {name, item};
ByteVectorList value;
for(auto it = itBegin; it != data.end(); ++it) {
value.append(it->data);
}
Item item(value);
item.setAtomDataType(type);
return {name, item};
}
return {atom->name(), Item()};
}

View File

@@ -158,7 +158,7 @@ namespace TagLib {
/*!
* Destroys the frame factory.
*/
virtual ~ItemFactory();
~ItemFactory();
/*!
* Returns mapping between atom names and handler types.

View File

@@ -69,7 +69,7 @@ public:
// public members
////////////////////////////////////////////////////////////////////////////////
MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style) :
MP4::Properties::Properties(File *file, const MP4::Atoms *atoms, ReadStyle style) :
AudioProperties(style),
d(std::make_unique<PropertiesPrivate>())
{
@@ -125,7 +125,7 @@ MP4::Properties::codec() const
////////////////////////////////////////////////////////////////////////////////
void
MP4::Properties::read(File *file, Atoms *atoms)
MP4::Properties::read(File *file, const Atoms *atoms)
{
MP4::Atom *moov = atoms->find("moov");
if(!moov) {
@@ -138,7 +138,7 @@ MP4::Properties::read(File *file, Atoms *atoms)
const MP4::AtomList trakList = moov->findall("trak");
for(const auto &track : trakList) {
MP4::Atom *hdlr = track->find("mdia", "hdlr");
const MP4::Atom *hdlr = track->find("mdia", "hdlr");
if(!hdlr) {
debug("MP4: Atom 'trak.mdia.hdlr' not found");
return;
@@ -156,7 +156,7 @@ MP4::Properties::read(File *file, Atoms *atoms)
return;
}
MP4::Atom *mdhd = trak->find("mdia", "mdhd");
const MP4::Atom *mdhd = trak->find("mdia", "mdhd");
if(!mdhd) {
debug("MP4: Atom 'trak.mdia.mdhd' not found");
return;
@@ -186,7 +186,7 @@ MP4::Properties::read(File *file, Atoms *atoms)
}
if(length == 0) {
// No length found in the media header (mdhd), try the movie header (mvhd)
if(MP4::Atom *mvhd = moov->find("mvhd")) {
if(const MP4::Atom *mvhd = moov->find("mvhd")) {
file->seek(mvhd->offset());
data = file->readBlock(mvhd->length());
if(data.size() >= 24 + 4) {
@@ -222,13 +222,13 @@ MP4::Properties::read(File *file, Atoms *atoms)
pos += 3;
}
pos += 10;
const unsigned int bitrateValue = data.toUInt(pos);
if(bitrateValue != 0 || d->length <= 0) {
if(const unsigned int bitrateValue = data.toUInt(pos);
bitrateValue != 0 || d->length <= 0) {
d->bitrate = static_cast<int>((bitrateValue + 500) / 1000.0 + 0.5);
}
else {
d->bitrate = static_cast<int>(
(calculateMdatLength(atoms->atoms()) * 8) / d->length);
calculateMdatLength(atoms->atoms()) * 8 / d->length);
}
}
}
@@ -245,7 +245,7 @@ MP4::Properties::read(File *file, Atoms *atoms)
// There are files which do not contain a nominal bitrate, e.g. those
// generated by refalac64.exe. Calculate the bitrate from the audio
// data size (mdat atoms) and the duration.
d->bitrate = static_cast<int>((calculateMdatLength(atoms->atoms()) * 8) / d->length);
d->bitrate = static_cast<int>(calculateMdatLength(atoms->atoms()) * 8 / d->length);
}
}
}

View File

@@ -44,7 +44,7 @@ namespace TagLib {
ALAC
};
Properties(File *file, Atoms *atoms, ReadStyle style = Average);
Properties(File *file, const Atoms *atoms, ReadStyle style = Average);
~Properties() override;
Properties(const Properties &) = delete;
@@ -88,7 +88,7 @@ namespace TagLib {
Codec codec() const;
private:
void read(File *file, Atoms *atoms);
void read(File *file, const Atoms *atoms);
class PropertiesPrivate;
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE

View File

@@ -25,7 +25,6 @@
#include "mp4tag.h"
#include <array>
#include <utility>
#include "tdebug.h"
@@ -65,7 +64,7 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms,
d->file = file;
d->atoms = atoms;
MP4::Atom *ilst = atoms->find("moov", "udta", "meta", "ilst");
const MP4::Atom *ilst = atoms->find("moov", "udta", "meta", "ilst");
if(!ilst) {
//debug("Atom moov.udta.meta.ilst not found.");
return;
@@ -74,8 +73,8 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms,
for(const auto &atom : ilst->children()) {
file->seek(atom->offset() + 8);
ByteVector data = d->file->readBlock(atom->length() - 8);
const auto &[name, itm] = d->factory->parseItem(atom, data);
if (itm.isValid()) {
if(const auto &[name, itm] = d->factory->parseItem(atom, data);
itm.isValid()) {
addItem(name, itm);
}
}
@@ -162,8 +161,7 @@ MP4::Tag::updateParents(const AtomList &path, offset_t delta, int ignore)
void
MP4::Tag::updateOffsets(offset_t delta, offset_t offset)
{
MP4::Atom *moov = d->atoms->find("moov");
if(moov) {
if(MP4::Atom *moov = d->atoms->find("moov")) {
const MP4::AtomList stco = moov->findall("stco", true);
for(const auto &atom : stco) {
if(atom->offset() > offset) {
@@ -205,8 +203,7 @@ MP4::Tag::updateOffsets(offset_t delta, offset_t offset)
}
}
MP4::Atom *moof = d->atoms->find("moof");
if(moof) {
if(MP4::Atom *moof = d->atoms->find("moof")) {
const MP4::AtomList tfhd = moof->findall("tfhd", true);
for(const auto &atom : tfhd) {
if(atom->offset() > offset) {
@@ -214,8 +211,8 @@ MP4::Tag::updateOffsets(offset_t delta, offset_t offset)
}
d->file->seek(atom->offset() + 9);
ByteVector data = d->file->readBlock(atom->length() - 9);
const unsigned int flags = data.toUInt(0, 3, true);
if(flags & 1) {
if(const unsigned int flags = data.toUInt(0, 3, true);
flags & 1) {
long long o = data.toLongLong(7U);
if(o > offset) {
o += delta;
@@ -268,8 +265,7 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
// check if there is an atom before 'ilst', and possibly use it as padding
if(index != meta->children().cbegin()) {
auto prevIndex = std::prev(index);
MP4::Atom *prev = *prevIndex;
if(prev->name() == "free") {
if(const MP4::Atom *prev = *prevIndex; prev->name() == "free") {
offset = prev->offset();
length += prev->length();
}
@@ -277,8 +273,7 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
// check if there is an atom after 'ilst', and possibly use it as padding
auto nextIndex = std::next(index);
if(nextIndex != meta->children().cend()) {
MP4::Atom *next = *nextIndex;
if(next->name() == "free") {
if(const MP4::Atom *next = *nextIndex; next->name() == "free") {
length += next->length();
}
}
@@ -303,8 +298,7 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
}
else {
// Strip meta if data is empty, only the case when called from strip().
MP4::Atom *udta = *std::prev(it);
if(udta->removeChild(meta)) {
if(MP4::Atom *udta = *std::prev(it); udta->removeChild(meta)) {
offset = meta->offset();
delta = - meta->length();
d->file->removeBlock(meta->offset(), meta->length());
@@ -470,8 +464,8 @@ PropertyMap MP4::Tag::properties() const
{
PropertyMap props;
for(const auto &[k, t] : std::as_const(d->items)) {
auto [key, val] = d->factory->itemToProperty(k.data(String::Latin1), t);
if(!key.isEmpty()) {
if(auto [key, val] = d->factory->itemToProperty(k.data(String::Latin1), t);
!key.isEmpty()) {
props[key] = val;
}
else {
@@ -498,8 +492,8 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
PropertyMap ignoredProps;
for(const auto &[prop, val] : props) {
auto [name, itm] = d->factory->itemFromProperty(prop, val);
if(itm.isValid()) {
if(auto [name, itm] = d->factory->itemFromProperty(prop, val);
itm.isValid()) {
d->items[name] = itm;
}
else {
@@ -522,8 +516,7 @@ StringList MP4::Tag::complexPropertyKeys() const
List<VariantMap> MP4::Tag::complexProperties(const String &key) const
{
List<VariantMap> props;
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
const CoverArtList pictures = d->items.value("covr").toCoverArtList();
for(const CoverArt &picture : pictures) {
String mimeType = "image/";
@@ -555,8 +548,7 @@ List<VariantMap> MP4::Tag::complexProperties(const String &key) const
bool MP4::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
{
const String uppercaseKey = key.upper();
if(uppercaseKey == "PICTURE") {
if(const String uppercaseKey = key.upper(); uppercaseKey == "PICTURE") {
CoverArtList pictures;
for(const auto &property : value) {
auto mimeType = property.value("mimeType").value<String>();

View File

@@ -26,7 +26,6 @@
#ifndef TAGLIB_MP4TAG_H
#define TAGLIB_MP4TAG_H
#include "tbytevectorlist.h"
#include "tfile.h"
#include "tmap.h"
#include "tstringlist.h"
@@ -40,6 +39,7 @@ namespace TagLib {
class ItemFactory;
//! An MP4 tag implementation
class TAGLIB_EXPORT Tag: public TagLib::Tag
{
public:
@@ -91,7 +91,7 @@ namespace TagLib {
void removeItem(const String &key);
/*!
* \return True if the tag contains an entry for \a key.
* \return \c true if the tag contains an entry for \a key.
*/
bool contains(const String &key) const;

View File

@@ -68,7 +68,7 @@ bool MPC::File::isSupported(IOStream *stream)
// have keys to do a quick check. An ID3v2 tag may precede.
const ByteVector id = Utils::readHeader(stream, 4, true);
return (id == "MPCK" || id.startsWith("MP+"));
return id == "MPCK" || id.startsWith("MP+");
}
////////////////////////////////////////////////////////////////////////////////
@@ -186,7 +186,7 @@ bool MPC::File::save()
insert(data, d->APELocation, d->APESize);
if(d->ID3v1Location >= 0)
d->ID3v1Location += (static_cast<long>(data.size()) - d->APESize);
d->ID3v1Location += static_cast<long>(data.size()) - d->APESize;
d->APESize = data.size();
}
@@ -236,12 +236,12 @@ void MPC::File::strip(int tags)
bool MPC::File::hasID3v1Tag() const
{
return (d->ID3v1Location >= 0);
return d->ID3v1Location >= 0;
}
bool MPC::File::hasAPETag() const
{
return (d->APELocation >= 0);
return d->APELocation >= 0;
}
////////////////////////////////////////////////////////////////////////////////
@@ -295,7 +295,7 @@ void MPC::File::read(bool readProperties)
if(d->ID3v2Location >= 0) {
seek(d->ID3v2Location + d->ID3v2Size);
streamLength -= (d->ID3v2Location + d->ID3v2Size);
streamLength -= d->ID3v2Location + d->ID3v2Size;
}
else {
seek(0);

View File

@@ -27,7 +27,6 @@
#define TAGLIB_MPCFILE_H
#include "tfile.h"
#include "tlist.h"
#include "taglib_export.h"
#include "tag.h"
#include "mpcproperties.h"
@@ -42,7 +41,7 @@ namespace TagLib {
//! An implementation of MPC metadata
/*!
* This is implementation of MPC metadata.
* This is an 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
@@ -82,7 +81,7 @@ namespace TagLib {
};
/*!
* Constructs an MPC file from \a file. If \a readProperties is true the
* Constructs an MPC file from \a file. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note In the current implementation, \a propertiesStyle is ignored.
@@ -91,7 +90,7 @@ namespace TagLib {
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Constructs an MPC file from \a stream. If \a readProperties is true the
* Constructs an MPC file from \a stream. If \a readProperties is \c true the
* file's audio properties will also be read.
*
* \note TagLib will *not* take ownership of the stream, the caller is
@@ -141,22 +140,22 @@ namespace TagLib {
/*!
* Saves the file.
*
* This returns true if the save was successful.
* This returns \c true if the save was successful.
*/
bool save() override;
/*!
* 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
* If \a create is \c false (the default) this returns a null pointer
* if there is no valid APE tag. If \a create is \c 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 <b>is still</b> owned by the MPEG::File and should not be
* \note The Tag <b>is still</b> owned by the MPC::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*
@@ -167,16 +166,16 @@ namespace TagLib {
/*!
* 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
* If \a create is \c false (the default) this may return a null pointer
* if there is no valid APE tag. If \a create is \c 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.
* there already is 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 <b>is still</b> owned by the MPEG::File and should not be
* \note The Tag <b>is still</b> owned by the MPC::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*

View File

@@ -162,7 +162,7 @@ namespace
do {
tmp = data[pos++];
size = (size << 7) | (tmp & 0x7F);
} while((tmp & 0x80) && (pos < data.size()));
} while((tmp & 0x80) && pos < data.size());
return size;
}
@@ -225,9 +225,9 @@ void MPC::Properties::readSV8(File *file, offset_t streamLength)
d->sampleRate = sftable[(flags >> 13) & 0x07];
d->channels = ((flags >> 4) & 0x0F) + 1;
const auto frameCount = d->sampleFrames - begSilence;
if(frameCount > 0 && d->sampleRate > 0) {
const double length = frameCount * 1000.0 / d->sampleRate;
if(const auto frameCount = d->sampleFrames - begSilence;
frameCount > 0 && d->sampleRate > 0) {
const auto length = static_cast<double>(frameCount) * 1000.0 / d->sampleRate;
d->length = static_cast<int>(length + 0.5);
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
}
@@ -243,8 +243,7 @@ void MPC::Properties::readSV8(File *file, offset_t streamLength)
readRG = true;
const int replayGainVersion = data[0];
if(replayGainVersion == 1) {
if(const int replayGainVersion = data[0]; replayGainVersion == 1) {
d->trackGain = data.toShort(1, true);
d->trackPeak = data.toShort(3, true);
d->albumGain = data.toShort(5, true);
@@ -304,8 +303,7 @@ void MPC::Properties::readSV7(const ByteVector &data, offset_t streamLength)
if (d->albumPeak != 0)
d->albumPeak = static_cast<int>(log10(static_cast<double>(d->albumPeak)) * 20 * 256 + .5);
bool trueGapless = (gapless >> 31) & 0x0001;
if(trueGapless) {
if((gapless >> 31) & 0x0001) {
unsigned int lastFrameSamples = (gapless >> 20) & 0x07FF;
d->sampleFrames = d->totalFrames * 1152 - lastFrameSamples;
}
@@ -329,7 +327,7 @@ void MPC::Properties::readSV7(const ByteVector &data, offset_t streamLength)
}
if(d->sampleFrames > 0 && d->sampleRate > 0) {
const double length = d->sampleFrames * 1000.0 / d->sampleRate;
const auto length = static_cast<double>(d->sampleFrames) * 1000.0 / d->sampleRate;
d->length = static_cast<int>(length + 0.5);
if(d->bitrate == 0)

View File

@@ -36,7 +36,7 @@ namespace TagLib {
class File;
static const unsigned int HeaderSize = 8 * 7;
static constexpr unsigned int HeaderSize = 8 * 7;
//! An implementation of audio property reading for MPC
@@ -50,7 +50,7 @@ namespace TagLib {
public:
/*!
* Create an instance of MPC::Properties with the data read directly
* from a MPC::File.
* from an MPC::File.
*/
Properties(File *file, offset_t streamLength, ReadStyle style = Average);

View File

@@ -247,10 +247,10 @@ ID3v1::GenreMap ID3v1::genreMap()
return m;
}
String ID3v1::genre(int i)
String ID3v1::genre(int index)
{
if(i >= 0 && static_cast<size_t>(i) < genres.size())
return String(genres[i]); // always make a copy
if(index >= 0 && static_cast<size_t>(index) < genres.size())
return String(genres[index]); // always make a copy
return String();
}

View File

@@ -216,10 +216,9 @@ void ID3v1::Tag::read()
if(d->file && d->file->isValid()) {
d->file->seek(d->tagOffset);
// read the tag -- always 128 bytes
const ByteVector data = d->file->readBlock(128);
// some initial sanity checking
if(data.size() == 128 && data.startsWith("TAG"))
if(const ByteVector data = d->file->readBlock(128);
data.size() == 128 && data.startsWith("TAG"))
parse(data);
else
debug("ID3v1 tag is not valid or could not be read at the specified offset.");

View File

@@ -27,6 +27,7 @@
#define TAGLIB_ID3V1TAG_H
#include "tbytevector.h"
#include "taglib.h"
#include "taglib_export.h"
#include "tag.h"
@@ -38,7 +39,7 @@ namespace TagLib {
namespace ID3v1 {
//! A abstraction for the string to data encoding in ID3v1 tags.
//! An abstraction for the string to data encoding in ID3v1 tags.
/*!
* ID3v1 should in theory always contain ISO-8859-1 (Latin1) data. In
@@ -196,7 +197,7 @@ namespace TagLib {
*/
void read();
/*!
* Pareses the body of the tag in \a data.
* Parses the body of the tag in \a data.
*/
void parse(const ByteVector &data);

View File

@@ -192,7 +192,7 @@ void AttachedPictureFrameV22::parseFields(const ByteVector &data)
int pos = 1;
String fixedString = String(data.mid(pos, 3), String::Latin1);
auto fixedString = String(data.mid(pos, 3), String::Latin1);
pos += 3;
// convert fixed string image type to mime string
if (fixedString.upper() == "JPG") {

View File

@@ -29,7 +29,6 @@
#include "taglib_export.h"
#include "tpicturetype.h"
#include "id3v2frame.h"
#include "id3v2header.h"
namespace TagLib {
@@ -50,7 +49,7 @@ namespace TagLib {
public:
/*!
/*
* This describes the function or content of the picture.
*/
DECLARE_PICTURE_TYPE_ENUM(Type)
@@ -67,7 +66,7 @@ namespace TagLib {
explicit AttachedPictureFrame(const ByteVector &data);
/*!
* Destroys the AttahcedPictureFrame instance.
* Destroys the AttachedPictureFrame instance.
*/
~AttachedPictureFrame() override;
@@ -150,7 +149,7 @@ namespace TagLib {
/*!
* Returns the image data as a ByteVector.
*
* \note ByteVector has a data() method that returns a const char * which
* \note ByteVector has a data() method that returns a <tt>const char *</tt> which
* should make it easy to export this data to external programs.
*
* \see setPicture()

View File

@@ -57,7 +57,7 @@ namespace TagLib {
* \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;
* \a embeddedFrames.
*
* All times are in milliseconds.
*/
@@ -100,7 +100,7 @@ namespace TagLib {
* 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.
* \note If the returned value is 0xFFFFFFFF, start time should be used instead.
* \see setStartOffset()
*/
unsigned int startOffset() const;
@@ -109,7 +109,7 @@ namespace TagLib {
* 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.
* \note If the returned value is 0xFFFFFFFF, end time should be used instead.
* \see setEndOffset()
*/
unsigned int endOffset() const;
@@ -153,7 +153,7 @@ namespace TagLib {
void setEndOffset(const unsigned int &eO);
/*!
* Returns a reference to the frame list map. This is an FrameListMap of
* Returns a reference to the frame list map. This is a FrameListMap of
* all of the frames embedded in the CHAP frame.
*
* This is the most convenient structure for accessing the CHAP frame's
@@ -169,11 +169,11 @@ namespace TagLib {
const FrameListMap &embeddedFrameListMap() const;
/*!
* Returns a reference to the embedded frame list. This is an FrameList
* Returns a reference to the embedded frame list. This is a 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
* This can be useful if for example you want to 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
@@ -204,8 +204,8 @@ namespace TagLib {
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.
* Remove an embedded frame from the CHAP frame. If \a del is \c true the frame's
* memory will be freed; if it is \c false, it must be deleted by the user.
*
* \note Using this method will invalidate any pointers on the list
* returned by embeddedFrameList()

View File

@@ -148,9 +148,8 @@ void CommentsFrame::parseFields(const ByteVector &data)
int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
if(l.size() == 2) {
if(ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
l.size() == 2) {
if(d->textEncoding == String::Latin1) {
d->description = Tag::latin1StringHandler()->parse(l.front());
d->text = Tag::latin1StringHandler()->parse(l.back());

View File

@@ -153,7 +153,7 @@ namespace TagLib {
/*!
* 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.
* frame is found that matches the given description, null is returned.
*
* \see description()
*/

View File

@@ -29,7 +29,6 @@
#include "tbytevectorlist.h"
#include "tdebug.h"
#include "tpropertymap.h"
#include "id3v2tag.h"
using namespace TagLib;

View File

@@ -124,7 +124,7 @@ namespace TagLib {
explicit EventTimingCodesFrame();
/*!
* Construct a event timing codes frame based on the data in \a data.
* Construct an event timing codes frame based on the data in \a data.
*/
explicit EventTimingCodesFrame(const ByteVector &data);
@@ -137,7 +137,7 @@ namespace TagLib {
EventTimingCodesFrame &operator=(const EventTimingCodesFrame &) = delete;
/*!
* Returns a null string.
* Returns an empty string.
*/
String toString() const override;

View File

@@ -31,7 +31,6 @@
#include "taglib_export.h"
#include "id3v2frame.h"
#include "id3v2header.h"
namespace TagLib {
@@ -42,7 +41,7 @@ namespace TagLib {
/*!
* 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
* There may be multiple GEOB frames in a single tag. Each GEOB is
* 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.
@@ -151,7 +150,7 @@ namespace TagLib {
/*!
* Returns the object data as a ByteVector.
*
* \note ByteVector has a data() method that returns a const char * which
* \note ByteVector has a data() method that returns a <tt>const char *</tt> which
* should make it easy to export this data to external programs.
*
* \see setObject()

View File

@@ -95,9 +95,9 @@ String OwnershipFrame::seller() const
return d->seller;
}
void OwnershipFrame::setSeller(const String &s)
void OwnershipFrame::setSeller(const String &seller)
{
d->seller = s;
d->seller = seller;
}
String::Type OwnershipFrame::textEncoding() const
@@ -127,7 +127,7 @@ void OwnershipFrame::parseFields(const ByteVector &data)
d->textEncoding = static_cast<String::Type>(data[0]);
pos += 1;
// Read the price paid this is a null terminate string
// Read the price paid, this is a null terminated string
d->pricePaid = readStringField(data, String::Latin1, &pos);
// If we don't have at least 8 bytes left then don't parse the rest of the

View File

@@ -51,7 +51,7 @@ namespace TagLib {
explicit OwnershipFrame(String::Type encoding = String::Latin1);
/*!
* Construct a ownership based on the data in \a data.
* Construct an ownership frame based on the data in \a data.
*/
explicit OwnershipFrame(const ByteVector &data);

View File

@@ -56,7 +56,7 @@ namespace TagLib {
PodcastFrame &operator=(const PodcastFrame &) = delete;
/*!
* Returns a null string.
* Returns an empty string.
*/
String toString() const override;

View File

@@ -98,7 +98,7 @@ void PrivateFrame::parseFields(const ByteVector &data)
// Owner identifier is assumed to be Latin1
const int byteAlign = 1;
constexpr int byteAlign = 1;
const int endOfOwner = data.find(textDelimiter(String::Latin1), 0, byteAlign);
d->owner = String(data.mid(0, endOfOwner));

View File

@@ -34,7 +34,7 @@ namespace TagLib {
namespace ID3v2 {
//! An implementation of ID3v2 privateframe
//! An implementation of ID3v2 private frame
class TAGLIB_EXPORT PrivateFrame : public Frame
{

View File

@@ -78,7 +78,7 @@ namespace TagLib {
ByteVector elementID() const;
/*!
* Returns true, if the frame is top-level (doesn't have
* Returns \c true, if the frame is top-level (doesn't have
* any parent CTOC frame).
*
* \see setIsTopLevel()
@@ -86,7 +86,7 @@ namespace TagLib {
bool isTopLevel() const;
/*!
* Returns true, if the child elements list entries
* Returns \c true, if the child elements list entries
* are ordered.
*
* \see setIsOrdered()
@@ -94,8 +94,8 @@ namespace TagLib {
bool isOrdered() const;
/*!
* Returns count of child elements of the frame. It always
* corresponds to size of child elements list.
* Returns the count of child elements of the frame. It always
* corresponds to the size of the child elements list.
*
* \see childElements()
*/
@@ -139,7 +139,7 @@ namespace TagLib {
void setChildElements(const ByteVectorList &l);
/*!
* Adds \a cE to list of child elements of the frame.
* Adds \a cE to the list of child elements of the frame.
*
* \see childElements()
*/
@@ -153,7 +153,7 @@ namespace TagLib {
void removeChildElement(const ByteVector &cE);
/*!
* Returns a reference to the frame list map. This is an FrameListMap of
* Returns a reference to the frame list map. This is a FrameListMap of
* all of the frames embedded in the CTOC frame.
*
* This is the most convenient structure for accessing the CTOC frame's
@@ -169,11 +169,11 @@ namespace TagLib {
const FrameListMap &embeddedFrameListMap() const;
/*!
* Returns a reference to the embedded frame list. This is an FrameList
* Returns a reference to the embedded frame list. This is a 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
* This can be useful if for example you want to 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
@@ -204,8 +204,8 @@ namespace TagLib {
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.
* Remove an embedded frame from the CTOC frame. If \a del is \c true the frame's
* memory will be freed; if it is \c false, it must be deleted by the user.
*
* \note Using this method will invalidate any pointers on the list
* returned by embeddedFrameList()
@@ -237,7 +237,7 @@ namespace TagLib {
/*!
* 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.
* within the tag can be top-level. This searches for a top-level CTOC frame.
*
* \see isTopLevel()
*/

View File

@@ -173,9 +173,9 @@ PropertyMap TextIdentificationFrame::asProperties() const
return makeTIPLProperties();
if(frameID() == "TMCL")
return makeTMCLProperties();
PropertyMap map;
String tagName = frameIDToKey(frameID());
if(tagName.isEmpty()) {
PropertyMap map;
map.addUnsupportedData(frameID());
return map;
}
@@ -241,7 +241,7 @@ void TextIdentificationFrame::parseFields(const ByteVector &data)
// type is the same specified for this frame
unsigned short firstBom = 0;
for(auto it = l.begin(); it != l.end(); it++) {
for(auto it = l.begin(); it != l.end(); ++it) {
if(!it->isEmpty() || (it == l.begin() && frameID() == "TXXX")) {
if(d->textEncoding == String::Latin1) {
d->fieldList.append(Tag::latin1StringHandler()->parse(*it));
@@ -278,7 +278,7 @@ ByteVector TextIdentificationFrame::renderFields() const
v.append(static_cast<char>(encoding));
for(auto it = d->fieldList.cbegin(); it != d->fieldList.cend(); it++) {
for(auto it = d->fieldList.cbegin(); it != d->fieldList.cend(); ++it) {
// Since the field list is null delimited, if this is not the first
// element in the list, append the appropriate delimiter for this
@@ -287,7 +287,7 @@ ByteVector TextIdentificationFrame::renderFields() const
if(it != d->fieldList.cbegin())
v.append(textDelimiter(encoding));
v.append((*it).data(encoding));
v.append(it->data(encoding));
}
return v;
@@ -437,7 +437,7 @@ PropertyMap UserTextIdentificationFrame::asProperties() const
}
UserTextIdentificationFrame *UserTextIdentificationFrame::find(
ID3v2::Tag *tag, const String &description) // static
const ID3v2::Tag *tag, const String &description) // static
{
for(const auto &frame : std::as_const(tag->frameList("TXXX"))) {
auto f = dynamic_cast<UserTextIdentificationFrame *>(frame);

View File

@@ -59,7 +59,7 @@ namespace TagLib {
* <li><b>TDTG</b> Tagging time</li>
* <li><b>TENC</b> Encoded by</li>
* <li><b>TEXT</b> Lyricist/Text writer</li>
* <li><b>TFLT</b> File type</li>
* <li><b>TFLT</b> %File type</li>
* <li><b>TIPL</b> Involved people list</li>
* <li><b>TIT1</b> Content group description</li>
* <li><b>TIT2</b> Title/songname/content description</li>
@@ -74,7 +74,7 @@ namespace TagLib {
* <li><b>TOFN</b> Original filename</li>
* <li><b>TOLY</b> Original lyricist(s)/text writer(s)</li>
* <li><b>TOPE</b> Original artist(s)/performer(s)</li>
* <li><b>TOWN</b> File owner/licensee</li>
* <li><b>TOWN</b> %File owner/licensee</li>
* <li><b>TPE1</b> Lead performer(s)/Soloist(s)</li>
* <li><b>TPE2</b> Band/orchestra/accompaniment</li>
* <li><b>TPE3</b> Conductor/performer refinement</li>
@@ -300,7 +300,7 @@ namespace TagLib {
* 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);
static UserTextIdentificationFrame *find(const Tag *tag, const String &description);
/*!
* Returns an appropriate TXXX frame description for the given free-form tag key.
@@ -314,7 +314,6 @@ namespace TagLib {
private:
UserTextIdentificationFrame(const ByteVector &data, Header *h);
UserTextIdentificationFrame(const TextIdentificationFrame &);
void checkFields();

View File

@@ -37,7 +37,7 @@ namespace TagLib {
/*!
* This class represents a frame type not known (or more often simply
* unimplemented) in TagLib. This is here provide a basic API for
* unimplemented) in TagLib. This is here to provide a basic API for
* manipulating the binary data of unknown frames and to provide a means
* of rendering such \e unknown frames.
*

View File

@@ -150,10 +150,9 @@ void UnsynchronizedLyricsFrame::parseFields(const ByteVector &data)
int byteAlign
= d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
ByteVectorList l =
ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
if(l.size() == 2) {
if(ByteVectorList l =
ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
l.size() == 2) {
if(d->textEncoding == String::Latin1) {
d->description = Tag::latin1StringHandler()->parse(l.front());
d->text = Tag::latin1StringHandler()->parse(l.back());

View File

@@ -50,7 +50,7 @@ namespace TagLib {
explicit UnsynchronizedLyricsFrame(String::Type encoding = String::Latin1);
/*!
* Construct a unsynchronized lyrics frame based on the data in \a data.
* Construct an unsynchronized lyrics frame based on the data in \a data.
*/
explicit UnsynchronizedLyricsFrame(const ByteVector &data);
@@ -153,7 +153,7 @@ namespace TagLib {
/*!
* 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.
* frame is found that matches the given description, null is returned.
*
* \see description()
*/

View File

@@ -173,7 +173,7 @@ PropertyMap UserUrlLinkFrame::asProperties() const
return map;
}
UserUrlLinkFrame *UserUrlLinkFrame::find(ID3v2::Tag *tag, const String &description) // static
UserUrlLinkFrame *UserUrlLinkFrame::find(const ID3v2::Tag *tag, const String &description) // static
{
for(const auto &frame : std::as_const(tag->frameList("WXXX"))) {
auto f = dynamic_cast<UserUrlLinkFrame *>(frame);

View File

@@ -158,7 +158,7 @@ namespace TagLib {
/*!
* Parses the UserUrlLinkFrame as PropertyMap. The description() is taken as key,
* and the URL as single value.
* and the URL as a 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/<description>"
@@ -170,7 +170,7 @@ namespace TagLib {
* 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);
static UserUrlLinkFrame *find(const Tag *tag, const String &description);
protected:
void parseFields(const ByteVector &data) override;

View File

@@ -8,6 +8,16 @@ namespace TagLib {
* This is a relatively complete and flexible framework for working with ID3v2
* tags.
*
* More information about ID3v2 tags can be found at
* - <a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.2.0.txt">
* id3v2.2.0.txt</a>
* - <a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.3.0.txt">
* id3v2.3.0.txt</a>
* - <a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-structure.txt">
* id3v2.4.0-structure.txt</a>
* - <a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-frames.txt">
* id3v2.4.0-frames.txt</a>
*
* \see ID3v2::Tag
*/
namespace ID3v2 {

View File

@@ -28,7 +28,6 @@
#include "tbytevector.h"
#include "taglib_export.h"
#include "taglib.h"
namespace TagLib {
@@ -42,7 +41,8 @@ namespace TagLib {
* the ID3v2 standard. The API is based on the properties of ID3v2 extended
* headers specified there. If any of the terms used in this documentation
* are unclear please check the specification in the linked section.
* (Structure, <a href="id3v2-structure.html#3.2">3.2</a>)
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-structure.txt">
* id3v2.4.0-structure.txt</a>, 3.2)
*/
class TAGLIB_EXPORT ExtendedHeader
@@ -56,7 +56,7 @@ namespace TagLib {
/*!
* Destroys the extended header.
*/
virtual ~ExtendedHeader();
~ExtendedHeader();
ExtendedHeader(const ExtendedHeader &) = delete;
ExtendedHeader &operator=(const ExtendedHeader &) = delete;

View File

@@ -57,7 +57,7 @@ namespace TagLib {
/*!
* Destroys the footer.
*/
virtual ~Footer();
~Footer();
Footer(const Footer &) = delete;
Footer &operator=(const Footer &) = delete;

View File

@@ -35,12 +35,7 @@
#include "id3v2tag.h"
#include "id3v2synchdata.h"
#include "frames/textidentificationframe.h"
#include "frames/urllinkframe.h"
#include "frames/unsynchronizedlyricsframe.h"
#include "frames/commentsframe.h"
#include "frames/uniquefileidentifierframe.h"
#include "frames/unknownframe.h"
#include "frames/podcastframe.h"
using namespace TagLib;
using namespace ID3v2;
@@ -92,7 +87,7 @@ const String Frame::urlPrefix("URL:");
// public members
////////////////////////////////////////////////////////////////////////////////
unsigned int Frame::headerSize()
unsigned int Frame::headerSize() const
{
return d->header->size();
}
@@ -421,7 +416,7 @@ public:
// public members (Frame::Header)
////////////////////////////////////////////////////////////////////////////////
unsigned int Frame::Header::size()
unsigned int Frame::Header::size() const
{
switch(d->version) {
case 0:

View File

@@ -45,10 +45,12 @@ namespace TagLib {
/*!
* 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, <a href="id3v2-structure.html#4">4</a>)
* (<a href="id3v2-frames.html">Frames</a>). This class provides an API for
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-structure.txt">
* id3v2.4.0-structure.txt</a>, 4)
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-frames.txt">
* id3v2.4.0-frames.txt</a>). 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.
* specific to a given frame type is handled in one of the many subclasses.
*/
class TAGLIB_EXPORT Frame
@@ -67,8 +69,11 @@ namespace TagLib {
Frame &operator=(const Frame &) = delete;
/*!
* Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
* (Frames, <a href="id3v2-frames.html#4">4</a>)
* Returns the Frame ID
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-structure.txt">
* id3v2.4.0-structure.txt</a>, 4)
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-frames.txt">
* id3v2.4.0-frames.txt</a>, 4)
*/
ByteVector frameID() const;
@@ -80,7 +85,7 @@ namespace TagLib {
/*!
* Returns the size of the frame header
*/
unsigned int headerSize();
unsigned int headerSize() const;
/*!
* Sets the data that will be used as the frame. Since the length is not
@@ -177,7 +182,7 @@ namespace TagLib {
explicit Frame(const ByteVector &data);
/*!
* This creates an Frame using the header \a h.
* This creates a 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.
@@ -185,7 +190,7 @@ namespace TagLib {
Frame(Header *h);
/*!
* Sets the header to \a h. If \a deleteCurrent is true, this will free
* Sets the header to \a h. If \a deleteCurrent is \c true, this will free
* the memory of the current header.
*
* The ownership of this header will be assigned to the frame and the
@@ -229,7 +234,7 @@ namespace TagLib {
int *position = nullptr);
/*!
* Checks a the list of string values to see if they can be used with the
* Checks 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.
@@ -271,7 +276,9 @@ namespace TagLib {
//! ID3v2 frame header implementation
/*!
* The ID3v2 Frame Header (Structure, <a href="id3v2-structure.html#4">4</a>)
* The ID3v2 Frame Header
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-structure.txt">
* id3v2.4.0-structure.txt</a>, 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
@@ -309,8 +316,11 @@ namespace TagLib {
void setData(const ByteVector &data, unsigned int version = 4);
/*!
* Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
* (Frames, <a href="id3v2-frames.html#4">4</a>)
* Returns the Frame ID
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-structure.txt">
* id3v2.4.0-structure.txt</a>, 4)
* (<a href="https://github.com/taglib/taglib/blob/master/taglib/mpeg/id3v2/id3v2.4.0-frames.txt">
* id3v2.4.0-frames.txt</a>, 4)
*/
ByteVector frameID() const;
@@ -350,10 +360,10 @@ namespace TagLib {
/*!
* Returns the size of the frame header in bytes.
*/
unsigned int size();
unsigned int size() const;
/*!
* Returns true if the flag for tag alter preservation is set.
* Returns \c 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
@@ -365,7 +375,7 @@ namespace TagLib {
/*!
* 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
* this is set to \c true the frame will not be written when the tag is
* saved.
*
* The semantics are a little backwards from what would seem natural
@@ -377,47 +387,47 @@ namespace TagLib {
void setTagAlterPreservation(bool preserve);
/*!
* Returns true if the flag for file alter preservation is set.
* Returns \c 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.
* Returns \c 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.
* Returns \c 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.
* Returns \c 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.
* Returns \c true if encryption is enabled for this frame.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool encryption() const;
/*!
* Returns true if unsynchronisation is enabled for this frame.
* Returns \c true if unsynchronisation is enabled for this frame.
*/
bool unsynchronisation() const;
/*!
* Returns true if the flag for a data length indicator is set.
* Returns \c true if the flag for a data length indicator is set.
*/
bool dataLengthIndicator() const;

View File

@@ -72,7 +72,7 @@ namespace
bool ok;
int number = genreCode.toInt(&ok);
if((ok && number >= 0 && number <= 255 &&
!(ID3v1::genre(number) == s)) ||
ID3v1::genre(number) != s) ||
genreCode == "RX" || genreCode == "CR")
newfields.append(genreCode);
}
@@ -122,7 +122,7 @@ std::pair<Frame::Header *, bool> FrameFactory::prepareFrameHeader(
// A quick sanity check -- make sure that the frameID is 4 uppercase Latin1
// characters. Also make sure that there is data in the frame.
if(frameID.size() != (version < 3 ? 3 : 4) ||
if(frameID.size() != (version < 3U ? 3U : 4U) ||
header->frameSize() <= static_cast<unsigned int>(header->dataLengthIndicator() ? 4 : 0) ||
header->frameSize() > data.size())
{
@@ -332,9 +332,9 @@ void FrameFactory::rebuildAggregateFrames(ID3v2::Tag *tag) const
tag->frameList("TDRC").size() == 1 &&
tag->frameList("TDAT").size() == 1)
{
TextIdentificationFrame *tdrc =
auto tdrc =
dynamic_cast<TextIdentificationFrame *>(tag->frameList("TDRC").front());
UnknownFrame *tdat = dynamic_cast<UnknownFrame *>(tag->frameList("TDAT").front());
auto tdat = dynamic_cast<UnknownFrame *>(tag->frameList("TDAT").front());
if(tdrc &&
tdrc->fieldList().size() == 1 &&
@@ -346,7 +346,7 @@ void FrameFactory::rebuildAggregateFrames(ID3v2::Tag *tag) const
if(date.length() == 4) {
tdrc->setText(tdrc->toString() + '-' + date.substr(2, 2) + '-' + date.substr(0, 2));
if(tag->frameList("TIME").size() == 1) {
UnknownFrame *timeframe = dynamic_cast<UnknownFrame *>(tag->frameList("TIME").front());
auto timeframe = dynamic_cast<UnknownFrame *>(tag->frameList("TIME").front());
if(timeframe && timeframe->data().size() >= 5) {
String time(timeframe->data().mid(1), static_cast<String::Type>(timeframe->data()[0]));
if(time.length() == 4) {
@@ -547,14 +547,13 @@ bool FrameFactory::updateFrame(Frame::Header *header) const
Frame *FrameFactory::createFrameForProperty(const String &key, const StringList &values) const
{
// check if the key is contained in the key<=>frameID mapping
ByteVector frameID = Frame::keyToFrameID(key);
if(!frameID.isEmpty()) {
if(ByteVector frameID = Frame::keyToFrameID(key); !frameID.isEmpty()) {
// Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number), GRP1 (Grouping) are in fact text frames.
if(frameID[0] == 'T' || frameID == "WFED" || frameID == "MVNM" || frameID == "MVIN" || frameID == "GRP1"){ // text frame
auto frame = new TextIdentificationFrame(frameID, String::UTF8);
frame->setText(values);
return frame;
} if((frameID[0] == 'W') && (values.size() == 1)){ // URL frame (not WXXX); support only one value
} if(frameID[0] == 'W' && values.size() == 1){ // URL frame (not WXXX); support only one value
auto frame = new UrlLinkFrame(frameID);
frame->setUrl(values.front());
return frame;

View File

@@ -50,14 +50,15 @@ namespace TagLib {
* 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.
* See \c testFrameFactory() in \e tests/test_mpeg.cpp for an example.
* See <a href="https://github.com/taglib/taglib/blob/master/tests/test_id3v2framefactory.cpp">
* tests/test_id3v2framefactory.cpp</a> for an example.
*
* This implements both <i>abstract factory</i> and <i>singleton</i> patterns
* of which more information is available on the web and in software design
* textbooks (Notably <i>Design Patterns</i>).
* textbooks (notably <i>Design Patterns</i>).
*
* \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)
* an ID3v2::Tag. You can instantiate frame subclasses directly (with \c new)
* and add them to a tag using ID3v2::Tag::addFrame()
*
* \see ID3v2::Tag::addFrame()
@@ -72,10 +73,10 @@ namespace TagLib {
static FrameFactory *instance();
/*!
* Create a frame based on \a data. \a tagHeader should be a valid
* Create a frame based on \a origData. \a tagHeader should be a valid
* ID3v2::Header instance.
*/
virtual Frame *createFrame(const ByteVector &data, const Header *tagHeader) const;
virtual Frame *createFrame(const ByteVector &origData, const Header *tagHeader) const;
/*!
* Creates a textual frame which corresponds to a single key in the
@@ -115,7 +116,7 @@ namespace TagLib {
void setDefaultTextEncoding(String::Type encoding);
/*!
* Returns true if defaultTextEncoding() is used.
* Returns \c true if defaultTextEncoding() is used.
* The default text encoding is used when setDefaultTextEncoding() has
* been called. In this case, reimplementations of FrameFactory should
* use defaultTextEncoding() on the frames (having a text encoding field)
@@ -136,7 +137,7 @@ namespace TagLib {
/*!
* Destroys the frame factory.
*/
virtual ~FrameFactory();
~FrameFactory();
/*!
* This method checks for compliance to the current ID3v2 standard (2.4)
@@ -144,8 +145,8 @@ namespace TagLib {
* 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.
* This method with return \c true (with or without changes to the frame) if
* this frame should be kept or \c false if it should be discarded.
*
* See the id3v2.4.0-changes.txt document for further information.
*/
@@ -157,7 +158,7 @@ namespace TagLib {
* \param data data of the frame (might be modified)
* \param tagHeader the tag header
* \return {header, ok}: header is a created frame header or nullptr
* if the frame is invalid; ok is true if the frame is supported.
* if the frame is invalid; ok is \c true if the frame is supported.
*/
std::pair<Frame::Header *, bool> prepareFrameHeader(
ByteVector &data, const Header *tagHeader) const;

Some files were not shown because too many files have changed in this diff Show More