/// <summary> /// Read all frames from specific FileStream /// </summary> /// <param name="Data">FileStream to read data from</param> /// <param name="Length">Length of data to read from FileStream</param> private void ReadFrames(FileStreamEx Data, int Length) { string FrameID; int FrameLength; FrameFlags Flags = new FrameFlags(); byte Buf; // If ID3v2 is ID3v2.2 FrameID, FrameLength of Frames is 3 byte // otherwise it's 4 character int FrameIDLen = VersionInfo.Minor == 2 ? 3 : 4; // Minimum frame size is 10 because frame header is 10 byte while (Length > 10) { // check for padding( 00 bytes ) Buf = Data.ReadByte(); if (Buf == 0) { Length--; continue; } // if readed byte is not zero. it must read as FrameID Data.Seek(-1, SeekOrigin.Current); // ---------- Read Frame Header ----------------------- FrameID = Data.ReadText(FrameIDLen, TextEncodings.Ascii); if (FrameIDLen == 3) FrameID = FramesInfo.Get4CharID(FrameID); FrameLength = Convert.ToInt32(Data.ReadUInt(FrameIDLen)); if (FrameIDLen == 4) Flags = (FrameFlags)Data.ReadUInt(2); else Flags = 0; // must set to default flag long Position = Data.Position; if (Length > 0x10000000) throw (new FileLoadException("This file contain frame that have more than 256MB data")); bool Added = false; if (IsAddable(FrameID)) // Check if frame is not filter Added = AddFrame(Data, FrameID, FrameLength, Flags); if (!Added) // if don't read this frame // we must go forward to read next frame Data.Position = Position + FrameLength; Length -= FrameLength + 10; } }
private void SaveRestOfFile(int StartIndex, FileStreamEx Orgin, FileStreamEx Temp, int Ver) { Orgin.Seek(StartIndex, SeekOrigin.Begin); byte[] Buf = new byte[Orgin.Length - StartIndex]; Orgin.Read(Buf, 0, Buf.Length); Temp.Write(Buf, 0, Buf.Length); Orgin.Close(); Temp.Close(); if (Ver != 0) SetMinorVersion(Ver); File.Delete(Orgin.Name); string FinallyName = Temp.Name.Remove(Temp.Name.Length - 5); File.Move(Temp.Name, FinallyName); _FilePath = FinallyName; }
/// <summary> /// Save ID3v1 information to file /// </summary> public void Save() { FileStreamEx fs = new FileStreamEx(_FilePath, FileMode.Open); bool HTag = fs.HaveID3v1(); if (HTag && !_HaveTag) // just delete ID3 fs.SetLength(fs.Length - 128); else if (!HTag && _HaveTag) { fs.Seek(0, SeekOrigin.End); fs.Write(GetTagBytes, 0, 128); } else if (HTag && _HaveTag) { fs.Seek(-128, SeekOrigin.End); fs.Write(GetTagBytes, 0, 128); } fs.Close(); }
/// <summary> /// Save ID3 info to file /// </summary> /// <param name="Ver">minor version of ID3v2</param> /// <param name="Formula">Formula to renaming file</param> public void Save(int Ver, string Formula) { if (Ver < 3 || Ver > 4) throw (new ArgumentOutOfRangeException("Version of ID3 can be between 3-4")); string NewFilePath; if (Formula == "") NewFilePath = _FilePath; else { string DirName = Path.GetDirectoryName(_FilePath); NewFilePath = DirName + ((DirName.Length > 0) ? "\\" : "") + this.FormulaFileName(Formula); } FileStreamEx Orgin = new FileStreamEx(_FilePath, FileMode.Open); FileStreamEx Temp = new FileStreamEx(NewFilePath + "~TEMP", FileMode.Create); int StartIndex = 0; if (Orgin.HaveID3v2()) { Orgin.Seek(3, SeekOrigin.Current); StartIndex = Orgin.ReadSize(); } if (!_HaveTag) { SaveRestOfFile(StartIndex, Orgin, Temp, 0); return; } // if Orginal file and current file both don't contain ID3 // we don't need to do anything WriteID3Header(Temp, Ver); foreach (TextFrame TF in _TextFrames.Items) { if (!FramesInfo.IsCompatible(TF.FrameID, Ver)) continue; if (TF.IsAvailable) TF.FrameStream(Ver).WriteTo(Temp); } foreach (UserTextFrame UTF in _UserTextFrames.Items) { if (!FramesInfo.IsCompatible(UTF.FrameID, Ver)) continue; if (UTF.IsAvailable) UTF.FrameStream(Ver).WriteTo(Temp); } foreach (PrivateFrame PF in _PrivateFrames.Items) { if (!FramesInfo.IsCompatible(PF.FrameID, Ver)) continue; if (PF.IsAvailable) PF.FrameStream(Ver).WriteTo(Temp); } foreach (TextWithLanguageFrame TWLF in _TextWithLangFrames.Items) { if (!FramesInfo.IsCompatible(TWLF.FrameID, Ver)) continue; if (TWLF.IsAvailable) TWLF.FrameStream(Ver).WriteTo(Temp); } foreach (SynchronisedText ST in _SynchronisedTextFrames.Items) { if (!FramesInfo.IsCompatible(ST.FrameID, Ver)) continue; if (ST.IsAvailable) ST.FrameStream(Ver).WriteTo(Temp); } foreach (AttachedPictureFrame AP in _AttachedPictureFrames.Items) { if (!FramesInfo.IsCompatible(AP.FrameID, Ver)) continue; if (AP.IsAvailable) AP.FrameStream(Ver).WriteTo(Temp); } foreach (GeneralFileFrame GF in _EncapsulatedObjectFrames.Items) { if (!FramesInfo.IsCompatible(GF.FrameID, Ver)) continue; if (GF.IsAvailable) GF.FrameStream(Ver).WriteTo(Temp); } foreach (PopularimeterFrame PF in _PopularimeterFrames.Items) { if (!FramesInfo.IsCompatible(PF.FrameID, Ver)) continue; if (PF.IsAvailable) PF.FrameStream(Ver).WriteTo(Temp); } foreach (AudioEncryptionFrame AE in _AudioEncryptionFrames.Items) { if (!FramesInfo.IsCompatible(AE.FrameID, Ver)) continue; if (AE.IsAvailable) AE.FrameStream(Ver).WriteTo(Temp); } foreach (LinkFrame LF in _LinkFrames.Items) { if (!FramesInfo.IsCompatible(LF.FrameID, Ver)) continue; if (LF.IsAvailable) LF.FrameStream(Ver).WriteTo(Temp); } foreach (TermOfUseFrame TU in _TermOfUseFrames.Items) { if (!FramesInfo.IsCompatible(TU.FrameID, Ver)) continue; if (TU.IsAvailable) TU.FrameStream(Ver).WriteTo(Temp); } foreach (DataWithSymbolFrame DS in _DataWithSymbolFrames.Items) { if (!FramesInfo.IsCompatible(DS.FrameID, Ver)) continue; if (DS.IsAvailable) DS.FrameStream(Ver).WriteTo(Temp); } // Saving Unknown Frames if (!_DropUnknown) foreach (BinaryFrame BF in _UnknownFrames.Items) if (BF.IsAvailable) BF.FrameStream(Ver).WriteTo(Temp); if (_MCDIFrame != null && FramesInfo.IsCompatible(_MCDIFrame.FrameID, Ver)) if (_MCDIFrame.IsAvailable) _MCDIFrame.FrameStream(Ver).WriteTo(Temp); if (_SYTCFrame != null && FramesInfo.IsCompatible(_SYTCFrame.FrameID, Ver)) if (_SYTCFrame.IsAvailable) _SYTCFrame.FrameStream(Ver).WriteTo(Temp); if (_PCNTFrame != null && FramesInfo.IsCompatible(_PCNTFrame.FrameID, Ver)) if (_PCNTFrame.IsAvailable) _PCNTFrame.FrameStream(Ver).WriteTo(Temp); if (_RBUFFrame != null && FramesInfo.IsCompatible(_RBUFFrame.FrameID, Ver)) if (_RBUFFrame.IsAvailable) _RBUFFrame.FrameStream(Ver).WriteTo(Temp); if (_OWNEFrame != null && FramesInfo.IsCompatible(_OWNEFrame.FrameID, Ver)) if (_OWNEFrame.IsAvailable) _OWNEFrame.FrameStream(Ver).WriteTo(Temp); if (_COMRFrame != null && FramesInfo.IsCompatible(_COMRFrame.FrameID, Ver)) if (_COMRFrame.IsAvailable) _COMRFrame.FrameStream(Ver).WriteTo(Temp); if (_RVRBFrame != null && FramesInfo.IsCompatible(_RVRBFrame.FrameID, Ver)) if (_RVRBFrame.IsAvailable) _RVRBFrame.FrameStream(Ver).WriteTo(Temp); if (_EQUAFrame != null && FramesInfo.IsCompatible(_EQUAFrame.FrameID, Ver)) if (_EQUAFrame.IsAvailable) _EQUAFrame.FrameStream(Ver).WriteTo(Temp); if (_RVADFrame != null && FramesInfo.IsCompatible(_RVADFrame.FrameID, Ver)) if (_RVADFrame.IsAvailable) _RVADFrame.FrameStream(Ver).WriteTo(Temp); if (_ETCOFrame != null && FramesInfo.IsCompatible(_ETCOFrame.FrameID, Ver)) if (_ETCOFrame.IsAvailable) _ETCOFrame.FrameStream(_ver.Minor).WriteTo(Temp); if (_POSSFrame != null && FramesInfo.IsCompatible(_POSSFrame.FrameID, Ver)) if (_POSSFrame.IsAvailable) _POSSFrame.FrameStream(Ver).WriteTo(Temp); SaveRestOfFile(StartIndex, Orgin, Temp, Ver); }
/// <summary> /// Load ID3v1 information from file /// </summary> public void Load() { FileStreamEx FS = new FileStreamEx(_FilePath, FileMode.Open); if (!FS.HaveID3v1()) { FS.Close(); _HaveTag = false; return; } _Title = FS.ReadText(30, TextEncodings.Ascii); FS.Seek(-95, SeekOrigin.End); _Artist = FS.ReadText(30, TextEncodings.Ascii); FS.Seek(-65, SeekOrigin.End); _Album = FS.ReadText(30, TextEncodings.Ascii); FS.Seek(-35, SeekOrigin.End); _Year = FS.ReadText(4, TextEncodings.Ascii); FS.Seek(-31, SeekOrigin.End); _Comment = FS.ReadText(28, TextEncodings.Ascii); FS.Seek(-2, SeekOrigin.End); _TrackNumber = FS.ReadByte(); _Genre = FS.ReadByte(); FS.Close(); _HaveTag = true; }