Exemplo n.º 1
0
        /* -------------------------------------------------------------------------- */

        public TFLACFile()
        {
            FID3v2          = new TID3v2();
            FHeader         = new TFlacHeader();
            aMetaBlockOther = new ArrayList();
            aExtraFields    = new ArrayList();
            FResetData(true, true);
        }
Exemplo n.º 2
0
		/* -------------------------------------------------------------------------- */
		// saves metablocks back to the file
		// always tries to rebuild header so padding exists after comment block and no more than 1 padding block exists
		private bool RebuildFile( String sFile, MemoryStream VorbisBlock)
		{  
			FileStream source = null;
			BinaryReader r = null;
			FileStream destination = null;
			BinaryWriter w = null;

			long iFileAge;
			int iNewPadding;
			int iMetaCount;
			int iExtraPadding;
			String sTmp;
			String BufferName = "";
			byte[] MetaDataBlockHeader = new byte[4];
			TFlacHeader oldHeader = new TFlacHeader();
			MemoryStream MetaBlocks = null;
			bool bRebuild;
			bool bRearrange;
			bool result = false;
  
			bRearrange = false;
			iExtraPadding = 0;
			if ( !File.Exists(sFile) ) return result;

			try
			{
				iFileAge = 0;
				if ( bTAG_PreserveDate ) iFileAge = File.GetLastWriteTime(sFile).Ticks;

				// re arrange other metadata in case of
				// 1. padding block is not aligned after vorbis comment
				// 2. insufficient padding - rearange upon file rebuild
				// 3. fragmented padding blocks
				iMetaCount = aMetaBlockOther.Count;
				if ( (FPaddingIndex != FVorbisIndex + 1) || (FPadding <= VorbisBlock.Length - FTagSize ) || FPaddingFragments ) 
				{
					MetaBlocks = new MemoryStream();
					for (int i = 0; i < iMetaCount; i++)
					{
						((TMetaData)aMetaBlockOther[ i ]).MetaDataBlockHeader[ 0 ] = (byte)( ((TMetaData)aMetaBlockOther[i]).MetaDataBlockHeader[ 0 ] & 0x7f ); // not last

						if (META_PADDING == ((TMetaData)aMetaBlockOther[ i ]).MetaDataBlockHeader[ 0 ])  
						{
							iExtraPadding += (int)( ((TMetaData)aMetaBlockOther[ i ]).Data.Length + 4 ); // add padding size plus 4 bytes of header block
						} 
						else 
						{
							((TMetaData)aMetaBlockOther[ i ]).Data.Position = 0;
							MetaBlocks.Write( ((TMetaData)aMetaBlockOther[ i ]).MetaDataBlockHeader,0,4 );

							Utils.CopyMemoryStreamFrom(MetaBlocks,((TMetaData)aMetaBlockOther[ i ]).Data, 0);
						}

					}
					MetaBlocks.Position = 0;
					bRearrange = true;
				}

				// set up file
				if (FPadding <= VorbisBlock.Length - FTagSize )  // no room rebuild the file from scratch
				{ 
					bRebuild = true;
					BufferName = sFile + "~";
					source = new FileStream( sFile, FileMode.Open, FileAccess.Read  ); // Set read-only and open old file, and create new
					r = new BinaryReader(source);
					destination = new FileStream( BufferName, FileMode.Create, FileAccess.Write);
					w = new BinaryWriter(destination);
		
					oldHeader.StreamMarker = r.ReadChars(4);
					oldHeader.MetaDataBlockHeader = r.ReadBytes(4);
					oldHeader.Info = r.ReadBytes(18);
					oldHeader.MD5Sum = r.ReadBytes(16);		
					oldHeader.MetaDataBlockHeader[0] = (byte)(oldHeader.MetaDataBlockHeader[0] & 0x7f ); //just in case no metadata existed

					//w.Write( oldHeader, 0, 32 );
					w.Write(oldHeader.StreamMarker);
					w.Write(oldHeader.MetaDataBlockHeader);
					w.Write(oldHeader.Info);
					w.Write(oldHeader.MD5Sum);

					Utils.CopyMemoryStreamFrom(w, MetaBlocks, 0);
				}
				else 
				{
					bRebuild = false;
					source = null;
					destination = new FileStream ( sFile, FileMode.Create, FileAccess.Write); // Set write-access and open file
					w = new BinaryWriter(destination);
					if (bRearrange)  
					{
						destination.Seek( 32, SeekOrigin.Begin );
						Utils.CopyMemoryStreamFrom(destination, MetaBlocks, 0);
					} 
					else 
					{
						destination.Seek( FVCOffset - 4, SeekOrigin.Begin);		  
					}
				}

				// finally write vorbis block
				MetaDataBlockHeader[0] = META_VORBIS_COMMENT;
				MetaDataBlockHeader[1] = (byte)(( VorbisBlock.Length >> 16 ) & 255 );
				MetaDataBlockHeader[2] = (byte)(( VorbisBlock.Length >> 8 ) & 255 );
				MetaDataBlockHeader[3] = (byte)( VorbisBlock.Length & 255 );
				destination.Write( MetaDataBlockHeader,0, 4 );
				Utils.CopyMemoryStreamFrom(destination,VorbisBlock,VorbisBlock.Length);

				// and add padding
				if (FPaddingLast || bRearrange)  
				{
					MetaDataBlockHeader[0] = META_PADDING | 0x80;
				} 
				else 
				{
					MetaDataBlockHeader[0] = META_PADDING;
				}
				if (bRebuild)  
				{
					iNewPadding = 4096; // why not...
				} 
				else 
				{
					if (FTagSize > VorbisBlock.Length )
					{ // tag got smaller increase padding
						iNewPadding = (int)(FPadding + FTagSize - VorbisBlock.Length) + iExtraPadding;
					} 
					else 
					{ // tag got bigger shrink padding
						iNewPadding = (int)(FPadding - VorbisBlock.Length + FTagSize ) + iExtraPadding;
					}
				}
				MetaDataBlockHeader[1] = (byte)(( iNewPadding >> 16 ) & 255 );
				MetaDataBlockHeader[2] = (byte)(( iNewPadding >> 8 ) & 255 );
				MetaDataBlockHeader[3] = (byte)( iNewPadding & 255 );
				w.Write(MetaDataBlockHeader,0,4);

				if ((FPadding != iNewPadding) | bRearrange )
				{ // fill the block with zeros
					sTmp = "";
					for (int i=0; i<iNewPadding; i++)
						sTmp += '\0';					
					w.Write( sTmp );
				}

				// finish
				if ( bRebuild )
				{ // time to put back the audio data...
					source.Seek( FAudioOffset, SeekOrigin.Begin );
					Utils.CopyMemoryStreamFrom(destination, source, source.Length - FAudioOffset);

					source.Close();
					destination.Close();

					//Replace old file and delete temporary file
					File.Delete( sFile );
					File.Copy( BufferName, sFile );
					result = true;
				} 
				else 
				{
					result = true;
					destination.Close();
				}

				// post save tasks
				DateTime newDateTime = new DateTime(iFileAge);
				if (bTAG_PreserveDate) File.SetLastWriteTime( sFile, newDateTime );
				if (bRearrange) MetaBlocks.Close();
			}
			catch (Exception e)
			{
				// Access error
				if ( File.Exists( BufferName ) )  File.Delete( BufferName );
				//LogDelegator.GetLogDelegate()(Log.LV_ERROR,e.Message);
				System.Console.WriteLine(e.StackTrace);
			}

			// stream deallocation
			if (destination != null) destination.Close();
			if (source != null) source.Close();	

			return result;
		}
Exemplo n.º 3
0
		/* -------------------------------------------------------------------------- */

		public TFLACFile()
		{  
			FID3v2 = new TID3v2();
			FHeader = new TFlacHeader();
			aMetaBlockOther = new ArrayList();
			aExtraFields = new ArrayList();
			FResetData( true, true );
		}
Exemplo n.º 4
0
        /* -------------------------------------------------------------------------- */
        // saves metablocks back to the file
        // always tries to rebuild header so padding exists after comment block and no more than 1 padding block exists
        private bool RebuildFile(String sFile, MemoryStream VorbisBlock)
        {
            FileStream   source      = null;
            BinaryReader r           = null;
            FileStream   destination = null;
            BinaryWriter w           = null;

            long   iFileAge;
            int    iNewPadding;
            int    iMetaCount;
            int    iExtraPadding;
            String sTmp;
            String BufferName = "";

            byte[]       MetaDataBlockHeader = new byte[4];
            TFlacHeader  oldHeader           = new TFlacHeader();
            MemoryStream MetaBlocks          = null;
            bool         bRebuild;
            bool         bRearrange;
            bool         result = false;

            bRearrange    = false;
            iExtraPadding = 0;
            if (!File.Exists(sFile))
            {
                return(result);
            }

            try
            {
                iFileAge = 0;
                if (bTAG_PreserveDate)
                {
                    iFileAge = File.GetLastWriteTime(sFile).Ticks;
                }

                // re arrange other metadata in case of
                // 1. padding block is not aligned after vorbis comment
                // 2. insufficient padding - rearange upon file rebuild
                // 3. fragmented padding blocks
                iMetaCount = aMetaBlockOther.Count;
                if ((FPaddingIndex != FVorbisIndex + 1) || (FPadding <= VorbisBlock.Length - FTagSize) || FPaddingFragments)
                {
                    MetaBlocks = new MemoryStream();
                    for (int i = 0; i < iMetaCount; i++)
                    {
                        ((TMetaData)aMetaBlockOther[i]).MetaDataBlockHeader[0] = (byte)(((TMetaData)aMetaBlockOther[i]).MetaDataBlockHeader[0] & 0x7f);                                 // not last

                        if (META_PADDING == ((TMetaData)aMetaBlockOther[i]).MetaDataBlockHeader[0])
                        {
                            iExtraPadding += (int)(((TMetaData)aMetaBlockOther[i]).Data.Length + 4);                                 // add padding size plus 4 bytes of header block
                        }
                        else
                        {
                            ((TMetaData)aMetaBlockOther[i]).Data.Position = 0;
                            MetaBlocks.Write(((TMetaData)aMetaBlockOther[i]).MetaDataBlockHeader, 0, 4);

                            Utils.CopyMemoryStreamFrom(MetaBlocks, ((TMetaData)aMetaBlockOther[i]).Data, 0);
                        }
                    }
                    MetaBlocks.Position = 0;
                    bRearrange          = true;
                }

                // set up file
                if (FPadding <= VorbisBlock.Length - FTagSize)                   // no room rebuild the file from scratch
                {
                    bRebuild    = true;
                    BufferName  = sFile + "~";
                    source      = new FileStream(sFile, FileMode.Open, FileAccess.Read);                   // Set read-only and open old file, and create new
                    r           = new BinaryReader(source);
                    destination = new FileStream(BufferName, FileMode.Create, FileAccess.Write);
                    w           = new BinaryWriter(destination);

                    oldHeader.StreamMarker        = r.ReadChars(4);
                    oldHeader.MetaDataBlockHeader = r.ReadBytes(4);
                    oldHeader.Info   = r.ReadBytes(18);
                    oldHeader.MD5Sum = r.ReadBytes(16);
                    oldHeader.MetaDataBlockHeader[0] = (byte)(oldHeader.MetaDataBlockHeader[0] & 0x7f);                      //just in case no metadata existed

                    //w.Write( oldHeader, 0, 32 );
                    w.Write(oldHeader.StreamMarker);
                    w.Write(oldHeader.MetaDataBlockHeader);
                    w.Write(oldHeader.Info);
                    w.Write(oldHeader.MD5Sum);

                    Utils.CopyMemoryStreamFrom(w, MetaBlocks, 0);
                }
                else
                {
                    bRebuild    = false;
                    source      = null;
                    destination = new FileStream(sFile, FileMode.Create, FileAccess.Write);                       // Set write-access and open file
                    w           = new BinaryWriter(destination);
                    if (bRearrange)
                    {
                        destination.Seek(32, SeekOrigin.Begin);
                        Utils.CopyMemoryStreamFrom(destination, MetaBlocks, 0);
                    }
                    else
                    {
                        destination.Seek(FVCOffset - 4, SeekOrigin.Begin);
                    }
                }

                // finally write vorbis block
                MetaDataBlockHeader[0] = META_VORBIS_COMMENT;
                MetaDataBlockHeader[1] = (byte)((VorbisBlock.Length >> 16) & 255);
                MetaDataBlockHeader[2] = (byte)((VorbisBlock.Length >> 8) & 255);
                MetaDataBlockHeader[3] = (byte)(VorbisBlock.Length & 255);
                destination.Write(MetaDataBlockHeader, 0, 4);
                Utils.CopyMemoryStreamFrom(destination, VorbisBlock, VorbisBlock.Length);

                // and add padding
                if (FPaddingLast || bRearrange)
                {
                    MetaDataBlockHeader[0] = META_PADDING | 0x80;
                }
                else
                {
                    MetaDataBlockHeader[0] = META_PADDING;
                }
                if (bRebuild)
                {
                    iNewPadding = 4096;                     // why not...
                }
                else
                {
                    if (FTagSize > VorbisBlock.Length)
                    {                     // tag got smaller increase padding
                        iNewPadding = (int)(FPadding + FTagSize - VorbisBlock.Length) + iExtraPadding;
                    }
                    else
                    {                     // tag got bigger shrink padding
                        iNewPadding = (int)(FPadding - VorbisBlock.Length + FTagSize) + iExtraPadding;
                    }
                }
                MetaDataBlockHeader[1] = (byte)((iNewPadding >> 16) & 255);
                MetaDataBlockHeader[2] = (byte)((iNewPadding >> 8) & 255);
                MetaDataBlockHeader[3] = (byte)(iNewPadding & 255);
                w.Write(MetaDataBlockHeader, 0, 4);

                if ((FPadding != iNewPadding) | bRearrange)
                {                 // fill the block with zeros
                    sTmp = "";
                    for (int i = 0; i < iNewPadding; i++)
                    {
                        sTmp += '\0';
                    }
                    w.Write(sTmp);
                }

                // finish
                if (bRebuild)
                {                 // time to put back the audio data...
                    source.Seek(FAudioOffset, SeekOrigin.Begin);
                    Utils.CopyMemoryStreamFrom(destination, source, source.Length - FAudioOffset);

                    source.Close();
                    destination.Close();

                    //Replace old file and delete temporary file
                    File.Delete(sFile);
                    File.Copy(BufferName, sFile);
                    result = true;
                }
                else
                {
                    result = true;
                    destination.Close();
                }

                // post save tasks
                DateTime newDateTime = new DateTime(iFileAge);
                if (bTAG_PreserveDate)
                {
                    File.SetLastWriteTime(sFile, newDateTime);
                }
                if (bRearrange)
                {
                    MetaBlocks.Close();
                }
            }
            catch (Exception e)
            {
                // Access error
                if (File.Exists(BufferName))
                {
                    File.Delete(BufferName);
                }
                //LogDelegator.GetLogDelegate()(Log.LV_ERROR,e.Message);
                System.Console.WriteLine(e.StackTrace);
            }

            // stream deallocation
            if (destination != null)
            {
                destination.Close();
            }
            if (source != null)
            {
                source.Close();
            }

            return(result);
        }