diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2360ada0..90feb9e5 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../taglib ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/toolkit ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/ape + ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/matroska ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v1 ${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2 @@ -38,6 +39,11 @@ target_link_libraries(framelist tag) add_executable(strip-id3v1 strip-id3v1.cpp) target_link_libraries(strip-id3v1 tag) +########### next target ############### + +add_executable(matroskareader matroskareader.cpp) +target_link_libraries(matroskareader tag) + install(TARGETS tagreader tagreader_c tagwriter framelist strip-id3v1 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/examples/matroskareader.cpp b/examples/matroskareader.cpp new file mode 100644 index 00000000..e1b6045b --- /dev/null +++ b/examples/matroskareader.cpp @@ -0,0 +1,52 @@ +#include +#include "matroskafile.h" +#include "matroskatag.h" +#include "matroskasimpletag.h" +#include "tstring.h" +#include "tutils.h" +#include "tbytevector.h" +#define GREEN_TEXT(s) "" s "" +#define PRINT_PRETTY(label, value) printf("" GREEN_TEXT(label) ": %s\n", value) + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + printf("Usage: matroskareader FILE\n"); + return 1; + } + TagLib::Matroska::File file(argv[1]); + if (!file.isValid()) { + printf("File is not valid\n"); + return 1; + } + auto tag = dynamic_cast(file.tag()); + if (!tag) { + printf("File has no tag\n"); + return 0; + } + + const TagLib::Matroska::SimpleTagsList &list = tag->simpleTagsList(); + printf("Found %i tags:\n\n", list.size()); + + for (TagLib::Matroska::SimpleTag *t : list) { + PRINT_PRETTY("Tag Name", t->name().toCString(true)); + + TagLib::Matroska::SimpleTagString *tString = nullptr; + TagLib::Matroska::SimpleTagBinary *tBinary = nullptr; + if ((tString = dynamic_cast(t))) + PRINT_PRETTY("Tag Value", tString->value().toCString(true)); + else if ((tBinary = dynamic_cast(t))) + PRINT_PRETTY("Tag Value", + TagLib::Utils::formatString("Binary with size %i", tBinary->value().size()).toCString(false) + ); + + auto targetTypeValue = static_cast(t->targetTypeValue()); + PRINT_PRETTY("Target Type Value", + targetTypeValue == 0 ? "None" : TagLib::Utils::formatString("%i", targetTypeValue).toCString(false) + ); + + printf("\n"); + } + + return 0; +} diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index 89f988aa..f833298d 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -5,6 +5,8 @@ set(tag_HDR_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2 ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2/frames ${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1 + ${CMAKE_CURRENT_SOURCE_DIR}/matroska + ${CMAKE_CURRENT_SOURCE_DIR}/matroska/ebml ) if(WITH_ASF) set(tag_HDR_DIRS ${tag_HDR_DIRS} @@ -66,7 +68,7 @@ if(WITH_SHORTEN) endif() include_directories(${tag_HDR_DIRS}) -set(tag_HDRS +set(tag_PUBLIC_HDRS tag.h fileref.h audioproperties.h @@ -90,6 +92,9 @@ set(tag_HDRS toolkit/tpropertymap.h toolkit/tdebuglistener.h toolkit/tversionnumber.h + matroska/matroskafile.h + matroska/matroskatag.h + matroska/matroskasimpletag.h mpeg/mpegfile.h mpeg/mpegproperties.h mpeg/mpegheader.h @@ -221,6 +226,34 @@ if(WITH_SHORTEN) ) endif() +set(tag_PRIVATE_HDRS + matroska/ebml/ebmlelement.h + matroska/ebml/ebmlmasterelement.h + matroska/ebml/ebmlmksegment.h + matroska/ebml/ebmlmktags.h + matroska/ebml/ebmlstringelement.h + matroska/ebml/ebmluintelement.h + matroska/ebml/ebmlutils.h +) + +set(tag_HDRS ${tag_PUBLIC_HDRS} ${tag_PRIVATE_HDRS}) + +set(matroska_SRCS + matroska/matroskafile.cpp + matroska/matroskasimpletag.cpp + matroska/matroskatag.cpp +) + +set(ebml_SRCS + matroska/ebml/ebmlelement.cpp + matroska/ebml/ebmlmasterelement.cpp + matroska/ebml/ebmlmksegment.cpp + matroska/ebml/ebmlmktags.cpp + matroska/ebml/ebmlstringelement.cpp + matroska/ebml/ebmluintelement.cpp + matroska/ebml/ebmlutils.cpp +) + set(mpeg_SRCS mpeg/mpegfile.cpp mpeg/mpegproperties.cpp @@ -429,7 +462,7 @@ set(toolkit_SRCS ) set(tag_LIB_SRCS - ${mpeg_SRCS} ${id3v1_SRCS} ${id3v2_SRCS} ${frames_SRCS} ${ogg_SRCS} + ${matroska_SRCS} ${ebml_SRCS} ${mpeg_SRCS} ${id3v1_SRCS} ${id3v2_SRCS} ${frames_SRCS} ${ogg_SRCS} ${vorbis_SRCS} ${oggflacs_SRCS} ${mpc_SRCS} ${ape_SRCS} ${toolkit_SRCS} ${flacs_SRCS} ${wavpack_SRCS} ${speex_SRCS} ${trueaudio_SRCS} ${riff_SRCS} ${aiff_SRCS} ${wav_SRCS} ${asf_SRCS} ${mp4_SRCS} ${mod_SRCS} ${s3m_SRCS} ${it_SRCS} ${xm_SRCS} ${opus_SRCS} @@ -458,8 +491,13 @@ set_target_properties(tag PROPERTIES SOVERSION ${TAGLIB_SOVERSION_MAJOR} INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR} DEFINE_SYMBOL MAKE_TAGLIB_LIB +<<<<<<< HEAD INTERFACE_LINK_LIBRARIES "${ZLIB_INTERFACE_LINK_LIBRARIES}" PUBLIC_HEADER "${tag_HDRS}" +======= + LINK_INTERFACE_LIBRARIES "" + PUBLIC_HEADER "${tag_PUBLIC_HDRS}" +>>>>>>> 770c1012 (Initial matroska support) ) if(NOT BUILD_SHARED_LIBS) target_compile_definitions(tag PUBLIC TAGLIB_STATIC) diff --git a/taglib/matroska/ebml/ebmlelement.cpp b/taglib/matroska/ebml/ebmlelement.cpp new file mode 100644 index 00000000..13129812 --- /dev/null +++ b/taglib/matroska/ebml/ebmlelement.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlelement.h" +#include "ebmlmasterelement.h" +#include "ebmlmksegment.h" +#include "ebmlmktags.h" +#include "ebmlstringelement.h" +#include "ebmluintelement.h" +#include "ebmlutils.h" +#include "tfile.h" +#include "tdebug.h" +#include "tutils.h" + +using namespace TagLib; + +EBML::Element* EBML::Element::factory(File &file) +{ + // Get the element ID + Id id = readId(file); + if (!id) { + debug("Failed to parse EMBL ElementID"); + return nullptr; + } + + // Get the size length and data length + const auto& [sizeLength, dataSize] = readVINT(file); + if (!sizeLength) + return nullptr; + + // Return the subclass + switch(id) { + case EBML_ID_HEAD: + return new Element(id, sizeLength, dataSize); + + case EBML_ID_MK_SEGMENT: + return new MkSegment(sizeLength, dataSize); + + case EBML_ID_MK_TAGS: + return new MkTags(sizeLength, dataSize); + + case EBML_ID_MK_TAG: + case EBML_ID_MK_TAG_TARGETS: + case EBML_ID_MK_SIMPLE_TAG: + return new MasterElement(id, sizeLength, dataSize); + + case EBML_ID_MK_TAG_NAME: + case EBML_ID_MK_TAG_STRING: + return new UTF8StringElement(id, sizeLength, dataSize); + + case EBML_ID_MK_TAG_LANGUAGE: + return new Latin1StringElement(id, sizeLength, dataSize); + + case EBML_ID_MK_TARGET_TYPE_VALUE: + return new UIntElement(id, sizeLength, dataSize); + + default: + return new Element(id, sizeLength, dataSize); + } + + return nullptr; +} + +void EBML::Element::skipData(File &file) +{ + file.seek(dataSize, File::Position::Current); +} diff --git a/taglib/matroska/ebml/ebmlelement.h b/taglib/matroska/ebml/ebmlelement.h new file mode 100644 index 00000000..db662293 --- /dev/null +++ b/taglib/matroska/ebml/ebmlelement.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_EBMLELEMENT_H +#define TAGLIB_EBMLELEMENT_H +#ifndef DO_NOT_DOCUMENT + +#include "tfile.h" +#include "ebmlutils.h" +#include "taglib.h" + +namespace TagLib { + namespace EBML { + class Element + { + public: + Element(Id id, int sizeLength, offset_t dataSize) + : id(id), sizeLength(sizeLength), dataSize(dataSize) + {} + virtual ~Element() = default; + virtual bool isMaster() const { return false; } + virtual bool read(File &file) { + skipData(file); + return true; + } + void skipData(File &file); + Id getId() const { return id; } + int getSizeLength() const { return sizeLength; } + int64_t getDataSize() const { return dataSize; } + static Element* factory(File &file); + + protected: + Id id; + int sizeLength; + offset_t dataSize; + }; + } +} + + +#endif +#endif diff --git a/taglib/matroska/ebml/ebmlmasterelement.cpp b/taglib/matroska/ebml/ebmlmasterelement.cpp new file mode 100644 index 00000000..a3595c8b --- /dev/null +++ b/taglib/matroska/ebml/ebmlmasterelement.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlmasterelement.h" +#include "ebmlutils.h" +#include "matroskafile.h" + +#include "tfile.h" +#include "tdebug.h" +#include "tutils.h" + +using namespace TagLib; + +EBML::MasterElement::~MasterElement() +{ + for (auto element : elements) + delete element; +} + +bool EBML::MasterElement::read(File &file) +{ + offset_t maxOffset = file.tell() + dataSize; + Element *element = nullptr; + while ((element = findNextElement(file, maxOffset))) { + if (!element->read(file)) + return false; + elements.append(element); + } + return file.tell() == maxOffset; +} diff --git a/taglib/matroska/ebml/ebmlmasterelement.h b/taglib/matroska/ebml/ebmlmasterelement.h new file mode 100644 index 00000000..8f769db3 --- /dev/null +++ b/taglib/matroska/ebml/ebmlmasterelement.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_EBMLMASTERELEMENT_H +#define TAGLIB_EBMLMASTERELEMENT_H +#ifndef DO_NOT_DOCUMENT + +#include "ebmlelement.h" +#include "ebmlutils.h" +#include "tlist.h" +#include "taglib.h" + +namespace TagLib { + namespace EBML { + class MasterElement : public Element + { + public: + MasterElement(Id id, int sizeLength, offset_t dataSize) + : Element(id, sizeLength, dataSize) + {} + ~MasterElement() override; + virtual bool isMaster() const override { return true; } + virtual bool read(File &file) override; + List::Iterator begin () { return elements.begin(); } + List::Iterator end () { return elements.end(); } + List::ConstIterator cbegin () const { return elements.cbegin(); } + List::ConstIterator cend () const { return elements.cend(); } + + protected: + List elements; + }; + + } +} + + +#endif +#endif diff --git a/taglib/matroska/ebml/ebmlmksegment.cpp b/taglib/matroska/ebml/ebmlmksegment.cpp new file mode 100644 index 00000000..e22537fa --- /dev/null +++ b/taglib/matroska/ebml/ebmlmksegment.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlmksegment.h" +#include "ebmlmktags.h" +#include "ebmlutils.h" +#include "matroskafile.h" +#include "matroskatag.h" +#include "tutils.h" +#include "tdebug.h" + +using namespace TagLib; + +EBML::MkSegment::~MkSegment() +{ + delete tags; +} + +bool EBML::MkSegment::read(File &file) +{ + offset_t maxOffset = file.tell() + dataSize; + tags = static_cast(findElement(file, EBML_ID_MK_TAGS, maxOffset)); + if (tags && !tags->read(file)) + return false; + return true; +} + +Matroska::Tag* EBML::MkSegment::parseTag() +{ + return tags ? tags->parse() : nullptr; +} diff --git a/taglib/matroska/ebml/ebmlmksegment.h b/taglib/matroska/ebml/ebmlmksegment.h new file mode 100644 index 00000000..a3a17375 --- /dev/null +++ b/taglib/matroska/ebml/ebmlmksegment.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlmasterelement.h" +#include "taglib.h" + +#ifndef TAGLIB_EBMLMKSEGMENT_H +#define TAGLIB_EBMLMKSEGMENT_H +#ifndef DO_NOT_DOCUMENT + +namespace TagLib { + namespace Matroska { + class Tag; + } + namespace EBML { + class Tags; + class MkTags; + class MkSegment : public MasterElement + { + public: + MkSegment(int sizeLength, offset_t dataSize) + : MasterElement(EBML_ID_MK_SEGMENT, sizeLength, dataSize) + {} + ~MkSegment() override; + bool read(File &file) override; + Matroska::Tag* parseTag(); + + private: + MkTags *tags = nullptr; + + }; + } +} + +#endif +#endif diff --git a/taglib/matroska/ebml/ebmlmktags.cpp b/taglib/matroska/ebml/ebmlmktags.cpp new file mode 100644 index 00000000..c088cae9 --- /dev/null +++ b/taglib/matroska/ebml/ebmlmktags.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlmktags.h" +#include "ebmluintelement.h" +#include "ebmlstringelement.h" +#include "ebmlutils.h" +#include "matroskafile.h" +#include "matroskatag.h" +#include "matroskasimpletag.h" +#include "tlist.h" +#include "tdebug.h" +#include "tutils.h" + +using namespace TagLib; + +Matroska::Tag* EBML::MkTags::parse() +{ + auto mTag = new Matroska::Tag(); + + // Loop through each element + for (auto tagsChild : elements) { + if (tagsChild->getId() != EBML_ID_MK_TAG) + continue; + auto tag = static_cast(tagsChild); + List simpleTags; + MasterElement *targets = nullptr; + + // Identify the element and the elements + for (auto tagChild : *tag) { + Id tagChildId = tagChild->getId(); + if (!targets && tagChildId == EBML_ID_MK_TAG_TARGETS) + targets = static_cast(tagChild); + else if (tagChildId == EBML_ID_MK_SIMPLE_TAG) + simpleTags.append(static_cast(tagChild)); + } + + // Parse the element + Matroska::Tag::TargetTypeValue targetTypeValue = Matroska::Tag::TargetTypeValue::None; + if (targets) { + for (auto targetsChild : *targets) { + Id id = targetsChild->getId(); + if (id == EBML_ID_MK_TARGET_TYPE_VALUE + && targetTypeValue == Matroska::Tag::TargetTypeValue::None) { + targetTypeValue = static_cast( + static_cast(targetsChild)->getValue() + ); + } + } + } + + // Parse each + for (auto simpleTag : simpleTags) { + const String *tagName = nullptr; + const String *tagValueString = nullptr; + const ByteVector *tagValueBinary = nullptr; + + for (auto simpleTagChild : *simpleTag) { + Id id = simpleTagChild->getId(); + if (id == EBML_ID_MK_TAG_NAME && !tagName) + tagName = &(static_cast(simpleTagChild)->getValue()); + else if (id == EBML_ID_MK_TAG_STRING && !tagValueString) + tagValueString = &(static_cast(simpleTagChild)->getValue()); + } + if (!tagName || (tagValueString && tagValueBinary) || (!tagValueString && !tagValueBinary)) + continue; + + // Create a Simple Tag object and add it to the Tag object + Matroska::SimpleTag *sTag = nullptr; + if (tagValueString) { + auto sTagString = new Matroska::SimpleTagString(targetTypeValue); + sTagString->setValue(*tagValueString); + sTag = sTagString; + } + else if (tagValueBinary) { + auto sTagBinary = new Matroska::SimpleTagBinary(targetTypeValue); + sTagBinary->setValue(*tagValueBinary); + sTag = sTagBinary; + } + sTag->setName(*tagName); + mTag->addSimpleTag(sTag); + } + } + return mTag; +} diff --git a/taglib/matroska/ebml/ebmlmktags.h b/taglib/matroska/ebml/ebmlmktags.h new file mode 100644 index 00000000..a54748de --- /dev/null +++ b/taglib/matroska/ebml/ebmlmktags.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlmasterelement.h" +#include "ebmlutils.h" +#include "taglib.h" + +#ifndef TAGLIB_EBMLMKTAGS_H +#define TAGLIB_EBMLMKTAGS_H +#ifndef DO_NOT_DOCUMENT + +namespace TagLib { + namespace Matroska { + class Tag; + } + //class Matroska::Tag; + namespace EBML { + class MkTags : public MasterElement + { + public: + MkTags(int sizeLength, offset_t dataSize) + : MasterElement(EBML_ID_MK_TAGS, sizeLength, dataSize) + {} + //virtual void read(File &file) override; + Matroska::Tag* parse(); + + }; + } +} +#endif +#endif diff --git a/taglib/matroska/ebml/ebmlstringelement.cpp b/taglib/matroska/ebml/ebmlstringelement.cpp new file mode 100644 index 00000000..e2cc51e7 --- /dev/null +++ b/taglib/matroska/ebml/ebmlstringelement.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlstringelement.h" +#include "tfile.h" +#include "tstring.h" +#include "tbytevector.h" +#include "tdebug.h" + +using namespace TagLib; + +template +bool EBML::StringElement::read(TagLib::File &file) +{ + ByteVector buffer = file.readBlock(dataSize); + if (buffer.size() != dataSize) { + debug("Failed to read string"); + return false; + } + + // The EBML strings aren't supposed to be null-terminated, + // but we'll check for it and stip the null terminator if found + int nullByte = buffer.find('\0'); + if (nullByte >= 0) + buffer = ByteVector(buffer.data(), nullByte); + value = String(buffer, t); + return true; +} +template bool EBML::StringElement::read(TagLib::File &file); +template bool EBML::StringElement::read(TagLib::File &file); diff --git a/taglib/matroska/ebml/ebmlstringelement.h b/taglib/matroska/ebml/ebmlstringelement.h new file mode 100644 index 00000000..c9c59d94 --- /dev/null +++ b/taglib/matroska/ebml/ebmlstringelement.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_EBMLSTRINGELEMENT_H +#define TAGLIB_EBMLSTRINGELEMENT_H +#ifndef DO_NOT_DOCUMENT + +#include +#include "ebmlelement.h" +#include "ebmlutils.h" +#include "tstring.h" + +namespace TagLib { + class File; + namespace EBML { + template + class StringElement : public Element + { + public: + StringElement(Id id, int sizeLength, offset_t dataSize) + : Element(id, sizeLength, dataSize) + {} + const String& getValue() const { return value; } + void setValue(const String &value) { this->value = value; } + //template + bool read(File &file) override; + + private: + String value; + }; + + using UTF8StringElement = StringElement; + using Latin1StringElement = StringElement; + } +} + +#endif +#endif diff --git a/taglib/matroska/ebml/ebmluintelement.cpp b/taglib/matroska/ebml/ebmluintelement.cpp new file mode 100644 index 00000000..f0d2c6b8 --- /dev/null +++ b/taglib/matroska/ebml/ebmluintelement.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmluintelement.h" +#include "ebmlutils.h" +#include "tbytevector.h" +#include "tfile.h" +#include "tdebug.h" + +using namespace TagLib; + +bool EBML::UIntElement::read(TagLib::File &file) +{ + ByteVector buffer = file.readBlock(dataSize); + if (buffer.size() != dataSize) { + debug("Failed to read EBML Uint element"); + return false; + } + const auto& [sizeLength, value] = parseVINT(buffer); + if (!sizeLength) { + debug("Failed to parse VINT"); + return false; + } + this->value = value; + return true; +} diff --git a/taglib/matroska/ebml/ebmluintelement.h b/taglib/matroska/ebml/ebmluintelement.h new file mode 100644 index 00000000..1464a3c3 --- /dev/null +++ b/taglib/matroska/ebml/ebmluintelement.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_EBMLUINTELEMENT_H +#define TAGLIB_EBMLUINTELEMENT_H +#ifndef DO_NOT_DOCUMENT + +#include +#include "ebmlelement.h" + +namespace TagLib { + class File; + + namespace EBML { + class UIntElement : public Element + { + public: + UIntElement(Id id, int sizeLength, offset_t dataSize) + : Element(id, sizeLength, dataSize) + {} + unsigned int getValue() const { return value; } + void setValue(unsigned int value) { this->value = value; } + bool read(File &file) override; + + private: + uint64_t value = 0; + + //protected: + + + }; + } +} + +#endif +#endif diff --git a/taglib/matroska/ebml/ebmlutils.cpp b/taglib/matroska/ebml/ebmlutils.cpp new file mode 100644 index 00000000..0b3418b1 --- /dev/null +++ b/taglib/matroska/ebml/ebmlutils.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "ebmlutils.h" +#include "ebmlelement.h" +#include "tbytevector.h" +#include "matroskafile.h" + +#include "tdebug.h" +#include "tutils.h" +#include "taglib.h" + +using namespace TagLib; + +namespace TagLib::EBML { + template + unsigned int getNumBytes(uint8_t firstByte); +} + + +EBML::Element* EBML::findElement(File &file, EBML::Id id, offset_t maxOffset) +{ + Element *element = nullptr; + while (file.tell() < maxOffset) { + element = Element::factory(file); + if (!element || element->getId() == id) + return element; + element->skipData(file); + delete element; + element = nullptr; + } + return element; +} + +EBML::Element* EBML::findNextElement(File &file, offset_t maxOffset) +{ + return file.tell() < maxOffset ? Element::factory(file) : nullptr; +} + +template +unsigned int EBML::getNumBytes(uint8_t firstByte) +{ + static_assert(maxSizeLength >= 1 && maxSizeLength <= 8); + if (!firstByte) { + debug("VINT with greater than 8 bytes not allowed"); + return 0; + } + uint8_t mask = 0b10000000; + unsigned int numBytes = 1; + while (!(mask & firstByte)) { + numBytes++; + mask >>= 1; + } + if (numBytes > maxSizeLength) { + debug(Utils::formatString("VINT size length exceeds %i bytes", maxSizeLength)); + return 0; + } + return numBytes; +} + +EBML::Id EBML::readId(File &file) +{ + auto buffer = file.readBlock(1); + if (buffer.size() != 1) { + debug("Failed to read VINT size"); + return 0; + } + unsigned int nb_bytes = getNumBytes<4>(*buffer.begin()); + if (!nb_bytes) + return 0; + if (nb_bytes > 1) + buffer.append(file.readBlock(nb_bytes - 1)); + if (buffer.size() != nb_bytes) { + debug("Failed to read VINT data"); + return 0; + } + return buffer.toUInt(true); +} + +template +std::pair EBML::readVINT(File &file) +{ + static_assert(sizeof(T) == 8); + auto buffer = file.readBlock(1); + if (buffer.size() != 1) { + debug("Failed to read VINT size"); + return {0, 0}; + } + unsigned int nb_bytes = getNumBytes<8>(*buffer.begin()); + if (!nb_bytes) + return {0, 0}; + + if (nb_bytes > 1) + buffer.append(file.readBlock(nb_bytes - 1)); + int bits_to_shift = (sizeof(T) * 8) - (7 * nb_bytes); + offset_t mask = 0xFFFFFFFFFFFFFFFF >> bits_to_shift; + return { nb_bytes, static_cast(buffer.toLongLong(true)) & mask }; +} +namespace TagLib::EBML { + template std::pair readVINT(File &file); + template std::pair readVINT(File &file); +} + +template +std::pair EBML::parseVINT(const ByteVector &buffer) +{ + if (buffer.isEmpty()) + return {0, 0}; + + unsigned int numBytes = getNumBytes<8>(*buffer.begin()); + if (!numBytes) + return {0, 0}; + + int bits_to_shift = (sizeof(T) * 8) - (7 * numBytes); + offset_t mask = 0xFFFFFFFFFFFFFFFF >> bits_to_shift; + return { numBytes, static_cast(buffer.toLongLong(true)) & mask }; +} +namespace TagLib::EBML { + template std::pair parseVINT(const ByteVector &buffer); + template std::pair parseVINT(const ByteVector &buffer); +} diff --git a/taglib/matroska/ebml/ebmlutils.h b/taglib/matroska/ebml/ebmlutils.h new file mode 100644 index 00000000..eae0d520 --- /dev/null +++ b/taglib/matroska/ebml/ebmlutils.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_EBMLUTILS_H +#define TAGLIB_EBMLUTILS_H +#ifndef DO_NOT_DOCUMENT + +#include +#include +#include "taglib.h" + +#define EBML_ID_HEAD 0x1A45DFA3 +#define EBML_ID_MK_SEGMENT 0x18538067 +#define EBML_ID_MK_TAGS 0x1254C367 +#define EBML_ID_MK_TAG 0x7373 +#define EBML_ID_MK_TAG_TARGETS 0x63C0 +#define EBML_ID_MK_TARGET_TYPE_VALUE 0x68CA +#define EBML_ID_MK_SIMPLE_TAG 0x67C8 +#define EBML_ID_MK_TAG_NAME 0x45A3 +#define EBML_ID_MK_TAG_LANGUAGE 0x447A +#define EBML_ID_MK_TAG_STRING 0x4487 + +namespace TagLib { + class File; + class ByteVector; + + namespace EBML { + class Element; + using Id = unsigned int; + + Id readId(File &file); + template + std::pair readVINT(File &file); + template + std::pair parseVINT(const ByteVector &buffer); + Element* findElement(File &file, EBML::Id id, offset_t maxLength); + Element* findNextElement(File &file, offset_t maxOffset); + + } +} + +#endif +#endif diff --git a/taglib/matroska/matroskafile.cpp b/taglib/matroska/matroskafile.cpp new file mode 100644 index 00000000..cbab7f25 --- /dev/null +++ b/taglib/matroska/matroskafile.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "matroskafile.h" +#include "matroskatag.h" +#include "ebmlutils.h" +#include "ebmlelement.h" +#include "ebmlmksegment.h" +#include "tlist.h" +#include "tdebug.h" +#include "tutils.h" + +#include + +using namespace TagLib; + +class Matroska::File::FilePrivate +{ +public: + FilePrivate() {} + + ~FilePrivate() + { + delete tag; + } + + FilePrivate(const FilePrivate &) = delete; + FilePrivate &operator=(const FilePrivate &) = delete; + Matroska::Tag *tag = nullptr; + + //Properties *properties = nullptr; +}; + +Matroska::File::File(FileName file, bool readProperties) +: TagLib::File(file), + d(std::make_unique()) +{ + if (!isOpen()) { + debug("Failed to open matroska file"); + setValid(false); + return; + } + read(readProperties); +} +Matroska::File::~File() = default; + +TagLib::Tag* Matroska::File::tag() const +{ + return d->tag; +} + +void Matroska::File::read(bool readProperties) +{ + offset_t fileLength = length(); + + // Find the EBML Header + std::unique_ptr head(EBML::Element::factory(*this)); + if (!head || head->getId() != EBML_ID_HEAD) { + debug("Failed to find EBML head"); + setValid(false); + return; + } + head->skipData(*this); + + // Find the Matroska segment + std::unique_ptr segment( + static_cast(EBML::findElement(*this, EBML_ID_MK_SEGMENT, fileLength - tell())) + ); + if (!segment) { + debug("Failed to find Matroska segment"); + setValid(false); + return; + } + if (!segment->read(*this)) { + debug("Failed to read segment"); + setValid(false); + return; + } + d->tag = segment->parseTag(); + +} diff --git a/taglib/matroska/matroskafile.h b/taglib/matroska/matroskafile.h new file mode 100644 index 00000000..4d3a46b8 --- /dev/null +++ b/taglib/matroska/matroskafile.h @@ -0,0 +1,64 @@ +/*************************************************************************** + copyright : (C) 2002 - 2008 by Scott Wheeler + email : wheeler@kde.org + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef HAS_MATROSKAFILE_H +#define HAS_MATROSKAFILE_H + +#include "taglib_export.h" +#include "tfile.h" +#include "tag.h" + + +namespace TagLib { + namespace Matroska { + class Properties; + class TAGLIB_EXPORT File : public TagLib::File + { + public: + File(FileName file, bool readProperties = true); + ~File() override; + File(const File &) = delete; + File &operator=(const File &) = delete; + AudioProperties *audioProperties() const override { return nullptr; } + TagLib::Tag *tag() const override; + bool save() override { return false; } + //PropertyMap properties() const override { return PropertyMap(); } + //void removeUnsupportedProperties(const StringList &properties) override { } + private: + void read(bool readProperties); + class FilePrivate; + std::unique_ptr d; + + }; + } +} + + + + + + + + #endif \ No newline at end of file diff --git a/taglib/matroska/matroskaproperties.h b/taglib/matroska/matroskaproperties.h new file mode 100644 index 00000000..a3a735f3 --- /dev/null +++ b/taglib/matroska/matroskaproperties.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef TAGLIB_MATROSKAPROPERTIES_H +#define TAGLIB_MATROSKAPROPERTIES_H + +#include "taglib_export.h" +#include "audioproperties.h" + + +namespace TagLib { + + namespace MPEG { + + class File; + + //! An implementation of audio property reading for MP3 + + /*! + * This reads the data from an MPEG Layer III stream found in the + * AudioProperties API. + */ + + class TAGLIB_EXPORT Properties : public AudioProperties + { + public: + + /*! + * Destroys this MPEG Properties instance. + */ + ~Properties() override {} + + Properties(const Properties &) = delete; + Properties &operator=(const Properties &) = delete; + + /*! + * Returns the length of the file in milliseconds. + * + * \see lengthInSeconds() + */ + int lengthInMilliseconds() const override {} + + /*! + * Returns the average bit rate of the file in kb/s. + */ + int bitrate() const override {} + + /*! + * Returns the sample rate in Hz. + */ + int sampleRate() const override {} + + /*! + * Returns the number of audio channels. + */ + int channels() const override {} + + private: + + class PropertiesPrivate; + std::unique_ptr d; + }; + } // namespace MPEG +} // namespace TagLib + +#endif diff --git a/taglib/matroska/matroskasimpletag.cpp b/taglib/matroska/matroskasimpletag.cpp new file mode 100644 index 00000000..923fc11f --- /dev/null +++ b/taglib/matroska/matroskasimpletag.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "matroskasimpletag.h" +#include "matroskatag.h" +#include "tstring.h" +#include "tbytevector.h" + +using namespace TagLib; + +class Matroska::SimpleTag::SimpleTagPrivate +{ + public: + SimpleTagPrivate() = default; + Tag::TargetTypeValue targetTypeValue; + String name; + +}; + +class Matroska::SimpleTagString::SimpleTagStringPrivate +{ + public: + SimpleTagStringPrivate() = default; + String value; + +}; + +class Matroska::SimpleTagBinary::SimpleTagBinaryPrivate +{ + public: + SimpleTagBinaryPrivate() = default; + ByteVector value; + +}; + +Matroska::SimpleTag::SimpleTag(Tag::TargetTypeValue targetTypeValue) +: d(std::make_unique()) +{ + d->targetTypeValue = targetTypeValue; +} +Matroska::SimpleTag::~SimpleTag() = default; + + +Matroska::Tag::TargetTypeValue Matroska::SimpleTag::targetTypeValue() const +{ + return d->targetTypeValue; +} + +void Matroska::SimpleTag::setTargetTypeValue(Matroska::Tag::TargetTypeValue targetTypeValue) +{ + d->targetTypeValue = targetTypeValue; +} + +const String& Matroska::SimpleTag::name() const +{ + return d->name; +} + +void Matroska::SimpleTag::setName(const String &name) +{ + d->name = name; +} + +Matroska::SimpleTagString::SimpleTagString(Tag::TargetTypeValue targetTypeValue) +: Matroska::SimpleTag(targetTypeValue), + dd(std::make_unique()) +{ + +} +Matroska::SimpleTagString::~SimpleTagString() = default; + +const String& Matroska::SimpleTagString::value() const +{ + return dd->value; +} + +void Matroska::SimpleTagString::setValue(const String &value) +{ + dd->value = value; +} + +Matroska::SimpleTagBinary::SimpleTagBinary(Tag::TargetTypeValue targetTypeValue) +: Matroska::SimpleTag(targetTypeValue), + dd(std::make_unique()) +{ + +} +Matroska::SimpleTagBinary::~SimpleTagBinary() = default; + +const ByteVector& Matroska::SimpleTagBinary::value() const +{ + return dd->value; +} + +void Matroska::SimpleTagBinary::setValue(const ByteVector &value) +{ + dd->value = value; +} diff --git a/taglib/matroska/matroskasimpletag.h b/taglib/matroska/matroskasimpletag.h new file mode 100644 index 00000000..52df0db0 --- /dev/null +++ b/taglib/matroska/matroskasimpletag.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef HAS_MATROSKASIMPLETAG_H +#define HAS_MATROSKASIMPLETAG_H + +#include +#include "tag.h" +#include "matroskatag.h" + +namespace TagLib { + class String; + class ByteVector; + namespace Matroska { + class TAGLIB_EXPORT SimpleTag + { + public: + const String& name() const; + Tag::TargetTypeValue targetTypeValue() const; + void setTargetTypeValue(Tag::TargetTypeValue targetTypeValue); + void setName(const String &name); + virtual ~SimpleTag(); + + private: + class SimpleTagPrivate; + std::unique_ptr d; + + protected: + SimpleTag(Tag::TargetTypeValue targetTypeValue); + }; + + class TAGLIB_EXPORT SimpleTagString : public SimpleTag + { + public: + SimpleTagString(Tag::TargetTypeValue targetTypeValue); + ~SimpleTagString() override; + const String& value() const; + void setValue(const String &value); + + private: + class SimpleTagStringPrivate; + std::unique_ptr dd; + }; + + class TAGLIB_EXPORT SimpleTagBinary : public SimpleTag + { + public: + SimpleTagBinary(Tag::TargetTypeValue targetTypeValue); + ~SimpleTagBinary() override; + const ByteVector& value() const; + void setValue(const ByteVector &value); + + private: + class SimpleTagBinaryPrivate; + std::unique_ptr dd; + }; + + } +} + +#endif diff --git a/taglib/matroska/matroskatag.cpp b/taglib/matroska/matroskatag.cpp new file mode 100644 index 00000000..d7fec1b0 --- /dev/null +++ b/taglib/matroska/matroskatag.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#include "matroskatag.h" +#include "matroskasimpletag.h" +#include "tlist.h" +#include "tdebug.h" + +using namespace TagLib; + +class Matroska::Tag::TagPrivate +{ + public: + TagPrivate() = default; + ~TagPrivate() { + for (auto tag : tags) + delete tag; + } + List tags; + +}; + +Matroska::Tag::Tag() +: TagLib::Tag(), + d(std::make_unique()) +{ + +} +Matroska::Tag::~Tag() = default; + +void Matroska::Tag::addSimpleTag(SimpleTag *tag) +{ + d->tags.append(tag); +} + +void Matroska::Tag::removeSimpleTag(SimpleTag *tag) +{ + auto it = d->tags.find(tag); + if (it != d->tags.end()) + d->tags.erase(it); +} + +const Matroska::SimpleTagsList& Matroska::Tag::simpleTagsList() const +{ + return d->tags; +} diff --git a/taglib/matroska/matroskatag.h b/taglib/matroska/matroskatag.h new file mode 100644 index 00000000..af5f9e3b --- /dev/null +++ b/taglib/matroska/matroskatag.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * + * 02110-1301 USA * + * * + * Alternatively, this file is available under the Mozilla Public * + * License Version 1.1. You may obtain a copy of the License at * + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + +#ifndef HAS_MATROSKATAG_H +#define HAS_MATROSKATAG_H + +#include + +#include "tag.h" +#include "tstring.h" +#include "tlist.h" +//#include "matroskasimpletag.h + +namespace TagLib { + namespace Matroska { + class SimpleTag; + using SimpleTagsList = List; + class TAGLIB_EXPORT Tag : public TagLib::Tag + { + public: + enum TargetTypeValue { + None = 0, + Shot = 10, + Subtrack = 20, + Track = 30, + Part = 40, + Album = 50, + Edition = 60, + Collection = 70 + }; + Tag(); + ~Tag() override; + void addSimpleTag(SimpleTag *tag); + void removeSimpleTag(SimpleTag *tag); + const SimpleTagsList& simpleTagsList() const; + String title() const override { return ""; } + String artist() const override { return ""; } + String album() const override { return ""; } + String comment() const override { return ""; } + String genre() const override { return ""; } + unsigned int year() const override { return 0; } + unsigned int track() const override { return 0; } + void setTitle(const String &s) override {} + void setArtist(const String &s) override {} + void setAlbum(const String &s) override {} + void setComment(const String &s) override {} + void setGenre(const String &s) override {} + void setYear(unsigned int i) override {} + void setTrack(unsigned int i) override {} + bool isEmpty() const override { return false; } + + private: + class TagPrivate; + std::unique_ptr d; + }; + } +} + +#endif