This page hosts a formal specification of ID3v2.4 tag for .mp3 files using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C++11/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream
). One can open local file for that, or use existing std::string
or char*
buffer.
#include <fstream>
std::ifstream is("path/to/local/file.mp3", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
id3v2_4_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.tag() // => get tag
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <vector>
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
/**
* \sa http://id3.org/id3v2.4.0-structure Source
* \sa http://id3.org/id3v2.4.0-frames Source
*/
class id3v2_4_t : public kaitai::kstruct {
public:
class u1be_synchsafe_t;
class u2be_synchsafe_t;
class tag_t;
class u4be_synchsafe_t;
class frame_t;
class header_ex_t;
class header_t;
class padding_t;
class footer_t;
id3v2_4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~id3v2_4_t();
class u1be_synchsafe_t : public kaitai::kstruct {
public:
u1be_synchsafe_t(kaitai::kstream* p__io, id3v2_4_t::u2be_synchsafe_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~u1be_synchsafe_t();
private:
bool m_padding;
uint64_t m_value;
id3v2_4_t* m__root;
id3v2_4_t::u2be_synchsafe_t* m__parent;
public:
bool padding() const { return m_padding; }
uint64_t value() const { return m_value; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::u2be_synchsafe_t* _parent() const { return m__parent; }
};
class u2be_synchsafe_t : public kaitai::kstruct {
public:
u2be_synchsafe_t(kaitai::kstream* p__io, id3v2_4_t::u4be_synchsafe_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~u2be_synchsafe_t();
private:
bool f_value;
int32_t m_value;
public:
int32_t value();
private:
std::unique_ptr<u1be_synchsafe_t> m_byte0;
std::unique_ptr<u1be_synchsafe_t> m_byte1;
id3v2_4_t* m__root;
id3v2_4_t::u4be_synchsafe_t* m__parent;
public:
u1be_synchsafe_t* byte0() const { return m_byte0.get(); }
u1be_synchsafe_t* byte1() const { return m_byte1.get(); }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::u4be_synchsafe_t* _parent() const { return m__parent; }
};
class tag_t : public kaitai::kstruct {
public:
tag_t(kaitai::kstream* p__io, id3v2_4_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~tag_t();
private:
std::unique_ptr<header_t> m_header;
std::unique_ptr<header_ex_t> m_header_ex;
bool n_header_ex;
public:
bool _is_null_header_ex() { header_ex(); return n_header_ex; };
private:
std::unique_ptr<std::vector<std::unique_ptr<frame_t>>> m_frames;
std::unique_ptr<padding_t> m_padding;
bool n_padding;
public:
bool _is_null_padding() { padding(); return n_padding; };
private:
std::unique_ptr<footer_t> m_footer;
bool n_footer;
public:
bool _is_null_footer() { footer(); return n_footer; };
private:
id3v2_4_t* m__root;
id3v2_4_t* m__parent;
public:
header_t* header() const { return m_header.get(); }
header_ex_t* header_ex() const { return m_header_ex.get(); }
std::vector<std::unique_ptr<frame_t>>* frames() const { return m_frames.get(); }
padding_t* padding() const { return m_padding.get(); }
footer_t* footer() const { return m_footer.get(); }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t* _parent() const { return m__parent; }
};
class u4be_synchsafe_t : public kaitai::kstruct {
public:
u4be_synchsafe_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~u4be_synchsafe_t();
private:
bool f_value;
int32_t m_value;
public:
int32_t value();
private:
std::unique_ptr<u2be_synchsafe_t> m_short0;
std::unique_ptr<u2be_synchsafe_t> m_short1;
id3v2_4_t* m__root;
kaitai::kstruct* m__parent;
public:
u2be_synchsafe_t* short0() const { return m_short0.get(); }
u2be_synchsafe_t* short1() const { return m_short1.get(); }
id3v2_4_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
class frame_t : public kaitai::kstruct {
public:
class flags_status_t;
class flags_format_t;
frame_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~frame_t();
class flags_status_t : public kaitai::kstruct {
public:
flags_status_t(kaitai::kstream* p__io, id3v2_4_t::frame_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~flags_status_t();
private:
bool m_reserved1;
bool m_flag_discard_alter_tag;
bool m_flag_discard_alter_file;
bool m_flag_read_only;
uint64_t m_reserved2;
id3v2_4_t* m__root;
id3v2_4_t::frame_t* m__parent;
public:
bool reserved1() const { return m_reserved1; }
bool flag_discard_alter_tag() const { return m_flag_discard_alter_tag; }
bool flag_discard_alter_file() const { return m_flag_discard_alter_file; }
bool flag_read_only() const { return m_flag_read_only; }
uint64_t reserved2() const { return m_reserved2; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::frame_t* _parent() const { return m__parent; }
};
class flags_format_t : public kaitai::kstruct {
public:
flags_format_t(kaitai::kstream* p__io, id3v2_4_t::frame_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~flags_format_t();
private:
bool m_reserved1;
bool m_flag_grouping;
uint64_t m_reserved2;
bool m_flag_compressed;
bool m_flag_encrypted;
bool m_flag_unsynchronisated;
bool m_flag_indicator;
id3v2_4_t* m__root;
id3v2_4_t::frame_t* m__parent;
public:
bool reserved1() const { return m_reserved1; }
bool flag_grouping() const { return m_flag_grouping; }
uint64_t reserved2() const { return m_reserved2; }
bool flag_compressed() const { return m_flag_compressed; }
bool flag_encrypted() const { return m_flag_encrypted; }
bool flag_unsynchronisated() const { return m_flag_unsynchronisated; }
bool flag_indicator() const { return m_flag_indicator; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::frame_t* _parent() const { return m__parent; }
};
private:
bool f_is_invalid;
bool m_is_invalid;
public:
bool is_invalid();
private:
std::string m_id;
std::unique_ptr<u4be_synchsafe_t> m_size;
std::unique_ptr<flags_status_t> m_flags_status;
std::unique_ptr<flags_format_t> m_flags_format;
std::string m_data;
id3v2_4_t* m__root;
id3v2_4_t::tag_t* m__parent;
public:
std::string id() const { return m_id; }
u4be_synchsafe_t* size() const { return m_size.get(); }
flags_status_t* flags_status() const { return m_flags_status.get(); }
flags_format_t* flags_format() const { return m_flags_format.get(); }
std::string data() const { return m_data; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::tag_t* _parent() const { return m__parent; }
};
class header_ex_t : public kaitai::kstruct {
public:
class flags_ex_t;
header_ex_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~header_ex_t();
class flags_ex_t : public kaitai::kstruct {
public:
flags_ex_t(kaitai::kstream* p__io, id3v2_4_t::header_ex_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~flags_ex_t();
private:
bool m_reserved1;
bool m_flag_update;
bool m_flag_crc;
bool m_flag_restrictions;
uint64_t m_reserved2;
id3v2_4_t* m__root;
id3v2_4_t::header_ex_t* m__parent;
public:
bool reserved1() const { return m_reserved1; }
bool flag_update() const { return m_flag_update; }
bool flag_crc() const { return m_flag_crc; }
bool flag_restrictions() const { return m_flag_restrictions; }
uint64_t reserved2() const { return m_reserved2; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::header_ex_t* _parent() const { return m__parent; }
};
private:
std::unique_ptr<u4be_synchsafe_t> m_size;
std::unique_ptr<flags_ex_t> m_flags_ex;
std::string m_data;
id3v2_4_t* m__root;
id3v2_4_t::tag_t* m__parent;
public:
u4be_synchsafe_t* size() const { return m_size.get(); }
flags_ex_t* flags_ex() const { return m_flags_ex.get(); }
std::string data() const { return m_data; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::tag_t* _parent() const { return m__parent; }
};
class header_t : public kaitai::kstruct {
public:
class flags_t;
header_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~header_t();
class flags_t : public kaitai::kstruct {
public:
flags_t(kaitai::kstream* p__io, id3v2_4_t::header_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~flags_t();
private:
bool m_flag_unsynchronization;
bool m_flag_headerex;
bool m_flag_experimental;
bool m_flag_footer;
uint64_t m_reserved;
id3v2_4_t* m__root;
id3v2_4_t::header_t* m__parent;
public:
bool flag_unsynchronization() const { return m_flag_unsynchronization; }
bool flag_headerex() const { return m_flag_headerex; }
bool flag_experimental() const { return m_flag_experimental; }
bool flag_footer() const { return m_flag_footer; }
uint64_t reserved() const { return m_reserved; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::header_t* _parent() const { return m__parent; }
};
private:
std::string m_magic;
uint8_t m_version_major;
uint8_t m_version_revision;
std::unique_ptr<flags_t> m_flags;
std::unique_ptr<u4be_synchsafe_t> m_size;
id3v2_4_t* m__root;
id3v2_4_t::tag_t* m__parent;
public:
std::string magic() const { return m_magic; }
uint8_t version_major() const { return m_version_major; }
uint8_t version_revision() const { return m_version_revision; }
flags_t* flags() const { return m_flags.get(); }
u4be_synchsafe_t* size() const { return m_size.get(); }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::tag_t* _parent() const { return m__parent; }
};
class padding_t : public kaitai::kstruct {
public:
padding_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~padding_t();
private:
std::string m_padding;
id3v2_4_t* m__root;
id3v2_4_t::tag_t* m__parent;
public:
std::string padding() const { return m_padding; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::tag_t* _parent() const { return m__parent; }
};
class footer_t : public kaitai::kstruct {
public:
class flags_t;
footer_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~footer_t();
class flags_t : public kaitai::kstruct {
public:
flags_t(kaitai::kstream* p__io, id3v2_4_t::footer_t* p__parent = nullptr, id3v2_4_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~flags_t();
private:
bool m_flag_unsynchronization;
bool m_flag_headerex;
bool m_flag_experimental;
bool m_flag_footer;
uint64_t m_reserved;
id3v2_4_t* m__root;
id3v2_4_t::footer_t* m__parent;
public:
bool flag_unsynchronization() const { return m_flag_unsynchronization; }
bool flag_headerex() const { return m_flag_headerex; }
bool flag_experimental() const { return m_flag_experimental; }
bool flag_footer() const { return m_flag_footer; }
uint64_t reserved() const { return m_reserved; }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::footer_t* _parent() const { return m__parent; }
};
private:
std::string m_magic;
uint8_t m_version_major;
uint8_t m_version_revision;
std::unique_ptr<flags_t> m_flags;
std::unique_ptr<u4be_synchsafe_t> m_size;
id3v2_4_t* m__root;
id3v2_4_t::tag_t* m__parent;
public:
std::string magic() const { return m_magic; }
uint8_t version_major() const { return m_version_major; }
uint8_t version_revision() const { return m_version_revision; }
flags_t* flags() const { return m_flags.get(); }
u4be_synchsafe_t* size() const { return m_size.get(); }
id3v2_4_t* _root() const { return m__root; }
id3v2_4_t::tag_t* _parent() const { return m__parent; }
};
private:
std::unique_ptr<tag_t> m_tag;
id3v2_4_t* m__root;
kaitai::kstruct* m__parent;
public:
tag_t* tag() const { return m_tag.get(); }
id3v2_4_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "id3v2_4.h"
#include "kaitai/exceptions.h"
id3v2_4_t::id3v2_4_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this;
m_tag = nullptr;
_read();
}
void id3v2_4_t::_read() {
m_tag = std::unique_ptr<tag_t>(new tag_t(m__io, this, m__root));
}
id3v2_4_t::~id3v2_4_t() {
_clean_up();
}
void id3v2_4_t::_clean_up() {
}
id3v2_4_t::u1be_synchsafe_t::u1be_synchsafe_t(kaitai::kstream* p__io, id3v2_4_t::u2be_synchsafe_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::u1be_synchsafe_t::_read() {
m_padding = m__io->read_bits_int_be(1);
m_value = m__io->read_bits_int_be(7);
}
id3v2_4_t::u1be_synchsafe_t::~u1be_synchsafe_t() {
_clean_up();
}
void id3v2_4_t::u1be_synchsafe_t::_clean_up() {
}
id3v2_4_t::u2be_synchsafe_t::u2be_synchsafe_t(kaitai::kstream* p__io, id3v2_4_t::u4be_synchsafe_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_byte0 = nullptr;
m_byte1 = nullptr;
f_value = false;
_read();
}
void id3v2_4_t::u2be_synchsafe_t::_read() {
m_byte0 = std::unique_ptr<u1be_synchsafe_t>(new u1be_synchsafe_t(m__io, this, m__root));
m_byte1 = std::unique_ptr<u1be_synchsafe_t>(new u1be_synchsafe_t(m__io, this, m__root));
}
id3v2_4_t::u2be_synchsafe_t::~u2be_synchsafe_t() {
_clean_up();
}
void id3v2_4_t::u2be_synchsafe_t::_clean_up() {
}
int32_t id3v2_4_t::u2be_synchsafe_t::value() {
if (f_value)
return m_value;
m_value = ((byte0()->value() << 7) | byte1()->value());
f_value = true;
return m_value;
}
id3v2_4_t::tag_t::tag_t(kaitai::kstream* p__io, id3v2_4_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_header = nullptr;
m_header_ex = nullptr;
m_frames = nullptr;
m_padding = nullptr;
m_footer = nullptr;
_read();
}
void id3v2_4_t::tag_t::_read() {
m_header = std::unique_ptr<header_t>(new header_t(m__io, this, m__root));
n_header_ex = true;
if (header()->flags()->flag_headerex()) {
n_header_ex = false;
m_header_ex = std::unique_ptr<header_ex_t>(new header_ex_t(m__io, this, m__root));
}
m_frames = std::unique_ptr<std::vector<std::unique_ptr<frame_t>>>(new std::vector<std::unique_ptr<frame_t>>());
{
int i = 0;
frame_t* _;
do {
_ = new frame_t(m__io, this, m__root);
m_frames->push_back(std::move(std::unique_ptr<frame_t>(_)));
i++;
} while (!( (((_io()->pos() + _->size()->value()) > header()->size()->value()) || (_->is_invalid())) ));
}
n_padding = true;
if (!(header()->flags()->flag_footer())) {
n_padding = false;
m_padding = std::unique_ptr<padding_t>(new padding_t(m__io, this, m__root));
}
n_footer = true;
if (header()->flags()->flag_footer()) {
n_footer = false;
m_footer = std::unique_ptr<footer_t>(new footer_t(m__io, this, m__root));
}
}
id3v2_4_t::tag_t::~tag_t() {
_clean_up();
}
void id3v2_4_t::tag_t::_clean_up() {
if (!n_header_ex) {
}
if (!n_padding) {
}
if (!n_footer) {
}
}
id3v2_4_t::u4be_synchsafe_t::u4be_synchsafe_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_short0 = nullptr;
m_short1 = nullptr;
f_value = false;
_read();
}
void id3v2_4_t::u4be_synchsafe_t::_read() {
m_short0 = std::unique_ptr<u2be_synchsafe_t>(new u2be_synchsafe_t(m__io, this, m__root));
m_short1 = std::unique_ptr<u2be_synchsafe_t>(new u2be_synchsafe_t(m__io, this, m__root));
}
id3v2_4_t::u4be_synchsafe_t::~u4be_synchsafe_t() {
_clean_up();
}
void id3v2_4_t::u4be_synchsafe_t::_clean_up() {
}
int32_t id3v2_4_t::u4be_synchsafe_t::value() {
if (f_value)
return m_value;
m_value = ((short0()->value() << 14) | short1()->value());
f_value = true;
return m_value;
}
id3v2_4_t::frame_t::frame_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_size = nullptr;
m_flags_status = nullptr;
m_flags_format = nullptr;
f_is_invalid = false;
_read();
}
void id3v2_4_t::frame_t::_read() {
m_id = kaitai::kstream::bytes_to_str(m__io->read_bytes(4), std::string("ASCII"));
m_size = std::unique_ptr<u4be_synchsafe_t>(new u4be_synchsafe_t(m__io, this, m__root));
m_flags_status = std::unique_ptr<flags_status_t>(new flags_status_t(m__io, this, m__root));
m_flags_format = std::unique_ptr<flags_format_t>(new flags_format_t(m__io, this, m__root));
m_data = m__io->read_bytes(size()->value());
}
id3v2_4_t::frame_t::~frame_t() {
_clean_up();
}
void id3v2_4_t::frame_t::_clean_up() {
}
id3v2_4_t::frame_t::flags_status_t::flags_status_t(kaitai::kstream* p__io, id3v2_4_t::frame_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::frame_t::flags_status_t::_read() {
m_reserved1 = m__io->read_bits_int_be(1);
m_flag_discard_alter_tag = m__io->read_bits_int_be(1);
m_flag_discard_alter_file = m__io->read_bits_int_be(1);
m_flag_read_only = m__io->read_bits_int_be(1);
m_reserved2 = m__io->read_bits_int_be(4);
}
id3v2_4_t::frame_t::flags_status_t::~flags_status_t() {
_clean_up();
}
void id3v2_4_t::frame_t::flags_status_t::_clean_up() {
}
id3v2_4_t::frame_t::flags_format_t::flags_format_t(kaitai::kstream* p__io, id3v2_4_t::frame_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::frame_t::flags_format_t::_read() {
m_reserved1 = m__io->read_bits_int_be(1);
m_flag_grouping = m__io->read_bits_int_be(1);
m_reserved2 = m__io->read_bits_int_be(2);
m_flag_compressed = m__io->read_bits_int_be(1);
m_flag_encrypted = m__io->read_bits_int_be(1);
m_flag_unsynchronisated = m__io->read_bits_int_be(1);
m_flag_indicator = m__io->read_bits_int_be(1);
}
id3v2_4_t::frame_t::flags_format_t::~flags_format_t() {
_clean_up();
}
void id3v2_4_t::frame_t::flags_format_t::_clean_up() {
}
bool id3v2_4_t::frame_t::is_invalid() {
if (f_is_invalid)
return m_is_invalid;
m_is_invalid = id() == (std::string("\000\000\000\000", 4));
f_is_invalid = true;
return m_is_invalid;
}
id3v2_4_t::header_ex_t::header_ex_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_size = nullptr;
m_flags_ex = nullptr;
_read();
}
void id3v2_4_t::header_ex_t::_read() {
m_size = std::unique_ptr<u4be_synchsafe_t>(new u4be_synchsafe_t(m__io, this, m__root));
m_flags_ex = std::unique_ptr<flags_ex_t>(new flags_ex_t(m__io, this, m__root));
m_data = m__io->read_bytes((size()->value() - 5));
}
id3v2_4_t::header_ex_t::~header_ex_t() {
_clean_up();
}
void id3v2_4_t::header_ex_t::_clean_up() {
}
id3v2_4_t::header_ex_t::flags_ex_t::flags_ex_t(kaitai::kstream* p__io, id3v2_4_t::header_ex_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::header_ex_t::flags_ex_t::_read() {
m_reserved1 = m__io->read_bits_int_be(1);
m_flag_update = m__io->read_bits_int_be(1);
m_flag_crc = m__io->read_bits_int_be(1);
m_flag_restrictions = m__io->read_bits_int_be(1);
m_reserved2 = m__io->read_bits_int_be(4);
}
id3v2_4_t::header_ex_t::flags_ex_t::~flags_ex_t() {
_clean_up();
}
void id3v2_4_t::header_ex_t::flags_ex_t::_clean_up() {
}
id3v2_4_t::header_t::header_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_flags = nullptr;
m_size = nullptr;
_read();
}
void id3v2_4_t::header_t::_read() {
m_magic = m__io->read_bytes(3);
if (!(magic() == std::string("\x49\x44\x33", 3))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x49\x44\x33", 3), magic(), _io(), std::string("/types/header/seq/0"));
}
m_version_major = m__io->read_u1();
m_version_revision = m__io->read_u1();
m_flags = std::unique_ptr<flags_t>(new flags_t(m__io, this, m__root));
m_size = std::unique_ptr<u4be_synchsafe_t>(new u4be_synchsafe_t(m__io, this, m__root));
}
id3v2_4_t::header_t::~header_t() {
_clean_up();
}
void id3v2_4_t::header_t::_clean_up() {
}
id3v2_4_t::header_t::flags_t::flags_t(kaitai::kstream* p__io, id3v2_4_t::header_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::header_t::flags_t::_read() {
m_flag_unsynchronization = m__io->read_bits_int_be(1);
m_flag_headerex = m__io->read_bits_int_be(1);
m_flag_experimental = m__io->read_bits_int_be(1);
m_flag_footer = m__io->read_bits_int_be(1);
m_reserved = m__io->read_bits_int_be(4);
}
id3v2_4_t::header_t::flags_t::~flags_t() {
_clean_up();
}
void id3v2_4_t::header_t::flags_t::_clean_up() {
}
id3v2_4_t::padding_t::padding_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::padding_t::_read() {
m_padding = m__io->read_bytes((_root()->tag()->header()->size()->value() - _io()->pos()));
}
id3v2_4_t::padding_t::~padding_t() {
_clean_up();
}
void id3v2_4_t::padding_t::_clean_up() {
}
id3v2_4_t::footer_t::footer_t(kaitai::kstream* p__io, id3v2_4_t::tag_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_flags = nullptr;
m_size = nullptr;
_read();
}
void id3v2_4_t::footer_t::_read() {
m_magic = m__io->read_bytes(3);
if (!(magic() == std::string("\x33\x44\x49", 3))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x33\x44\x49", 3), magic(), _io(), std::string("/types/footer/seq/0"));
}
m_version_major = m__io->read_u1();
m_version_revision = m__io->read_u1();
m_flags = std::unique_ptr<flags_t>(new flags_t(m__io, this, m__root));
m_size = std::unique_ptr<u4be_synchsafe_t>(new u4be_synchsafe_t(m__io, this, m__root));
}
id3v2_4_t::footer_t::~footer_t() {
_clean_up();
}
void id3v2_4_t::footer_t::_clean_up() {
}
id3v2_4_t::footer_t::flags_t::flags_t(kaitai::kstream* p__io, id3v2_4_t::footer_t* p__parent, id3v2_4_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void id3v2_4_t::footer_t::flags_t::_read() {
m_flag_unsynchronization = m__io->read_bits_int_be(1);
m_flag_headerex = m__io->read_bits_int_be(1);
m_flag_experimental = m__io->read_bits_int_be(1);
m_flag_footer = m__io->read_bits_int_be(1);
m_reserved = m__io->read_bits_int_be(4);
}
id3v2_4_t::footer_t::flags_t::~flags_t() {
_clean_up();
}
void id3v2_4_t::footer_t::flags_t::_clean_up() {
}