6 #include "../exceptions.h" 8 #include <c++utilities/conversion/stringconversion.h> 9 #include <c++utilities/io/binarywriter.h> 29 case KnownField::EncoderSettings:
51 case TagTextEncoding::Utf16BigEndian:
69 case KnownField::EncoderSettings:
84 std::vector<const TagValue *> Mp4Tag::values(
KnownField field)
const 90 for (
auto i = range.first; i != range.second; ++i) {
91 if (extendedId.
matches(i->second)) {
92 values.emplace_back(&i->second.value());
104 const TagValue &Mp4Tag::value(
const char *mean,
const char *name)
const 107 for (
auto i = range.first; i != range.second; ++i) {
108 if (i->second.mean() == mean && i->second.name() == name) {
109 return i->second.value();
112 return TagValue::empty();
118 const TagValue &Mp4Tag::value(
const string mean,
const string name)
const 120 return (this->*
static_cast<const TagValue &(
Mp4Tag::*)(
const string &,
const string &)const
>(&Mp4Tag::value))(mean, name);
125 using namespace Mp4TagAtomIds;
170 KnownField Mp4Tag::internallyGetKnownField(
const IdentifierType &
id)
const 172 using namespace Mp4TagAtomIds;
214 return KnownField::Invalid;
222 switch (value.
type()) {
223 case TagDataType::StandardGenreIndex:
230 case KnownField::EncoderSettings:
242 bool Mp4Tag::setValues(
KnownField field,
const std::vector<TagValue> &values)
246 auto valuesIterator = values.cbegin();
248 for (; valuesIterator != values.cend() && range.first != range.second;) {
249 if (!valuesIterator->isEmpty()) {
250 if (extendedId.
matches(range.first->second) && (!extendedId.
updateOnly || !range.first->second.value().isEmpty())) {
251 range.first->second.setValue(*valuesIterator);
259 for (; valuesIterator != values.cend(); ++valuesIterator) {
265 for (; range.first != range.second; ++range.first) {
266 range.first->second.setValue(
TagValue());
279 bool Mp4Tag::setValue(
const char *mean,
const char *name,
const TagValue &value)
282 for (
auto i = range.first; i != range.second; ++i) {
283 if (i->second.mean() == mean && i->second.name() == name) {
284 i->second.setValue(value);
295 bool Mp4Tag::setValue(
const string mean,
const string name,
const TagValue &value)
297 return (this->*
static_cast<bool (
Mp4Tag::*)(
const string &,
const string &,
const TagValue &)
>(&Mp4Tag::setValue))(mean, name, value);
319 static const string context(
"parsing MP4 tag");
320 istream &stream = metaAtom.
container().stream();
321 BinaryReader &reader = metaAtom.
container().reader();
327 diag.emplace_back(DiagLevel::Critical,
"Unable to parse child atoms of meta atom (stores hdlr and ilst atoms).", context);
331 int versionByte = reader.readByte();
332 if (versionByte != 0) {
333 diag.emplace_back(DiagLevel::Warning,
"Version is unknown.", context);
335 if (reader.readUInt24BE()) {
336 diag.emplace_back(DiagLevel::Warning,
"Flags (hdlr atom) aren't set to 0.", context);
338 if (reader.readInt32BE()) {
339 diag.emplace_back(DiagLevel::Warning,
"Predefined 32-bit integer (hdlr atom) ins't set to 0.", context);
341 uint64 handlerType = reader.readUInt64BE();
342 if ( (handlerType != 0x6d6469726170706c)) {
343 diag.emplace_back(DiagLevel::Warning,
"Handler type (value in hdlr atom) is unknown. Trying to parse meta information anyhow.", context);
345 m_version = ConversionUtilities::numberToString(versionByte);
352 diag.emplace_back(DiagLevel::Critical,
"Unable to parse child atoms of meta atom (stores hdlr and ilst atoms).", context);
355 for (
auto *child = subAtom->
firstChild(); child; child = child->nextSibling()) {
359 tagField.
reparse(*child, diag);
360 fields().emplace(child->id(), move(tagField));
365 diag.emplace_back(DiagLevel::Warning,
"No ilst atom found (stores attached meta information).", context);
393 prepareMaking(diag).make(stream, diag);
417 m_omitPreDefinedGenre(m_tag.fields().count(m_tag.hasField(Mp4TagAtomIds::
Genre)))
419 m_maker.reserve(m_tag.fields().size());
420 for (
auto &field : m_tag.fields()) {
423 m_maker.emplace_back(field.second.prepareMaking(diag));
424 m_ilstSize += m_maker.back().requiredSize();
425 }
catch (
const Failure &) {
429 if (m_ilstSize != 8) {
430 m_metaSize += m_ilstSize;
444 BinaryWriter writer(&stream);
445 writer.writeUInt32BE(m_metaSize);
448 static const byte hdlrData[37] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x68, 0x64, 0x6C, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x6D, 0x64, 0x69, 0x72, 0x61, 0x70, 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
450 stream.write(reinterpret_cast<const char *>(hdlrData),
sizeof(hdlrData));
451 if (m_ilstSize != 8) {
453 writer.writeUInt32BE(m_ilstSize);
456 for (
auto &maker : m_maker) {
FieldMapBasedTagTraits< Mp4Tag >::FieldType::IdentifierType IdentifierType
void make(std::ostream &stream, Diagnostics &diag)
Saves the tag (specified when constructing the object) to the specified stream.
const char * mean
mean parameter, usually Mp4TagExtendedMeanIds::iTunes
bool matches(const Mp4TagField &field) const
Returns whether the current parameter match the specified field.
ImplementationType * firstChild()
Returns the first child of the element.
uint64 startOffset() const
Returns the start offset in the related stream.
KnownField
Specifies the field.
uint64 totalSize() const
Returns the total size of the element.
const char * name
name parameter
bool isEmpty() const
Returns an indication whether an value is assigned.
Contains utility classes helping to read and write streams.
ContainerType & container()
Returns the related container.
FieldMapBasedTagTraits< Mp4Tag >::FieldType FieldType
void setMean(const std::string &mean)
Sets the "mean" for the "extended" field.
uint32 headerSize() const
Returns the header size of the element in byte.
TagDataType type() const
Returns the type of the assigned value.
void reparse(Mp4Atom &ilstChild, Diagnostics &diag)
Parses field information from the specified Mp4Atom.
void setName(const std::string &name)
Sets the "name" for the "extended" field.
bool updateOnly
Whether only existing fields should be updated but no new extended field should be created...
ImplementationType * childById(const IdentifierType &id, Diagnostics &diag)
Returns the first child with the specified id.
TagTextEncoding
Specifies the text encoding.