mirror of
https://github.com/taglib/taglib.git
synced 2026-06-13 09:49:18 -04:00
Apply TagLib code formatting, fix static analysis issues
This commit is contained in:
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
const TagLib::Matroska::SimpleTagsList &list = tag->simpleTagsList();
|
||||
printf("Found %u tag(s):\n", list.size());
|
||||
|
||||
|
||||
for(TagLib::Matroska::SimpleTag *t : list) {
|
||||
PRINT_PRETTY("Tag Name", t->name().toCString(true));
|
||||
|
||||
@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
|
||||
if((tString = dynamic_cast<TagLib::Matroska::SimpleTagString*>(t)))
|
||||
PRINT_PRETTY("Tag Value", tString->value().toCString(true));
|
||||
else if((tBinary = dynamic_cast<TagLib::Matroska::SimpleTagBinary*>(t)))
|
||||
PRINT_PRETTY("Tag Value",
|
||||
PRINT_PRETTY("Tag Value",
|
||||
TagLib::Utils::formatString("Binary with size %i", tBinary->value().size()).toCString(false)
|
||||
);
|
||||
|
||||
|
||||
@@ -228,21 +228,21 @@ if(WITH_SHORTEN)
|
||||
endif()
|
||||
if(WITH_MATROSKA)
|
||||
set(tag_HDRS ${tag_HDRS}
|
||||
matroska/matroskafile.h
|
||||
matroska/matroskatag.h
|
||||
matroska/matroskasimpletag.h
|
||||
matroska/matroskaattachedfile.h
|
||||
matroska/matroskaattachments.h
|
||||
matroska/matroskafile.h
|
||||
matroska/matroskatag.h
|
||||
matroska/matroskasimpletag.h
|
||||
matroska/matroskacues.h
|
||||
matroska/matroskaelement.h
|
||||
matroska/matroskafile.h
|
||||
matroska/matroskaproperties.h
|
||||
matroska/matroskaseekhead.h
|
||||
matroska/matroskasegment.h
|
||||
matroska/matroskasimpletag.h
|
||||
matroska/matroskatag.h
|
||||
matroska/ebml/ebmlbinaryelement.h
|
||||
matroska/ebml/ebmlelement.h
|
||||
matroska/ebml/ebmlmasterelement.h
|
||||
matroska/ebml/ebmlmkattachments.h
|
||||
matroska/ebml/ebmlmkcues.h
|
||||
matroska/ebml/ebmlmkseekhead.h
|
||||
matroska/ebml/ebmlmksegment.h
|
||||
matroska/ebml/ebmlmktags.h
|
||||
@@ -446,8 +446,10 @@ if(WITH_MATROSKA)
|
||||
set(matroska_SRCS
|
||||
matroska/matroskaattachedfile.cpp
|
||||
matroska/matroskaattachments.cpp
|
||||
matroska/matroskacues.cpp
|
||||
matroska/matroskaelement.cpp
|
||||
matroska/matroskafile.cpp
|
||||
matroska/matroskaproperties.cpp
|
||||
matroska/matroskaseekhead.cpp
|
||||
matroska/matroskasegment.cpp
|
||||
matroska/matroskasimpletag.cpp
|
||||
@@ -459,6 +461,7 @@ if(WITH_MATROSKA)
|
||||
matroska/ebml/ebmlelement.cpp
|
||||
matroska/ebml/ebmlmasterelement.cpp
|
||||
matroska/ebml/ebmlmkattachments.cpp
|
||||
matroska/ebml/ebmlmkcues.cpp
|
||||
matroska/ebml/ebmlmkseekhead.cpp
|
||||
matroska/ebml/ebmlmksegment.cpp
|
||||
matroska/ebml/ebmlmktags.cpp
|
||||
|
||||
@@ -19,14 +19,11 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "ebmlbinaryelement.h"
|
||||
#include "tfile.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tdebug.h"
|
||||
#include <string>
|
||||
#include "ebmlutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
bool EBML::BinaryElement::read(TagLib::File &file)
|
||||
bool EBML::BinaryElement::read(File &file)
|
||||
{
|
||||
value = file.readBlock(dataSize);
|
||||
if(value.size() != dataSize) {
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
#define TAGLIB_EBMLBINARYELEMENT_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include <cstdint>
|
||||
#include "ebmlelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "tbytevector.h"
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
@@ -33,13 +30,16 @@ namespace TagLib {
|
||||
class BinaryElement : public Element
|
||||
{
|
||||
public:
|
||||
BinaryElement(Id id, int sizeLength, offset_t dataSize)
|
||||
: Element(id, sizeLength, dataSize)
|
||||
{}
|
||||
BinaryElement(Id id)
|
||||
: Element(id, 0, 0)
|
||||
{}
|
||||
const ByteVector& getValue() const { return value; }
|
||||
BinaryElement(Id id, int sizeLength, offset_t dataSize) :
|
||||
Element(id, sizeLength, dataSize)
|
||||
{
|
||||
}
|
||||
|
||||
explicit BinaryElement(Id id) :
|
||||
Element(id, 0, 0)
|
||||
{
|
||||
}
|
||||
const ByteVector &getValue() const { return value; }
|
||||
void setValue(const ByteVector &value) { this->value = value; }
|
||||
bool read(File &file) override;
|
||||
ByteVector render() override;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
EBML::Element* EBML::Element::factory(File &file)
|
||||
EBML::Element *EBML::Element::factory(File &file)
|
||||
{
|
||||
// Get the element ID
|
||||
offset_t offset = file.tell();
|
||||
@@ -48,61 +48,59 @@ EBML::Element* EBML::Element::factory(File &file)
|
||||
}
|
||||
|
||||
// Get the size length and data length
|
||||
const auto& [sizeLength, dataSize] = readVINT<offset_t>(file);
|
||||
const auto &[sizeLength, dataSize] = readVINT<offset_t>(file);
|
||||
if(!sizeLength)
|
||||
return nullptr;
|
||||
|
||||
// Return the subclass
|
||||
switch(id) {
|
||||
case ElementIDs::EBMLHeader:
|
||||
return new Element(id, sizeLength, dataSize);
|
||||
|
||||
case ElementIDs::MkSegment:
|
||||
return new MkSegment(sizeLength, dataSize, offset);
|
||||
case ElementIDs::EBMLHeader:
|
||||
return new Element(id, sizeLength, dataSize);
|
||||
|
||||
case ElementIDs::MkTags:
|
||||
return new MkTags(sizeLength, dataSize, offset);
|
||||
case ElementIDs::MkSegment:
|
||||
return new MkSegment(sizeLength, dataSize, offset);
|
||||
|
||||
case ElementIDs::MkAttachments:
|
||||
return new MkAttachments(sizeLength, dataSize, offset);
|
||||
case ElementIDs::MkTags:
|
||||
return new MkTags(sizeLength, dataSize, offset);
|
||||
|
||||
case ElementIDs::MkTag:
|
||||
case ElementIDs::MkTagTargets:
|
||||
case ElementIDs::MkSimpleTag:
|
||||
case ElementIDs::MkAttachedFile:
|
||||
case ElementIDs::MkSeek:
|
||||
return new MasterElement(id, sizeLength, dataSize, offset);
|
||||
case ElementIDs::MkAttachments:
|
||||
return new MkAttachments(sizeLength, dataSize, offset);
|
||||
|
||||
case ElementIDs::MkTagName:
|
||||
case ElementIDs::MkTagString:
|
||||
case ElementIDs::MkAttachedFileName:
|
||||
case ElementIDs::MkAttachedFileDescription:
|
||||
return new UTF8StringElement(id, sizeLength, dataSize);
|
||||
case ElementIDs::MkTag:
|
||||
case ElementIDs::MkTagTargets:
|
||||
case ElementIDs::MkSimpleTag:
|
||||
case ElementIDs::MkAttachedFile:
|
||||
case ElementIDs::MkSeek:
|
||||
return new MasterElement(id, sizeLength, dataSize, offset);
|
||||
|
||||
case ElementIDs::MkTagLanguage:
|
||||
case ElementIDs::MkAttachedFileMediaType:
|
||||
return new Latin1StringElement(id, sizeLength, dataSize);
|
||||
case ElementIDs::MkTagName:
|
||||
case ElementIDs::MkTagString:
|
||||
case ElementIDs::MkAttachedFileName:
|
||||
case ElementIDs::MkAttachedFileDescription:
|
||||
return new UTF8StringElement(id, sizeLength, dataSize);
|
||||
|
||||
case ElementIDs::MkTagTargetTypeValue:
|
||||
case ElementIDs::MkAttachedFileUID:
|
||||
case ElementIDs::MkSeekPosition:
|
||||
return new UIntElement(id, sizeLength, dataSize);
|
||||
case ElementIDs::MkTagLanguage:
|
||||
case ElementIDs::MkAttachedFileMediaType:
|
||||
return new Latin1StringElement(id, sizeLength, dataSize);
|
||||
|
||||
case ElementIDs::MkAttachedFileData:
|
||||
case ElementIDs::MkSeekID:
|
||||
return new BinaryElement(id, sizeLength, dataSize);
|
||||
|
||||
case ElementIDs::MkSeekHead:
|
||||
return new MkSeekHead(sizeLength, dataSize, offset);
|
||||
case ElementIDs::MkTagTargetTypeValue:
|
||||
case ElementIDs::MkAttachedFileUID:
|
||||
case ElementIDs::MkSeekPosition:
|
||||
return new UIntElement(id, sizeLength, dataSize);
|
||||
|
||||
case ElementIDs::VoidElement:
|
||||
return new VoidElement(sizeLength, dataSize);
|
||||
case ElementIDs::MkAttachedFileData:
|
||||
case ElementIDs::MkSeekID:
|
||||
return new BinaryElement(id, sizeLength, dataSize);
|
||||
|
||||
default:
|
||||
return new Element(id, sizeLength, dataSize);
|
||||
case ElementIDs::MkSeekHead:
|
||||
return new MkSeekHead(sizeLength, dataSize, offset);
|
||||
|
||||
case ElementIDs::VoidElement:
|
||||
return new VoidElement(sizeLength, dataSize);
|
||||
|
||||
default:
|
||||
return new Element(id, sizeLength, dataSize);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EBML::Element::Id EBML::Element::readId(File &file)
|
||||
@@ -124,14 +122,14 @@ EBML::Element::Id EBML::Element::readId(File &file)
|
||||
return buffer.toUInt(true);
|
||||
}
|
||||
|
||||
void EBML::Element::skipData(File &file)
|
||||
void EBML::Element::skipData(File &file)
|
||||
{
|
||||
file.seek(dataSize, File::Position::Current);
|
||||
}
|
||||
|
||||
offset_t EBML::Element::headSize() const
|
||||
{
|
||||
return EBML::idSize(id) + sizeLength;
|
||||
{
|
||||
return idSize(id) + sizeLength;
|
||||
}
|
||||
|
||||
ByteVector EBML::Element::render()
|
||||
@@ -141,9 +139,10 @@ ByteVector EBML::Element::render()
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ByteVector EBML::Element::renderId()
|
||||
ByteVector EBML::Element::renderId() const
|
||||
{
|
||||
int numBytes = idSize(id);
|
||||
id = Utils::byteSwap(id);
|
||||
return ByteVector((char*) &id + (4 - numBytes), numBytes);
|
||||
static const auto byteOrder = Utils::systemByteOrder();
|
||||
uint32_t data = byteOrder == Utils::LittleEndian ? Utils::byteSwap(id) : id;
|
||||
return ByteVector(reinterpret_cast<char *>(&data) + (4 - numBytes), numBytes);
|
||||
}
|
||||
|
||||
@@ -26,64 +26,77 @@
|
||||
#include "tutils.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace EBML {
|
||||
class Element
|
||||
namespace TagLib::EBML {
|
||||
class Element
|
||||
{
|
||||
public:
|
||||
using Id = unsigned int;
|
||||
Element(Id id, int sizeLength, offset_t dataSize) :
|
||||
id(id), sizeLength(sizeLength), dataSize(dataSize)
|
||||
{
|
||||
public:
|
||||
using Id = unsigned int;
|
||||
Element(Id id, int sizeLength, offset_t dataSize)
|
||||
: id(id), sizeLength(sizeLength), dataSize(dataSize)
|
||||
{}
|
||||
virtual ~Element() = default;
|
||||
virtual bool read(File &file) {
|
||||
skipData(file);
|
||||
return true;
|
||||
}
|
||||
void skipData(File &file);
|
||||
Id getId() const { return id; }
|
||||
offset_t headSize() const;
|
||||
offset_t getSize() const { return headSize() + dataSize; }
|
||||
int getSizeLength() const { return sizeLength; }
|
||||
int64_t getDataSize() const { return dataSize; }
|
||||
ByteVector renderId();
|
||||
virtual ByteVector render();
|
||||
static Element* factory(File &file);
|
||||
static Id readId(File &file);
|
||||
|
||||
protected:
|
||||
Id id;
|
||||
int sizeLength;
|
||||
offset_t dataSize;
|
||||
};
|
||||
|
||||
namespace ElementIDs {
|
||||
inline constexpr Element::Id EBMLHeader = 0x1A45DFA3;
|
||||
inline constexpr Element::Id VoidElement = 0xEC;
|
||||
inline constexpr Element::Id MkSegment = 0x18538067;
|
||||
inline constexpr Element::Id MkTags = 0x1254C367;
|
||||
inline constexpr Element::Id MkTag = 0x7373;
|
||||
inline constexpr Element::Id MkTagTargets = 0x63C0;
|
||||
inline constexpr Element::Id MkTagTargetTypeValue = 0x68CA;
|
||||
inline constexpr Element::Id MkSimpleTag = 0x67C8;
|
||||
inline constexpr Element::Id MkTagName = 0x45A3;
|
||||
inline constexpr Element::Id MkTagLanguage = 0x447A;
|
||||
inline constexpr Element::Id MkTagString = 0x4487;
|
||||
inline constexpr Element::Id MkTagsTagLanguage = 0x447A;
|
||||
inline constexpr Element::Id MkTagsLanguageDefault = 0x4484;
|
||||
inline constexpr Element::Id MkAttachments = 0x1941A469;
|
||||
inline constexpr Element::Id MkAttachedFile = 0x61A7;
|
||||
inline constexpr Element::Id MkAttachedFileDescription = 0x467E;
|
||||
inline constexpr Element::Id MkAttachedFileName = 0x466E;
|
||||
inline constexpr Element::Id MkAttachedFileMediaType = 0x4660;
|
||||
inline constexpr Element::Id MkAttachedFileData = 0x465C;
|
||||
inline constexpr Element::Id MkAttachedFileUID = 0x46AE;
|
||||
inline constexpr Element::Id MkSeekHead = 0x114D9B74;
|
||||
inline constexpr Element::Id MkSeek = 0x4DBB;
|
||||
inline constexpr Element::Id MkSeekID = 0x53AB;
|
||||
inline constexpr Element::Id MkSeekPosition = 0x53AC;
|
||||
|
||||
}
|
||||
virtual ~Element() = default;
|
||||
virtual bool read(File &file)
|
||||
{
|
||||
skipData(file);
|
||||
return true;
|
||||
}
|
||||
void skipData(File &file);
|
||||
Id getId() const { return id; }
|
||||
offset_t headSize() const;
|
||||
offset_t getSize() const { return headSize() + dataSize; }
|
||||
int getSizeLength() const { return sizeLength; }
|
||||
int64_t getDataSize() const { return dataSize; }
|
||||
ByteVector renderId() const;
|
||||
virtual ByteVector render();
|
||||
static Element *factory(File &file);
|
||||
static Id readId(File &file);
|
||||
|
||||
protected:
|
||||
Id id;
|
||||
int sizeLength;
|
||||
offset_t dataSize;
|
||||
};
|
||||
|
||||
namespace ElementIDs {
|
||||
inline constexpr Element::Id EBMLHeader = 0x1A45DFA3;
|
||||
inline constexpr Element::Id VoidElement = 0xEC;
|
||||
inline constexpr Element::Id MkSegment = 0x18538067;
|
||||
inline constexpr Element::Id MkTags = 0x1254C367;
|
||||
inline constexpr Element::Id MkTag = 0x7373;
|
||||
inline constexpr Element::Id MkTagTargets = 0x63C0;
|
||||
inline constexpr Element::Id MkTagTargetTypeValue = 0x68CA;
|
||||
inline constexpr Element::Id MkSimpleTag = 0x67C8;
|
||||
inline constexpr Element::Id MkTagName = 0x45A3;
|
||||
inline constexpr Element::Id MkTagLanguage = 0x447A;
|
||||
inline constexpr Element::Id MkTagString = 0x4487;
|
||||
inline constexpr Element::Id MkTagsTagLanguage = 0x447A;
|
||||
inline constexpr Element::Id MkTagsLanguageDefault = 0x4484;
|
||||
inline constexpr Element::Id MkAttachments = 0x1941A469;
|
||||
inline constexpr Element::Id MkAttachedFile = 0x61A7;
|
||||
inline constexpr Element::Id MkAttachedFileDescription = 0x467E;
|
||||
inline constexpr Element::Id MkAttachedFileName = 0x466E;
|
||||
inline constexpr Element::Id MkAttachedFileMediaType = 0x4660;
|
||||
inline constexpr Element::Id MkAttachedFileData = 0x465C;
|
||||
inline constexpr Element::Id MkAttachedFileUID = 0x46AE;
|
||||
inline constexpr Element::Id MkSeekHead = 0x114D9B74;
|
||||
inline constexpr Element::Id MkSeek = 0x4DBB;
|
||||
inline constexpr Element::Id MkSeekID = 0x53AB;
|
||||
inline constexpr Element::Id MkSeekPosition = 0x53AC;
|
||||
inline constexpr Element::Id MkCluster = 0x1F43B675;
|
||||
inline constexpr Element::Id MkCodecState = 0xA4;
|
||||
inline constexpr Element::Id MkCues = 0x1C53BB6B;
|
||||
inline constexpr Element::Id MkCuePoint = 0xBB;
|
||||
inline constexpr Element::Id MkCueTime = 0xB3;
|
||||
inline constexpr Element::Id MkCueTrackPositions = 0xB7;
|
||||
inline constexpr Element::Id MkCueTrack = 0xF7;
|
||||
inline constexpr Element::Id MkCueClusterPosition = 0xF1;
|
||||
inline constexpr Element::Id MkCueRelativePosition = 0xF0;
|
||||
inline constexpr Element::Id MkCueDuration = 0xB2;
|
||||
inline constexpr Element::Id MkCueBlockNumber = 0x5378;
|
||||
inline constexpr Element::Id MkCueCodecState = 0xEA;
|
||||
inline constexpr Element::Id MkCueReference = 0xDB;
|
||||
inline constexpr Element::Id MkCueRefTime = 0x96;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,7 @@
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlvoidelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "matroskafile.h"
|
||||
|
||||
#include "tfile.h"
|
||||
#include "tdebug.h"
|
||||
#include "tutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@@ -56,9 +52,9 @@ ByteVector EBML::MasterElement::render()
|
||||
dataSize = data.size();
|
||||
buffer.append(renderVINT(dataSize, 0));
|
||||
buffer.append(data);
|
||||
if (minRenderSize) {
|
||||
if(minRenderSize) {
|
||||
auto bufferSize = buffer.size();
|
||||
if(minRenderSize >= (bufferSize + MIN_VOID_ELEMENT_SIZE))
|
||||
if(minRenderSize >= bufferSize + MIN_VOID_ELEMENT_SIZE)
|
||||
buffer.append(VoidElement::renderSize(minRenderSize - bufferSize));
|
||||
}
|
||||
return buffer;
|
||||
|
||||
@@ -22,48 +22,46 @@
|
||||
#define TAGLIB_EBMLMASTERELEMENT_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include "ebmlutils.h"
|
||||
#include "ebmlelement.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tlist.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace EBML {
|
||||
class MasterElement : public Element
|
||||
namespace TagLib::EBML {
|
||||
class MasterElement : public Element
|
||||
{
|
||||
public:
|
||||
MasterElement(Id id, int sizeLength, offset_t dataSize, offset_t offset) :
|
||||
Element(id, sizeLength, dataSize), offset(offset)
|
||||
{
|
||||
public:
|
||||
MasterElement(Id id, int sizeLength, offset_t dataSize, offset_t offset)
|
||||
: Element(id, sizeLength, dataSize), offset(offset)
|
||||
{}
|
||||
MasterElement(Id id)
|
||||
: Element(id, 0, 0), offset(0)
|
||||
{}
|
||||
~MasterElement() override;
|
||||
offset_t getOffset() const { return offset; }
|
||||
bool read(File &file) override;
|
||||
ByteVector render() override;
|
||||
void appendElement(Element *element) { elements.append(element); }
|
||||
List<Element*>::Iterator begin () { return elements.begin(); }
|
||||
List<Element*>::Iterator end () { return elements.end(); }
|
||||
List<Element*>::ConstIterator cbegin () const { return elements.cbegin(); }
|
||||
List<Element*>::ConstIterator cend () const { return elements.cend(); }
|
||||
offset_t getPadding() const { return padding; }
|
||||
void setPadding(offset_t padding) { this->padding = padding; }
|
||||
offset_t getMinRenderSize() const { return minRenderSize; }
|
||||
void setMinRenderSize(offset_t minRenderSize) { this->minRenderSize = minRenderSize; }
|
||||
}
|
||||
|
||||
explicit MasterElement(Id id) :
|
||||
Element(id, 0, 0), offset(0)
|
||||
{
|
||||
}
|
||||
~MasterElement() override;
|
||||
offset_t getOffset() const { return offset; }
|
||||
bool read(File &file) override;
|
||||
ByteVector render() override;
|
||||
void appendElement(Element *element) { elements.append(element); }
|
||||
List<Element *>::Iterator begin() { return elements.begin(); }
|
||||
List<Element *>::Iterator end() { return elements.end(); }
|
||||
List<Element *>::ConstIterator cbegin() const { return elements.cbegin(); }
|
||||
List<Element *>::ConstIterator cend() const { return elements.cend(); }
|
||||
offset_t getPadding() const { return padding; }
|
||||
void setPadding(offset_t padding) { this->padding = padding; }
|
||||
offset_t getMinRenderSize() const { return minRenderSize; }
|
||||
void setMinRenderSize(offset_t minRenderSize) { this->minRenderSize = minRenderSize; }
|
||||
|
||||
protected:
|
||||
offset_t offset;
|
||||
offset_t padding = 0;
|
||||
offset_t minRenderSize = 0;
|
||||
List<Element *> elements;
|
||||
};
|
||||
|
||||
protected:
|
||||
offset_t offset;
|
||||
offset_t padding = 0;
|
||||
offset_t minRenderSize = 0;
|
||||
List<Element*> elements;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -24,12 +24,10 @@
|
||||
#include "ebmlbinaryelement.h"
|
||||
#include "matroskaattachments.h"
|
||||
#include "matroskaattachedfile.h"
|
||||
#include "tdebug.h"
|
||||
#include "tutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
Matroska::Attachments* EBML::MkAttachments::parse()
|
||||
Matroska::Attachments *EBML::MkAttachments::parse()
|
||||
{
|
||||
auto attachments = new Matroska::Attachments();
|
||||
attachments->setOffset(offset);
|
||||
@@ -44,19 +42,19 @@ Matroska::Attachments* EBML::MkAttachments::parse()
|
||||
const String *mediaType = nullptr;
|
||||
const ByteVector *data = nullptr;
|
||||
Matroska::AttachedFile::UID uid = 0;
|
||||
auto attachedFile = static_cast<MasterElement*>(element);
|
||||
auto attachedFile = static_cast<MasterElement *>(element);
|
||||
for(auto attachedFileChild : *attachedFile) {
|
||||
Id id = attachedFileChild->getId();
|
||||
if(id == ElementIDs::MkAttachedFileName)
|
||||
filename = &(static_cast<UTF8StringElement*>(attachedFileChild)->getValue());
|
||||
filename = &(static_cast<UTF8StringElement *>(attachedFileChild)->getValue());
|
||||
else if(id == ElementIDs::MkAttachedFileData)
|
||||
data = &(static_cast<BinaryElement*>(attachedFileChild)->getValue());
|
||||
data = &(static_cast<BinaryElement *>(attachedFileChild)->getValue());
|
||||
else if(id == ElementIDs::MkAttachedFileDescription)
|
||||
description = &(static_cast<UTF8StringElement*>(attachedFileChild)->getValue());
|
||||
description = &(static_cast<UTF8StringElement *>(attachedFileChild)->getValue());
|
||||
else if(id == ElementIDs::MkAttachedFileMediaType)
|
||||
mediaType = &(static_cast<Latin1StringElement*>(attachedFileChild)->getValue());
|
||||
mediaType = &(static_cast<Latin1StringElement *>(attachedFileChild)->getValue());
|
||||
else if(id == ElementIDs::MkAttachedFileUID)
|
||||
uid = static_cast<UIntElement*>(attachedFileChild)->getValue();
|
||||
uid = static_cast<UIntElement *>(attachedFileChild)->getValue();
|
||||
}
|
||||
if(!(filename && data))
|
||||
continue;
|
||||
@@ -70,7 +68,7 @@ Matroska::Attachments* EBML::MkAttachments::parse()
|
||||
file->setMediaType(*mediaType);
|
||||
if(uid)
|
||||
file->setUID(uid);
|
||||
|
||||
|
||||
attachments->addAttachedFile(file);
|
||||
}
|
||||
return attachments;
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "taglib.h"
|
||||
|
||||
#ifndef TAGLIB_EBMLMKATTACHMENTS_H
|
||||
#define TAGLIB_EBMLMKATTACHMENTS_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class Attachments;
|
||||
@@ -34,16 +34,18 @@ namespace TagLib {
|
||||
class MkAttachments : public MasterElement
|
||||
{
|
||||
public:
|
||||
MkAttachments(int sizeLength, offset_t dataSize, offset_t offset)
|
||||
: MasterElement(ElementIDs::MkAttachments, sizeLength, dataSize, offset)
|
||||
{}
|
||||
MkAttachments()
|
||||
: MasterElement(ElementIDs::MkAttachments, 0, 0, 0)
|
||||
{}
|
||||
Matroska::Attachments* parse();
|
||||
|
||||
MkAttachments(int sizeLength, offset_t dataSize, offset_t offset) :
|
||||
MasterElement(ElementIDs::MkAttachments, sizeLength, dataSize, offset)
|
||||
{
|
||||
}
|
||||
MkAttachments() :
|
||||
MasterElement(ElementIDs::MkAttachments, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
Matroska::Attachments *parse();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -20,55 +20,50 @@
|
||||
|
||||
#include "ebmlmkcues.h"
|
||||
#include "ebmluintelement.h"
|
||||
#include "ebmlstringelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "matroskafile.h"
|
||||
#include "matroskacues.h"
|
||||
#include "tdebug.h"
|
||||
#include "tutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
Matroska::Cues* EBML::MkCues::parse()
|
||||
Matroska::Cues *EBML::MkCues::parse()
|
||||
{
|
||||
auto cues = new Matroska::Cues();
|
||||
cues->setOffset(offset);
|
||||
cues->setSize(getSize());
|
||||
cues->setID(id);
|
||||
|
||||
for (auto cuesChild : elements) {
|
||||
if (cuesChild->getId() != ElementIDs::MkCuePoint)
|
||||
for(auto cuesChild : elements) {
|
||||
if(cuesChild->getId() != ElementIDs::MkCuePoint)
|
||||
continue;
|
||||
auto cuePointElement = static_cast<MasterElement*>(cuesChild);
|
||||
auto cuePointElement = static_cast<MasterElement *>(cuesChild);
|
||||
auto cuePoint = new Matroska::CuePoint();
|
||||
|
||||
for (auto cuePointChild : *cuePointElement) {
|
||||
for(auto cuePointChild : *cuePointElement) {
|
||||
Id id = cuePointChild->getId();
|
||||
if (id == ElementIDs::MkCueTime)
|
||||
cuePoint->setTime(static_cast<UIntElement*>(cuePointChild)->getValue());
|
||||
else if (id == ElementIDs::MkCueTrackPositions) {
|
||||
if(id == ElementIDs::MkCueTime)
|
||||
cuePoint->setTime(static_cast<UIntElement *>(cuePointChild)->getValue());
|
||||
else if(id == ElementIDs::MkCueTrackPositions) {
|
||||
auto cueTrack = new Matroska::CueTrack();
|
||||
auto cueTrackElement = static_cast<MasterElement*>(cuePointChild);
|
||||
for (auto cueTrackChild : *cueTrackElement) {
|
||||
auto cueTrackElement = static_cast<MasterElement *>(cuePointChild);
|
||||
for(auto cueTrackChild : *cueTrackElement) {
|
||||
Id trackId = cueTrackChild->getId();
|
||||
if (trackId == ElementIDs::MkCueTrack)
|
||||
cueTrack->setTrackNumber(static_cast<UIntElement*>(cueTrackChild)->getValue());
|
||||
else if (trackId == ElementIDs::MkCueClusterPosition)
|
||||
cueTrack->setClusterPosition(static_cast<UIntElement*>(cueTrackChild)->getValue());
|
||||
else if (trackId == ElementIDs::MkCueRelativePosition)
|
||||
cueTrack->setRelativePosition(static_cast<UIntElement*>(cueTrackChild)->getValue());
|
||||
else if (trackId == ElementIDs::MkCueDuration)
|
||||
cueTrack->setDuration(static_cast<UIntElement*>(cueTrackChild)->getValue());
|
||||
else if (trackId == ElementIDs::MkCueBlockNumber)
|
||||
cueTrack->setBlockNumber(static_cast<UIntElement*>(cueTrackChild)->getValue());
|
||||
else if (trackId == ElementIDs::MkCueCodecState)
|
||||
cueTrack->setCodecState(static_cast<UIntElement*>(cueTrackChild)->getValue());
|
||||
else if (trackId == ElementIDs::MkCueReference) {
|
||||
auto cueReference = static_cast<MasterElement*>(cueTrackChild);
|
||||
for (auto cueReferenceChild : *cueReference) {
|
||||
if (cueReferenceChild->getId() != ElementIDs::MkCueReference)
|
||||
if(trackId == ElementIDs::MkCueTrack)
|
||||
cueTrack->setTrackNumber(static_cast<UIntElement *>(cueTrackChild)->getValue());
|
||||
else if(trackId == ElementIDs::MkCueClusterPosition)
|
||||
cueTrack->setClusterPosition(static_cast<UIntElement *>(cueTrackChild)->getValue());
|
||||
else if(trackId == ElementIDs::MkCueRelativePosition)
|
||||
cueTrack->setRelativePosition(static_cast<UIntElement *>(cueTrackChild)->getValue());
|
||||
else if(trackId == ElementIDs::MkCueDuration)
|
||||
cueTrack->setDuration(static_cast<UIntElement *>(cueTrackChild)->getValue());
|
||||
else if(trackId == ElementIDs::MkCueBlockNumber)
|
||||
cueTrack->setBlockNumber(static_cast<UIntElement *>(cueTrackChild)->getValue());
|
||||
else if(trackId == ElementIDs::MkCueCodecState)
|
||||
cueTrack->setCodecState(static_cast<UIntElement *>(cueTrackChild)->getValue());
|
||||
else if(trackId == ElementIDs::MkCueReference) {
|
||||
auto cueReference = static_cast<MasterElement *>(cueTrackChild);
|
||||
for(auto cueReferenceChild : *cueReference) {
|
||||
if(cueReferenceChild->getId() != ElementIDs::MkCueReference)
|
||||
continue;
|
||||
cueTrack->addReferenceTime(static_cast<UIntElement*>(cueReferenceChild)->getValue());
|
||||
cueTrack->addReferenceTime(static_cast<UIntElement *>(cueReferenceChild)->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "taglib.h"
|
||||
|
||||
#ifndef TAGLIB_EBMLMKCUES_H
|
||||
#define TAGLIB_EBMLMKCUES_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class Cues;
|
||||
@@ -35,17 +35,19 @@ namespace TagLib {
|
||||
class MkCues : public MasterElement
|
||||
{
|
||||
public:
|
||||
MkCues(int sizeLength, offset_t dataSize, offset_t offset)
|
||||
: MasterElement(ElementIDs::MkCues, sizeLength, dataSize, offset)
|
||||
{}
|
||||
MkCues()
|
||||
: MasterElement(ElementIDs::MkCues, 0, 0, 0)
|
||||
{}
|
||||
|
||||
Matroska::Cues* parse();
|
||||
MkCues(int sizeLength, offset_t dataSize, offset_t offset) :
|
||||
MasterElement(ElementIDs::MkCues, sizeLength, dataSize, offset)
|
||||
{
|
||||
}
|
||||
MkCues() :
|
||||
MasterElement(ElementIDs::MkCues, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
Matroska::Cues *parse();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
Matroska::SeekHead* EBML::MkSeekHead::parse()
|
||||
Matroska::SeekHead *EBML::MkSeekHead::parse()
|
||||
{
|
||||
auto seekHead = new Matroska::SeekHead();
|
||||
seekHead->setOffset(offset);
|
||||
@@ -34,18 +34,18 @@ Matroska::SeekHead* EBML::MkSeekHead::parse()
|
||||
for(auto element : elements) {
|
||||
if(element->getId() != ElementIDs::MkSeek)
|
||||
continue;
|
||||
auto seekElement = static_cast<MasterElement*>(element);
|
||||
auto seekElement = static_cast<MasterElement *>(element);
|
||||
Matroska::Element::ID entryId = 0;
|
||||
offset_t offset = 0;
|
||||
for(auto seekElementChild : *seekElement) {
|
||||
Id id = seekElementChild->getId();
|
||||
if(id == ElementIDs::MkSeekID && !entryId) {
|
||||
auto data = static_cast<BinaryElement*>(seekElementChild)->getValue();
|
||||
auto data = static_cast<BinaryElement *>(seekElementChild)->getValue();
|
||||
if(data.size() == 4)
|
||||
entryId = data.toUInt(true);
|
||||
}
|
||||
else if(id == ElementIDs::MkSeekPosition && !offset)
|
||||
offset = static_cast<UIntElement*>(seekElementChild)->getValue();
|
||||
offset = static_cast<UIntElement *>(seekElementChild)->getValue();
|
||||
}
|
||||
if(entryId && offset)
|
||||
seekHead->addEntry(entryId, offset);
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "taglib.h"
|
||||
|
||||
#ifndef TAGLIB_EBMLMKSEEKHEAD_H
|
||||
#define TAGLIB_EBMLMKSEEKHEAD_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class SeekHead;
|
||||
@@ -33,17 +33,19 @@ namespace TagLib {
|
||||
class MkSeekHead : public MasterElement
|
||||
{
|
||||
public:
|
||||
MkSeekHead(int sizeLength, offset_t dataSize, offset_t offset)
|
||||
: MasterElement(ElementIDs::MkSeekHead, sizeLength, dataSize, offset)
|
||||
{}
|
||||
MkSeekHead()
|
||||
: MasterElement(ElementIDs::MkSeekHead, 0, 0, 0)
|
||||
{}
|
||||
|
||||
Matroska::SeekHead* parse();
|
||||
MkSeekHead(int sizeLength, offset_t dataSize, offset_t offset) :
|
||||
MasterElement(ElementIDs::MkSeekHead, sizeLength, dataSize, offset)
|
||||
{
|
||||
}
|
||||
MkSeekHead() :
|
||||
MasterElement(ElementIDs::MkSeekHead, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
Matroska::SeekHead *parse();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
#include "matroskaattachments.h"
|
||||
#include "matroskaseekhead.h"
|
||||
#include "matroskasegment.h"
|
||||
#include "tutils.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@@ -44,31 +41,31 @@ EBML::MkSegment::~MkSegment()
|
||||
bool EBML::MkSegment::read(File &file)
|
||||
{
|
||||
offset_t maxOffset = file.tell() + dataSize;
|
||||
EBML::Element *element = nullptr;
|
||||
Element *element = nullptr;
|
||||
int i = 0;
|
||||
int seekHeadIndex = -1;
|
||||
while((element = findNextElement(file, maxOffset))) {
|
||||
Id id = element->getId();
|
||||
if(id == ElementIDs::MkSeekHead) {
|
||||
seekHeadIndex = i;
|
||||
seekHead = static_cast<MkSeekHead*>(element);
|
||||
seekHead = static_cast<MkSeekHead *>(element);
|
||||
if(!seekHead->read(file))
|
||||
return false;
|
||||
}
|
||||
else if(id == ElementIDs::MkTags) {
|
||||
tags = static_cast<MkTags*>(element);
|
||||
tags = static_cast<MkTags *>(element);
|
||||
if(!tags->read(file))
|
||||
return false;
|
||||
}
|
||||
else if(id == ElementIDs::MkAttachments) {
|
||||
attachments = static_cast<MkAttachments*>(element);
|
||||
attachments = static_cast<MkAttachments *>(element);
|
||||
if(!attachments->read(file))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(id == ElementIDs::VoidElement
|
||||
&& seekHead
|
||||
&& seekHeadIndex == (i - 1))
|
||||
&& seekHead
|
||||
&& seekHeadIndex == i - 1)
|
||||
seekHead->setPadding(element->getSize());
|
||||
|
||||
element->skipData(file);
|
||||
@@ -79,22 +76,22 @@ bool EBML::MkSegment::read(File &file)
|
||||
return true;
|
||||
}
|
||||
|
||||
Matroska::Tag* EBML::MkSegment::parseTag()
|
||||
Matroska::Tag *EBML::MkSegment::parseTag()
|
||||
{
|
||||
return tags ? tags->parse() : nullptr;
|
||||
}
|
||||
|
||||
Matroska::Attachments* EBML::MkSegment::parseAttachments()
|
||||
Matroska::Attachments *EBML::MkSegment::parseAttachments()
|
||||
{
|
||||
return attachments ? attachments->parse() : nullptr;
|
||||
}
|
||||
|
||||
Matroska::SeekHead* EBML::MkSegment::parseSeekHead()
|
||||
Matroska::SeekHead *EBML::MkSegment::parseSeekHead()
|
||||
{
|
||||
return seekHead ? seekHead->parse() : nullptr;
|
||||
}
|
||||
|
||||
Matroska::Segment* EBML::MkSegment::parseSegment()
|
||||
Matroska::Segment *EBML::MkSegment::parseSegment()
|
||||
{
|
||||
return new Matroska::Segment(sizeLength, dataSize, offset + idSize(id));
|
||||
}
|
||||
|
||||
@@ -18,14 +18,13 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "taglib.h"
|
||||
#include <tuple>
|
||||
|
||||
#ifndef TAGLIB_EBMLMKSEGMENT_H
|
||||
#define TAGLIB_EBMLMKSEGMENT_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class Tag;
|
||||
@@ -40,15 +39,16 @@ namespace TagLib {
|
||||
class MkSegment : public MasterElement
|
||||
{
|
||||
public:
|
||||
MkSegment(int sizeLength, offset_t dataSize, offset_t offset)
|
||||
: MasterElement(ElementIDs::MkSegment, sizeLength, dataSize, offset)
|
||||
{}
|
||||
MkSegment(int sizeLength, offset_t dataSize, offset_t offset) :
|
||||
MasterElement(ElementIDs::MkSegment, sizeLength, dataSize, offset)
|
||||
{
|
||||
}
|
||||
~MkSegment() override;
|
||||
bool read(File &file) override;
|
||||
Matroska::Tag* parseTag();
|
||||
Matroska::Attachments* parseAttachments();
|
||||
Matroska::SeekHead* parseSeekHead();
|
||||
Matroska::Segment* parseSegment();
|
||||
Matroska::Tag *parseTag();
|
||||
Matroska::Attachments *parseAttachments();
|
||||
Matroska::SeekHead *parseSeekHead();
|
||||
Matroska::Segment *parseSegment();
|
||||
|
||||
private:
|
||||
MkTags *tags = nullptr;
|
||||
|
||||
@@ -21,17 +21,13 @@
|
||||
#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()
|
||||
Matroska::Tag *EBML::MkTags::parse()
|
||||
{
|
||||
auto mTag = new Matroska::Tag();
|
||||
mTag->setOffset(offset);
|
||||
@@ -42,17 +38,17 @@ Matroska::Tag* EBML::MkTags::parse()
|
||||
for(auto tagsChild : elements) {
|
||||
if(tagsChild->getId() != ElementIDs::MkTag)
|
||||
continue;
|
||||
auto tag = static_cast<MasterElement*>(tagsChild);
|
||||
List<MasterElement*> simpleTags;
|
||||
auto tag = static_cast<MasterElement *>(tagsChild);
|
||||
List<MasterElement *> simpleTags;
|
||||
MasterElement *targets = nullptr;
|
||||
|
||||
// Identify the <Targets> element and the <SimpleTag> elements
|
||||
for(auto tagChild : *tag) {
|
||||
Id tagChildId = tagChild->getId();
|
||||
if(!targets && tagChildId == ElementIDs::MkTagTargets)
|
||||
targets = static_cast<MasterElement*>(tagChild);
|
||||
targets = static_cast<MasterElement *>(tagChild);
|
||||
else if(tagChildId == ElementIDs::MkSimpleTag)
|
||||
simpleTags.append(static_cast<MasterElement*>(tagChild));
|
||||
simpleTags.append(static_cast<MasterElement *>(tagChild));
|
||||
}
|
||||
|
||||
// Parse the <Targets> element
|
||||
@@ -63,8 +59,8 @@ Matroska::Tag* EBML::MkTags::parse()
|
||||
if(id == ElementIDs::MkTagTargetTypeValue
|
||||
&& targetTypeValue == Matroska::SimpleTag::TargetTypeValue::None) {
|
||||
targetTypeValue = static_cast<Matroska::SimpleTag::TargetTypeValue>(
|
||||
static_cast<UIntElement*>(targetsChild)->getValue()
|
||||
);
|
||||
static_cast<UIntElement *>(targetsChild)->getValue()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,13 +76,14 @@ Matroska::Tag* EBML::MkTags::parse()
|
||||
for(auto simpleTagChild : *simpleTag) {
|
||||
Id id = simpleTagChild->getId();
|
||||
if(id == ElementIDs::MkTagName && !tagName)
|
||||
tagName = &(static_cast<UTF8StringElement*>(simpleTagChild)->getValue());
|
||||
tagName = &(static_cast<UTF8StringElement *>(simpleTagChild)->getValue());
|
||||
else if(id == ElementIDs::MkTagString && !tagValueString)
|
||||
tagValueString = &(static_cast<UTF8StringElement*>(simpleTagChild)->getValue());
|
||||
tagValueString = &(static_cast<UTF8StringElement *>(simpleTagChild)->getValue());
|
||||
// TODO implement binary
|
||||
else if(id == ElementIDs::MkTagsTagLanguage && !language)
|
||||
language = &(static_cast<Latin1StringElement*>(simpleTagChild)->getValue());
|
||||
language = &(static_cast<Latin1StringElement *>(simpleTagChild)->getValue());
|
||||
else if(id == ElementIDs::MkTagsLanguageDefault)
|
||||
defaultLanguageFlag = static_cast<UIntElement*>(simpleTagChild)->getValue() ? true : false;
|
||||
defaultLanguageFlag = static_cast<UIntElement *>(simpleTagChild)->getValue() ? true : false;
|
||||
}
|
||||
if(!tagName || (tagValueString && tagValueBinary) || (!tagValueString && !tagValueBinary))
|
||||
continue;
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
* 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
|
||||
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class Tag;
|
||||
@@ -35,17 +35,19 @@ namespace TagLib {
|
||||
class MkTags : public MasterElement
|
||||
{
|
||||
public:
|
||||
MkTags(int sizeLength, offset_t dataSize, offset_t offset)
|
||||
: MasterElement(ElementIDs::MkTags, sizeLength, dataSize, offset)
|
||||
{}
|
||||
MkTags()
|
||||
: MasterElement(ElementIDs::MkTags, 0, 0, 0)
|
||||
{}
|
||||
|
||||
Matroska::Tag* parse();
|
||||
MkTags(int sizeLength, offset_t dataSize, offset_t offset) :
|
||||
MasterElement(ElementIDs::MkTags, sizeLength, dataSize, offset)
|
||||
{
|
||||
}
|
||||
MkTags() :
|
||||
MasterElement(ElementIDs::MkTags, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
Matroska::Tag *parse();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "ebmlstringelement.h"
|
||||
#include <string>
|
||||
#include "tfile.h"
|
||||
#include "tstring.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tdebug.h"
|
||||
#include <string>
|
||||
#include "ebmlutils.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
template<String::Type t>
|
||||
bool EBML::StringElement<t>::read(TagLib::File &file)
|
||||
template <String::Type t>
|
||||
bool EBML::StringElement<t>::read(File &file)
|
||||
{
|
||||
ByteVector buffer = file.readBlock(dataSize);
|
||||
if(buffer.size() != dataSize) {
|
||||
@@ -44,10 +45,10 @@ bool EBML::StringElement<t>::read(TagLib::File &file)
|
||||
value = String(buffer, t);
|
||||
return true;
|
||||
}
|
||||
template bool EBML::StringElement<String::UTF8>::read(TagLib::File &file);
|
||||
template bool EBML::StringElement<String::Latin1>::read(TagLib::File &file);
|
||||
template bool EBML::StringElement<String::UTF8>::read(File &file);
|
||||
template bool EBML::StringElement<String::Latin1>::read(File &file);
|
||||
|
||||
template<String::Type t>
|
||||
template <String::Type t>
|
||||
ByteVector EBML::StringElement<t>::render()
|
||||
{
|
||||
ByteVector buffer = renderId();
|
||||
|
||||
@@ -22,26 +22,27 @@
|
||||
#define TAGLIB_EBMLSTRINGELEMENT_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include <cstdint>
|
||||
#include "ebmlelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tstring.h"
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
namespace EBML {
|
||||
template<String::Type t>
|
||||
template <String::Type t>
|
||||
class StringElement : public Element
|
||||
{
|
||||
public:
|
||||
StringElement(Id id, int sizeLength, offset_t dataSize)
|
||||
: Element(id, sizeLength, dataSize)
|
||||
{}
|
||||
StringElement(Id id)
|
||||
: Element(id, 0, 0)
|
||||
{}
|
||||
const String& getValue() const { return value; }
|
||||
StringElement(Id id, int sizeLength, offset_t dataSize) :
|
||||
Element(id, sizeLength, dataSize)
|
||||
{
|
||||
}
|
||||
|
||||
explicit StringElement(Id id) :
|
||||
Element(id, 0, 0)
|
||||
{
|
||||
}
|
||||
const String &getValue() const { return value; }
|
||||
void setValue(const String &value) { this->value = value; }
|
||||
bool read(File &file) override;
|
||||
ByteVector render() override;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
bool EBML::UIntElement::read(TagLib::File &file)
|
||||
bool EBML::UIntElement::read(File &file)
|
||||
{
|
||||
ByteVector buffer = file.readBlock(dataSize);
|
||||
if(buffer.size() != dataSize) {
|
||||
@@ -61,9 +61,9 @@ ByteVector EBML::UIntElement::render()
|
||||
buffer.append(renderVINT(dataSize, 0));
|
||||
uint64_t value = this->value;
|
||||
static const auto byteOrder = Utils::systemByteOrder();
|
||||
if (byteOrder == Utils::LittleEndian)
|
||||
if(byteOrder == Utils::LittleEndian)
|
||||
value = Utils::byteSwap(value);
|
||||
|
||||
buffer.append(ByteVector((char*) &value + (sizeof(value) - dataSize), dataSize));
|
||||
buffer.append(ByteVector(reinterpret_cast<char *>(&value) + (sizeof(value) - dataSize), dataSize));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define TAGLIB_EBMLUINTELEMENT_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include <cstdint>
|
||||
#include "ebmlelement.h"
|
||||
|
||||
namespace TagLib {
|
||||
@@ -32,12 +31,15 @@ namespace TagLib {
|
||||
class UIntElement : public Element
|
||||
{
|
||||
public:
|
||||
UIntElement(Id id, int sizeLength, offset_t dataSize)
|
||||
: Element(id, sizeLength, dataSize)
|
||||
{}
|
||||
UIntElement(Id id)
|
||||
: UIntElement(id, 0, 0)
|
||||
{}
|
||||
UIntElement(Id id, int sizeLength, offset_t dataSize) :
|
||||
Element(id, sizeLength, dataSize)
|
||||
{
|
||||
}
|
||||
|
||||
explicit UIntElement(Id id) :
|
||||
UIntElement(id, 0, 0)
|
||||
{
|
||||
}
|
||||
unsigned long long getValue() const { return value; }
|
||||
void setValue(unsigned long long value) { this->value = value; }
|
||||
bool read(File &file) override;
|
||||
@@ -45,10 +47,6 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
unsigned long long value = 0;
|
||||
|
||||
//protected:
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
EBML::Element* EBML::findElement(File &file, EBML::Element::Id id, offset_t maxOffset)
|
||||
EBML::Element *EBML::findElement(File &file, Element::Id id, offset_t maxOffset)
|
||||
{
|
||||
Element *element = nullptr;
|
||||
while(file.tell() < maxOffset) {
|
||||
@@ -44,12 +44,12 @@ EBML::Element* EBML::findElement(File &file, EBML::Element::Id id, offset_t maxO
|
||||
return element;
|
||||
}
|
||||
|
||||
EBML::Element* EBML::findNextElement(File &file, offset_t maxOffset)
|
||||
EBML::Element *EBML::findNextElement(File &file, offset_t maxOffset)
|
||||
{
|
||||
return file.tell() < maxOffset ? Element::factory(file) : nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::pair<int, T> EBML::readVINT(File &file)
|
||||
{
|
||||
static_assert(sizeof(T) == 8);
|
||||
@@ -64,7 +64,7 @@ std::pair<int, T> EBML::readVINT(File &file)
|
||||
|
||||
if(nb_bytes > 1)
|
||||
buffer.append(file.readBlock(nb_bytes - 1));
|
||||
int bits_to_shift = static_cast<int>(sizeof(T) * 8) - (7 * nb_bytes);
|
||||
int bits_to_shift = static_cast<int>(sizeof(T) * 8) - 7 * nb_bytes;
|
||||
offset_t mask = 0xFFFFFFFFFFFFFFFF >> bits_to_shift;
|
||||
return { nb_bytes, static_cast<T>(buffer.toLongLong(true)) & mask };
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace TagLib::EBML {
|
||||
template std::pair<int, uint64_t> readVINT<uint64_t>(File &file);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::pair<int, T> EBML::parseVINT(const ByteVector &buffer)
|
||||
{
|
||||
if(buffer.isEmpty())
|
||||
@@ -83,7 +83,7 @@ std::pair<int, T> EBML::parseVINT(const ByteVector &buffer)
|
||||
if(!numBytes)
|
||||
return {0, 0};
|
||||
|
||||
int bits_to_shift = static_cast<int>(sizeof(T) * 8) - (7 * numBytes);
|
||||
int bits_to_shift = static_cast<int>(sizeof(T) * 8) - 7 * numBytes;
|
||||
offset_t mask = 0xFFFFFFFFFFFFFFFF >> bits_to_shift;
|
||||
return { numBytes, static_cast<T>(buffer.toLongLong(true)) & mask };
|
||||
}
|
||||
@@ -95,11 +95,11 @@ namespace TagLib::EBML {
|
||||
ByteVector EBML::renderVINT(uint64_t number, int minSizeLength)
|
||||
{
|
||||
int numBytes = std::max(minSizeLength, minSize(number));
|
||||
number |= (1ULL << (numBytes * 7));
|
||||
number |= 1ULL << (numBytes * 7);
|
||||
static const auto byteOrder = Utils::systemByteOrder();
|
||||
if (byteOrder == Utils::LittleEndian)
|
||||
if(byteOrder == Utils::LittleEndian)
|
||||
number = Utils::byteSwap(number);
|
||||
return ByteVector((char*) &number + (sizeof(number) - numBytes), numBytes);
|
||||
return ByteVector(reinterpret_cast<char *>(&number) + (sizeof(number) - numBytes), numBytes);
|
||||
}
|
||||
|
||||
unsigned long long EBML::randomUID()
|
||||
|
||||
@@ -23,32 +23,18 @@
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include "taglib.h"
|
||||
#include "tutils.h"
|
||||
#include "tdebug.h"
|
||||
#include "ebmlelement.h"
|
||||
#include "tbytevector.h"
|
||||
|
||||
/*
|
||||
#define EBMLHeader 0x1A45DFA3
|
||||
#define MkSegment 0x18538067
|
||||
#define MkTags 0x1254C367
|
||||
#define MkTag 0x7373
|
||||
#define MkTagTargets 0x63C0
|
||||
#define MkTagTargetTypeValue 0x68CA
|
||||
#define MkSimpleTag 0x67C8
|
||||
#define MkTagName 0x45A3
|
||||
#define MkTagLanguage 0x447A
|
||||
#define MkTagString 0x4487
|
||||
*/
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
class ByteVector;
|
||||
|
||||
namespace EBML {
|
||||
template<int maxSizeLength>
|
||||
template <int maxSizeLength>
|
||||
constexpr unsigned int VINTSizeLength(uint8_t firstByte)
|
||||
{
|
||||
static_assert(maxSizeLength >= 1 && maxSizeLength <= 8);
|
||||
@@ -69,12 +55,12 @@ namespace TagLib {
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::pair<int, T> readVINT(File &file);
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
std::pair<int, T> parseVINT(const ByteVector &buffer);
|
||||
Element* findElement(File &file, Element::Id id, offset_t maxLength);
|
||||
Element* findNextElement(File &file, offset_t maxOffset);
|
||||
Element *findElement(File &file, Element::Id id, offset_t maxOffset);
|
||||
Element *findNextElement(File &file, offset_t maxOffset);
|
||||
ByteVector renderVINT(uint64_t number, int minSizeLength);
|
||||
unsigned long long randomUID();
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "ebmlvoidelement.h"
|
||||
#include "ebmlutils.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -36,7 +35,7 @@ ByteVector EBML::VoidElement::render()
|
||||
bytesNeeded -= sizeLength;
|
||||
dataSize = bytesNeeded;
|
||||
buffer.append(renderVINT(dataSize, sizeLength));
|
||||
if (dataSize)
|
||||
if(dataSize)
|
||||
buffer.append(ByteVector(static_cast<unsigned int>(dataSize), 0));
|
||||
|
||||
return buffer;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/***************************************************************************
|
||||
/***************************************************************************
|
||||
* 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. *
|
||||
@@ -22,9 +22,7 @@
|
||||
#define TAGLIB_EBMLVOIDELEMENT_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include <cstdint>
|
||||
#include "ebmlelement.h"
|
||||
#include "tutils.h"
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
@@ -34,20 +32,19 @@ namespace TagLib {
|
||||
class VoidElement : public Element
|
||||
{
|
||||
public:
|
||||
VoidElement(int sizeLength, offset_t dataSize)
|
||||
: Element(ElementIDs::VoidElement, sizeLength, dataSize)
|
||||
VoidElement(int sizeLength, offset_t dataSize) :
|
||||
Element(ElementIDs::VoidElement, sizeLength, dataSize)
|
||||
{}
|
||||
VoidElement()
|
||||
: Element(ElementIDs::VoidElement, 0, 0)
|
||||
VoidElement() :
|
||||
Element(ElementIDs::VoidElement, 0, 0)
|
||||
{}
|
||||
ByteVector render() override;
|
||||
offset_t getTargetSize() const;
|
||||
void setTargetSize(offset_t targetSize);
|
||||
static ByteVector renderSize(offset_t size);
|
||||
static ByteVector renderSize(offset_t targetSize);
|
||||
|
||||
private:
|
||||
offset_t targetSize = MIN_VOID_ELEMENT_SIZE;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using namespace TagLib;
|
||||
class Matroska::AttachedFile::AttachedFilePrivate
|
||||
{
|
||||
public:
|
||||
AttachedFilePrivate() {}
|
||||
AttachedFilePrivate() = default;
|
||||
~AttachedFilePrivate() = default;
|
||||
AttachedFilePrivate(const AttachedFilePrivate &) = delete;
|
||||
AttachedFilePrivate &operator=(const AttachedFilePrivate &) = delete;
|
||||
@@ -19,10 +19,9 @@ public:
|
||||
UID uid = 0;
|
||||
};
|
||||
|
||||
Matroska::AttachedFile::AttachedFile()
|
||||
: d(std::make_unique<AttachedFilePrivate>())
|
||||
Matroska::AttachedFile::AttachedFile() :
|
||||
d(std::make_unique<AttachedFilePrivate>())
|
||||
{
|
||||
|
||||
}
|
||||
Matroska::AttachedFile::~AttachedFile() = default;
|
||||
|
||||
@@ -31,7 +30,7 @@ void Matroska::AttachedFile::setFileName(const String &fileName)
|
||||
d->fileName = fileName;
|
||||
}
|
||||
|
||||
const String& Matroska::AttachedFile::fileName() const
|
||||
const String &Matroska::AttachedFile::fileName() const
|
||||
{
|
||||
return d->fileName;
|
||||
}
|
||||
@@ -41,7 +40,7 @@ void Matroska::AttachedFile::setDescription(const String &description)
|
||||
d->description = description;
|
||||
}
|
||||
|
||||
const String& Matroska::AttachedFile::description() const
|
||||
const String &Matroska::AttachedFile::description() const
|
||||
{
|
||||
return d->description;
|
||||
}
|
||||
@@ -51,7 +50,7 @@ void Matroska::AttachedFile::setMediaType(const String &mediaType)
|
||||
d->mediaType = mediaType;
|
||||
}
|
||||
|
||||
const String& Matroska::AttachedFile::mediaType() const
|
||||
const String &Matroska::AttachedFile::mediaType() const
|
||||
{
|
||||
return d->mediaType;
|
||||
}
|
||||
@@ -61,7 +60,7 @@ void Matroska::AttachedFile::setData(const ByteVector &data)
|
||||
d->data = data;
|
||||
}
|
||||
|
||||
const ByteVector& Matroska::AttachedFile::data() const
|
||||
const ByteVector &Matroska::AttachedFile::data() const
|
||||
{
|
||||
return d->data;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "taglib_export.h"
|
||||
|
||||
|
||||
namespace TagLib {
|
||||
class String;
|
||||
class ByteVector;
|
||||
@@ -36,13 +35,13 @@ namespace TagLib {
|
||||
~AttachedFile();
|
||||
|
||||
void setFileName(const String &fileName);
|
||||
const String& fileName() const;
|
||||
const String &fileName() const;
|
||||
void setDescription(const String &description);
|
||||
const String& description() const;
|
||||
const String &description() const;
|
||||
void setMediaType(const String &mediaType);
|
||||
const String& mediaType() const;
|
||||
const String &mediaType() const;
|
||||
void setData(const ByteVector &data);
|
||||
const ByteVector& data() const;
|
||||
const ByteVector &data() const;
|
||||
void setUID(UID uid);
|
||||
UID uid() const;
|
||||
|
||||
|
||||
@@ -14,15 +14,15 @@ using namespace TagLib;
|
||||
class Matroska::Attachments::AttachmentsPrivate
|
||||
{
|
||||
public:
|
||||
AttachmentsPrivate() {}
|
||||
AttachmentsPrivate() = default;
|
||||
~AttachmentsPrivate() = default;
|
||||
AttachmentsPrivate(const AttachmentsPrivate &) = delete;
|
||||
AttachmentsPrivate &operator=(const AttachmentsPrivate &) = delete;
|
||||
List<AttachedFile*> files;
|
||||
List<AttachedFile *> files;
|
||||
};
|
||||
|
||||
Matroska::Attachments::Attachments()
|
||||
: Element(ElementIDs::MkAttachments),
|
||||
Matroska::Attachments::Attachments() :
|
||||
Element(ElementIDs::MkAttachments),
|
||||
d(std::make_unique<AttachmentsPrivate>())
|
||||
{
|
||||
d->files.setAutoDelete(true);
|
||||
@@ -48,7 +48,7 @@ void Matroska::Attachments::clear()
|
||||
d->files.clear();
|
||||
}
|
||||
|
||||
const Matroska::Attachments::AttachedFileList& Matroska::Attachments::attachedFileList() const
|
||||
const Matroska::Attachments::AttachedFileList &Matroska::Attachments::attachedFileList() const
|
||||
{
|
||||
return d->files;
|
||||
}
|
||||
@@ -96,11 +96,10 @@ bool Matroska::Attachments::render()
|
||||
auto beforeSize = size();
|
||||
auto data = attachments.render();
|
||||
auto afterSize = data.size();
|
||||
if (beforeSize != afterSize) {
|
||||
if (!emitSizeChanged(afterSize - beforeSize))
|
||||
if(beforeSize != afterSize) {
|
||||
if(!emitSizeChanged(afterSize - beforeSize))
|
||||
return false;
|
||||
}
|
||||
setData(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "tlist.h"
|
||||
#include "matroskaelement.h"
|
||||
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
namespace EBML {
|
||||
@@ -37,23 +36,23 @@ namespace TagLib {
|
||||
class File;
|
||||
class TAGLIB_EXPORT Attachments
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
: private Element
|
||||
: private Element
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
using AttachedFileList = List<AttachedFile*>;
|
||||
using AttachedFileList = List<AttachedFile *>;
|
||||
Attachments();
|
||||
virtual ~Attachments();
|
||||
|
||||
void addAttachedFile(AttachedFile *file);
|
||||
void removeAttachedFile(AttachedFile *file);
|
||||
void clear();
|
||||
const AttachedFileList& attachedFileList() const;
|
||||
bool render() override;
|
||||
void addAttachedFile(AttachedFile *file);
|
||||
void removeAttachedFile(AttachedFile *file);
|
||||
void clear();
|
||||
const AttachedFileList &attachedFileList() const;
|
||||
bool render() override;
|
||||
|
||||
private:
|
||||
friend class EBML::MkAttachments;
|
||||
friend class Matroska::File;
|
||||
friend class File;
|
||||
class AttachmentsPrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<AttachmentsPrivate> d;
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
Matroska::Cues::Cues()
|
||||
: Element(ElementIDs::MkCues)
|
||||
Matroska::Cues::Cues() :
|
||||
Element(ElementIDs::MkCues)
|
||||
{
|
||||
cuePoints.setAutoDelete(true);
|
||||
}
|
||||
@@ -38,21 +38,21 @@ Matroska::Cues::Cues()
|
||||
ByteVector Matroska::Cues::renderInternal()
|
||||
{
|
||||
EBML::MkCues cues;
|
||||
for (auto &cuePoint : cuePoints) {
|
||||
for(auto &cuePoint : cuePoints) {
|
||||
auto cuePointElement = new EBML::MasterElement(EBML::ElementIDs::MkCuePoint);
|
||||
auto timestamp = new EBML::UIntElement(EBML::ElementIDs::MkCueTime);
|
||||
timestamp->setValue(cuePoint->getTime());
|
||||
cuePointElement->appendElement(timestamp);
|
||||
|
||||
auto trackList = cuePoint->cueTrackList();
|
||||
for (auto &cueTrack : trackList) {
|
||||
for(auto &cueTrack : trackList) {
|
||||
auto cueTrackElement = new EBML::MasterElement(EBML::ElementIDs::MkCueTrackPositions);
|
||||
|
||||
|
||||
// Track number
|
||||
auto trackNumber = new EBML::UIntElement(EBML::ElementIDs::MkCueTrack);
|
||||
trackNumber->setValue(cueTrack->getTrackNumber());
|
||||
cueTrackElement->appendElement(trackNumber);
|
||||
|
||||
|
||||
// Cluster position
|
||||
auto clusterPosition = new EBML::UIntElement(EBML::ElementIDs::MkCueClusterPosition);
|
||||
clusterPosition->setValue(cueTrack->getClusterPosition());
|
||||
@@ -60,12 +60,11 @@ ByteVector Matroska::Cues::renderInternal()
|
||||
|
||||
// Todo - other elements
|
||||
|
||||
|
||||
// Reference times
|
||||
auto referenceTimes = cueTrack->referenceTimes();
|
||||
if (!referenceTimes.isEmpty()) {
|
||||
if(!referenceTimes.isEmpty()) {
|
||||
auto cueReference = new EBML::MasterElement(EBML::ElementIDs::MkCueReference);
|
||||
for (auto reference : referenceTimes) {
|
||||
for(auto reference : referenceTimes) {
|
||||
auto refTime = new EBML::UIntElement(EBML::ElementIDs::MkCueRefTime);
|
||||
refTime->setValue(reference);
|
||||
cueReference->appendElement(refTime);
|
||||
@@ -80,11 +79,10 @@ ByteVector Matroska::Cues::renderInternal()
|
||||
|
||||
bool Matroska::Cues::render()
|
||||
{
|
||||
if (!needsRender)
|
||||
if(!needsRender)
|
||||
return true;
|
||||
|
||||
|
||||
setData(cues.render());
|
||||
setData(renderInternal());
|
||||
needsRender = false;
|
||||
return true;
|
||||
}
|
||||
@@ -92,15 +90,15 @@ bool Matroska::Cues::render()
|
||||
bool Matroska::Cues::sizeChanged(Element &caller, offset_t delta)
|
||||
{
|
||||
offset_t offset = caller.offset();
|
||||
for (auto cuePoint : cuePoints)
|
||||
for(auto cuePoint : cuePoints)
|
||||
needsRender |= cuePoint->adjustOffset(offset, delta);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matroska::Cues::isValid(TagLib::File &file, offset_t segmentDataOffset) const
|
||||
{
|
||||
for (const auto cuePoint : cuePoints) {
|
||||
if (!cuePoint->isValid(file, segmentDataOffset))
|
||||
for(const auto cuePoint : cuePoints) {
|
||||
if(!cuePoint->isValid(file, segmentDataOffset))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -113,8 +111,8 @@ Matroska::CuePoint::CuePoint()
|
||||
|
||||
bool Matroska::CuePoint::isValid(TagLib::File &file, offset_t segmentDataOffset) const
|
||||
{
|
||||
for (const auto track : cueTracks) {
|
||||
if (!track->isValid(file, segmentDataOffset))
|
||||
for(const auto track : cueTracks) {
|
||||
if(!track->isValid(file, segmentDataOffset))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -123,7 +121,7 @@ bool Matroska::CuePoint::isValid(TagLib::File &file, offset_t segmentDataOffset)
|
||||
bool Matroska::CuePoint::adjustOffset(offset_t offset, offset_t delta)
|
||||
{
|
||||
bool ret = false;
|
||||
for (auto cueTrack : cueTracks)
|
||||
for(auto cueTrack : cueTracks)
|
||||
ret |= cueTrack->adjustOffset(offset, delta);
|
||||
|
||||
return ret;
|
||||
@@ -131,22 +129,22 @@ bool Matroska::CuePoint::adjustOffset(offset_t offset, offset_t delta)
|
||||
|
||||
bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset) const
|
||||
{
|
||||
if (!trackNumber) {
|
||||
if(!trackNumber) {
|
||||
debug("Cue track number not set");
|
||||
return false;
|
||||
}
|
||||
if (!clusterPosition) {
|
||||
if(!clusterPosition) {
|
||||
debug("Cue track cluster position not set");
|
||||
return false;
|
||||
}
|
||||
file.seek(segmentDataOffset + clusterPosition);
|
||||
if (EBML::Element::readId(file) != EBML::ElementIDs::MkCluster) {
|
||||
if(EBML::Element::readId(file) != EBML::ElementIDs::MkCluster) {
|
||||
debug("No cluster found at position");
|
||||
return false;
|
||||
}
|
||||
if (codecState) {
|
||||
if(codecState) {
|
||||
file.seek(segmentDataOffset + codecState);
|
||||
if (EBML::Element::readId(file) != EBML::ElementIDs::MkCodecState) {
|
||||
if(EBML::Element::readId(file) != EBML::ElementIDs::MkCodecState) {
|
||||
debug("No codec state found at position");
|
||||
return false;
|
||||
}
|
||||
@@ -154,8 +152,7 @@ bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matroska::CueTrack::adjustOffset(offset_t offset, offset_t delta)
|
||||
bool Matroska::CueTrack::adjustOffset(offset_t, offset_t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
#define HAS_MATROSKACUES_H
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "tlist.h"
|
||||
#include "matroskaelement.h"
|
||||
|
||||
@@ -41,39 +37,37 @@ namespace TagLib {
|
||||
class Cues : public Element
|
||||
{
|
||||
public:
|
||||
using CuePointList = List<CuePoint*>;
|
||||
using CuePointList = List<CuePoint *>;
|
||||
Cues();
|
||||
~Cues() override = default;
|
||||
bool isValid(TagLib::File &file, offset_t segmentDataOffset) const;
|
||||
bool isValid(File &file, offset_t segmentDataOffset) const;
|
||||
void addCuePoint(CuePoint *cuePoint) { cuePoints.append(cuePoint); }
|
||||
CuePointList cuePointList() { return cuePoints; }
|
||||
bool sizeChanged(Element &caller, offset_t delta) override;
|
||||
bool render() override;
|
||||
|
||||
|
||||
private:
|
||||
friend class EBML::MkCues;
|
||||
ByteVector renderInternal();
|
||||
bool needsRender = false;
|
||||
|
||||
List<CuePoint*> cuePoints;
|
||||
List<CuePoint *> cuePoints;
|
||||
};
|
||||
|
||||
class CuePoint
|
||||
{
|
||||
public:
|
||||
using CueTrackList = List<CueTrack*>;
|
||||
using CueTrackList = List<CueTrack *>;
|
||||
using Time = unsigned long long;
|
||||
CuePoint();
|
||||
~CuePoint() = default;
|
||||
bool isValid(TagLib::File &file, offset_t segmentDataOffset) const;
|
||||
bool isValid(File &file, offset_t segmentDataOffset) const;
|
||||
void addCueTrack(CueTrack *cueTrack) { cueTracks.append(cueTrack); }
|
||||
CueTrackList cueTrackList() const { return cueTracks; }
|
||||
void setTime(Time time) { this->time = time; }
|
||||
Time getTime() const { return time; }
|
||||
bool adjustOffset(offset_t offset, offset_t delta);
|
||||
|
||||
|
||||
private:
|
||||
CueTrackList cueTracks;
|
||||
Time time = 0;
|
||||
@@ -85,29 +79,28 @@ namespace TagLib {
|
||||
using ReferenceTimeList = List<unsigned long long>;
|
||||
CueTrack() = default;
|
||||
~CueTrack() = default;
|
||||
bool isValid(TagLib::File &file, offset_t segmentDataOffset) const;
|
||||
void setTrackNumber(unsigned int trackNumber) { this->trackNumber = trackNumber; }
|
||||
unsigned int getTrackNumber() const { return trackNumber; }
|
||||
bool isValid(File &file, offset_t segmentDataOffset) const;
|
||||
void setTrackNumber(unsigned long long trackNumber) { this->trackNumber = trackNumber; }
|
||||
unsigned long long getTrackNumber() const { return trackNumber; }
|
||||
void setClusterPosition(offset_t clusterPosition) { this->clusterPosition = clusterPosition; }
|
||||
offset_t getClusterPosition() const { return clusterPosition; }
|
||||
void setRelativePosition(offset_t relativePosition) { this->relativePosition = relativePosition; }
|
||||
offset_t getRelativePosition() const { return relativePosition; }
|
||||
void setCodecState(offset_t codecState) { this->codecState = codecState; }
|
||||
offset_t getCodecState() const { return codecState; }
|
||||
void setBlockNumber(unsigned int blockNumber) { this->blockNumber = blockNumber; }
|
||||
unsigned int getBlockNumber() const { return blockNumber; }
|
||||
void setBlockNumber(unsigned long long blockNumber) { this->blockNumber = blockNumber; }
|
||||
unsigned long long getBlockNumber() const { return blockNumber; }
|
||||
void setDuration(unsigned long long duration) { this->duration = duration; }
|
||||
unsigned long long getDuration() const { return duration; }
|
||||
void addReferenceTime(unsigned long long refTime) { refTimes.append(refTime); }
|
||||
ReferenceTimeList referenceTimes() const { return refTimes; }
|
||||
bool adjustOffset(offset_t offset, offset_t delta);
|
||||
|
||||
|
||||
private:
|
||||
unsigned int trackNumber = 0;
|
||||
unsigned long long trackNumber = 0;
|
||||
offset_t clusterPosition = 0;
|
||||
offset_t relativePosition = 0;
|
||||
unsigned int blockNumber = 0;
|
||||
unsigned long long blockNumber = 0;
|
||||
unsigned long long duration = 0;
|
||||
offset_t codecState = 0;
|
||||
ReferenceTimeList refTimes;
|
||||
|
||||
@@ -28,7 +28,7 @@ using namespace TagLib;
|
||||
class Matroska::Element::ElementPrivate
|
||||
{
|
||||
public:
|
||||
ElementPrivate() {}
|
||||
ElementPrivate() = default;
|
||||
~ElementPrivate() = default;
|
||||
ElementPrivate(const ElementPrivate &) = delete;
|
||||
ElementPrivate &operator=(const ElementPrivate &) = delete;
|
||||
@@ -36,13 +36,12 @@ public:
|
||||
offset_t offset = 0;
|
||||
ID id = 0;
|
||||
ByteVector data;
|
||||
List<Element*> sizeListeners;
|
||||
List<Element*> offsetListeners;
|
||||
|
||||
List<Element *> sizeListeners;
|
||||
List<Element *> offsetListeners;
|
||||
};
|
||||
|
||||
Matroska::Element::Element(ID id)
|
||||
: e(std::make_unique<ElementPrivate>())
|
||||
Matroska::Element::Element(ID id) :
|
||||
e(std::make_unique<ElementPrivate>())
|
||||
{
|
||||
e->id = id;
|
||||
}
|
||||
@@ -63,12 +62,11 @@ void Matroska::Element::setData(const ByteVector &data)
|
||||
e->data = data;
|
||||
}
|
||||
|
||||
const ByteVector& Matroska::Element::data() const
|
||||
const ByteVector &Matroska::Element::data() const
|
||||
{
|
||||
return e->data;
|
||||
}
|
||||
|
||||
|
||||
void Matroska::Element::setOffset(offset_t offset)
|
||||
{
|
||||
e->offset = offset;
|
||||
@@ -94,7 +92,7 @@ void Matroska::Element::addSizeListener(Element *element)
|
||||
e->sizeListeners.append(element);
|
||||
}
|
||||
|
||||
void Matroska::Element::addSizeListeners(const List<Element*> &elements)
|
||||
void Matroska::Element::addSizeListeners(const List<Element *> &elements)
|
||||
{
|
||||
e->sizeListeners.append(elements);
|
||||
}
|
||||
@@ -104,7 +102,7 @@ void Matroska::Element::addOffsetListener(Element *element)
|
||||
e->offsetListeners.append(element);
|
||||
}
|
||||
|
||||
void Matroska::Element::addOffsetListeners(const List<Element*> &elements)
|
||||
void Matroska::Element::addOffsetListeners(const List<Element *> &elements)
|
||||
{
|
||||
e->offsetListeners.append(elements);
|
||||
}
|
||||
@@ -117,7 +115,7 @@ void Matroska::Element::setID(ID id)
|
||||
bool Matroska::Element::emitSizeChanged(offset_t delta)
|
||||
{
|
||||
for(auto element : e->sizeListeners) {
|
||||
if (!element->sizeChanged(*this, delta))
|
||||
if(!element->sizeChanged(*this, delta))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -134,7 +132,7 @@ bool Matroska::Element::emitOffsetChanged(offset_t delta)
|
||||
|
||||
bool Matroska::Element::sizeChanged(Element &caller, offset_t delta)
|
||||
{
|
||||
if (caller.offset() < e->offset) {
|
||||
if(caller.offset() < e->offset) {
|
||||
e->offset += delta;
|
||||
//return emitOffsetChanged(delta);
|
||||
}
|
||||
@@ -147,7 +145,7 @@ bool Matroska::Element::offsetChanged(Element &, offset_t)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Matroska::Element::write(TagLib::File &file)
|
||||
void Matroska::Element::write(File &file)
|
||||
{
|
||||
file.insert(e->data, e->offset, e->size);
|
||||
e->size = e->data.size();
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
#include <memory>
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tutils.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tlist.h"
|
||||
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
namespace Matroska {
|
||||
@@ -37,7 +35,7 @@ namespace TagLib {
|
||||
{
|
||||
public:
|
||||
using ID = unsigned int;
|
||||
Element(ID id);
|
||||
explicit Element(ID id);
|
||||
virtual ~Element();
|
||||
|
||||
offset_t size() const;
|
||||
@@ -50,12 +48,12 @@ namespace TagLib {
|
||||
//virtual ByteVector render() = 0;
|
||||
virtual bool render() = 0;
|
||||
void setData(const ByteVector &data);
|
||||
const ByteVector& data() const;
|
||||
const ByteVector &data() const;
|
||||
virtual void write(TagLib::File &file);
|
||||
void addSizeListener(Element *element);
|
||||
void addSizeListeners(const List<Element*> &elements);
|
||||
void addSizeListeners(const List<Element *> &elements);
|
||||
void addOffsetListener(Element *element);
|
||||
void addOffsetListeners(const List<Element*> &elements);
|
||||
void addOffsetListeners(const List<Element *> &elements);
|
||||
//virtual void updatePosition(Element &caller, offset_t delta) = 0;
|
||||
bool emitSizeChanged(offset_t delta);
|
||||
bool emitOffsetChanged(offset_t delta);
|
||||
@@ -72,6 +70,7 @@ namespace TagLib {
|
||||
inline constexpr Element::ID MkAttachments = 0x1941A469;
|
||||
inline constexpr Element::ID MkSeekHead = 0x114D9B74;
|
||||
inline constexpr Element::ID MkSegment = 0x18538067;
|
||||
inline constexpr Element::ID MkCues = 0x1C53BB6B;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,8 @@
|
||||
#include "ebmlmksegment.h"
|
||||
#include "tlist.h"
|
||||
#include "tdebug.h"
|
||||
#include "tutils.h"
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace TagLib;
|
||||
@@ -39,7 +37,7 @@ using namespace TagLib;
|
||||
class Matroska::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() {}
|
||||
FilePrivate() = default;
|
||||
~FilePrivate()
|
||||
{
|
||||
delete tag;
|
||||
@@ -49,7 +47,7 @@ public:
|
||||
|
||||
FilePrivate(const FilePrivate &) = delete;
|
||||
FilePrivate &operator=(const FilePrivate &) = delete;
|
||||
Matroska::Tag *tag = nullptr;
|
||||
Tag *tag = nullptr;
|
||||
Attachments *attachments = nullptr;
|
||||
SeekHead *seekHead = nullptr;
|
||||
Segment *segment = nullptr;
|
||||
@@ -70,8 +68,8 @@ bool Matroska::File::isSupported(IOStream *)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Matroska::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle readStyle)
|
||||
: TagLib::File(file),
|
||||
Properties::ReadStyle readStyle) :
|
||||
TagLib::File(file),
|
||||
d(std::make_unique<FilePrivate>())
|
||||
{
|
||||
if(!isOpen()) {
|
||||
@@ -83,8 +81,8 @@ Matroska::File::File(FileName file, bool readProperties,
|
||||
}
|
||||
|
||||
Matroska::File::File(IOStream *stream, bool readProperties,
|
||||
Properties::ReadStyle readStyle)
|
||||
: TagLib::File(stream),
|
||||
Properties::ReadStyle readStyle) :
|
||||
TagLib::File(stream),
|
||||
d(std::make_unique<FilePrivate>())
|
||||
{
|
||||
if(!isOpen()) {
|
||||
@@ -97,23 +95,23 @@ Matroska::File::File(IOStream *stream, bool readProperties,
|
||||
|
||||
Matroska::File::~File() = default;
|
||||
|
||||
TagLib::Tag* Matroska::File::tag() const
|
||||
Tag *Matroska::File::tag() const
|
||||
{
|
||||
return tag(true);
|
||||
}
|
||||
|
||||
Matroska::Tag* Matroska::File::tag(bool create) const
|
||||
Matroska::Tag *Matroska::File::tag(bool create) const
|
||||
{
|
||||
if(d->tag)
|
||||
return d->tag;
|
||||
else {
|
||||
if(create)
|
||||
d->tag = new Matroska::Tag();
|
||||
d->tag = new Tag();
|
||||
return d->tag;
|
||||
}
|
||||
}
|
||||
|
||||
Matroska::Attachments* Matroska::File::attachments(bool create) const
|
||||
Matroska::Attachments *Matroska::File::attachments(bool create) const
|
||||
{
|
||||
if(d->attachments)
|
||||
return d->attachments;
|
||||
@@ -139,7 +137,7 @@ void Matroska::File::read(bool, Properties::ReadStyle)
|
||||
|
||||
// Find the Matroska segment in the file
|
||||
std::unique_ptr<EBML::MkSegment> segment(
|
||||
static_cast<EBML::MkSegment*>(
|
||||
static_cast<EBML::MkSegment *>(
|
||||
EBML::findElement(*this, EBML::ElementIDs::MkSegment, fileLength - tell())
|
||||
)
|
||||
);
|
||||
@@ -176,34 +174,34 @@ bool Matroska::File::save()
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Element*> renderList;
|
||||
List<Element*> newElements;
|
||||
List<Element *> renderList;
|
||||
List<Element *> newElements;
|
||||
|
||||
// List of all possible elements we can write
|
||||
List<Element*> elements {
|
||||
List<Element *> elements {
|
||||
d->attachments,
|
||||
d->tag
|
||||
};
|
||||
|
||||
/* Build render list. New elements will be added
|
||||
* to the end of the file. For new elements,
|
||||
* the order is from least likely to change,
|
||||
* to most likely to change:
|
||||
* 1. Bookmarks (todo)
|
||||
* 2. Attachments
|
||||
* 3. Tags
|
||||
*/
|
||||
for (auto element : elements) {
|
||||
if (!element)
|
||||
/* Build render list. New elements will be added
|
||||
* to the end of the file. For new elements,
|
||||
* the order is from least likely to change,
|
||||
* to most likely to change:
|
||||
* 1. Bookmarks (todo)
|
||||
* 2. Attachments
|
||||
* 3. Tags
|
||||
*/
|
||||
for(auto element : elements) {
|
||||
if(!element)
|
||||
continue;
|
||||
if (element->size())
|
||||
if(element->size())
|
||||
renderList.append(element);
|
||||
else {
|
||||
element->setOffset(length());
|
||||
newElements.append(element);
|
||||
}
|
||||
}
|
||||
if (renderList.isEmpty())
|
||||
if(renderList.isEmpty())
|
||||
return true;
|
||||
|
||||
auto sortAscending = [](const auto a, const auto b) { return a->offset() < b->offset(); };
|
||||
@@ -211,18 +209,18 @@ bool Matroska::File::save()
|
||||
renderList.append(newElements);
|
||||
|
||||
// Add our new elements to the Seek Head (if the file has one)
|
||||
if (d->seekHead) {
|
||||
if(d->seekHead) {
|
||||
auto segmentDataOffset = d->segment->dataOffset();
|
||||
for (auto element : newElements)
|
||||
for(auto element : newElements)
|
||||
d->seekHead->addEntry(element->id(), element->offset() - segmentDataOffset);
|
||||
d->seekHead->sort();
|
||||
}
|
||||
|
||||
// Set up listeners, add seek head and segment length to the end
|
||||
for(auto it = renderList.begin(); it != renderList.end(); ++it) {
|
||||
for (auto it2 = std::next(it); it2 != renderList.end(); ++it2)
|
||||
for(auto it2 = std::next(it); it2 != renderList.end(); ++it2)
|
||||
(*it)->addSizeListener(*it2);
|
||||
if (d->seekHead)
|
||||
if(d->seekHead)
|
||||
(*it)->addSizeListener(d->seekHead);
|
||||
(*it)->addSizeListener(d->segment);
|
||||
}
|
||||
@@ -235,7 +233,7 @@ bool Matroska::File::save()
|
||||
|
||||
// Render the elements
|
||||
for(auto element : renderList) {
|
||||
if (!element->render())
|
||||
if(!element->render())
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,46 +26,43 @@
|
||||
#include "tag.h"
|
||||
#include "matroskaproperties.h"
|
||||
|
||||
namespace TagLib::Matroska {
|
||||
class Properties;
|
||||
class Tag;
|
||||
class Attachments;
|
||||
class TAGLIB_EXPORT File : public TagLib::File
|
||||
{
|
||||
public:
|
||||
explicit File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle readStyle = Properties::Average);
|
||||
explicit File(IOStream *stream, bool readProperties = true,
|
||||
Properties::ReadStyle readStyle = Properties::Average);
|
||||
~File() override;
|
||||
File(const File &) = delete;
|
||||
File &operator=(const File &) = delete;
|
||||
AudioProperties *audioProperties() const override { return nullptr; }
|
||||
TagLib::Tag *tag() const override;
|
||||
Attachments *attachments(bool create = false) const;
|
||||
Tag *tag(bool create) const;
|
||||
bool save() override;
|
||||
//PropertyMap properties() const override { return PropertyMap(); }
|
||||
//void removeUnsupportedProperties(const StringList &properties) override { }
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class Properties;
|
||||
class Tag;
|
||||
class Attachments;
|
||||
class TAGLIB_EXPORT File : public TagLib::File
|
||||
{
|
||||
public:
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle readStyle = Properties::Average);
|
||||
File(IOStream *stream, bool readProperties = true,
|
||||
Properties::ReadStyle readStyle = Properties::Average);
|
||||
~File() override;
|
||||
File(const File &) = delete;
|
||||
File &operator=(const File &) = delete;
|
||||
AudioProperties *audioProperties() const override { return nullptr; }
|
||||
TagLib::Tag *tag() const override;
|
||||
Attachments* attachments(bool create = false) const;
|
||||
Matroska::Tag *tag(bool create) const;
|
||||
bool save() override;
|
||||
//PropertyMap properties() const override { return PropertyMap(); }
|
||||
//void removeUnsupportedProperties(const StringList &properties) override { }
|
||||
/*!
|
||||
* Returns whether or not the given \a stream can be opened as a Matroska
|
||||
* file.
|
||||
*
|
||||
* \note This method is designed to do a quick check. The result may
|
||||
* not necessarily be correct.
|
||||
*/
|
||||
static bool isSupported(IOStream *stream);
|
||||
|
||||
/*!
|
||||
* Returns whether or not the given \a stream can be opened as a Matroska
|
||||
* file.
|
||||
*
|
||||
* \note This method is designed to do a quick check. The result may
|
||||
* not necessarily be correct.
|
||||
*/
|
||||
static bool isSupported(IOStream *stream);
|
||||
|
||||
private:
|
||||
void read(bool readProperties, Properties::ReadStyle readStyle);
|
||||
class FilePrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<FilePrivate> d;
|
||||
};
|
||||
}
|
||||
private:
|
||||
void read(bool readProperties, Properties::ReadStyle readStyle);
|
||||
class FilePrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<FilePrivate> d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,7 @@ int Matroska::Properties::channels() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Matroska::Properties::read(File *file)
|
||||
void Matroska::Properties::read(File *)
|
||||
{
|
||||
// TODO implement.
|
||||
}
|
||||
|
||||
@@ -24,54 +24,49 @@
|
||||
#include "taglib_export.h"
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib::Matroska {
|
||||
|
||||
namespace TagLib {
|
||||
class File;
|
||||
|
||||
namespace Matroska {
|
||||
//! An implementation of Matroska audio properties
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
explicit Properties(File *file, ReadStyle style = Average);
|
||||
~Properties() override;
|
||||
|
||||
class File;
|
||||
Properties(const Properties &) = delete;
|
||||
Properties &operator=(const Properties &) = delete;
|
||||
|
||||
//! An implementation of Matroska audio properties
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Returns the length of the file in milliseconds.
|
||||
*
|
||||
* \see lengthInSeconds()
|
||||
*/
|
||||
int lengthInMilliseconds() const override;
|
||||
|
||||
Properties(File *file, ReadStyle style = Average);
|
||||
~Properties() override;
|
||||
/*!
|
||||
* Returns the average bit rate of the file in kb/s.
|
||||
*/
|
||||
int bitrate() const override;
|
||||
|
||||
Properties(const Properties &) = delete;
|
||||
Properties &operator=(const Properties &) = delete;
|
||||
/*!
|
||||
* Returns the sample rate in Hz.
|
||||
*/
|
||||
int sampleRate() const override;
|
||||
|
||||
/*!
|
||||
* Returns the length of the file in milliseconds.
|
||||
*
|
||||
* \see lengthInSeconds()
|
||||
*/
|
||||
int lengthInMilliseconds() const override;
|
||||
/*!
|
||||
* Returns the number of audio channels.
|
||||
*/
|
||||
int channels() const override;
|
||||
|
||||
/*!
|
||||
* Returns the average bit rate of the file in kb/s.
|
||||
*/
|
||||
int bitrate() const override;
|
||||
private:
|
||||
void read(File *file);
|
||||
|
||||
/*!
|
||||
* Returns the sample rate in Hz.
|
||||
*/
|
||||
int sampleRate() const override;
|
||||
|
||||
/*!
|
||||
* Returns the number of audio channels.
|
||||
*/
|
||||
int channels() const override;
|
||||
|
||||
private:
|
||||
void read(File *file);
|
||||
|
||||
class PropertiesPrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<PropertiesPrivate> d;
|
||||
};
|
||||
} // namespace Matroska
|
||||
} // namespace TagLib
|
||||
class PropertiesPrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<PropertiesPrivate> d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,19 +18,16 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "matroskaseekhead.h"
|
||||
#include "ebmlmkseekhead.h"
|
||||
#include "ebmlbinaryelement.h"
|
||||
#include "ebmluintelement.h"
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "matroskaseekhead.h"
|
||||
#include "ebmlmkseekhead.h"
|
||||
#include "ebmlbinaryelement.h"
|
||||
#include "ebmluintelement.h"
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#include "tdebug.h"
|
||||
#include "tfile.h"
|
||||
#include "tutils.h"
|
||||
using namespace TagLib;
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
void Matroska::SeekHead::addEntry(Element &element)
|
||||
void Matroska::SeekHead::addEntry(const Element &element)
|
||||
{
|
||||
entries.append({element.id(), element.offset()});
|
||||
debug("adding to seekhead");
|
||||
@@ -48,7 +45,7 @@ ByteVector Matroska::SeekHead::renderInternal()
|
||||
auto beforeSize = size();
|
||||
EBML::MkSeekHead seekHead;
|
||||
seekHead.setMinRenderSize(beforeSize);
|
||||
for(const auto& [id, position] : entries) {
|
||||
for(const auto &[id, position] : entries) {
|
||||
auto seekElement = new EBML::MasterElement(EBML::ElementIDs::MkSeek);
|
||||
auto idElement = new EBML::BinaryElement(EBML::ElementIDs::MkSeekID);
|
||||
idElement->setValue(ByteVector::fromUInt(id, true));
|
||||
@@ -65,17 +62,17 @@ ByteVector Matroska::SeekHead::renderInternal()
|
||||
|
||||
bool Matroska::SeekHead::render()
|
||||
{
|
||||
if (!needsRender)
|
||||
if(!needsRender)
|
||||
return true;
|
||||
|
||||
auto beforeSize = size();
|
||||
auto data = renderInternal();
|
||||
needsRender = false;
|
||||
auto afterSize = data.size();
|
||||
if (afterSize != beforeSize) {
|
||||
if(afterSize != beforeSize) {
|
||||
return false;
|
||||
// To do, handle expansion of seek head
|
||||
if (!emitSizeChanged(afterSize - beforeSize))
|
||||
// TODO handle expansion of seek head
|
||||
if(!emitSizeChanged(afterSize - beforeSize))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,9 +80,9 @@ bool Matroska::SeekHead::render()
|
||||
return true;
|
||||
}
|
||||
|
||||
void Matroska::SeekHead::write(TagLib::File &file)
|
||||
void Matroska::SeekHead::write(File &file)
|
||||
{
|
||||
if (!data().isEmpty())
|
||||
if(!data().isEmpty())
|
||||
Element::write(file);
|
||||
}
|
||||
|
||||
@@ -97,19 +94,19 @@ void Matroska::SeekHead::sort()
|
||||
bool Matroska::SeekHead::sizeChanged(Element &caller, offset_t delta)
|
||||
{
|
||||
ID callerID = caller.id();
|
||||
if (callerID == ElementIDs::MkSegment) {
|
||||
if(callerID == ElementIDs::MkSegment) {
|
||||
adjustOffset(delta);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
offset_t offset = caller.offset();
|
||||
auto it = entries.begin();
|
||||
while (it != entries.end()) {
|
||||
while(it != entries.end()) {
|
||||
it = std::find_if(it,
|
||||
entries.end(),
|
||||
[offset](const auto a){ return a.second > offset; }
|
||||
);
|
||||
if (it != entries.end()) {
|
||||
if(it != entries.end()) {
|
||||
it->second += delta;
|
||||
needsRender = true;
|
||||
++it;
|
||||
@@ -117,5 +114,4 @@ bool Matroska::SeekHead::sizeChanged(Element &caller, offset_t delta)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "matroskaelement.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tutils.h"
|
||||
#include "tlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
@@ -33,9 +32,9 @@ namespace TagLib {
|
||||
class SeekHead : public Element
|
||||
{
|
||||
public:
|
||||
SeekHead() : Element(ElementIDs::MkSeekHead) {};
|
||||
virtual ~SeekHead() {};
|
||||
void addEntry(Element &element);
|
||||
SeekHead() : Element(ElementIDs::MkSeekHead) {}
|
||||
~SeekHead() override = default;
|
||||
void addEntry(const Element &element);
|
||||
void addEntry(ID id, offset_t offset);
|
||||
bool render() override;
|
||||
void write(TagLib::File &file) override;
|
||||
|
||||
@@ -26,12 +26,12 @@ using namespace TagLib;
|
||||
bool Matroska::Segment::render()
|
||||
{
|
||||
auto data = EBML::renderVINT(dataSize, static_cast<int>(sizeLength));
|
||||
if (data.size() != sizeLength) {
|
||||
if(data.size() != sizeLength) {
|
||||
sizeLength = 8;
|
||||
if (!emitSizeChanged(sizeLength - data.size()))
|
||||
if(!emitSizeChanged(sizeLength - data.size()))
|
||||
return false;
|
||||
data = EBML::renderVINT(dataSize, static_cast<int>(sizeLength));
|
||||
if (data.size() != sizeLength)
|
||||
if(data.size() != sizeLength)
|
||||
return false;
|
||||
}
|
||||
setData(data);
|
||||
|
||||
@@ -23,30 +23,29 @@
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
|
||||
#include "matroskaelement.h"
|
||||
#include "tutils.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
class Segment : public Element
|
||||
namespace TagLib::Matroska {
|
||||
class Segment : public Element
|
||||
{
|
||||
public:
|
||||
Segment(offset_t sizeLength, offset_t dataSize, offset_t lengthOffset) :
|
||||
Element(ElementIDs::MkSegment), sizeLength(sizeLength), dataSize(dataSize)
|
||||
{
|
||||
public:
|
||||
Segment(offset_t sizeLength, offset_t dataSize, offset_t lengthOffset)
|
||||
: Element(ElementIDs::MkSegment), sizeLength(sizeLength), dataSize(dataSize)
|
||||
{
|
||||
setOffset(lengthOffset);
|
||||
setSize(sizeLength);
|
||||
}
|
||||
virtual ~Segment() = default;
|
||||
bool render() override;
|
||||
bool sizeChanged(Element &caller, offset_t delta) override;
|
||||
offset_t dataOffset() const { return offset() + sizeLength; }
|
||||
|
||||
private:
|
||||
offset_t sizeLength;
|
||||
offset_t dataSize;
|
||||
};
|
||||
}
|
||||
setOffset(lengthOffset);
|
||||
setSize(sizeLength);
|
||||
}
|
||||
|
||||
~Segment() override = default;
|
||||
bool render() override;
|
||||
bool sizeChanged(Element &caller, offset_t delta) override;
|
||||
offset_t dataOffset() const { return offset() + sizeLength; }
|
||||
|
||||
private:
|
||||
offset_t sizeLength;
|
||||
offset_t dataSize;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -27,39 +27,34 @@ using namespace TagLib;
|
||||
|
||||
class Matroska::SimpleTag::SimpleTagPrivate
|
||||
{
|
||||
public:
|
||||
SimpleTagPrivate() = default;
|
||||
SimpleTag::TargetTypeValue targetTypeValue = TargetTypeValue::None;
|
||||
String name;
|
||||
String language;
|
||||
bool defaultLanguageFlag = true;
|
||||
|
||||
public:
|
||||
SimpleTagPrivate() = default;
|
||||
TargetTypeValue targetTypeValue = None;
|
||||
String name;
|
||||
String language;
|
||||
bool defaultLanguageFlag = true;
|
||||
};
|
||||
|
||||
class Matroska::SimpleTagString::SimpleTagStringPrivate
|
||||
{
|
||||
public:
|
||||
SimpleTagStringPrivate() = default;
|
||||
String value;
|
||||
|
||||
public:
|
||||
SimpleTagStringPrivate() = default;
|
||||
String value;
|
||||
};
|
||||
|
||||
class Matroska::SimpleTagBinary::SimpleTagBinaryPrivate
|
||||
{
|
||||
public:
|
||||
SimpleTagBinaryPrivate() = default;
|
||||
ByteVector value;
|
||||
|
||||
public:
|
||||
SimpleTagBinaryPrivate() = default;
|
||||
ByteVector value;
|
||||
};
|
||||
|
||||
Matroska::SimpleTag::SimpleTag()
|
||||
: d(std::make_unique<SimpleTagPrivate>())
|
||||
Matroska::SimpleTag::SimpleTag() :
|
||||
d(std::make_unique<SimpleTagPrivate>())
|
||||
{
|
||||
|
||||
}
|
||||
Matroska::SimpleTag::~SimpleTag() = default;
|
||||
|
||||
|
||||
Matroska::SimpleTag::TargetTypeValue Matroska::SimpleTag::targetTypeValue() const
|
||||
{
|
||||
return d->targetTypeValue;
|
||||
@@ -70,12 +65,12 @@ void Matroska::SimpleTag::setTargetTypeValue(TargetTypeValue targetTypeValue)
|
||||
d->targetTypeValue = targetTypeValue;
|
||||
}
|
||||
|
||||
const String& Matroska::SimpleTag::name() const
|
||||
const String &Matroska::SimpleTag::name() const
|
||||
{
|
||||
return d->name;
|
||||
}
|
||||
|
||||
const String& Matroska::SimpleTag::language() const
|
||||
const String &Matroska::SimpleTag::language() const
|
||||
{
|
||||
return d->language;
|
||||
}
|
||||
@@ -100,15 +95,13 @@ void Matroska::SimpleTag::setName(const String &name)
|
||||
d->name = name;
|
||||
}
|
||||
|
||||
Matroska::SimpleTagString::SimpleTagString()
|
||||
: Matroska::SimpleTag(),
|
||||
Matroska::SimpleTagString::SimpleTagString() :
|
||||
dd(std::make_unique<SimpleTagStringPrivate>())
|
||||
{
|
||||
|
||||
}
|
||||
Matroska::SimpleTagString::~SimpleTagString() = default;
|
||||
|
||||
const String& Matroska::SimpleTagString::value() const
|
||||
const String &Matroska::SimpleTagString::value() const
|
||||
{
|
||||
return dd->value;
|
||||
}
|
||||
@@ -118,15 +111,13 @@ void Matroska::SimpleTagString::setValue(const String &value)
|
||||
dd->value = value;
|
||||
}
|
||||
|
||||
Matroska::SimpleTagBinary::SimpleTagBinary()
|
||||
: Matroska::SimpleTag(),
|
||||
Matroska::SimpleTagBinary::SimpleTagBinary() :
|
||||
dd(std::make_unique<SimpleTagBinaryPrivate>())
|
||||
{
|
||||
|
||||
}
|
||||
Matroska::SimpleTagBinary::~SimpleTagBinary() = default;
|
||||
|
||||
const ByteVector& Matroska::SimpleTagBinary::value() const
|
||||
const ByteVector &Matroska::SimpleTagBinary::value() const
|
||||
{
|
||||
return dd->value;
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ namespace TagLib {
|
||||
Edition = 60,
|
||||
Collection = 70
|
||||
};
|
||||
const String& name() const;
|
||||
const String &name() const;
|
||||
TargetTypeValue targetTypeValue() const;
|
||||
const String& language() const;
|
||||
const String &language() const;
|
||||
bool defaultLanguageFlag() const;
|
||||
void setName(const String &name);
|
||||
void setTargetTypeValue(TargetTypeValue targetTypeValue);
|
||||
@@ -66,7 +66,7 @@ namespace TagLib {
|
||||
public:
|
||||
SimpleTagString();
|
||||
~SimpleTagString() override;
|
||||
const String& value() const;
|
||||
const String &value() const;
|
||||
void setValue(const String &value);
|
||||
|
||||
private:
|
||||
@@ -80,7 +80,7 @@ namespace TagLib {
|
||||
public:
|
||||
SimpleTagBinary();
|
||||
~SimpleTagBinary() override;
|
||||
const ByteVector& value() const;
|
||||
const ByteVector &value() const;
|
||||
void setValue(const ByteVector &value);
|
||||
|
||||
private:
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "matroskatag.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
#include "matroskasimpletag.h"
|
||||
#include "ebmlmasterelement.h"
|
||||
#include "ebmlstringelement.h"
|
||||
@@ -27,35 +30,24 @@
|
||||
#include "ebmlutils.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tlist.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace TagLib {
|
||||
namespace Matroska {
|
||||
namespace Utils {
|
||||
std::pair<String, Matroska::SimpleTag::TargetTypeValue> translateKey(const String &key);
|
||||
String translateTag(const String &name, Matroska::SimpleTag::TargetTypeValue targetTypeValue);
|
||||
}
|
||||
}
|
||||
namespace TagLib::Matroska::Utils {
|
||||
std::pair<String, SimpleTag::TargetTypeValue> translateKey(const String &key);
|
||||
String translateTag(const String &name, SimpleTag::TargetTypeValue targetTypeValue);
|
||||
}
|
||||
|
||||
class Matroska::Tag::TagPrivate
|
||||
class Matroska::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
TagPrivate() = default;
|
||||
~TagPrivate() = default;
|
||||
List<SimpleTag*> tags;
|
||||
ByteVector data;
|
||||
|
||||
public:
|
||||
TagPrivate() = default;
|
||||
~TagPrivate() = default;
|
||||
List<SimpleTag *> tags;
|
||||
ByteVector data;
|
||||
};
|
||||
|
||||
Matroska::Tag::Tag()
|
||||
: TagLib::Tag(),
|
||||
Matroska::Tag::Tag() :
|
||||
Element(ElementIDs::MkTags),
|
||||
d(std::make_unique<TagPrivate>())
|
||||
{
|
||||
@@ -82,17 +74,17 @@ void Matroska::Tag::clearSimpleTags()
|
||||
d->tags.clear();
|
||||
}
|
||||
|
||||
const Matroska::SimpleTagsList& Matroska::Tag::simpleTagsList() const
|
||||
const Matroska::SimpleTagsList &Matroska::Tag::simpleTagsList() const
|
||||
{
|
||||
return d->tags;
|
||||
}
|
||||
|
||||
Matroska::SimpleTagsList& Matroska::Tag::simpleTagsListPrivate()
|
||||
Matroska::SimpleTagsList &Matroska::Tag::simpleTagsListPrivate()
|
||||
{
|
||||
return d->tags;
|
||||
}
|
||||
|
||||
const Matroska::SimpleTagsList& Matroska::Tag::simpleTagsListPrivate() const
|
||||
const Matroska::SimpleTagsList &Matroska::Tag::simpleTagsListPrivate() const
|
||||
{
|
||||
return d->tags;
|
||||
}
|
||||
@@ -135,31 +127,31 @@ void Matroska::Tag::setTrack(unsigned int i)
|
||||
String Matroska::Tag::title() const
|
||||
{
|
||||
const auto value = getTag("TITLE");
|
||||
return value ? *value : String();
|
||||
return value ? *value : String();
|
||||
}
|
||||
|
||||
String Matroska::Tag::artist() const
|
||||
{
|
||||
const auto value = getTag("ARTIST");
|
||||
return value ? *value : String();
|
||||
return value ? *value : String();
|
||||
}
|
||||
|
||||
String Matroska::Tag::album() const
|
||||
{
|
||||
const auto value = getTag("ALBUM");
|
||||
return value ? *value : String();
|
||||
return value ? *value : String();
|
||||
}
|
||||
|
||||
String Matroska::Tag::comment() const
|
||||
{
|
||||
{
|
||||
const auto value = getTag("COMMENT");
|
||||
return value ? *value : String();
|
||||
return value ? *value : String();
|
||||
}
|
||||
|
||||
String Matroska::Tag::genre() const
|
||||
{
|
||||
const auto value = getTag("GENRE");
|
||||
return value ? *value : String();
|
||||
return value ? *value : String();
|
||||
}
|
||||
|
||||
unsigned int Matroska::Tag::year() const
|
||||
@@ -188,7 +180,7 @@ bool Matroska::Tag::isEmpty() const
|
||||
bool Matroska::Tag::render()
|
||||
{
|
||||
EBML::MkTags tags;
|
||||
List<List<SimpleTag*>*> targetList;
|
||||
List<List<SimpleTag *> *> targetList;
|
||||
targetList.setAutoDelete(true);
|
||||
|
||||
// Build target-based list
|
||||
@@ -202,7 +194,7 @@ bool Matroska::Tag::render()
|
||||
}
|
||||
);
|
||||
if(it == targetList.end()) {
|
||||
auto list = new List<SimpleTag*>();
|
||||
auto list = new List<SimpleTag *>();
|
||||
list->append(tag);
|
||||
targetList.append(list);
|
||||
}
|
||||
@@ -216,7 +208,7 @@ bool Matroska::Tag::render()
|
||||
|
||||
// Build <Tag Targets> element
|
||||
auto targets = new EBML::MasterElement(EBML::ElementIDs::MkTagTargets);
|
||||
if(targetTypeValue != Matroska::SimpleTag::TargetTypeValue::None) {
|
||||
if(targetTypeValue != SimpleTag::TargetTypeValue::None) {
|
||||
auto element = new EBML::UIntElement(EBML::ElementIDs::MkTagTargetTypeValue);
|
||||
element->setValue(static_cast<unsigned int>(targetTypeValue));
|
||||
targets->appendElement(element);
|
||||
@@ -231,14 +223,14 @@ bool Matroska::Tag::render()
|
||||
t->appendElement(tagName);
|
||||
|
||||
// Tag Value
|
||||
Matroska::SimpleTagString *tStr = nullptr;
|
||||
Matroska::SimpleTagBinary *tBin = nullptr;
|
||||
if((tStr = dynamic_cast<Matroska::SimpleTagString*>(simpleTag))) {
|
||||
SimpleTagString *tStr = nullptr;
|
||||
SimpleTagBinary *tBin = nullptr;
|
||||
if((tStr = dynamic_cast<SimpleTagString *>(simpleTag))) {
|
||||
auto tagValue = new EBML::UTF8StringElement(EBML::ElementIDs::MkTagString);
|
||||
tagValue->setValue(tStr->value());
|
||||
t->appendElement(tagValue);
|
||||
}
|
||||
else if((tBin = dynamic_cast<Matroska::SimpleTagBinary*>(simpleTag))) {
|
||||
else if((tBin = dynamic_cast<Matroska::SimpleTagBinary *>(simpleTag))) {
|
||||
// Todo
|
||||
}
|
||||
|
||||
@@ -261,8 +253,8 @@ bool Matroska::Tag::render()
|
||||
auto data = tags.render();
|
||||
auto beforeSize = size();
|
||||
auto afterSize = data.size();
|
||||
if (afterSize != beforeSize) {
|
||||
if (!emitSizeChanged(afterSize - beforeSize))
|
||||
if(afterSize != beforeSize) {
|
||||
if(!emitSizeChanged(afterSize - beforeSize))
|
||||
return false;
|
||||
}
|
||||
setData(data);
|
||||
@@ -307,20 +299,20 @@ namespace
|
||||
|
||||
bool Matroska::Tag::setTag(const String &key, const String &value)
|
||||
{
|
||||
const auto pair = Matroska::Utils::translateKey(key);
|
||||
const auto pair = Utils::translateKey(key);
|
||||
// Workaround Clang issue - no lambda capture of structured bindings
|
||||
const String &name = pair.first;
|
||||
auto targetTypeValue = pair.second;
|
||||
if(name.isEmpty())
|
||||
return false;
|
||||
removeSimpleTags(
|
||||
[&name, targetTypeValue] (auto t) {
|
||||
return t->name() == name
|
||||
[&name, targetTypeValue] (auto t) {
|
||||
return t->name() == name
|
||||
&& t->targetTypeValue() == targetTypeValue;
|
||||
}
|
||||
);
|
||||
if(!value.isEmpty()) {
|
||||
auto t = new Matroska::SimpleTagString();
|
||||
auto t = new SimpleTagString();
|
||||
t->setTargetTypeValue(targetTypeValue);
|
||||
t->setName(name);
|
||||
t->setValue(value);
|
||||
@@ -329,15 +321,15 @@ bool Matroska::Tag::setTag(const String &key, const String &value)
|
||||
return true;
|
||||
}
|
||||
|
||||
const String* Matroska::Tag::getTag(const String &key) const
|
||||
const String *Matroska::Tag::getTag(const String &key) const
|
||||
{
|
||||
const auto pair = Matroska::Utils::translateKey(key);
|
||||
const auto pair = Utils::translateKey(key);
|
||||
// Workaround Clang issue - no lambda capture of structured bindings
|
||||
const String &name = pair.first;
|
||||
auto targetTypeValue = pair.second;
|
||||
if(name.isEmpty())
|
||||
return nullptr;
|
||||
auto tag = dynamic_cast<const Matroska::SimpleTagString*>(
|
||||
auto tag = dynamic_cast<const SimpleTagString *>(
|
||||
findSimpleTag(
|
||||
[&name, targetTypeValue] (auto t) {
|
||||
return t->name() == name
|
||||
@@ -351,16 +343,16 @@ const String* Matroska::Tag::getTag(const String &key) const
|
||||
std::pair<String, Matroska::SimpleTag::TargetTypeValue> Matroska::Utils::translateKey(const String &key)
|
||||
{
|
||||
auto it = std::find_if(simpleTagsTranslation.cbegin(),
|
||||
simpleTagsTranslation.cend(),
|
||||
simpleTagsTranslation.cend(),
|
||||
[&key](const auto &t) { return key == std::get<0>(t); }
|
||||
);
|
||||
if(it != simpleTagsTranslation.end())
|
||||
return { std::get<1>(*it), std::get<2>(*it) };
|
||||
else
|
||||
return { String(), Matroska::SimpleTag::TargetTypeValue::None };
|
||||
return { String(), SimpleTag::TargetTypeValue::None };
|
||||
}
|
||||
|
||||
String Matroska::Utils::translateTag(const String &name, Matroska::SimpleTag::TargetTypeValue targetTypeValue)
|
||||
String Matroska::Utils::translateTag(const String &name, SimpleTag::TargetTypeValue targetTypeValue)
|
||||
{
|
||||
auto it = std::find_if(simpleTagsTranslation.cbegin(),
|
||||
simpleTagsTranslation.cend(),
|
||||
@@ -375,7 +367,7 @@ String Matroska::Utils::translateTag(const String &name, Matroska::SimpleTag::Ta
|
||||
PropertyMap Matroska::Tag::setProperties(const PropertyMap &propertyMap)
|
||||
{
|
||||
PropertyMap unsupportedProperties;
|
||||
for(const auto& [key, value] : propertyMap) {
|
||||
for(const auto &[key, value] : propertyMap) {
|
||||
if(!setTag(key, value.toString()))
|
||||
unsupportedProperties[key] = value;
|
||||
}
|
||||
@@ -385,10 +377,10 @@ PropertyMap Matroska::Tag::setProperties(const PropertyMap &propertyMap)
|
||||
PropertyMap Matroska::Tag::properties() const
|
||||
{
|
||||
PropertyMap properties;
|
||||
Matroska::SimpleTagString *tStr = nullptr;
|
||||
SimpleTagString *tStr = nullptr;
|
||||
for(auto simpleTag : d->tags) {
|
||||
if((tStr = dynamic_cast<Matroska::SimpleTagString*>(simpleTag))) {
|
||||
String key = Matroska::Utils::translateTag(tStr->name(), tStr->targetTypeValue());
|
||||
if((tStr = dynamic_cast<SimpleTagString *>(simpleTag))) {
|
||||
String key = Utils::translateTag(tStr->name(), tStr->targetTypeValue());
|
||||
if(!key.isEmpty() && !properties.contains(key))
|
||||
properties[key] = tStr->value();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace TagLib {
|
||||
}
|
||||
|
||||
namespace Matroska {
|
||||
using SimpleTagsList = List<SimpleTag*>;
|
||||
using SimpleTagsList = List<SimpleTag *>;
|
||||
class TAGLIB_EXPORT Tag : public TagLib::Tag
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
, private Element
|
||||
@@ -51,7 +51,7 @@ namespace TagLib {
|
||||
void addSimpleTag(SimpleTag *tag);
|
||||
void removeSimpleTag(SimpleTag *tag);
|
||||
void clearSimpleTags();
|
||||
const SimpleTagsList& simpleTagsList() const;
|
||||
const SimpleTagsList &simpleTagsList() const;
|
||||
String title() const override;
|
||||
String artist() const override;
|
||||
String album() const override;
|
||||
@@ -71,7 +71,7 @@ namespace TagLib {
|
||||
PropertyMap properties() const override;
|
||||
PropertyMap setProperties(const PropertyMap &propertyMap) override;
|
||||
template <typename T>
|
||||
int removeSimpleTags(T&& p)
|
||||
int removeSimpleTags(T &&p)
|
||||
{
|
||||
auto &list = simpleTagsListPrivate();
|
||||
int numRemoved = 0;
|
||||
@@ -87,8 +87,8 @@ namespace TagLib {
|
||||
return numRemoved;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SimpleTagsList findSimpleTags(T&& p)
|
||||
template <typename T>
|
||||
SimpleTagsList findSimpleTags(T &&p)
|
||||
{
|
||||
auto &list = simpleTagsListPrivate();
|
||||
for(auto it = list.begin(); it != list.end();) {
|
||||
@@ -101,8 +101,8 @@ namespace TagLib {
|
||||
return list;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const Matroska::SimpleTag* findSimpleTag(T&& p) const
|
||||
template <typename T>
|
||||
const SimpleTag *findSimpleTag(T &&p) const
|
||||
{
|
||||
auto &list = simpleTagsListPrivate();
|
||||
auto it = std::find_if(list.begin(), list.end(), std::forward<T>(p));
|
||||
@@ -110,20 +110,20 @@ namespace TagLib {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Matroska::SimpleTag* findSimpleTag(T&&p)
|
||||
SimpleTag *findSimpleTag(T &&p)
|
||||
{
|
||||
return const_cast<Matroska::SimpleTag*>(
|
||||
const_cast<const Matroska::Tag*>(this)->findSimpleTag(std::forward<T>(p))
|
||||
return const_cast<SimpleTag *>(
|
||||
const_cast<const Tag *>(this)->findSimpleTag(std::forward<T>(p))
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Matroska::File;
|
||||
friend class File;
|
||||
friend class EBML::MkTags;
|
||||
SimpleTagsList& simpleTagsListPrivate();
|
||||
const SimpleTagsList& simpleTagsListPrivate() const;
|
||||
SimpleTagsList &simpleTagsListPrivate();
|
||||
const SimpleTagsList &simpleTagsListPrivate() const;
|
||||
bool setTag(const String &key, const String &value);
|
||||
const String* getTag(const String &key) const;
|
||||
const String *getTag(const String &key) const;
|
||||
class TagPrivate;
|
||||
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
|
||||
std::unique_ptr<TagPrivate> d;
|
||||
|
||||
Reference in New Issue
Block a user