123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- #include "frameheader.h"
- #include "util.h"
- #include "values.h"
- #include "nu/ByteReader.h"
- #include "nu/ByteWriter.h"
- #include <string.h>
- #include "foundation/error.h"
- /* === ID3v2 common === */
- ID3v2::FrameHeader::FrameHeader(const ID3v2::Header &_header) : tagHeader(_header)
- {
- }
- static bool CharOK(int8_t c)
- {
- if (c >= '0' && c <= '9')
- return true;
- if (c >= 'A' && c <= 'Z')
- return true;
- return false;
- }
- /* === ID3v2.2 === */
- ID3v2_2::FrameHeader::FrameHeader(const ID3v2_2::FrameHeader &frame_header, const ID3v2::Header &_header) : ID3v2::FrameHeader(_header)
- {
- frameHeaderData = frame_header.frameHeaderData;
- }
- ID3v2_2::FrameHeader::FrameHeader(const ID3v2::Header &_header, const int8_t *id, int flags) : ID3v2::FrameHeader(_header)
- {
- memcpy(&frameHeaderData.id, id, 3);
- frameHeaderData.id[3]=0;
- memset(&frameHeaderData.size, 0, 3);
- }
- ID3v2_2::FrameHeader::FrameHeader(const ID3v2::Header &_header, const void *data) : ID3v2::FrameHeader(_header)
- {
- char temp_data[FrameHeader::SIZE];
- if (tagHeader.Unsynchronised())
- {
- ID3v2::Util::UnsynchroniseTo(temp_data, data, sizeof(temp_data));
- data = temp_data;
- }
- bytereader_value_t byte_reader;
- bytereader_init(&byte_reader, data, FrameHeader::SIZE);
- bytereader_read_n(&byte_reader, &frameHeaderData.id, 3);
- frameHeaderData.id[3]=0;
- bytereader_read_n(&byte_reader, &frameHeaderData.size, 3);
- }
- bool ID3v2_2::FrameHeader::IsValid() const
- {
- if (CharOK(frameHeaderData.id[0])
- && CharOK(frameHeaderData.id[1])
- && CharOK(frameHeaderData.id[2]))
- return true;
- return false;
- }
- const int8_t *ID3v2_2::FrameHeader::GetIdentifier() const
- {
- return frameHeaderData.id;
- }
- bool ID3v2_2::FrameHeader::Unsynchronised() const
- {
- return tagHeader.Unsynchronised();
- }
- uint32_t ID3v2_2::FrameHeader::FrameSize() const
- {
- return (frameHeaderData.size[0] << 16) | (frameHeaderData.size[1] << 8) | (frameHeaderData.size[2]);
- }
- void ID3v2_2::FrameHeader::SetSize(uint32_t data_size)
- {
- frameHeaderData.size[0] = data_size >> 16;
- frameHeaderData.size[1] = data_size >> 8;
- frameHeaderData.size[2] = data_size;
- }
- int ID3v2_2::FrameHeader::SerializedSize(uint32_t *written) const
- {
- if (tagHeader.Unsynchronised())
- {
- uint8_t data[SIZE];
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, data, SIZE);
- bytewriter_write_n(&byte_writer, frameHeaderData.id, 3);
- bytewriter_write_n(&byte_writer, frameHeaderData.size, 3);
- *written = ID3v2::Util::SynchronisedSize(data, SIZE);
- }
- else
- {
- *written = SIZE;
- }
- return NErr_Success;
- }
- int ID3v2_2::FrameHeader::Serialize(void *data) const
- {
- if (tagHeader.Unsynchronised())
- {
- uint8_t temp[SIZE];
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, temp, SIZE);
- bytewriter_write_n(&byte_writer, frameHeaderData.id, 3);
- bytewriter_write_n(&byte_writer, frameHeaderData.size, 3);
- ID3v2::Util::SynchroniseTo(data, temp, SIZE);
- }
- else
- {
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, data, SIZE);
- bytewriter_write_n(&byte_writer, frameHeaderData.id, 3);
- bytewriter_write_n(&byte_writer, frameHeaderData.size, 3);
- }
- return NErr_Success;
- }
- /* === ID3v2.3+ common === */
- ID3v2_3::FrameHeaderBase::FrameHeaderBase(const ID3v2_3::FrameHeaderBase &frame_header_base, const ID3v2::Header &_header) : ID3v2::FrameHeader(_header)
- {
- memcpy(id, frame_header_base.id, 4);
- size=frame_header_base.size;
- flags[0] = frame_header_base.flags[0];
- flags[1] = frame_header_base.flags[1];
- }
- ID3v2_3::FrameHeaderBase::FrameHeaderBase(const ID3v2::Header &_header) : ID3v2::FrameHeader(_header)
- {
- }
- ID3v2_3::FrameHeaderBase::FrameHeaderBase(const ID3v2::Header &_header, const int8_t *_id, int _flags) : ID3v2::FrameHeader(_header)
- {
- memcpy(id, _id, 4);
- size=0;
- // TODO: flags
- flags[0]=0;
- flags[1]=0;
- }
- const int8_t *ID3v2_3::FrameHeaderBase::GetIdentifier() const
- {
- return id;
- }
- bool ID3v2_3::FrameHeaderBase::IsValid() const
- {
- if (CharOK(id[0])
- && CharOK(id[1])
- && CharOK(id[2])
- && CharOK(id[3]))
- return true;
- return false;
- }
- /* === ID3v2.3 === */
- ID3v2_3::FrameHeader::FrameHeader(const ID3v2_3::FrameHeader &frame_header, const ID3v2::Header &tag_header) : ID3v2_3::FrameHeaderBase(frame_header, tag_header)
- {
- }
- ID3v2_3::FrameHeader::FrameHeader(const ID3v2::Header &_header, const int8_t *id, int flags) : ID3v2_3::FrameHeaderBase(_header, id, flags)
- {
- }
- ID3v2_3::FrameHeader::FrameHeader(const ID3v2::Header &_header, const void *data) : ID3v2_3::FrameHeaderBase(_header)
- {
- char temp_data[FrameHeaderBase::SIZE];
- if (tagHeader.Unsynchronised())
- {
- ID3v2::Util::UnsynchroniseTo(temp_data, data, sizeof(temp_data));
- data = temp_data;
- }
- bytereader_value_t byte_reader;
- bytereader_init(&byte_reader, data, FrameHeaderBase::SIZE);
- bytereader_read_n(&byte_reader, &id, 4);
- size = bytereader_read_u32_be(&byte_reader);
- bytereader_read_n(&byte_reader, &flags, 2);
- }
- int ID3v2_3::FrameHeaderBase::SerializedSize(uint32_t *written) const
- {
- if (tagHeader.Unsynchronised())
- {
- uint8_t data[SIZE];
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, data, SIZE);
- bytewriter_write_n(&byte_writer, id, 4);
- bytewriter_write_u32_be(&byte_writer, size);
- bytewriter_write_u8(&byte_writer, flags[0]);
- bytewriter_write_u8(&byte_writer, flags[1]);
- *written = ID3v2::Util::SynchronisedSize(data, SIZE);
- }
- else
- {
- *written = SIZE;
- }
- return NErr_Success;
- }
- int ID3v2_3::FrameHeaderBase::Serialize(void *data, uint32_t *written) const
- {
- if (tagHeader.Unsynchronised())
- {
- uint8_t temp[SIZE];
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, temp, SIZE);
- bytewriter_write_n(&byte_writer, id, 4);
- bytewriter_write_u32_be(&byte_writer, size);
- bytewriter_write_u8(&byte_writer, flags[0]);
- bytewriter_write_u8(&byte_writer, flags[1]);
- *written = ID3v2::Util::SynchroniseTo(data, temp, SIZE);
- }
- else
- {
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, data, SIZE);
- bytewriter_write_n(&byte_writer, id, 4);
- bytewriter_write_u32_be(&byte_writer, size);
- bytewriter_write_u8(&byte_writer, flags[0]);
- bytewriter_write_u8(&byte_writer, flags[1]);
- *written = SIZE;
- }
- return NErr_Success;
- }
- uint32_t ID3v2_3::FrameHeader::FrameSize() const
- {
- return size;
- }
- bool ID3v2_3::FrameHeader::ReadOnly() const
- {
- return !!(flags[0] & (1<<5));
- }
- bool ID3v2_3::FrameHeader::Encrypted() const
- {
- return !!(flags[1] & (1<<6));
- }
- bool ID3v2_3::FrameHeader::Unsynchronised() const
- {
- return tagHeader.Unsynchronised();
- }
- bool ID3v2_3::FrameHeader::Grouped() const
- {
- return !!(flags[1] & (1 << 5));
- }
- bool ID3v2_3::FrameHeader::Compressed() const
- {
- return !!(flags[1] & (1 << 7));
- }
- bool ID3v2_3::FrameHeader::TagAlterPreservation() const
- {
- return !!(flags[0] & (1<<7));
- }
- bool ID3v2_3::FrameHeader::FileAlterPreservation() const
- {
- return !!(flags[0] & (1<<6));
- }
- void ID3v2_3::FrameHeader::ClearCompressed()
- {
- flags[1] &= ~(1 << 7);
- }
- void ID3v2_3::FrameHeader::SetSize(uint32_t data_size)
- {
- if (Compressed())
- data_size+=4;
- if (Grouped())
- data_size++;
- size = data_size;
- }
- /* === ID3v2.4 === */
- ID3v2_4::FrameHeader::FrameHeader(const ID3v2_4::FrameHeader &frame_header, const ID3v2::Header &tag_header) : ID3v2_3::FrameHeaderBase(frame_header, tag_header)
- {
- }
- ID3v2_4::FrameHeader::FrameHeader(const ID3v2::Header &_header, const int8_t *id, int flags) : ID3v2_3::FrameHeaderBase(_header, id, flags)
- {
- }
- ID3v2_4::FrameHeader::FrameHeader(const ID3v2::Header &_header, const void *data) : ID3v2_3::FrameHeaderBase(_header)
- {
- bytereader_value_t byte_reader;
- bytereader_init(&byte_reader, data, FrameHeaderBase::SIZE);
- bytereader_read_n(&byte_reader, &id, 4);
- size = bytereader_read_u32_be(&byte_reader);
- bytereader_read_n(&byte_reader, &flags, 2);
- }
- uint32_t ID3v2_4::FrameHeader::FrameSize() const
- {
- // many programs write non-syncsafe sizes (iTunes is the biggest culprit)
- // so we'll try to detect it. unfortunately this isn't foolproof
- // ID3v2_4::Frame will have some additional checks
- int mask = size & 0x80808080;
- if (mask)
- return size;
- else
- return ID3v2::Util::Int28To32(size);
- }
- bool ID3v2_4::FrameHeader::ReadOnly() const
- {
- return !!(flags[0] & (1<<4));
- }
- bool ID3v2_4::FrameHeader::Encrypted() const
- {
- return !!(flags[1] & (1<<3));
- }
- bool ID3v2_4::FrameHeader::Unsynchronised() const
- {
- return tagHeader.Unsynchronised() || !!(flags[1] & (1 << 1));
- }
- bool ID3v2_4::FrameHeader::FrameUnsynchronised() const
- {
- return !!(flags[1] & (1 << 1));
- }
- bool ID3v2_4::FrameHeader::DataLengthIndicated() const
- {
- return !!(flags[1] & (1 << 0));
- }
- bool ID3v2_4::FrameHeader::Compressed() const
- {
- return !!(flags[1] & (1 << 3));
- }
- bool ID3v2_4::FrameHeader::Grouped() const
- {
- return !!(flags[1] & (1 << 6));
- }
- bool ID3v2_4::FrameHeader::TagAlterPreservation() const
- {
- return !!(flags[0] & (1<<6));
- }
- bool ID3v2_4::FrameHeader::FileAlterPreservation() const
- {
- return !!(flags[0] & (1<<5));
- }
- void ID3v2_4::FrameHeader::ClearUnsynchronized()
- {
- flags[1] &= ~(1 << 1);
- }
- void ID3v2_4::FrameHeader::ClearCompressed()
- {
- flags[1] &= ~(1 << 3);
- }
- void ID3v2_4::FrameHeader::SetSize(uint32_t data_size)
- {
- if (Compressed() || DataLengthIndicated())
- data_size+=4;
- if (Grouped())
- data_size++;
- size = ID3v2::Util::Int32To28(data_size);
- }
- int ID3v2_4::FrameHeader::SerializedSize(uint32_t *written) const
- {
- *written = SIZE;
- return NErr_Success;
- }
- int ID3v2_4::FrameHeader::Serialize(void *data, uint32_t *written) const
- {
- bytewriter_s byte_writer;
- bytewriter_init(&byte_writer, data, SIZE);
- bytewriter_write_n(&byte_writer, id, 4);
- bytewriter_write_u32_be(&byte_writer, size);
- bytewriter_write_u8(&byte_writer, flags[0]);
- bytewriter_write_u8(&byte_writer, flags[1]);
- *written = SIZE;
- return NErr_Success;
- }
|