void id3::v2::render(ID3_Writer& writer, const ID3_TagImpl& tag) { // There has to be at least one frame for there to be a tag... if (tag.NumFrames() == 0) { ID3D_WARNING( "id3::v2::render(): no frames to render" ); return; } ID3D_NOTICE( "id3::v2::render(): rendering" ); ID3_TagHeader hdr; hdr.SetSpec(tag.GetSpec()); hdr.SetExtended(tag.GetExtended()); hdr.SetExperimental(tag.GetExperimental()); // set up the encryption and grouping IDs // ... String frms; io::StringWriter frmWriter(frms); if (!tag.GetUnsync()) { ID3D_NOTICE( "id3::v2::render(): rendering frames" ); renderFrames(frmWriter, tag); hdr.SetUnsync(false); } else { ID3D_NOTICE( "id3::v2::render(): rendering unsynced frames" ); io::UnsyncedWriter uw(frmWriter); renderFrames(uw, tag); uw.flush(); ID3D_NOTICE( "id3::v2::render(): numsyncs = " << uw.getNumSyncs() ); hdr.SetUnsync(uw.getNumSyncs() > 0); } size_t frmSize = frms.size(); if (frmSize == 0) { ID3D_WARNING( "id3::v2::render(): rendered frame size is 0 bytes" ); return; } // zero the remainder of the buffer so that our padding bytes are zero luint nPadding = tag.PaddingSize(frmSize); ID3D_NOTICE( "id3::v2::render(): padding size = " << nPadding ); hdr.SetDataSize(frmSize + nPadding); hdr.Render(writer); writer.writeChars(frms.data(), frms.size()); for (size_t i = 0; i < nPadding; ++i) { if (writer.writeChar('\0') == ID3_Writer::END_OF_WRITER) { break; } } }
luint ID3_Tag::Render( uchar *buffer ) { luint bytesUsed = 0; if ( buffer ) { ID3_Elem *cur = frameList; ID3_TagHeader header; SetVersion ( ID3_TAGVERSION, ID3_TAGREVISION ); header.SetVersion ( m_nVersion, m_nRevision ); bytesUsed += header.Size(); // set up the encryption and grouping IDs // ... while( cur ) { // PL // Check that frame has a valid FrameID if( ( cur->frame->GetID() <= 0 ) || (cur->frame->GetID() > ID3FID_CRYPTOREG )) { // TRACE( "Invalide FrameID\n" ); cur = cur->next; continue; } // End PL if ( cur->frame ) { cur->frame->compression = m_bCompression; cur->frame->SetVersion ( m_nVersion, m_nRevision ); bytesUsed += cur->frame->Render ( &buffer[ bytesUsed ] ); } cur = cur->next; } if ( m_bSyncOn ) { uchar *tempz; luint newTagSize; newTagSize = GetUnSyncSize ( &buffer[ header.Size() ], bytesUsed - header.Size() ); if ( newTagSize > 0 && ( newTagSize + header.Size() ) > bytesUsed ) { #ifdef _DEBUG // ASSERT( newTagSize < MAX_ALLOC ); // PL #endif if ( tempz = new uchar[ newTagSize ] ) { UnSync ( tempz, newTagSize, &buffer[ header.Size() ], bytesUsed - header.Size() ); header.SetFlags ( ID3HF_UNSYNC ); memcpy ( &buffer[ header.Size() ], tempz, newTagSize ); bytesUsed = newTagSize + header.Size(); delete[] tempz; } else ID3_THROW ( ID3E_NoMemory ); } } // zero the remainder of the buffer so that our // padding bytes are zero for ( luint i = 0; i < PaddingSize ( bytesUsed ); i++ ) buffer[ bytesUsed + i ] = 0; bytesUsed += PaddingSize ( bytesUsed ); header.SetDataSize ( bytesUsed - header.Size() ); header.Render ( buffer ); } else ID3_THROW ( ID3E_NoBuffer ); // set the flag which says that the tag hasn't changed m_bHasChanged = false; return bytesUsed; }