diff options
Diffstat (limited to 'src/tag')
44 files changed, 414 insertions, 242 deletions
diff --git a/src/tag/Aiff.cxx b/src/tag/Aiff.cxx index c2498c9e9..7235b76a8 100644 --- a/src/tag/Aiff.cxx +++ b/src/tag/Aiff.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/Aiff.hxx b/src/tag/Aiff.hxx index cd323ee2e..f9b11b5a6 100644 --- a/src/tag/Aiff.hxx +++ b/src/tag/Aiff.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx index f51cb5c0b..b1759a730 100644 --- a/src/tag/ApeLoader.cxx +++ b/src/tag/ApeLoader.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "ApeLoader.hxx" #include "system/ByteOrder.hxx" #include "fs/FileSystem.hxx" +#include "util/StringView.hxx" #include <stdint.h> #include <assert.h> @@ -89,7 +90,7 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) if (remaining < size) break; - if (!callback(flags, key, p, size)) + if (!callback(flags, key, {p, size})) break; p += size; @@ -103,7 +104,7 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) bool tag_ape_scan(Path path_fs, ApeTagCallback callback) { - FILE *fp = FOpen(path_fs, "rb"); + FILE *fp = FOpen(path_fs, PATH_LITERAL("rb")); if (fp == nullptr) return false; diff --git a/src/tag/ApeLoader.hxx b/src/tag/ApeLoader.hxx index ce82cc35d..4587ff063 100644 --- a/src/tag/ApeLoader.hxx +++ b/src/tag/ApeLoader.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -26,11 +26,11 @@ #include <stddef.h> +struct StringView; class Path; typedef std::function<bool(unsigned long flags, const char *key, - const char *value, - size_t value_length)> ApeTagCallback; + StringView value)> ApeTagCallback; /** * Scans the APE tag values from a file. diff --git a/src/tag/ApeReplayGain.cxx b/src/tag/ApeReplayGain.cxx index 345f45710..883885369 100644 --- a/src/tag/ApeReplayGain.cxx +++ b/src/tag/ApeReplayGain.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,15 +21,16 @@ #include "ApeReplayGain.hxx" #include "ApeLoader.hxx" #include "ReplayGain.hxx" -#include "util/ASCII.hxx" #include "fs/Path.hxx" +#include "util/ASCII.hxx" +#include "util/StringView.hxx" #include <string.h> #include <stdlib.h> static bool replay_gain_ape_callback(unsigned long flags, const char *key, - const char *_value, size_t value_length, + StringView _value, ReplayGainInfo &info) { /* we only care about utf-8 text tags */ @@ -37,11 +38,11 @@ replay_gain_ape_callback(unsigned long flags, const char *key, return false; char value[16]; - if (value_length >= sizeof(value)) + if (_value.size >= sizeof(value)) return false; - memcpy(value, _value, value_length); - value[value_length] = 0; + memcpy(value, _value.data, _value.size); + value[_value.size] = 0; return ParseReplayGainTag(info, key, value); } @@ -53,10 +54,9 @@ replay_gain_ape_read(Path path_fs, ReplayGainInfo &info) auto callback = [&info, &found] (unsigned long flags, const char *key, - const char *value, - size_t value_length) { + StringView value) { found |= replay_gain_ape_callback(flags, key, - value, value_length, + value, info); return true; }; diff --git a/src/tag/ApeReplayGain.hxx b/src/tag/ApeReplayGain.hxx index 03c899c5c..faf68f0e3 100644 --- a/src/tag/ApeReplayGain.hxx +++ b/src/tag/ApeReplayGain.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/ApeTag.cxx b/src/tag/ApeTag.cxx index f714a1624..81318a771 100644 --- a/src/tag/ApeTag.cxx +++ b/src/tag/ApeTag.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -24,13 +24,13 @@ #include "TagTable.hxx" #include "TagHandler.hxx" #include "fs/Path.hxx" +#include "util/StringView.hxx" #include <string> #include <string.h> const struct tag_table ape_tags[] = { - { "album artist", TAG_ALBUM_ARTIST }, { "year", TAG_DATE }, { nullptr, TAG_NUM_OF_ITEM_TYPES } }; @@ -76,17 +76,18 @@ ForEachValue(const char *value, const char *end, C &&callback) */ static bool tag_ape_import_item(unsigned long flags, - const char *key, const char *value, size_t value_length, + const char *key, StringView value, const struct tag_handler *handler, void *handler_ctx) { /* we only care about utf-8 text tags */ if ((flags & (0x3 << 1)) != 0) return false; - const char *const end = value + value_length; + const auto begin = value.begin(); + const auto end = value.end(); if (handler->pair != nullptr) - ForEachValue(value, end, [handler, handler_ctx, + ForEachValue(begin, end, [handler, handler_ctx, key](const char *_value) { handler->pair(key, _value, handler_ctx); }); @@ -95,8 +96,8 @@ tag_ape_import_item(unsigned long flags, if (type == TAG_NUM_OF_ITEM_TYPES) return false; - ForEachValue(value, end, [handler, handler_ctx, - type](const char *_value) { + ForEachValue(begin, end, [handler, handler_ctx, + type](const char *_value) { tag_handler_invoke_tag(handler, handler_ctx, type, _value); }); @@ -112,10 +113,8 @@ tag_ape_scan2(Path path_fs, auto callback = [handler, handler_ctx, &recognized] (unsigned long flags, const char *key, - const char *value, - size_t value_length) { + StringView value) { recognized |= tag_ape_import_item(flags, key, value, - value_length, handler, handler_ctx); return true; }; diff --git a/src/tag/ApeTag.hxx b/src/tag/ApeTag.hxx index edebf076c..20d1d7b81 100644 --- a/src/tag/ApeTag.hxx +++ b/src/tag/ApeTag.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/Format.cxx b/src/tag/Format.cxx new file mode 100644 index 000000000..de4db57ef --- /dev/null +++ b/src/tag/Format.cxx @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2003-2015 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "Format.hxx" +#include "Tag.hxx" +#include "util/format.h" +#include "util/StringUtil.hxx" + +#include <algorithm> + +#include <string.h> +#include <time.h> + +struct FormatTagContext { + const Tag &tag; + + char buffer[256]; + + explicit FormatTagContext(const Tag &_tag):tag(_tag) {} +}; + +/** + * Is this a character unsafe to use in a path name segment? + */ +static constexpr bool +IsUnsafeChar(char ch) +{ + return + /* disallow characters illegal in file names on + Windows (Linux allows almost anything) */ + ch == '\\' || ch == '/' || ch == ':' || ch == '*' || + ch == '?' || ch == '<' || ch == '>' || ch == '|' || + /* allow space, but disallow all other whitespace */ + (unsigned char)ch < 0x20; +} + +gcc_pure +static bool +HasUnsafeChar(const char *s) +{ + for (; *s; ++s) + if (IsUnsafeChar(*s)) + return true; + + return false; +} + +static const char * +SanitizeString(const char *s, char *buffer, size_t buffer_size) +{ + /* skip leading dots to avoid generating "../" sequences */ + while (*s == '.') + ++s; + + if (!HasUnsafeChar(s)) + return s; + + char *end = CopyString(buffer, s, buffer_size); + std::replace_if(buffer, end, IsUnsafeChar, ' '); + return buffer; +} + +gcc_pure gcc_nonnull_all +static const char * +TagGetter(const void *object, const char *name) +{ + const auto &_ctx = *(const FormatTagContext *)object; + auto &ctx = const_cast<FormatTagContext &>(_ctx); + + if (strcmp(name, "iso8601") == 0) { + time_t t = time(nullptr); +#ifdef WIN32 + const struct tm *tm2 = gmtime(&t); +#else + struct tm tm; + const struct tm *tm2 = gmtime_r(&t, &tm); +#endif + if (tm2 == nullptr) + return ""; + + strftime(ctx.buffer, sizeof(ctx.buffer), +#ifdef WIN32 + /* kludge: use underscore instead of colon on + Windows because colons are not allowed in + file names, and this library is mostly + used to generate file names */ + "%Y-%m-%dT%H_%M_%SZ", +#else + "%FT%TZ", +#endif + tm2); + return ctx.buffer; + } + + const Tag &tag = ctx.tag; + + TagType tag_type = tag_name_parse_i(name); + if (tag_type == TAG_NUM_OF_ITEM_TYPES) + /* unknown tag name */ + return nullptr; + + const char *value = tag.GetValue(tag_type); + if (value == nullptr) + /* known tag name, but not present in this object */ + value = ""; + + // TODO: handle multiple tag values + return SanitizeString(value, ctx.buffer, sizeof(ctx.buffer)); +} + +char * +FormatTag(const Tag &tag, const char *format) +{ + FormatTagContext ctx(tag); + return format_object(format, &ctx, TagGetter); +} diff --git a/src/tag/Format.hxx b/src/tag/Format.hxx new file mode 100644 index 000000000..a08e687d0 --- /dev/null +++ b/src/tag/Format.hxx @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2003-2015 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_TAG_FORMAT_HXX +#define MPD_TAG_FORMAT_HXX + +#include "check.h" +#include "Compiler.h" + +struct Tag; + +gcc_malloc gcc_nonnull_all +char * +FormatTag(const Tag &tag, const char *format); + +#endif diff --git a/src/tag/TagSettings.c b/src/tag/Mask.hxx index e0c577c2b..9576d56e7 100644 --- a/src/tag/TagSettings.c +++ b/src/tag/Mask.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,9 +17,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "TagSettings.h" +#ifndef MPD_TAG_MASK_HXX +#define MPD_TAG_MASK_HXX -bool ignore_tag_items[TAG_NUM_OF_ITEM_TYPES] = { - /* ignore comments by default */ - [TAG_COMMENT] = true, -}; +#include <stdint.h> + +typedef uint_least32_t tag_mask_t; + +#endif diff --git a/src/tag/MixRamp.cxx b/src/tag/MixRamp.cxx index e1b6e43c5..cbec047de 100644 --- a/src/tag/MixRamp.cxx +++ b/src/tag/MixRamp.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/MixRamp.hxx b/src/tag/MixRamp.hxx index 5b4e2dc30..7255bac4d 100644 --- a/src/tag/MixRamp.hxx +++ b/src/tag/MixRamp.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/ReplayGain.cxx b/src/tag/ReplayGain.cxx index 83a48f243..edf8c92f1 100644 --- a/src/tag/ReplayGain.cxx +++ b/src/tag/ReplayGain.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/ReplayGain.hxx b/src/tag/ReplayGain.hxx index 2bf5e0db1..a2e897235 100644 --- a/src/tag/ReplayGain.hxx +++ b/src/tag/ReplayGain.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/Riff.cxx b/src/tag/Riff.cxx index c630f082d..741225813 100644 --- a/src/tag/Riff.cxx +++ b/src/tag/Riff.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/Riff.hxx b/src/tag/Riff.hxx index a9af67b7a..b15716882 100644 --- a/src/tag/Riff.hxx +++ b/src/tag/Riff.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/Set.cxx b/src/tag/Set.cxx index 6a55a450f..6499321e6 100644 --- a/src/tag/Set.cxx +++ b/src/tag/Set.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ #include "Set.hxx" #include "TagBuilder.hxx" -#include "TagSettings.h" +#include "Settings.hxx" #include <assert.h> @@ -58,16 +58,16 @@ CopyTagItem(TagBuilder &dest, const Tag &src, TagType type) * Copy all tag items of the types in the mask. */ static void -CopyTagMask(TagBuilder &dest, const Tag &src, uint32_t mask) +CopyTagMask(TagBuilder &dest, const Tag &src, tag_mask_t mask) { for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) - if ((mask & (1u << i)) != 0) + if ((mask & (tag_mask_t(1) << i)) != 0) CopyTagItem(dest, src, TagType(i)); } void TagSet::InsertUnique(const Tag &src, TagType type, const char *value, - uint32_t group_mask) + tag_mask_t group_mask) { TagBuilder builder; if (value == nullptr) @@ -75,7 +75,7 @@ TagSet::InsertUnique(const Tag &src, TagType type, const char *value, else builder.AddItem(type, value); CopyTagMask(builder, src, group_mask); -#if defined(__clang__) || GCC_CHECK_VERSION(4,8) +#if CLANG_OR_GCC_VERSION(4,8) emplace(builder.Commit()); #else insert(builder.Commit()); @@ -85,7 +85,7 @@ TagSet::InsertUnique(const Tag &src, TagType type, const char *value, bool TagSet::CheckUnique(TagType dest_type, const Tag &tag, TagType src_type, - uint32_t group_mask) + tag_mask_t group_mask) { bool found = false; @@ -101,16 +101,16 @@ TagSet::CheckUnique(TagType dest_type, void TagSet::InsertUnique(const Tag &tag, - TagType type, uint32_t group_mask) + TagType type, tag_mask_t group_mask) { static_assert(sizeof(group_mask) * 8 >= TAG_NUM_OF_ITEM_TYPES, "Mask is too small"); - assert((group_mask & (1u << unsigned(type))) == 0); + assert((group_mask & (tag_mask_t(1) << unsigned(type))) == 0); if (!CheckUnique(type, tag, type, group_mask) && (type != TAG_ALBUM_ARTIST || - ignore_tag_items[TAG_ALBUM_ARTIST] || + !IsTagEnabled(TAG_ALBUM_ARTIST) || /* fall back to "Artist" if no "AlbumArtist" was found */ !CheckUnique(type, tag, TAG_ARTIST, group_mask))) InsertUnique(tag, type, nullptr, group_mask); diff --git a/src/tag/Set.hxx b/src/tag/Set.hxx index b5acfcb36..587b25a3a 100644 --- a/src/tag/Set.hxx +++ b/src/tag/Set.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -22,11 +22,11 @@ #include "Compiler.h" #include "Tag.hxx" +#include "Mask.hxx" #include <set> #include <string.h> -#include <stdint.h> /** * Helper class for #TagSet which compares two #Tag objects. @@ -59,15 +59,15 @@ struct TagLess { class TagSet : public std::set<Tag, TagLess> { public: void InsertUnique(const Tag &tag, - TagType type, uint32_t group_mask); + TagType type, tag_mask_t group_mask); private: void InsertUnique(const Tag &src, TagType type, const char *value, - uint32_t group_mask); + tag_mask_t group_mask); bool CheckUnique(TagType dest_type, const Tag &tag, TagType src_type, - uint32_t group_mask); + tag_mask_t group_mask); }; #endif diff --git a/src/tag/TagSettings.h b/src/tag/Settings.cxx index 33f89d4be..83c626db8 100644 --- a/src/tag/TagSettings.h +++ b/src/tag/Settings.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -17,13 +17,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef MPD_TAG_SETTINGS_H -#define MPD_TAG_SETTINGS_H +#include "Settings.hxx" -#include "TagType.h" - -#include <stdbool.h> - -extern bool ignore_tag_items[TAG_NUM_OF_ITEM_TYPES]; - -#endif +tag_mask_t global_tag_mask = (tag_mask_t)-1 & ~(1 << TAG_COMMENT); diff --git a/src/tag/Settings.hxx b/src/tag/Settings.hxx new file mode 100644 index 000000000..332454b8f --- /dev/null +++ b/src/tag/Settings.hxx @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2003-2015 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_TAG_SETTINGS_HXX +#define MPD_TAG_SETTINGS_HXX + +#include "Mask.hxx" +#include "TagType.h" +#include "Compiler.h" + +#include <stdint.h> + +extern tag_mask_t global_tag_mask; + +gcc_const +static inline bool +IsTagEnabled(unsigned tag) +{ + return global_tag_mask & (1u << tag); +} + +gcc_const +static inline bool +IsTagEnabled(TagType tag) +{ + return IsTagEnabled(unsigned(tag)); +} + +#endif diff --git a/src/tag/Tag.cxx b/src/tag/Tag.cxx index 92ac4214c..fc124df0d 100644 --- a/src/tag/Tag.cxx +++ b/src/tag/Tag.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,7 +21,6 @@ #include "Tag.hxx" #include "TagPool.hxx" #include "TagString.hxx" -#include "TagSettings.h" #include "TagBuilder.hxx" #include "util/ASCII.hxx" diff --git a/src/tag/Tag.hxx b/src/tag/Tag.hxx index f1d3d5767..aca2bf6a0 100644 --- a/src/tag/Tag.hxx +++ b/src/tag/Tag.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagBuilder.cxx b/src/tag/TagBuilder.cxx index 0882f9561..82d99006a 100644 --- a/src/tag/TagBuilder.cxx +++ b/src/tag/TagBuilder.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,11 +19,12 @@ #include "config.h" #include "TagBuilder.hxx" -#include "TagSettings.h" +#include "Settings.hxx" #include "TagPool.hxx" #include "TagString.hxx" #include "Tag.hxx" #include "util/WritableBuffer.hxx" +#include "util/StringView.hxx" #include <array> @@ -189,22 +190,16 @@ TagBuilder::Complement(const Tag &other) } inline void -TagBuilder::AddItemInternal(TagType type, const char *value, size_t length) +TagBuilder::AddItemInternal(TagType type, StringView value) { -#if !CLANG_CHECK_VERSION(3,6) - /* disabled on clang due to -Wtautological-pointer-compare */ - assert(value != nullptr); -#endif - assert(length > 0); + assert(!value.IsEmpty()); - auto f = FixTagString(value, length); - if (!f.IsNull()) { - value = f.data; - length = f.size; - } + auto f = FixTagString(value); + if (!f.IsNull()) + value = { f.data, f.size }; tag_pool_lock.lock(); - auto i = tag_pool_get_item(type, value, length); + auto i = tag_pool_get_item(type, value); tag_pool_lock.unlock(); free(f.data); @@ -213,17 +208,12 @@ TagBuilder::AddItemInternal(TagType type, const char *value, size_t length) } void -TagBuilder::AddItem(TagType type, const char *value, size_t length) +TagBuilder::AddItem(TagType type, StringView value) { -#if !CLANG_CHECK_VERSION(3,6) - /* disabled on clang due to -Wtautological-pointer-compare */ - assert(value != nullptr); -#endif - - if (length == 0 || ignore_tag_items[type]) + if (value.IsEmpty() || !IsTagEnabled(type)) return; - AddItemInternal(type, value, length); + AddItemInternal(type, value); } void @@ -234,14 +224,14 @@ TagBuilder::AddItem(TagType type, const char *value) assert(value != nullptr); #endif - AddItem(type, value, strlen(value)); + AddItem(type, StringView(value)); } void TagBuilder::AddEmptyItem(TagType type) { tag_pool_lock.lock(); - auto i = tag_pool_get_item(type, "", 0); + auto i = tag_pool_get_item(type, StringView::Empty()); tag_pool_lock.unlock(); items.push_back(i); diff --git a/src/tag/TagBuilder.hxx b/src/tag/TagBuilder.hxx index aff581313..08c66d0b3 100644 --- a/src/tag/TagBuilder.hxx +++ b/src/tag/TagBuilder.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -28,6 +28,7 @@ #include <stddef.h> +struct StringView; struct TagItem; struct Tag; @@ -138,10 +139,10 @@ public: * * @param type the type of the new tag item * @param value the value of the tag item (not null-terminated) - * @param len the length of #value + * @param length the length of #value */ gcc_nonnull_all - void AddItem(TagType type, const char *value, size_t length); + void AddItem(TagType type, StringView value); /** * Appends a new tag item. @@ -171,7 +172,7 @@ public: private: gcc_nonnull_all - void AddItemInternal(TagType type, const char *value, size_t length); + void AddItemInternal(TagType type, StringView value); }; #endif diff --git a/src/tag/TagConfig.cxx b/src/tag/TagConfig.cxx index 00f20d1c0..b0e7b8ff0 100644 --- a/src/tag/TagConfig.cxx +++ b/src/tag/TagConfig.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ #include "config.h" #include "TagConfig.hxx" -#include "TagSettings.h" +#include "Settings.hxx" #include "Tag.hxx" #include "config/ConfigGlobal.hxx" #include "config/ConfigOption.hxx" @@ -35,11 +35,11 @@ void TagLoadConfig() { - const char *value = config_get_string(CONF_METADATA_TO_USE, nullptr); + const char *value = config_get_string(ConfigOption::METADATA_TO_USE); if (value == nullptr) return; - std::fill_n(ignore_tag_items, size_t(TAG_NUM_OF_ITEM_TYPES), true); + global_tag_mask = 0; if (StringEqualsCaseASCII(value, "none")) return; @@ -62,7 +62,7 @@ TagLoadConfig() FormatFatalError("error parsing metadata item \"%s\"", c); - ignore_tag_items[type] = false; + global_tag_mask |= tag_mask_t(1) << unsigned(type); s++; c = s; diff --git a/src/tag/TagConfig.hxx b/src/tag/TagConfig.hxx index 0088e9757..05c6594c6 100644 --- a/src/tag/TagConfig.hxx +++ b/src/tag/TagConfig.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagHandler.cxx b/src/tag/TagHandler.cxx index 2cbb83242..bbd30877a 100644 --- a/src/tag/TagHandler.cxx +++ b/src/tag/TagHandler.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -22,6 +22,9 @@ #include "TagBuilder.hxx" #include "util/ASCII.hxx" +#include <stdio.h> +#include <stdlib.h> + static void add_tag_duration(SongTime duration, void *ctx) { @@ -35,7 +38,17 @@ add_tag_tag(TagType type, const char *value, void *ctx) { TagBuilder &tag = *(TagBuilder *)ctx; - tag.AddItem(type, value); + if (type == TAG_TRACK || type == TAG_DISC) { + /* filter out this extra data and leading zeroes */ + char *end; + unsigned n = strtoul(value, &end, 10); + if (value != end) { + char s[21]; + if (snprintf(s, 21, "%u", n) >= 0) + tag.AddItem(type, s); + } + } else + tag.AddItem(type, value); } const struct tag_handler add_tag_handler = { diff --git a/src/tag/TagHandler.hxx b/src/tag/TagHandler.hxx index c12b605bc..e87c299fc 100644 --- a/src/tag/TagHandler.hxx +++ b/src/tag/TagHandler.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagId3.cxx b/src/tag/TagId3.cxx index 02dc58364..288f239d1 100644 --- a/src/tag/TagId3.cxx +++ b/src/tag/TagId3.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -33,10 +33,6 @@ #include "fs/Path.hxx" #include "fs/FileSystem.hxx" -#ifdef HAVE_GLIB -#include <glib.h> -#endif - #include <id3tag.h> #include <string> @@ -66,12 +62,14 @@ static constexpr Domain id3_domain("id3"); +gcc_pure static inline bool tag_is_id3v1(struct id3_tag *tag) { return (id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) != 0; } +gcc_pure static id3_utf8_t * tag_id3_getstring(const struct id3_frame *frame, unsigned i) { @@ -89,42 +87,11 @@ tag_id3_getstring(const struct id3_frame *frame, unsigned i) /* This will try to convert a string to utf-8, */ static id3_utf8_t * -import_id3_string(bool is_id3v1, const id3_ucs4_t *ucs4) +import_id3_string(const id3_ucs4_t *ucs4) { - id3_utf8_t *utf8; - -#ifdef HAVE_GLIB - /* use encoding field here? */ - const char *encoding; - if (is_id3v1 && - (encoding = config_get_string(CONF_ID3V1_ENCODING, nullptr)) != nullptr) { - id3_latin1_t *isostr = id3_ucs4_latin1duplicate(ucs4); - if (gcc_unlikely(isostr == nullptr)) - return nullptr; - - utf8 = (id3_utf8_t *) - g_convert_with_fallback((const char*)isostr, -1, - "utf-8", encoding, - nullptr, nullptr, - nullptr, nullptr); - if (utf8 == nullptr) { - FormatWarning(id3_domain, - "Unable to convert %s string to UTF-8: '%s'", - encoding, isostr); - free(isostr); - return nullptr; - } - free(isostr); - } else { -#else - (void)is_id3v1; -#endif - utf8 = id3_ucs4_utf8duplicate(ucs4); - if (gcc_unlikely(utf8 == nullptr)) - return nullptr; -#ifdef HAVE_GLIB - } -#endif + id3_utf8_t *utf8 = id3_ucs4_utf8duplicate(ucs4); + if (gcc_unlikely(utf8 == nullptr)) + return nullptr; id3_utf8_t *utf8_stripped = (id3_utf8_t *) xstrdup(Strip((char *)utf8)); @@ -141,7 +108,7 @@ import_id3_string(bool is_id3v1, const id3_ucs4_t *ucs4) * - string list */ static void -tag_id3_import_text_frame(struct id3_tag *tag, const struct id3_frame *frame, +tag_id3_import_text_frame(const struct id3_frame *frame, TagType type, const struct tag_handler *handler, void *handler_ctx) { @@ -170,7 +137,7 @@ tag_id3_import_text_frame(struct id3_tag *tag, const struct id3_frame *frame, if (type == TAG_GENRE) ucs4 = id3_genre_name(ucs4); - id3_utf8_t *utf8 = import_id3_string(tag_is_id3v1(tag), ucs4); + id3_utf8_t *utf8 = import_id3_string(ucs4); if (utf8 == nullptr) continue; @@ -191,7 +158,7 @@ tag_id3_import_text(struct id3_tag *tag, const char *id, TagType type, const struct id3_frame *frame; for (unsigned i = 0; (frame = id3_tag_findframe(tag, id, i)) != nullptr; ++i) - tag_id3_import_text_frame(tag, frame, type, + tag_id3_import_text_frame(frame, type, handler, handler_ctx); } @@ -205,8 +172,7 @@ tag_id3_import_text(struct id3_tag *tag, const char *id, TagType type, * - full string (we use this one) */ static void -tag_id3_import_comment_frame(struct id3_tag *tag, - const struct id3_frame *frame, TagType type, +tag_id3_import_comment_frame(const struct id3_frame *frame, TagType type, const struct tag_handler *handler, void *handler_ctx) { @@ -222,7 +188,7 @@ tag_id3_import_comment_frame(struct id3_tag *tag, if (ucs4 == nullptr) return; - id3_utf8_t *utf8 = import_id3_string(tag_is_id3v1(tag), ucs4); + id3_utf8_t *utf8 = import_id3_string(ucs4); if (utf8 == nullptr) return; @@ -241,7 +207,7 @@ tag_id3_import_comment(struct id3_tag *tag, const char *id, TagType type, const struct id3_frame *frame; for (unsigned i = 0; (frame = id3_tag_findframe(tag, id, i)) != nullptr; ++i) - tag_id3_import_comment_frame(tag, frame, type, + tag_id3_import_comment_frame(frame, type, handler, handler_ctx); } @@ -249,10 +215,11 @@ tag_id3_import_comment(struct id3_tag *tag, const char *id, TagType type, * Parse a TXXX name, and convert it to a TagType enum value. * Returns TAG_NUM_OF_ITEM_TYPES if the TXXX name is not understood. */ +gcc_pure static TagType tag_id3_parse_txxx_name(const char *name) { - static const struct tag_table txxx_tags[] = { + static constexpr struct tag_table txxx_tags[] = { { "ALBUMARTISTSORT", TAG_ALBUM_ARTIST_SORT }, { "MusicBrainz Artist Id", TAG_MUSICBRAINZ_ARTISTID }, { "MusicBrainz Album Id", TAG_MUSICBRAINZ_ALBUMID }, @@ -517,7 +484,7 @@ tag_id3_riff_aiff_load(FILE *file) struct id3_tag * tag_id3_load(Path path_fs, Error &error) { - FILE *file = FOpen(path_fs, "rb"); + FILE *file = FOpen(path_fs, PATH_LITERAL("rb")); if (file == nullptr) { error.FormatErrno("Failed to open file %s", path_fs.c_str()); return nullptr; diff --git a/src/tag/TagId3.hxx b/src/tag/TagId3.hxx index 1928d539d..94dfb1794 100644 --- a/src/tag/TagId3.hxx +++ b/src/tag/TagId3.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ struct Tag; struct id3_tag; class Error; -#ifdef HAVE_ID3TAG +#ifdef ENABLE_ID3TAG bool tag_id3_scan(Path path_fs, diff --git a/src/tag/TagItem.hxx b/src/tag/TagItem.hxx index 489ecde3a..0aa52f700 100644 --- a/src/tag/TagItem.hxx +++ b/src/tag/TagItem.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagNames.c b/src/tag/TagNames.c index e051c5863..056d714e4 100644 --- a/src/tag/TagNames.c +++ b/src/tag/TagNames.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagPool.cxx b/src/tag/TagPool.cxx index 29f605337..88b2ba333 100644 --- a/src/tag/TagPool.cxx +++ b/src/tag/TagPool.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -22,6 +22,7 @@ #include "TagItem.hxx" #include "util/Cast.hxx" #include "util/VarSize.hxx" +#include "util/StringView.hxx" #include <assert.h> #include <string.h> @@ -37,39 +38,37 @@ struct TagPoolSlot { TagItem item; TagPoolSlot(TagPoolSlot *_next, TagType type, - const char *value, size_t length) + StringView value) :next(_next), ref(1) { item.type = type; - memcpy(item.value, value, length); - item.value[length] = 0; + memcpy(item.value, value.data, value.size); + item.value[value.size] = 0; } static TagPoolSlot *Create(TagPoolSlot *_next, TagType type, - const char *value, size_t length); + StringView value); } gcc_packed; TagPoolSlot * TagPoolSlot::Create(TagPoolSlot *_next, TagType type, - const char *value, size_t length) + StringView value) { TagPoolSlot *dummy; return NewVarSize<TagPoolSlot>(sizeof(dummy->item.value), - length + 1, + value.size + 1, _next, type, - value, length); + value); } static TagPoolSlot *slots[NUM_SLOTS]; static inline unsigned -calc_hash_n(TagType type, const char *p, size_t length) +calc_hash(TagType type, StringView p) { unsigned hash = 5381; - assert(p != nullptr); - - while (length-- > 0) - hash = (hash << 5) + hash + *p++; + for (auto ch : p) + hash = (hash << 5) + hash + ch; return hash ^ type; } @@ -87,7 +86,7 @@ calc_hash(TagType type, const char *p) return hash ^ type; } -#if defined(__clang__) || GCC_CHECK_VERSION(4,7) +#if CLANG_OR_GCC_VERSION(4,7) constexpr #endif static inline TagPoolSlot * @@ -97,9 +96,9 @@ tag_item_to_slot(TagItem *item) } static inline TagPoolSlot ** -tag_value_slot_p(TagType type, const char *value, size_t length) +tag_value_slot_p(TagType type, StringView value) { - return &slots[calc_hash_n(type, value, length) % NUM_SLOTS]; + return &slots[calc_hash(type, value) % NUM_SLOTS]; } static inline TagPoolSlot ** @@ -109,13 +108,12 @@ tag_value_slot_p(TagType type, const char *value) } TagItem * -tag_pool_get_item(TagType type, const char *value, size_t length) +tag_pool_get_item(TagType type, StringView value) { - auto slot_p = tag_value_slot_p(type, value, length); + auto slot_p = tag_value_slot_p(type, value); for (auto slot = *slot_p; slot != nullptr; slot = slot->next) { if (slot->item.type == type && - length == strlen(slot->item.value) && - memcmp(value, slot->item.value, length) == 0 && + value.Equals(slot->item.value) && slot->ref < 0xff) { assert(slot->ref > 0); ++slot->ref; @@ -123,7 +121,7 @@ tag_pool_get_item(TagType type, const char *value, size_t length) } } - auto slot = TagPoolSlot::Create(*slot_p, type, value, length); + auto slot = TagPoolSlot::Create(*slot_p, type, value); *slot_p = slot; return &slot->item; } @@ -141,11 +139,9 @@ tag_pool_dup_item(TagItem *item) } else { /* the reference counter overflows above 0xff; duplicate the item, and start with 1 */ - size_t length = strlen(item->value); - auto slot_p = tag_value_slot_p(item->type, - item->value, length); + auto slot_p = tag_value_slot_p(item->type, item->value); slot = TagPoolSlot::Create(*slot_p, item->type, - item->value, strlen(item->value)); + item->value); *slot_p = slot; return &slot->item; } diff --git a/src/tag/TagPool.hxx b/src/tag/TagPool.hxx index 990ee87bd..7b4b5dadf 100644 --- a/src/tag/TagPool.hxx +++ b/src/tag/TagPool.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -26,9 +26,10 @@ extern Mutex tag_pool_lock; struct TagItem; +struct StringView; TagItem * -tag_pool_get_item(TagType type, const char *value, size_t length); +tag_pool_get_item(TagType type, StringView value); TagItem * tag_pool_dup_item(TagItem *item); diff --git a/src/tag/TagRva2.cxx b/src/tag/TagRva2.cxx index bbb6d11e6..8e22cd693 100644 --- a/src/tag/TagRva2.cxx +++ b/src/tag/TagRva2.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -26,42 +26,42 @@ #include <stdint.h> #include <string.h> -enum rva2_channel { - CHANNEL_OTHER = 0x00, - CHANNEL_MASTER_VOLUME = 0x01, - CHANNEL_FRONT_RIGHT = 0x02, - CHANNEL_FRONT_LEFT = 0x03, - CHANNEL_BACK_RIGHT = 0x04, - CHANNEL_BACK_LEFT = 0x05, - CHANNEL_FRONT_CENTRE = 0x06, - CHANNEL_BACK_CENTRE = 0x07, - CHANNEL_SUBWOOFER = 0x08 +enum class Rva2Channel : uint8_t { + OTHER = 0x00, + MASTER_VOLUME = 0x01, + FRONT_RIGHT = 0x02, + FRONT_LEFT = 0x03, + BACK_RIGHT = 0x04, + BACK_LEFT = 0x05, + FRONT_CENTRE = 0x06, + BACK_CENTRE = 0x07, + SUBWOOFER = 0x08 }; -struct rva2_data { - uint8_t type; +struct Rva2Data { + Rva2Channel type; uint8_t volume_adjustment[2]; uint8_t peak_bits; }; static inline id3_length_t -rva2_peak_bytes(const struct rva2_data *data) +rva2_peak_bytes(const Rva2Data &data) { - return (data->peak_bits + 7) / 8; + return (data.peak_bits + 7) / 8; } static inline int -rva2_fixed_volume_adjustment(const struct rva2_data *data) +rva2_fixed_volume_adjustment(const Rva2Data &data) { signed int voladj_fixed; - voladj_fixed = (data->volume_adjustment[0] << 8) | - data->volume_adjustment[1]; + voladj_fixed = (data.volume_adjustment[0] << 8) | + data.volume_adjustment[1]; voladj_fixed |= -(voladj_fixed & 0x8000); return voladj_fixed; } static inline float -rva2_float_volume_adjustment(const struct rva2_data *data) +rva2_float_volume_adjustment(const Rva2Data &data) { /* * "The volume adjustment is encoded as a fixed point decibel @@ -74,9 +74,9 @@ rva2_float_volume_adjustment(const struct rva2_data *data) static inline bool rva2_apply_data(ReplayGainInfo &rgi, - const struct rva2_data *data, const id3_latin1_t *id) + const Rva2Data &data, const id3_latin1_t *id) { - if (data->type != CHANNEL_MASTER_VOLUME) + if (data.type != Rva2Channel::MASTER_VOLUME) return false; float volume_adjustment = rva2_float_volume_adjustment(data); @@ -117,7 +117,7 @@ rva2_apply_frame(ReplayGainInfo &replay_gain_info, */ while (length >= 4) { - const struct rva2_data *d = (const struct rva2_data *)data; + const Rva2Data &d = *(const Rva2Data *)data; unsigned int peak_bytes = rva2_peak_bytes(d); if (4 + peak_bytes > length) break; diff --git a/src/tag/TagRva2.hxx b/src/tag/TagRva2.hxx index df559f472..615d5a282 100644 --- a/src/tag/TagRva2.hxx +++ b/src/tag/TagRva2.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -26,7 +26,7 @@ struct id3_tag; struct ReplayGainInfo; /** - * Parse the RVA2 tag, and fill the #replay_gain_info struct. This is + * Parse the RVA2 tag, and fill the #ReplayGainInfo struct. This is * used by decoder plugins with ID3 support. * * @return true on success diff --git a/src/tag/TagString.cxx b/src/tag/TagString.cxx index 4f07cd62a..d30a07a27 100644 --- a/src/tag/TagString.cxx +++ b/src/tag/TagString.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "TagString.hxx" #include "util/Alloc.hxx" #include "util/WritableBuffer.hxx" +#include "util/StringView.hxx" #include "util/UTF8.hxx" #include <assert.h> @@ -54,14 +55,14 @@ FindInvalidUTF8(const char *p, const char *const end) * Replace invalid sequences with the question mark. */ static WritableBuffer<char> -patch_utf8(const char *src, size_t length, const char *_invalid) +patch_utf8(StringView src, const char *_invalid) { /* duplicate the string, and replace invalid bytes in that buffer */ - char *dest = (char *)xmemdup(src, length); - char *const end = dest + length; + char *dest = (char *)xmemdup(src.data, src.size); + char *const end = dest + src.size; - char *invalid = dest + (_invalid - src); + char *invalid = dest + (_invalid - src.data); do { *invalid = '?'; @@ -69,19 +70,19 @@ patch_utf8(const char *src, size_t length, const char *_invalid) invalid = const_cast<char *>(__invalid); } while (invalid != nullptr); - return { dest, length }; + return { dest, src.size }; } static WritableBuffer<char> -fix_utf8(const char *str, size_t length) +fix_utf8(StringView p) { /* check if the string is already valid UTF-8 */ - const char *invalid = FindInvalidUTF8(str, str + length); + const char *invalid = FindInvalidUTF8(p.begin(), p.end()); if (invalid == nullptr) return nullptr; /* no, broken - patch invalid sequences */ - return patch_utf8(str, length, invalid); + return patch_utf8(p, invalid); } static bool @@ -91,11 +92,11 @@ char_is_non_printable(unsigned char ch) } static const char * -find_non_printable(const char *p, size_t length) +find_non_printable(StringView p) { - for (size_t i = 0; i < length; ++i) - if (char_is_non_printable(p[i])) - return p + i; + for (const char &ch : p) + if (char_is_non_printable(ch)) + return &ch; return nullptr; } @@ -105,31 +106,29 @@ find_non_printable(const char *p, size_t length) * Returns nullptr if nothing needs to be cleared. */ static WritableBuffer<char> -clear_non_printable(const char *p, size_t length) +clear_non_printable(StringView src) { - const char *first = find_non_printable(p, length); + const char *first = find_non_printable(src); if (first == nullptr) return nullptr; - char *dest = (char *)xmemdup(p, length); + char *dest = (char *)xmemdup(src.data, src.size); - for (size_t i = first - p; i < length; ++i) + for (size_t i = first - src.data; i < src.size; ++i) if (char_is_non_printable(dest[i])) dest[i] = ' '; - return { dest, length }; + return { dest, src.size }; } WritableBuffer<char> -FixTagString(const char *p, size_t length) +FixTagString(StringView p) { - auto utf8 = fix_utf8(p, length); - if (!utf8.IsNull()) { - p = utf8.data; - length = utf8.size; - } + auto utf8 = fix_utf8(p); + if (!utf8.IsNull()) + p = {utf8.data, utf8.size}; - WritableBuffer<char> cleared = clear_non_printable(p, length); + WritableBuffer<char> cleared = clear_non_printable(p); if (cleared.IsNull()) cleared = utf8; else diff --git a/src/tag/TagString.hxx b/src/tag/TagString.hxx index eccc2aa47..53fbc7abd 100644 --- a/src/tag/TagString.hxx +++ b/src/tag/TagString.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -25,10 +25,11 @@ #include <stddef.h> +struct StringView; template<typename T> struct WritableBuffer; gcc_nonnull_all WritableBuffer<char> -FixTagString(const char *p, size_t length); +FixTagString(StringView p); #endif diff --git a/src/tag/TagTable.cxx b/src/tag/TagTable.cxx index c6e1cff54..e2a22b642 100644 --- a/src/tag/TagTable.cxx +++ b/src/tag/TagTable.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagTable.hxx b/src/tag/TagTable.hxx index 095b4cbff..0d72cba99 100644 --- a/src/tag/TagTable.hxx +++ b/src/tag/TagTable.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/TagType.h b/src/tag/TagType.h index 0aa6b4a51..6f68d53d0 100644 --- a/src/tag/TagType.h +++ b/src/tag/TagType.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/VorbisComment.cxx b/src/tag/VorbisComment.cxx index 2dfc058d8..2c45470d4 100644 --- a/src/tag/VorbisComment.cxx +++ b/src/tag/VorbisComment.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/tag/VorbisComment.hxx b/src/tag/VorbisComment.hxx index 1dd3371c8..e48e9b7a9 100644 --- a/src/tag/VorbisComment.hxx +++ b/src/tag/VorbisComment.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify |