asffile.cpp
来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 548 行 · 第 1/2 页
CPP
548 行
}ByteVectorASF::File::MetadataObject::render(ASF::File *file){ data.clear(); data.append(ByteVector::fromShort(attributeData.size(), false)); data.append(attributeData.toByteVector(ByteVector::null)); return BaseObject::render(file);}ByteVectorASF::File::MetadataLibraryObject::guid(){ return metadataLibraryGuid;}voidASF::File::MetadataLibraryObject::parse(ASF::File *file, uint /*size*/){ file->d->metadataLibraryObject = this; int count = file->readWORD(); while(count--) { ASF::Attribute attribute; String name = attribute.parse(*file, 2); file->d->tag->addAttribute(name, attribute); }}ByteVectorASF::File::MetadataLibraryObject::render(ASF::File *file){ data.clear(); data.append(ByteVector::fromShort(attributeData.size(), false)); data.append(attributeData.toByteVector(ByteVector::null)); return BaseObject::render(file);}ByteVectorASF::File::HeaderExtensionObject::guid(){ return headerExtensionGuid;}voidASF::File::HeaderExtensionObject::parse(ASF::File *file, uint /*size*/){ file->d->headerExtensionObject = this; file->seek(18, File::Current); long long dataSize = file->readDWORD(); long long dataPos = 0; while(dataPos < dataSize) { ByteVector guid = file->readBlock(16); long long size = file->readQWORD(); BaseObject *obj; if(guid == metadataGuid) { obj = new MetadataObject(); } else if(guid == metadataLibraryGuid) { obj = new MetadataLibraryObject(); } else { obj = new UnknownObject(guid); } obj->parse(file, size); objects.append(obj); dataPos += size; }}ByteVectorASF::File::HeaderExtensionObject::render(ASF::File *file){ data.clear(); for(unsigned int i = 0; i < objects.size(); i++) { data.append(objects[i]->render(file)); } data = ByteVector("\x11\xD2\xD3\xAB\xBA\xA9\xcf\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65\x06\x00", 18) + ByteVector::fromUInt(data.size(), false) + data; return BaseObject::render(file);}////////////////////////////////////////////////////////////////////////////////// public members////////////////////////////////////////////////////////////////////////////////ASF::File::File(const char *file, bool readProperties, Properties::ReadStyle propertiesStyle) : TagLib::File(file){ d = new FilePrivate; read(readProperties, propertiesStyle);}ASF::File::~File(){ for(unsigned int i = 0; i < d->objects.size(); i++) { delete d->objects[i]; } if(d->tag) { delete d->tag; } if(d->properties) { delete d->properties; } delete d;}ASF::Tag *ASF::File::tag() const{ return d->tag;}ASF::Properties *ASF::File::audioProperties() const{ return d->properties;}void ASF::File::read(bool /*readProperties*/, Properties::ReadStyle /*propertiesStyle*/){ if(!isValid()) return; ByteVector guid = readBlock(16); if(guid != headerGuid) { return; } d->tag = new ASF::Tag(); d->properties = new ASF::Properties(); d->size = readQWORD(); int numObjects = readDWORD(); seek(2, Current); for(int i = 0; i < numObjects; i++) { ByteVector guid = readBlock(16); long size = (long)readQWORD(); BaseObject *obj; if(guid == filePropertiesGuid) { obj = new FilePropertiesObject(); } else if(guid == streamPropertiesGuid) { obj = new StreamPropertiesObject(); } else if(guid == contentDescriptionGuid) { obj = new ContentDescriptionObject(); } else if(guid == extendedContentDescriptionGuid) { obj = new ExtendedContentDescriptionObject(); } else if(guid == headerExtensionGuid) { obj = new HeaderExtensionObject(); } else { obj = new UnknownObject(guid); } obj->parse(this, size); d->objects.append(obj); }}bool ASF::File::save(){ if(readOnly()) { return false; } if(!d->contentDescriptionObject) { d->contentDescriptionObject = new ContentDescriptionObject(); d->objects.append(d->contentDescriptionObject); } if(!d->extendedContentDescriptionObject) { d->extendedContentDescriptionObject = new ExtendedContentDescriptionObject(); d->objects.append(d->extendedContentDescriptionObject); } if(!d->headerExtensionObject) { d->headerExtensionObject = new HeaderExtensionObject(); d->objects.append(d->headerExtensionObject); } if(!d->metadataObject) { d->metadataObject = new MetadataObject(); d->headerExtensionObject->objects.append(d->metadataObject); } if(!d->metadataLibraryObject) { d->metadataLibraryObject = new MetadataLibraryObject(); d->headerExtensionObject->objects.append(d->metadataLibraryObject); } ASF::AttributeListMap::ConstIterator it = d->tag->attributeListMap().begin(); for(; it != d->tag->attributeListMap().end(); it++) { const String &name = it->first; const AttributeList &attributes = it->second; bool inExtendedContentDescriptionObject = false; bool inMetadataObject = false; for(unsigned int j = 0; j < attributes.size(); j++) { const Attribute &attribute = attributes[j]; if(!inExtendedContentDescriptionObject && attribute.language() == 0 && attribute.stream() == 0) { d->extendedContentDescriptionObject->attributeData.append(attribute.render(name)); inExtendedContentDescriptionObject = true; } else if(!inMetadataObject && attribute.language() == 0 && attribute.stream() != 0) { d->metadataObject->attributeData.append(attribute.render(name, 1)); inMetadataObject = true; } else { d->metadataLibraryObject->attributeData.append(attribute.render(name, 2)); } } } ByteVector data; for(unsigned int i = 0; i < d->objects.size(); i++) { data.append(d->objects[i]->render(this)); } data = headerGuid + ByteVector::fromLongLong(data.size() + 30, false) + ByteVector::fromUInt(d->objects.size(), false) + ByteVector("\x01\x02", 2) + data; insert(data, 0, d->size); return true;}////////////////////////////////////////////////////////////////////////////////// protected members////////////////////////////////////////////////////////////////////////////////int ASF::File::readBYTE(){ ByteVector v = readBlock(1); return v[0];}int ASF::File::readWORD(){ ByteVector v = readBlock(2); return v.toShort(false);}unsigned int ASF::File::readDWORD(){ ByteVector v = readBlock(4); return v.toUInt(false);}long long ASF::File::readQWORD(){ ByteVector v = readBlock(8); return v.toLongLong(false);}StringASF::File::readString(int length){ ByteVector data = readBlock(length); unsigned int size = data.size(); while (size >= 2) { if(data[size - 1] != '\0' || data[size - 2] != '\0') { break; } size -= 2; } if(size != data.size()) { data.resize(size); } return String(data, String::UTF16LE);}ByteVectorASF::File::renderString(const String &str, bool includeLength){ ByteVector data = str.data(String::UTF16LE) + ByteVector::fromShort(0, false); if(includeLength) { data = ByteVector::fromShort(data.size(), false) + data; } return data;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?