Exemple #1
0
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;
        }
    }
}
Exemple #2
0
luint ID3_Tag::Size( void )
{
	luint			bytesUsed	= 0;
	ID3_Elem		*cur		= frameList;
	ID3_TagHeader	header;

	header.SetVersion ( m_nVersion, m_nRevision );
	bytesUsed += header.Size();

	while( cur )
	{	
		// PL
		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->SetVersion ( m_nVersion, m_nRevision );
			bytesUsed += cur->frame->Size();
		}

		cur = cur->next;
	}

	// add 30% for sync
	if	( m_bSyncOn )
		bytesUsed += bytesUsed / 3;

	bytesUsed += PaddingSize ( bytesUsed );

	return bytesUsed;
}
Exemple #3
0
size_t ID3_TagImpl::Size() const
{
    if (this->NumFrames() == 0)
    {
        return 0;
    }
    ID3_TagHeader hdr;

    hdr.SetSpec(this->GetSpec());
    size_t bytesUsed = hdr.Size();

    size_t frameBytes = 0;
    for (const_iterator cur = _frames.begin(); cur != _frames.end(); ++cur)
    {
        if (*cur)
        {
            (*cur)->SetSpec(this->GetSpec());
            frameBytes += (*cur)->Size();
        }
    }

    if (!frameBytes)
    {
        return 0;
    }

    bytesUsed += frameBytes;
    // add 30% for sync
    if (this->GetUnsync())
    {
        bytesUsed += bytesUsed / 3;
    }

    bytesUsed += this->PaddingSize(bytesUsed);
    return bytesUsed;
}
Exemple #4
0
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;
}
Exemple #5
0
bool id3::v2::parse(ID3_TagImpl& tag, ID3_Reader& reader)
{
  ID3_Reader::pos_type beg = reader.getCur();
  io::ExitTrigger et(reader);

  ID3_TagHeader hdr;

  io::WindowedReader wr(reader, ID3_TagHeader::SIZE);

  if (!hdr.Parse(wr) || wr.getCur() == beg)
  {
    ID3D_NOTICE( "id3::v2::parse(): parsing header failes" );
    return false;
  }
  if (hdr.GetExtended())
  {
    hdr.ParseExtended(reader);
  }
  tag.SetSpec(hdr.GetSpec());

  size_t dataSize = hdr.GetDataSize();
  ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): dataSize = " << dataSize);

  wr.setWindow(wr.getCur(), dataSize);
  et.setExitPos(wr.getEnd());

  ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): data window beg = " << wr.getBeg() );
  ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): data window cur = " << wr.getCur() );
  ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): data window end = " << wr.getEnd() );
  tag.SetExtended(hdr.GetExtended());
  if (!hdr.GetUnsync())
  {
    tag.SetUnsync(false);
    parseFrames(tag, wr);
  }
  else
  {
    // The buffer has been unsynced.  It will have to be resynced to be
    // readable.  This has to be done a character at a time.
    //
    // The original reader may be reading in characters from a file.  Doing
    // this a character at a time is quite slow.  To improve performance, read
    // in the entire buffer into a string, then create an UnsyncedReader from
    // the string.
    //
    // It might be better to implement a BufferedReader so that the details
    // of this can be abstracted away behind a class
    tag.SetUnsync(true);
    BString raw = io::readAllBinary(wr);
    io::BStringReader bsr(raw);
    io::UnsyncedReader ur(bsr);
    ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): unsync beg = " << ur.getBeg() );
    ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): unsync cur = " << ur.getCur() );
    ID3D_NOTICE( "ID3_TagImpl::Parse(ID3_Reader&): unsync end = " << ur.getEnd() );

    // Now read the UnsyncedReader into another string, and parse the frames
    // from the string.  This is done so that 1. the unsynced reader is
    // unsynced exactly once, removing the possibility of multiple unsyncings
    // of the same string, and 2) so that calls to readChars aren't done a
    // character at a time for every call
    BString synced = io::readAllBinary(ur);
    io::BStringReader sr(synced);
    parseFrames(tag, sr);
  }

  return true;
}