void MP4::Tag::parseFreeForm(const MP4::Atom *atom) { AtomDataList data = parseData2(atom, -1, true); if(data.size() > 2) { String name = "----:" + String(data[0].data, String::UTF8) + ':' + String(data[1].data, String::UTF8); AtomDataType type = data[2].type; for(uint i = 2; i < data.size(); i++) { if(data[i].type != type) { debug("MP4: We currently don't support values with multiple types"); break; } } if(type == TypeUTF8) { StringList value; for(uint i = 2; i < data.size(); i++) { value.append(String(data[i].data, String::UTF8)); } Item item(value); item.setAtomDataType(type); addItem(name, item); } else { ByteVectorList value; for(uint i = 2; i < data.size(); i++) { value.append(data[i].data); } Item item(value); item.setAtomDataType(type); addItem(name, item); } } }
MP4::AtomDataList MP4::Tag::parseData2(MP4::Atom *atom, TagLib::File *file, int expectedFlags, bool freeForm) { AtomDataList result; ByteVector data = file->readBlock(atom->length - 8); int i = 0; unsigned int pos = 0; while ( pos < data.size() ) { const int length = static_cast<int> ( data.toUInt(pos) ); ByteVector name = data.mid(pos + 4, 4); const int flags = static_cast<int> ( data.toUInt(pos + 8) ); if ( freeForm && (i < 2) ) { if ( (i == 0) && (name != "mean") ) { debug("MP4: Unexpected atom \"" + name + "\", expecting \"mean\""); return result; } else if ( (i == 1) && (name != "name") ) { debug("MP4: Unexpected atom \"" + name + "\", expecting \"name\""); return result; } result.append( AtomData( AtomDataType(flags), data.mid(pos + 12, length - 12) ) ); } else { if ( name != "data" ) { debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\""); return result; } if ( (expectedFlags == -1) || (flags == expectedFlags) ) { result.append( AtomData( AtomDataType(flags), data.mid(pos + 16, length - 16) ) ); } } pos += length; i++; } return result; }
ByteVectorList MP4::Tag::parseData(const MP4::Atom *atom, int expectedFlags, bool freeForm) { AtomDataList data = parseData2(atom, expectedFlags, freeForm); ByteVectorList result; for(uint i = 0; i < data.size(); i++) { result.append(data[i].data); } return result; }
ByteVectorList MP4::Tag::parseData(const MP4::Atom *atom, int expectedFlags, bool freeForm) { AtomDataList data = parseData2(atom, expectedFlags, freeForm); ByteVectorList result; for(AtomDataList::ConstIterator it = data.begin(); it != data.end(); ++it) { result.append(it->data); } return result; }
void MP4::Tag::parseFreeForm(const MP4::Atom *atom) { AtomDataList data = parseData2(atom, -1, true); if(data.size() > 2) { AtomDataList::ConstIterator itBegin = data.begin(); String name = "----:"; name += String((itBegin++)->data, String::UTF8); // data[0].data name += ':'; name += String((itBegin++)->data, String::UTF8); // data[1].data AtomDataType type = itBegin->type; // data[2].type for(AtomDataList::ConstIterator it = itBegin; it != data.end(); ++it) { if(it->type != type) { debug("MP4: We currently don't support values with multiple types"); break; } } if(type == TypeUTF8) { StringList value; for(AtomDataList::ConstIterator it = itBegin; it != data.end(); ++it) { value.append(String(it->data, String::UTF8)); } Item item(value); item.setAtomDataType(type); addItem(name, item); } else { ByteVectorList value; for(AtomDataList::ConstIterator it = itBegin; it != data.end(); ++it) { value.append(it->data); } Item item(value); item.setAtomDataType(type); addItem(name, item); } } }