diff --git a/src/tag/Id3Scan.cxx b/src/tag/Id3Scan.cxx index ef787f412..8a7b1cd52 100644 --- a/src/tag/Id3Scan.cxx +++ b/src/tag/Id3Scan.cxx @@ -18,6 +18,7 @@ */ #include "Id3Scan.hxx" +#include "Id3String.hxx" #include "Id3Load.hxx" #include "Handler.hxx" #include "Table.hxx" @@ -63,18 +64,18 @@ #endif gcc_pure -static id3_utf8_t * +static Id3String tag_id3_getstring(const struct id3_frame *frame, unsigned i) noexcept { id3_field *field = id3_frame_field(frame, i); if (field == nullptr) - return nullptr; + return {}; const id3_ucs4_t *ucs4 = id3_field_getstring(field); if (ucs4 == nullptr) - return nullptr; + return {}; - return id3_ucs4_utf8duplicate(ucs4); + return Id3String::FromUCS4(ucs4); } /* This will try to convert a string to utf-8, @@ -82,13 +83,11 @@ tag_id3_getstring(const struct id3_frame *frame, unsigned i) noexcept static id3_utf8_t * import_id3_string(const id3_ucs4_t *ucs4) { - id3_utf8_t *utf8 = id3_ucs4_utf8duplicate(ucs4); - if (gcc_unlikely(utf8 == nullptr)) + auto utf8 = Id3String::FromUCS4(ucs4); + if (!utf8) return nullptr; - AtScopeExit(utf8) { free(utf8); }; - - return (id3_utf8_t *)xstrdup(Strip((char *)utf8)); + return (id3_utf8_t *)xstrdup(Strip(utf8.c_str())); } /** @@ -226,24 +225,20 @@ tag_id3_import_musicbrainz(const struct id3_tag *id3_tag, if (frame == nullptr) break; - id3_utf8_t *name = tag_id3_getstring(frame, 1); - if (name == nullptr) + const auto name = tag_id3_getstring(frame, 1); + if (!name) continue; - AtScopeExit(name) { free(name); }; - - id3_utf8_t *value = tag_id3_getstring(frame, 2); - if (value == nullptr) + const auto value = tag_id3_getstring(frame, 2); + if (!value) continue; - AtScopeExit(value) { free(value); }; + handler.OnPair(name.c_str(), value.c_str()); - handler.OnPair((const char *)name, (const char *)value); - - TagType type = tag_id3_parse_txxx_name((const char*)name); + TagType type = tag_id3_parse_txxx_name(name.c_str()); if (type != TAG_NUM_OF_ITEM_TYPES) - handler.OnTag(type, (const char*)value); + handler.OnTag(type, value.c_str()); } } diff --git a/src/tag/Id3String.hxx b/src/tag/Id3String.hxx new file mode 100644 index 000000000..f0d6e50c2 --- /dev/null +++ b/src/tag/Id3String.hxx @@ -0,0 +1,59 @@ +/* + * Copyright 2003-2021 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. + */ + +#pragma once + +#include + +#include + +/** + * A UTF-8 string allocated by libid3tag. + */ +class Id3String { + id3_utf8_t *p = nullptr; + + Id3String(id3_utf8_t *_p) noexcept:p(_p) {} + +public: + Id3String() noexcept = default; + + ~Id3String() noexcept { + free(p); + } + + Id3String(const Id3String &) = delete; + Id3String &operator=(const Id3String &) = delete; + + static Id3String FromUCS4(const id3_ucs4_t *ucs4) noexcept { + return id3_ucs4_utf8duplicate(ucs4); + } + + operator bool() const noexcept { + return p != nullptr; + } + + char *c_str() noexcept { + return (char *)p; + } + + const char *c_str() const noexcept { + return (const char *)p; + } +};