From nobody Fri Jun 14 05:29:37 2024 X-Original-To: dev-commits-ports-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4W0nsF54yCz5NQgw; Fri, 14 Jun 2024 05:29:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4W0nsF3zfTz4v3Y; Fri, 14 Jun 2024 05:29:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1718342977; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XoM+sITMN3eqNGK/48oY4bML4ZYF0ZKw9ruKFn0eqBk=; b=mYZQQQIRvW/PEtat8CJVel+tTU+WTx3PZAj3SocQ0S66FQlsUy4LsyH41du3YuMG3Lgr13 nDG27n6VMhXYEMNWNt4RnQwyoTttXARMUGrPW6kFZAKwbs3RoN6yFJw0xigTN/xBJY+X1k z3ebIpfmo1KoIJp2cF+A3iwHse3TCpKTs4pXYXbySegKHLbhHSWrCgHkcGxFEJodsn6xTj tMqZ4OMPubXa9apC0jpi20lhprFMJ4OEsDcysXRfmC1rdXGb7Vva/eaYsOmTjprTcq6v2E Y2p8CTOKeK5nAMTzVFs8rnA9W/oSlFq3AVdZrxCh8OCFnacNLeol3nuFW+8GTg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1718342977; a=rsa-sha256; cv=none; b=nl5V7p01PY1gnPWu8/ipkNwTLpcKfFLCl1wmmrAPwLxC+BQ3rM8v0mh7EWPDiTqQCO2Zwi 3TtvZJq8R+laNmoQ6hiLfnVd5tVNwR1Q3f/X75AGb6fTtw3UX3zUsLwOspLkkn6kXAVB2T e2poR3ZtamZFIGvGcqdXxnXrl48jsGQB9Zss/K/5Aha4hHVLtq9ifYjcY0tMK0+CsFbxME HMJ2NmfKlvk/Vyi0p3eqmK1wcaDzTrWec0olAkmGoNW+AJ9NtN1O8SlFQUmUxzneu5mVPT 4zz4YgMdFtjvRorcn8RfOFcg9sy5E2wuDmfVlHOp650yk3mM+HPcFwudM7X7hA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1718342977; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XoM+sITMN3eqNGK/48oY4bML4ZYF0ZKw9ruKFn0eqBk=; b=HtoOqs71O3oWHXMrJfGQHMIZbhSvAVi+cc+4VXWKKPY0bI/TpjuawEkPDOv2khSgdcmtUn bvpPYLkqADJGyI7MVkk+Ov8tsZUf/Y/L8Pv9T/10ufY0ULEjd/XiEIlEmCvUYIFHnAfYvY ISA3IhOxnSHUqIXKq5DbXKcVOOTL6wDOVdNIaG5cwgDERqkVVitlgerBaJovIiU+PzoTYa Rv8oloLv9mfh3I6dmISC1XLWezx/aFExyGag5vlWxvvdn01cKPSdX+qrqB0lHTvrvw0y/D spHpLT9XHPJ+pN8KER7sUQuoVdwMRGdMvpYM1KzzJ9bGWqGG0pOXL8Ulwrt7Bw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4W0nsF3ZK0z17G4; Fri, 14 Jun 2024 05:29:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 45E5Tbrf068431; Fri, 14 Jun 2024 05:29:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 45E5TboD068428; Fri, 14 Jun 2024 05:29:37 GMT (envelope-from git) Date: Fri, 14 Jun 2024 05:29:37 GMT Message-Id: <202406140529.45E5TboD068428@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: "Jason E. Hale" Subject: git: 13b6ffc52c68 - main - converters/gbsdconv: Fix build with Taglib 2.x List-Id: Commits to the main branch of the FreeBSD ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-ports-main@freebsd.org Sender: owner-dev-commits-ports-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhale X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 13b6ffc52c687a5cfae752a46c384755550580a9 Auto-Submitted: auto-generated The branch main has been updated by jhale: URL: https://cgit.FreeBSD.org/ports/commit/?id=13b6ffc52c687a5cfae752a46c384755550580a9 commit 13b6ffc52c687a5cfae752a46c384755550580a9 Author: Jason E. Hale AuthorDate: 2024-06-06 22:23:06 +0000 Commit: Jason E. Hale CommitDate: 2024-06-14 05:29:26 +0000 converters/gbsdconv: Fix build with Taglib 2.x PR: 276677 --- converters/gbsdconv/Makefile | 2 +- converters/gbsdconv/files/patch-gbsdconv | 30 + converters/gbsdconv/files/patch-taglib_tag__c.cpp | 873 ++++++++++++++++++++++ converters/gbsdconv/files/patch-taglib_tag__c.h | 428 +++++++++++ 4 files changed, 1332 insertions(+), 1 deletion(-) diff --git a/converters/gbsdconv/Makefile b/converters/gbsdconv/Makefile index b595457d0d52..00945c6296e2 100644 --- a/converters/gbsdconv/Makefile +++ b/converters/gbsdconv/Makefile @@ -1,6 +1,6 @@ PORTNAME= gbsdconv PORTVERSION= 11.3 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= converters python MAINTAINER= buganini@gmail.com diff --git a/converters/gbsdconv/files/patch-gbsdconv b/converters/gbsdconv/files/patch-gbsdconv new file mode 100644 index 000000000000..2a6056a3cede --- /dev/null +++ b/converters/gbsdconv/files/patch-gbsdconv @@ -0,0 +1,30 @@ +--- gbsdconv.orig 2024-06-06 19:33:30 UTC ++++ gbsdconv +@@ -38,10 +38,10 @@ taglib.taglib_mpeg_file.restype=c_void_p + taglib.taglib_mpeg_file.argtypes=[c_void_p] + taglib.taglib_mpeg_file.restype=c_void_p + +-taglib.taglib_mpeg_file_save3.argtypes=[c_void_p, c_int, c_bool, c_int] ++taglib.taglib_mpeg_file_save3.argtypes=[c_void_p, c_int, c_bool, c_int, c_bool] + taglib.taglib_mpeg_file_save3.restype=c_bool + +-taglib.taglib_mpeg_file_strip.argtypes=[c_void_p, c_int] ++taglib.taglib_mpeg_file_strip.argtypes=[c_void_p, c_int, c_bool] + taglib.taglib_mpeg_file_strip.restype=c_bool + + taglib.taglib_file_tag.argtypes=[c_void_p] +@@ -1281,12 +1281,12 @@ class gBsdConv(object): + + mpeg=taglib.taglib_mpeg_file(mfile) + if mpeg and builder.get_object('chk_use_id3v2_3').get_active(): +- taglib.taglib_mpeg_file_save3(mpeg, 0xffff, False, 3) ++ taglib.taglib_mpeg_file_save3(mpeg, 0xffff, False, 3, True) + else: + taglib.taglib_file_save(mfile) + + if mpeg and builder.get_object('chk_remove_id3v1').get_active(): +- taglib.taglib_mpeg_file_strip(mpeg, 0x0001) ++ taglib.taglib_mpeg_file_strip(mpeg, 0x0001, True) + + taglib.taglib_tag_free_strings() + taglib.taglib_file_free(mfile) diff --git a/converters/gbsdconv/files/patch-taglib_tag__c.cpp b/converters/gbsdconv/files/patch-taglib_tag__c.cpp new file mode 100644 index 000000000000..c3459a63aa34 --- /dev/null +++ b/converters/gbsdconv/files/patch-taglib_tag__c.cpp @@ -0,0 +1,873 @@ +--- taglib/tag_c.cpp.orig 2014-02-15 21:45:54 UTC ++++ taglib/tag_c.cpp +@@ -19,43 +19,82 @@ + * USA * + ***************************************************************************/ + ++#include "tag_c.h" ++ ++#include ++#include ++#include ++#include ++ + #ifdef HAVE_CONFIG_H +-#include "config.h" ++# include "config.h" + #endif ++#include "tstringlist.h" ++#include "tbytevectorstream.h" ++#include "tiostream.h" ++#include "tfile.h" ++#include "tpropertymap.h" ++#include "fileref.h" ++#include "asffile.h" ++#include "vorbisfile.h" ++#include "mpegfile.h" ++#include "flacfile.h" ++#include "oggflacfile.h" ++#include "mpcfile.h" ++#include "wavpackfile.h" ++#include "speexfile.h" ++#include "trueaudiofile.h" ++#include "mp4file.h" ++#include "aifffile.h" ++#include "wavfile.h" ++#include "apefile.h" ++#include "itfile.h" ++#include "modfile.h" ++#include "s3mfile.h" ++#include "xmfile.h" ++#include "opusfile.h" ++#include "dsffile.h" ++#include "dsdifffile.h" ++#include "tag.h" ++#include "id3v2framefactory.h" + +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include ++using namespace TagLib; + +-#include "tag_c.h" ++namespace ++{ ++ List strings; ++ bool unicodeStrings = true; ++ bool stringManagementEnabled = true; + +-using namespace TagLib; ++ char *stringToCharArray(const String &s) ++ { ++ const std::string str = s.to8Bit(unicodeStrings); + +-static List strings; +-static bool unicodeStrings = true; +-static bool stringManagementEnabled = true; ++#ifdef HAVE_ISO_STRDUP + ++ return ::_strdup(str.c_str()); ++ ++#else ++ ++ return ::strdup(str.c_str()); ++ ++#endif ++ } ++ ++ String charArrayToString(const char *s) ++ { ++ return String(s, unicodeStrings ? String::UTF8 : String::Latin1); ++ } ++} // namespace ++ + void taglib_set_strings_unicode(BOOL unicode) + { +- unicodeStrings = bool(unicode); ++ unicodeStrings = (unicode != 0); + } + + void taglib_set_string_management_enabled(BOOL management) + { +- stringManagementEnabled = bool(management); ++ stringManagementEnabled = (management != 0); + } + + void taglib_free(void* pointer) +@@ -64,69 +103,130 @@ void taglib_free(void* pointer) + } + + //////////////////////////////////////////////////////////////////////////////// +-// TagLib::File wrapper ++// TagLib::IOStream wrapper + //////////////////////////////////////////////////////////////////////////////// + ++TagLib_IOStream *taglib_memory_iostream_new(const char *data, unsigned int size) ++{ ++ return reinterpret_cast( ++ new ByteVectorStream(ByteVector(data, size))); ++} ++ ++void taglib_iostream_free(TagLib_IOStream *stream) ++{ ++ delete reinterpret_cast(stream); ++} ++ ++//////////////////////////////////////////////////////////////////////////////// ++// TagLib::FileRef wrapper ++//////////////////////////////////////////////////////////////////////////////// ++ + TagLib_File *taglib_file_new(const char *filename) + { +- return reinterpret_cast(FileRef::create(filename)); ++ return reinterpret_cast(new FileRef(filename)); + } + + TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type) + { ++ File *file = NULL; + switch(type) { + case TagLib_File_MPEG: +- return reinterpret_cast(new MPEG::File(filename)); ++ file = new MPEG::File(filename); ++ break; + case TagLib_File_OggVorbis: +- return reinterpret_cast(new Ogg::Vorbis::File(filename)); ++ file = new Ogg::Vorbis::File(filename); ++ break; + case TagLib_File_FLAC: +- return reinterpret_cast(new FLAC::File(filename)); ++ file = new FLAC::File(filename); ++ break; + case TagLib_File_MPC: +- return reinterpret_cast(new MPC::File(filename)); ++ file = new MPC::File(filename); ++ break; + case TagLib_File_OggFlac: +- return reinterpret_cast(new Ogg::FLAC::File(filename)); ++ file = new Ogg::FLAC::File(filename); ++ break; + case TagLib_File_WavPack: +- return reinterpret_cast(new WavPack::File(filename)); ++ file = new WavPack::File(filename); ++ break; + case TagLib_File_Speex: +- return reinterpret_cast(new Ogg::Speex::File(filename)); ++ file = new Ogg::Speex::File(filename); ++ break; + case TagLib_File_TrueAudio: +- return reinterpret_cast(new TrueAudio::File(filename)); ++ file = new TrueAudio::File(filename); ++ break; + case TagLib_File_MP4: +- return reinterpret_cast(new MP4::File(filename)); ++ file = new MP4::File(filename); ++ break; + case TagLib_File_ASF: +- return reinterpret_cast(new ASF::File(filename)); ++ file = new ASF::File(filename); ++ break; ++ case TagLib_File_AIFF: ++ file = new RIFF::AIFF::File(filename); ++ break; ++ case TagLib_File_WAV: ++ file = new RIFF::WAV::File(filename); ++ break; ++ case TagLib_File_APE: ++ file = new APE::File(filename); ++ break; ++ case TagLib_File_IT: ++ file = new IT::File(filename); ++ break; ++ case TagLib_File_Mod: ++ file = new Mod::File(filename); ++ break; ++ case TagLib_File_S3M: ++ file = new S3M::File(filename); ++ break; ++ case TagLib_File_XM: ++ file = new XM::File(filename); ++ break; ++ case TagLib_File_Opus: ++ file = new Ogg::Opus::File(filename); ++ break; ++ case TagLib_File_DSF: ++ file = new DSF::File(filename); ++ break; ++ case TagLib_File_DSDIFF: ++ file = new DSDIFF::File(filename); ++ break; + default: +- return 0; ++ break; + } ++ return file ? reinterpret_cast(new FileRef(file)) : NULL; ++} + +- return 0; ++TagLib_File *taglib_file_new_iostream(TagLib_IOStream *stream) ++{ ++ return reinterpret_cast( ++ new FileRef(reinterpret_cast(stream))); + } + + void taglib_file_free(TagLib_File *file) + { +- delete reinterpret_cast(file); ++ delete reinterpret_cast(file); + } + + BOOL taglib_file_is_valid(const TagLib_File *file) + { +- return reinterpret_cast(file)->isValid(); ++ return !reinterpret_cast(file)->isNull(); + } + + TagLib_Tag *taglib_file_tag(const TagLib_File *file) + { +- const File *f = reinterpret_cast(file); ++ auto f = reinterpret_cast(file); + return reinterpret_cast(f->tag()); + } + + const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file) + { +- const File *f = reinterpret_cast(file); ++ auto f = reinterpret_cast(file); + return reinterpret_cast(f->audioProperties()); + } + + BOOL taglib_file_save(TagLib_File *file) + { +- return reinterpret_cast(file)->save(); ++ return reinterpret_cast(file)->save(); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -135,8 +235,8 @@ char *taglib_tag_title(const TagLib_Tag *tag) + + char *taglib_tag_title(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); +- char *s = ::strdup(t->title().toCString(unicodeStrings)); ++ auto t = reinterpret_cast(tag); ++ char *s = stringToCharArray(t->title()); + if(stringManagementEnabled) + strings.append(s); + return s; +@@ -144,8 +244,8 @@ char *taglib_tag_artist(const TagLib_Tag *tag) + + char *taglib_tag_artist(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); +- char *s = ::strdup(t->artist().toCString(unicodeStrings)); ++ auto t = reinterpret_cast(tag); ++ char *s = stringToCharArray(t->artist()); + if(stringManagementEnabled) + strings.append(s); + return s; +@@ -153,8 +253,8 @@ char *taglib_tag_album(const TagLib_Tag *tag) + + char *taglib_tag_album(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); +- char *s = ::strdup(t->album().toCString(unicodeStrings)); ++ auto t = reinterpret_cast(tag); ++ char *s = stringToCharArray(t->album()); + if(stringManagementEnabled) + strings.append(s); + return s; +@@ -162,8 +262,8 @@ char *taglib_tag_comment(const TagLib_Tag *tag) + + char *taglib_tag_comment(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); +- char *s = ::strdup(t->comment().toCString(unicodeStrings)); ++ auto t = reinterpret_cast(tag); ++ char *s = stringToCharArray(t->comment()); + if(stringManagementEnabled) + strings.append(s); + return s; +@@ -171,8 +271,8 @@ char *taglib_tag_genre(const TagLib_Tag *tag) + + char *taglib_tag_genre(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); +- char *s = ::strdup(t->genre().toCString(unicodeStrings)); ++ auto t = reinterpret_cast(tag); ++ char *s = stringToCharArray(t->genre()); + if(stringManagementEnabled) + strings.append(s); + return s; +@@ -180,55 +280,55 @@ unsigned int taglib_tag_year(const TagLib_Tag *tag) + + unsigned int taglib_tag_year(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); ++ auto t = reinterpret_cast(tag); + return t->year(); + } + + unsigned int taglib_tag_track(const TagLib_Tag *tag) + { +- const Tag *t = reinterpret_cast(tag); ++ auto t = reinterpret_cast(tag); + return t->track(); + } + + void taglib_tag_set_title(TagLib_Tag *tag, const char *title) + { +- Tag *t = reinterpret_cast(tag); +- t->setTitle(String(title, unicodeStrings ? String::UTF8 : String::Latin1)); ++ auto t = reinterpret_cast(tag); ++ t->setTitle(charArrayToString(title)); + } + + void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist) + { +- Tag *t = reinterpret_cast(tag); +- t->setArtist(String(artist, unicodeStrings ? String::UTF8 : String::Latin1)); ++ auto t = reinterpret_cast(tag); ++ t->setArtist(charArrayToString(artist)); + } + + void taglib_tag_set_album(TagLib_Tag *tag, const char *album) + { +- Tag *t = reinterpret_cast(tag); +- t->setAlbum(String(album, unicodeStrings ? String::UTF8 : String::Latin1)); ++ auto t = reinterpret_cast(tag); ++ t->setAlbum(charArrayToString(album)); + } + + void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment) + { +- Tag *t = reinterpret_cast(tag); +- t->setComment(String(comment, unicodeStrings ? String::UTF8 : String::Latin1)); ++ auto t = reinterpret_cast(tag); ++ t->setComment(charArrayToString(comment)); + } + + void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre) + { +- Tag *t = reinterpret_cast(tag); +- t->setGenre(String(genre, unicodeStrings ? String::UTF8 : String::Latin1)); ++ auto t = reinterpret_cast(tag); ++ t->setGenre(charArrayToString(genre)); + } + + void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year) + { +- Tag *t = reinterpret_cast(tag); ++ auto t = reinterpret_cast(tag); + t->setYear(year); + } + + void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track) + { +- Tag *t = reinterpret_cast(tag); ++ auto t = reinterpret_cast(tag); + t->setTrack(track); + } + +@@ -237,8 +337,8 @@ void taglib_tag_free_strings() + if(!stringManagementEnabled) + return; + +- for(List::Iterator it = strings.begin(); it != strings.end(); ++it) +- free(*it); ++ for(auto &string : std::as_const(strings)) ++ free(string); + strings.clear(); + } + +@@ -248,25 +348,25 @@ int taglib_audioproperties_length(const TagLib_AudioPr + + int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties) + { +- const AudioProperties *p = reinterpret_cast(audioProperties); +- return p->length(); ++ auto p = reinterpret_cast(audioProperties); ++ return p->lengthInSeconds(); + } + + int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties) + { +- const AudioProperties *p = reinterpret_cast(audioProperties); ++ auto p = reinterpret_cast(audioProperties); + return p->bitrate(); + } + + int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties) + { +- const AudioProperties *p = reinterpret_cast(audioProperties); ++ auto p = reinterpret_cast(audioProperties); + return p->sampleRate(); + } + + int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties) + { +- const AudioProperties *p = reinterpret_cast(audioProperties); ++ auto p = reinterpret_cast(audioProperties); + return p->channels(); + } + +@@ -293,6 +393,423 @@ void taglib_id3v2_set_default_text_encoding(TagLib_ID3 + ID3v2::FrameFactory::instance()->setDefaultTextEncoding(type); + } + ++ ++/****************************************************************************** ++ * Properties API ++ ******************************************************************************/ ++namespace { ++ ++void _taglib_property_set(TagLib_File *file, const char* prop, const char* value, bool append) ++{ ++ if(file == NULL || prop == NULL) ++ return; ++ ++ auto tfile = reinterpret_cast(file); ++ PropertyMap map = tfile->tag()->properties(); ++ ++ if(value) { ++ auto property = map.find(prop); ++ if(property == map.end()) { ++ map.insert(prop, StringList(charArrayToString(value))); ++ } ++ else { ++ if(append) { ++ property->second.append(charArrayToString(value)); ++ } ++ else { ++ property->second = StringList(charArrayToString(value)); ++ } ++ } ++ } ++ else { ++ map.erase(prop); ++ } ++ ++ tfile->setProperties(map); ++} ++ ++} // namespace ++ ++void taglib_property_set(TagLib_File *file, const char *prop, const char *value) ++{ ++ _taglib_property_set(file, prop, value, false); ++} ++ ++void taglib_property_set_append(TagLib_File *file, const char *prop, const char *value) ++{ ++ _taglib_property_set(file, prop, value, true); ++} ++ ++char** taglib_property_keys(const TagLib_File *file) ++{ ++ if(file == NULL) ++ return NULL; ++ ++ const PropertyMap map = reinterpret_cast(file)->properties(); ++ if(map.isEmpty()) ++ return NULL; ++ ++ auto props = static_cast(malloc(sizeof(char *) * (map.size() + 1))); ++ char **pp = props; ++ ++ for(const auto &i : map) { ++ *pp++ = stringToCharArray(i.first); ++ } ++ *pp = NULL; ++ ++ return props; ++} ++ ++char **taglib_property_get(const TagLib_File *file, const char *prop) ++{ ++ if(file == NULL || prop == NULL) ++ return NULL; ++ ++ const PropertyMap map = reinterpret_cast(file)->properties(); ++ ++ auto property = map.find(prop); ++ if(property == map.end()) ++ return NULL; ++ ++ auto props = static_cast(malloc(sizeof(char *) * (property->second.size() + 1))); ++ char **pp = props; ++ ++ for(const auto &i : property->second) { ++ *pp++ = stringToCharArray(i); ++ } ++ *pp = NULL; ++ ++ return props; ++} ++ ++void taglib_property_free(char **props) ++{ ++ if(props == NULL) ++ return; ++ ++ char **p = props; ++ while(*p) { ++ free(*p++); ++ } ++ free(props); ++} ++ ++ ++/****************************************************************************** ++ * Complex Properties API ++ ******************************************************************************/ ++ ++namespace { ++ ++bool _taglib_complex_property_set( ++ TagLib_File *file, const char *key, ++ const TagLib_Complex_Property_Attribute **value, bool append) ++{ ++ if(file == NULL || key == NULL) ++ return false; ++ ++ auto tfile = reinterpret_cast(file); ++ ++ if(value == NULL) { ++ return tfile->setComplexProperties(key, {}); ++ } ++ ++ VariantMap map; ++ const TagLib_Complex_Property_Attribute** attrPtr = value; ++ while(*attrPtr) { ++ const TagLib_Complex_Property_Attribute *attr = *attrPtr; ++ String attrKey(attr->key); ++ switch(attr->value.type) { ++ case TagLib_Variant_Void: ++ map.insert(attrKey, Variant()); ++ break; ++ case TagLib_Variant_Bool: ++ map.insert(attrKey, attr->value.value.boolValue != 0); ++ break; ++ case TagLib_Variant_Int: ++ map.insert(attrKey, attr->value.value.intValue); ++ break; ++ case TagLib_Variant_UInt: ++ map.insert(attrKey, attr->value.value.uIntValue); ++ break; ++ case TagLib_Variant_LongLong: ++ map.insert(attrKey, attr->value.value.longLongValue); ++ break; ++ case TagLib_Variant_ULongLong: ++ map.insert(attrKey, attr->value.value.uLongLongValue); ++ break; ++ case TagLib_Variant_Double: ++ map.insert(attrKey, attr->value.value.doubleValue); ++ break; ++ case TagLib_Variant_String: ++ map.insert(attrKey, charArrayToString(attr->value.value.stringValue)); ++ break; ++ case TagLib_Variant_StringList: { ++ StringList strs; ++ if(attr->value.value.stringListValue) { ++ char **s = attr->value.value.stringListValue;; ++ while(*s) { ++ strs.append(charArrayToString(*s++)); ++ } ++ } ++ map.insert(attrKey, strs); ++ break; ++ } ++ case TagLib_Variant_ByteVector: ++ map.insert(attrKey, ByteVector(attr->value.value.byteVectorValue, ++ attr->value.size)); ++ break; ++ } ++ ++attrPtr; ++ } ++ ++ return append ? tfile->setComplexProperties(key, tfile->complexProperties(key).append(map)) ++ : tfile->setComplexProperties(key, {map}); ++} ++ ++} // namespace ++ ++BOOL taglib_complex_property_set( ++ TagLib_File *file, const char *key, ++ const TagLib_Complex_Property_Attribute **value) ++{ ++ return _taglib_complex_property_set(file, key, value, false); ++} ++ ++BOOL taglib_complex_property_set_append( ++ TagLib_File *file, const char *key, ++ const TagLib_Complex_Property_Attribute **value) ++{ ++ return _taglib_complex_property_set(file, key, value, true); ++} ++ ++char** taglib_complex_property_keys(const TagLib_File *file) ++{ ++ if(file == NULL) { ++ return NULL; ++ } ++ ++ const StringList strs = reinterpret_cast(file)->complexPropertyKeys(); ++ if(strs.isEmpty()) { ++ return NULL; ++ } ++ ++ auto keys = static_cast(malloc(sizeof(char *) * (strs.size() + 1))); ++ char **keyPtr = keys; ++ ++ for(const auto &str : strs) { ++ *keyPtr++ = stringToCharArray(str); ++ } ++ *keyPtr = NULL; ++ ++ return keys; ++} ++ ++TagLib_Complex_Property_Attribute*** taglib_complex_property_get( ++ const TagLib_File *file, const char *key) ++{ ++ if(file == NULL || key == NULL) { ++ return NULL; ++ } ++ ++ const auto variantMaps = reinterpret_cast(file)->complexProperties(key); ++ if(variantMaps.isEmpty()) { ++ return NULL; ++ } ++ ++ auto props = static_cast( ++ malloc(sizeof(TagLib_Complex_Property_Attribute **) * (variantMaps.size() + 1))); ++ TagLib_Complex_Property_Attribute ***propPtr = props; ++ ++ for(const auto &variantMap : variantMaps) { ++ if(!variantMap.isEmpty()) { ++ auto attrs = static_cast( ++ malloc(sizeof(TagLib_Complex_Property_Attribute *) * (variantMap.size() + 1))); ++ auto attr = static_cast( ++ malloc(sizeof(TagLib_Complex_Property_Attribute) * variantMap.size())); ++ TagLib_Complex_Property_Attribute **attrPtr = attrs; ++ // The next assignment is redundant to silence the clang analyzer, ++ // it is done at the end of the loop, which must be entered because ++ // variantMap is not empty. ++ *attrPtr = attr; ++ for(const auto &[k, v] : variantMap) { ++ attr->key = stringToCharArray(k); ++ attr->value.size = 0; ++ switch(v.type()) { ++ case Variant::Void: ++ attr->value.type = TagLib_Variant_Void; ++ attr->value.value.stringValue = NULL; ++ break; ++ case Variant::Bool: ++ attr->value.type = TagLib_Variant_Bool; ++ attr->value.value.boolValue = v.value(); ++ break; ++ case Variant::Int: ++ attr->value.type = TagLib_Variant_Int; ++ attr->value.value.intValue = v.value(); ++ break; ++ case Variant::UInt: ++ attr->value.type = TagLib_Variant_UInt; ++ attr->value.value.uIntValue = v.value(); ++ break; ++ case Variant::LongLong: ++ attr->value.type = TagLib_Variant_LongLong; ++ attr->value.value.longLongValue = v.value(); ++ break; ++ case Variant::ULongLong: ++ attr->value.type = TagLib_Variant_ULongLong; ++ attr->value.value.uLongLongValue = v.value(); ++ break; ++ case Variant::Double: ++ attr->value.type = TagLib_Variant_Double; ++ attr->value.value.doubleValue = v.value(); ++ break; ++ case Variant::String: { ++ attr->value.type = TagLib_Variant_String; ++ auto str = v.value(); ++ attr->value.value.stringValue = stringToCharArray(str); ++ attr->value.size = str.size(); ++ break; ++ } ++ case Variant::StringList: { ++ attr->value.type = TagLib_Variant_StringList; ++ auto strs = v.value(); ++ auto strPtr = static_cast(malloc(sizeof(char *) * (strs.size() + 1))); ++ attr->value.value.stringListValue = strPtr; ++ attr->value.size = strs.size(); ++ for(const auto &str : strs) { ++ *strPtr++ = stringToCharArray(str); ++ } ++ *strPtr = NULL; ++ break; ++ } ++ case Variant::ByteVector: { ++ attr->value.type = TagLib_Variant_ByteVector; ++ const ByteVector data = v.value(); ++ auto bytePtr = static_cast(malloc(data.size())); ++ attr->value.value.byteVectorValue = bytePtr; ++ attr->value.size = data.size(); ++ ::memcpy(bytePtr, data.data(), data.size()); ++ break; ++ } ++ case Variant::ByteVectorList: ++ case Variant::VariantList: ++ case Variant::VariantMap: { ++ attr->value.type = TagLib_Variant_String; ++ std::stringstream ss; ++ ss << v; ++ attr->value.value.stringValue = stringToCharArray(ss.str()); ++ break; ++ } ++ } ++ *attrPtr++ = attr++; ++ } ++ *attrPtr = NULL; ++ *propPtr++ = attrs; ++ } ++ } ++ *propPtr = NULL; ++ return props; ++} ++ ++void taglib_picture_from_complex_property( ++ TagLib_Complex_Property_Attribute*** properties, ++ TagLib_Complex_Property_Picture_Data *picture) ++{ ++ if(!properties || !picture) { ++ return; ++ } ++ std::memset(picture, 0, sizeof(*picture)); ++ TagLib_Complex_Property_Attribute*** propPtr = properties; ++ while(!picture->data && *propPtr) { ++ TagLib_Complex_Property_Attribute** attrPtr = *propPtr; ++ while(*attrPtr) { ++ TagLib_Complex_Property_Attribute *attr = *attrPtr; ++ switch(attr->value.type) { ++ case TagLib_Variant_String: ++ if(strcmp("mimeType", attr->key) == 0) { ++ picture->mimeType = attr->value.value.stringValue; ++ } ++ else if(strcmp("description", attr->key) == 0) { ++ picture->description = attr->value.value.stringValue; ++ } ++ else if(strcmp("pictureType", attr->key) == 0) { ++ picture->pictureType = attr->value.value.stringValue; ++ } ++ break; ++ case TagLib_Variant_ByteVector: ++ if(strcmp("data", attr->key) == 0) { ++ picture->data = attr->value.value.byteVectorValue; ++ picture->size = attr->value.size; ++ } ++ break; ++ default: ++ break; ++ } ++ ++attrPtr; ++ } ++ ++propPtr; ++ } ++} ++ ++void taglib_complex_property_free_keys(char **keys) ++{ ++ if(keys == NULL) { ++ return; ++ } ++ ++ char **k = keys; ++ while(*k) { ++ free(*k++); ++ } ++ free(keys); ++} ++ ++void taglib_complex_property_free( ++ TagLib_Complex_Property_Attribute ***props) ++{ ++ if(props == NULL) { ++ return; ++ } ++ TagLib_Complex_Property_Attribute*** propPtr = props; ++ while(*propPtr) { ++ TagLib_Complex_Property_Attribute** attrPtr = *propPtr; ++ while(*attrPtr) { ++ TagLib_Complex_Property_Attribute *attr = *attrPtr; ++ switch(attr->value.type) { ++ case TagLib_Variant_String: ++ free(attr->value.value.stringValue); ++ break; ++ case TagLib_Variant_StringList: ++ if(attr->value.value.stringListValue) { ++ char **s = attr->value.value.stringListValue; ++ while(*s) { ++ free(*s++); ++ } ++ free(attr->value.value.stringListValue); ++ } ++ break; ++ case TagLib_Variant_ByteVector: ++ free(attr->value.value.byteVectorValue); ++ break; ++ case TagLib_Variant_Void: ++ case TagLib_Variant_Bool: ++ case TagLib_Variant_Int: ++ case TagLib_Variant_UInt: ++ case TagLib_Variant_LongLong: ++ case TagLib_Variant_ULongLong: ++ case TagLib_Variant_Double: ++ break; ++ } ++ free(attr->key); ++ ++attrPtr; ++ } ++ free(**propPtr); ++ free(*propPtr++); ++ } ++ free(props); ++} ++ + //////////////////////////////////////////////////////////////////////////////// + // TagLib::MPEG::File wrapper + //////////////////////////////////////////////////////////////////////////////// +@@ -302,15 +819,18 @@ TagLib_Mpeg_File *taglib_mpeg_file(TagLib_File *file) + return reinterpret_cast(dynamic_cast(reinterpret_cast(file))); + } + +-BOOL taglib_mpeg_file_save3(TagLib_Mpeg_File *file, int tags, BOOL stripOthers, int id3v2Version) ++BOOL taglib_mpeg_file_save3(TagLib_Mpeg_File *file, int tags, BOOL stripOthers, int id3v2Version, BOOL duplicateTags) + { + MPEG::File *f=reinterpret_cast(file); +- return f->save(tags, (bool)stripOthers, id3v2Version); ++ return f->save(tags, ++ stripOthers ? File::StripOthers : File::StripNone, ++ id3v2Version == 3 ? ID3v2::v3 : ID3v2::v4, ++ duplicateTags ? File::Duplicate : File::DoNotDuplicate); + } + +-BOOL taglib_mpeg_file_strip(TagLib_Mpeg_File *file, int tags) ++BOOL taglib_mpeg_file_strip(TagLib_Mpeg_File *file, int tags, BOOL freeMemory) + { + MPEG::File *f=reinterpret_cast(file); +- return f->strip(tags); ++ return f->strip(tags, freeMemory); + + } diff --git a/converters/gbsdconv/files/patch-taglib_tag__c.h b/converters/gbsdconv/files/patch-taglib_tag__c.h new file mode 100644 index 000000000000..d63029d25d7a --- /dev/null +++ b/converters/gbsdconv/files/patch-taglib_tag__c.h @@ -0,0 +1,428 @@ +--- taglib/tag_c.h.orig 2014-02-15 21:45:54 UTC ++++ taglib/tag_c.h +@@ -29,7 +29,9 @@ extern "C" { + extern "C" { + #endif + +-#if defined(_WIN32) || defined(_WIN64) ++#if defined(TAGLIB_STATIC) ++#define TAGLIB_C_EXPORT ++#elif defined(_WIN32) || defined(_WIN64) + #ifdef MAKE_TAGLIB_C_LIB + #define TAGLIB_C_EXPORT __declspec(dllexport) + #else +@@ -41,7 +43,10 @@ extern "C" { + #define TAGLIB_C_EXPORT + #endif + +-#ifndef BOOL ++#ifdef _MSC_VER ++/* minwindef.h contains typedef int BOOL */ ++#include ++#elif !defined BOOL + #define BOOL int + #endif + +@@ -55,14 +60,15 @@ extern "C" { + *******************************************************************************/ + + /* +- * These are used for type provide some type safety to the C API (as opposed to +- * using void *, but pointers to them are simply cast to the corresponding C++ ++ * These are used to give the C API some type safety (as opposed to ++ * using void * ), but pointers to them are simply cast to the corresponding C++ *** 395 LINES SKIPPED ***