ID3v2_CommentsFrame* ID3v2_Tag::findCommentFrame() const { ID3v2_FrameList* list = frameList(wxT("COMM")); ID3v2_CommentsFrame* frame; if( list ) { // prefer comments without description, start searching with the last (mostly the newest) ID3v2_FrameList::Node* node = list->GetLast(); while( node ) { frame = (ID3v2_CommentsFrame*)node->GetData(); if( frame->description().IsEmpty() && !frame->text().IsEmpty() ) { return frame; } node = node->GetPrevious(); } // try to return empty frames without description list->GetLast(); while( node ) { frame = (ID3v2_CommentsFrame*)node->GetData(); if( frame->description().IsEmpty() ) { return frame; } node = node->GetPrevious(); } /* if( !forWrite ) // do not overwrite eg. MusicMatch comments { // okay, no comment so far, check all comment frames and return the first non-empty comment node = list->GetFirst(); while( node ) { frame = (ID3v2_CommentsFrame*)node->GetData(); if( !frame->text().IsEmpty() ) { return frame; } node = node->GetNext(); } // just use the first frame node = list->GetFirst(); if( node ) { return (ID3v2_CommentsFrame*)node->GetData(); } }*/ } return NULL; }
void ID3v2_Tag::setTextFrame(const wxString &id, const wxString &value) { if(value.IsEmpty()) { removeFrames(id); return; } //if(!d->frameListMap[id].isEmpty()) // d->frameListMap[id].front()->setText(value); ID3v2_FrameList* it = frameList(id); if( it ) { ID3v2_FrameList::Node* l = it->GetFirst(); if( l ) { l->GetData()->setText(value); } } else { const SjStringType encoding = m_factory->defaultTextEncoding(); SjByteVector idBv; idBv.appendString(id, SJ_LATIN1); ID3v2_TextIdentificationFrame *f = new ID3v2_TextIdentificationFrame(idBv, encoding); addFrame(f); f->setText(value); } }
wxString ID3v2_Tag::simpleFrame(const wxString& frameId) const { ID3v2_FrameList* list = frameList(frameId); if( list ) { ID3v2_FrameList::Node* node = list->GetFirst(); if( node ) { return node->GetData()->toString(); } } return wxEmptyString; }
void ID3v2_Tag::removeFrames(const wxString &id) { /*FrameList l = d->frameListMap[id]; for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) removeFrame(*it, true);*/ ID3v2_FrameList* l = frameList(id); if( l ) { ID3v2_FrameList::Node* first; while( (first=l->GetFirst()) != NULL ) { removeFrame(first->GetData(), true); } } }
ID3v2_Tag::~ID3v2_Tag() { if( m_extendedHeader) delete m_extendedHeader; if( m_footer ) delete m_footer; // delete all frame list contents, the frame list itself is destroyed automatically ID3v2_FrameList::Node* node = m_frameList.GetFirst(); for( ; node; node = node->GetNext() ) { delete node->GetData(); } // delete all frame hash values, the hash itself is destroyed automatically SjHashIterator iterator; ID3v2_FrameList* frameList; wxString frameId; while( (frameList=(ID3v2_FrameList*)m_frameListMap.Iterate(iterator, frameId)) ) { delete frameList; } }
SjByteVector ID3v2_Tag::render() { // We need to render the "tag data" first so that we have to correct size to // render in the tag's header. The "tag data" -- everything that is included // in ID3v2::Header::tagSize() -- includes the extended header, frames and // padding, but does not include the tag's header or footer. SjByteVector tagData; // TODO: Render the extended header. // Loop through the frames rendering them and adding them to the tagData. //for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) for ( ID3v2_FrameList::Node *node = m_frameList.GetFirst(); node; node = node->GetNext() ) { ID3v2_Frame* it = node->GetData(); if(!it->header()->tagAlterPreservation()) tagData.append(it->render()); } // Compute the amount of padding, and append that to tagData. SjUint paddingSize = 0; SjUint originalSize = m_header.tagSize(); if(tagData.size() < originalSize) paddingSize = originalSize - tagData.size(); else paddingSize = 1024; tagData.append(SjByteVector(paddingSize, char(0))); // Set the tag size. m_header.setTagSize(tagData.size()); // TODO: This should eventually include d->footer->render(). return m_header.render() + tagData; }
ID3v2_UserTextIdentificationFrame *find(ID3v2_Tag *tag, const wxString &description) // static { const ID3v2_FrameList* l = tag->frameList(wxT("TXXX")); /*for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) { UserTextIdentificationFrame *f = dynamic_cast<UserTextIdentificationFrame *>(*it); if(f && f->description() == description) return f; } */ if( l ) { for ( ID3v2_FrameList::Node *node = l->GetFirst(); node; node = node->GetNext() ) { ID3v2_UserTextIdentificationFrame *f = (ID3v2_UserTextIdentificationFrame*)node->GetData(); if( f && f->description() == description ) return f; } } return 0; }