diff --git a/ext/libstrawberry-tagreader/CMakeLists.txt b/ext/libstrawberry-tagreader/CMakeLists.txt index e91b473c3..1b6becc0c 100644 --- a/ext/libstrawberry-tagreader/CMakeLists.txt +++ b/ext/libstrawberry-tagreader/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) set(MESSAGES tagreadermessages.proto) -set(SOURCES fmpsparser.cpp tagreader.cpp) +set(SOURCES tagreader.cpp) protobuf_generate_cpp(PROTO_SOURCES PROTO_HEADERS ${MESSAGES}) diff --git a/ext/libstrawberry-tagreader/fmpsparser.cpp b/ext/libstrawberry-tagreader/fmpsparser.cpp deleted file mode 100644 index 0ac0f52a3..000000000 --- a/ext/libstrawberry-tagreader/fmpsparser.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of Strawberry. - Copyright 2010, David Sansome - - Strawberry 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 3 of the License, or - (at your option) any later version. - - Strawberry 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 Strawberry. If not, see . -*/ - -#include "config.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include "fmpsparser.h" - -using std::placeholders::_1; -using std::placeholders::_2; - -FMPSParser::FMPSParser() : - // The float regex ends with (?:$|(?=::|;;)) to ensure it matches all the way - // up to the end of the value. Without it, it would match a string that - // starts with a number, like "123abc". - float_re_("\\s*([+-]?\\d+(?:\\.\\d+)?)\\s*(?:$|(?=::|;;))"), - - // Matches any character except unescaped slashes, colons and semicolons. - string_re_("((?:[^\\\\;:]|(?:\\\\[\\\\:;]))+)(?:$|(?=::|;;))"), - - // Used for replacing escaped characters. - escape_re_("\\\\([\\\\:;])") {} - -// Parses a list of things (of type T) that are separated by two consecutive -// Separator characters. Each individual thing is parsed by the F function. -// For example, to parse this data: -// foo::bar::baz -// Use: -// QVariantList ret; -// ParseContainer<':'>(data, ParseValue, &ret); -// ret will then contain "foo", "bar", and "baz". -// Returns the number of characters that were consumed from data. -// -// You can parse lists of lists by using different separator characters: -// ParseContainer<';'>(data, ParseContainer<':'>, &ret); -template -static int ParseContainer(const QStringRef& data, F f, QList* ret) { - ret->clear(); - - T value; - int pos = 0; - while (pos < data.length()) { - const int len = data.length() - pos; - int matched_len = f(QStringRef(data.string(), data.position() + pos, len), &value); - if (matched_len == -1 || matched_len > len) - break; - - ret->append(value); - pos += matched_len; - - // Expect two separators in a row - if (pos + 2 <= data.length() && data.at(pos) == Separator && data.at(pos+1) == Separator) { - pos += 2; - } else { - break; - } - } - - return pos; -} - -bool FMPSParser::Parse(const QString &data) { - - result_ = Result(); - - // Only return success if we matched the whole string - return ParseListList(data, &result_) == data.length(); -} - -int FMPSParser::ParseValueRef(const QStringRef& data, QVariant* ret) const { - // Try to match a float - QRegularExpressionMatch re_match = float_re_.match(*data.string(), data.position()); - if (re_match.capturedStart() == data.position()) { - *ret = re_match.captured(1).toDouble(); - return re_match.capturedLength(); - } - - // Otherwise try to match a string - re_match = string_re_.match(*data.string(), data.position()); - if (re_match.capturedStart() == data.position()) { - // Replace escape sequences with their actual characters - QString value = re_match.captured(1); - value.replace(escape_re_, "\\1"); - *ret = value; - return re_match.capturedLength(); - } - - return -1; -} - -// Parses an inner list - a list of values -int FMPSParser::ParseListRef(const QStringRef &data, QVariantList *ret) const { - return ParseContainer<':'>(data, std::bind(&FMPSParser::ParseValueRef, this, _1, _2), ret); -} - -// Parses an outer list - a list of lists -int FMPSParser::ParseListListRef(const QStringRef &data, Result *ret) const { - return ParseContainer<';'>(data, std::bind(&FMPSParser::ParseListRef, this, _1, _2), ret); -} - -// Convenience functions that take QStrings instead of QStringRefs. Use the QStringRef versions if possible, they're faster. -int FMPSParser::ParseValue(const QString &data, QVariant *ret) const { - return ParseValueRef(QStringRef(&data), ret); -} -int FMPSParser::ParseList(const QString &data, QVariantList *ret) const { - return ParseListRef(QStringRef(&data), ret); -} -int FMPSParser::ParseListList(const QString &data, Result *ret) const { - return ParseListListRef(QStringRef(&data), ret); -} diff --git a/ext/libstrawberry-tagreader/fmpsparser.h b/ext/libstrawberry-tagreader/fmpsparser.h deleted file mode 100644 index a8ec57481..000000000 --- a/ext/libstrawberry-tagreader/fmpsparser.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Strawberry. - Copyright 2010, David Sansome - - Strawberry 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 3 of the License, or - (at your option) any later version. - - Strawberry 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 Strawberry. If not, see . -*/ - -#ifndef FMPSPARSER_H -#define FMPSPARSER_H - -#include "config.h" - -#include -#include -#include -#include - -class QVariant; - -class FMPSParser { - public: - FMPSParser(); - - // A FMPS result is a list of lists of values (where a value is a string or - // a float). - typedef QList Result; - - // Parses a FMPS value and returns true on success. - bool Parse(const QString &data); - - // Gets the result of the last successful Parse. - Result result() const { return result_; } - - // Returns true if result() is empty. - bool is_empty() const { return result().isEmpty() || result()[0].isEmpty(); } - - // Internal functions, public for unit tests - int ParseValue(const QString &data, QVariant *ret) const; - int ParseValueRef(const QStringRef &data, QVariant *ret) const; - - int ParseList(const QString &data, QVariantList *ret) const; - int ParseListRef(const QStringRef &data, QVariantList *ret) const; - - int ParseListList(const QString &data, Result *ret) const; - int ParseListListRef(const QStringRef &data, Result *ret) const; - - private: - QRegularExpression float_re_; - QRegularExpression string_re_; - QRegularExpression escape_re_; - Result result_; -}; - -#endif // FMPSPARSER_H diff --git a/ext/libstrawberry-tagreader/tagreader.cpp b/ext/libstrawberry-tagreader/tagreader.cpp index 0c8811082..6bb055c3b 100644 --- a/ext/libstrawberry-tagreader/tagreader.cpp +++ b/ext/libstrawberry-tagreader/tagreader.cpp @@ -90,8 +90,6 @@ #include "core/logging.h" #include "core/messagehandler.h" - -#include "fmpsparser.h" #include "core/timeconstants.h" class FileRefFactory { @@ -300,15 +298,6 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s } } - // Parse FMPS frames - for (uint i = 0; i < map["TXXX"].size(); ++i) { - const TagLib::ID3v2::UserTextIdentificationFrame *frame = dynamic_cast(map["TXXX"][i]); - - if (frame && frame->description().startsWith("FMPS_")) { - ParseFMPSFrame(TStringToQString(frame->description()), TStringToQString(frame->fieldList()[1]), song); - } - } - } } @@ -523,33 +512,6 @@ void TagReader::ParseAPETag(const TagLib::APE::ItemListMap &map, const QTextCode } -void TagReader::ParseFMPSFrame(const QString &name, const QString &value, pb::tagreader::SongMetadata *song) const { - - qLog(Debug) << "Parsing FMPSFrame" << name << ", " << value; - FMPSParser parser; - - if (!parser.Parse(value) || parser.is_empty()) return; - - QVariant var; - - if (name == "FMPS_PlayCount") { - var = parser.result()[0][0]; - if (var.type() == QVariant::Double) { - song->set_playcount(var.toDouble()); - } - } - else if (name == "FMPS_PlayCount_User") { - // Take a user playcount only if there's no playcount already set - if (song->playcount() == 0 && parser.result()[0].count() >= 2) { - var = parser.result()[0][1]; - if (var.type() == QVariant::Double) { - song->set_playcount(var.toDouble()); - } - } - } - -} - void TagReader::SetVorbisComments(TagLib::Ogg::XiphComment *vorbis_comments, const pb::tagreader::SongMetadata &song) const { vorbis_comments->addField("COMPOSER", StdStringToTaglibString(song.composer()), true); diff --git a/ext/libstrawberry-tagreader/tagreader.h b/ext/libstrawberry-tagreader/tagreader.h index dbb9af70f..0724270a7 100644 --- a/ext/libstrawberry-tagreader/tagreader.h +++ b/ext/libstrawberry-tagreader/tagreader.h @@ -66,7 +66,6 @@ class TagReader { void ParseOggTag(const TagLib::Ogg::FieldListMap &map, const QTextCodec *codec, QString *disc, QString *compilation, pb::tagreader::SongMetadata *song) const; void ParseAPETag(const TagLib::APE::ItemListMap &map, const QTextCodec *codec, QString *disc, QString *compilation, pb::tagreader::SongMetadata *song) const; - void ParseFMPSFrame(const QString &name, const QString &value, pb::tagreader::SongMetadata *song) const; void SetVorbisComments(TagLib::Ogg::XiphComment *vorbis_comments, const pb::tagreader::SongMetadata &song) const; void SaveAPETag(TagLib::APE::Tag *tag, const pb::tagreader::SongMetadata &song) const;