示例#1
0
        public override void Validate(ID3Versions version)
        {
            Exception innerException = null;

            if ((version & ID3Versions.V2) != ID3Versions.V2)
            {
                innerException = new UnsupportedVersionException(version);
            }
            else
            {
                try
                {
                    text.Validate(version);
                }
                catch (IOValidationException ex)
                {
                    innerException = ex;
                }
            }

            if (innerException != null)
            {
                throw new FrameValidationException("Validation failed.", this, innerException);
            }
        }
示例#2
0
            public FrameParameters(ID3Versions version)
            {
                switch (version)
                {
                case ID3Versions.V2_2:
                    HeaderLength    = ID3V2_2FrameHeaderLength;
                    IDLength        = ID3V2_2FrameIdFieldLength;
                    SizeLength      = ID3V2_2FrameSizeFieldLength;
                    FlagsLength     = ID3V2_2FrameFlagsField;
                    SizeIsSynchSafe = false;
                    break;

                case ID3Versions.V2_3:
                    HeaderLength    = ID3V2_3FrameHeaderLength;
                    IDLength        = ID3V2_3FrameIdFieldLength;
                    SizeLength      = ID3V2_3FrameSizeFieldLength;
                    FlagsLength     = ID3V2_3FrameFlagsField;
                    SizeIsSynchSafe = false;
                    break;

                case ID3Versions.V2_4:
                    HeaderLength    = ID3V2_4FrameHeaderLength;
                    IDLength        = ID3V2_4FrameIdFieldLength;
                    SizeLength      = ID3V2_4FrameSizeFieldLength;
                    FlagsLength     = ID3V2_4FrameFlagsField;
                    SizeIsSynchSafe = true;
                    break;

                default:
                    throw new UnsupportedVersionException(version);
                }
            }
示例#3
0
 public override void Validate(ID3Versions version)
 {
     foreach (ID3v2Frame frame in frames)
     {
         frame.Validate(version);
     }
 }
示例#4
0
        /// <summary>
        /// Writes the tag to a stream using the format specified by a particular ID3 version.
        /// Only V1_0 and V1_1 are supported.
        /// </summary>
        /// <param name="stream">The stream to write the tag to.</param>
        /// <param name="version">The version to use. Only V1_0 and V1_1 are supported.</param>
        public override void WriteTag(Stream stream, ID3Versions version)
        {
            if ((version & ID3Versions.V1) != ID3Versions.V1)
            {
                throw new UnsupportedVersionException("Only versions 1.x are supported by this method.", version);
            }

            EnsureSpace(stream);
            string tagTitle  = FormatString(this.Title, TitleFieldLength);
            string tagArtist = FormatString(this.Artist, ArtistFieldLength);
            string tagAlbum  = FormatString(this.Album, AlbumFieldLength);
            string tagYear   = FormatString(this.Year, YearFieldLength);

            stream.Seek(-TagLenth, SeekOrigin.End);
            stream.Write(StringToBytes("TAG"), 0, 3);
            stream.Write(StringToBytes(tagTitle), 0, TitleFieldLength);
            stream.Write(StringToBytes(tagArtist), 0, ArtistFieldLength);
            stream.Write(StringToBytes(tagAlbum), 0, AlbumFieldLength);
            stream.Write(StringToBytes(tagYear), 0, YearFieldLength);

            if (version == ID3Versions.V1_0)
            {
                string tagComment = FormatString(this.Comments, ID3v1CommentsFieldLength);
                stream.Write(StringToBytes(tagComment), 0, ID3v1CommentsFieldLength);
            }
            else
            {
                string tagComment = FormatString(this.Comments, ID3v1_1CommentsFieldLength);
                stream.Write(StringToBytes(tagComment), 0, ID3v1_1CommentsFieldLength);
                stream.WriteByte((byte)0x0);
                stream.WriteByte((byte)this.TrackNumber);
            }
            stream.WriteByte((byte)this.GenreAsInt);
        }
示例#5
0
        /// <summary>
        /// Parses the raw frame data.
        /// </summary>
        /// <param name="frameData">The raw frame data.</param>
        /// <param name="version">The ID3v2 version of the tag being parsed.</param>
        protected override void ParseFrameData(byte[] frameData, ID3Versions version)
        {
            if (frameData.Length >= 5)
            {
                // Encoding type
                TextEncodingType encType = (TextEncodingType)frameData[0];

                // Language
                char[] languageBytes = new char[COMMFrame.LanguageFieldLength];
                Array.Copy(frameData, 1, languageBytes, 0, languageBytes.Length);
                string languageStr = (new String(languageBytes)).ToUpper();
                language = new EncodedString(LanguageEncodingType, languageStr);

                // Text
                byte[] textBytes = new byte[frameData.Length - 4];
                Array.Copy(frameData, 4, textBytes, 0, textBytes.Length);
                IList <EncodedString> strings = EncodedString.CreateStrings(encType, textBytes);
                if (strings.Count >= 2)
                {
                    description      = strings[0];
                    base.EncodedText = strings[1];
                    SetEncodedStringSettings();
                }
            }
        }
示例#6
0
        public override void Validate(ID3Versions version)
        {
            base.Validate(version);

            Exception innerException = null;

            if ((version & ID3Versions.V2) != ID3Versions.V2)
            {
                innerException = new UnsupportedVersionException(version);
            }
            else if (description.TextEncodingType != base.EncodedText.TextEncodingType)
            {
                innerException = new InvalidTextEncodingTypeException(
                    "URL not set with required TextEncodingType.",
                    description.TextEncodingType);
            }
            else
            {
                try
                {
                    description.Validate(version);
                }
                catch (IOValidationException ex)
                {
                    innerException = ex;
                }
            }

            if (innerException != null)
            {
                throw new FrameValidationException("Validation failed.", this, innerException);
            }
        }
示例#7
0
        /// <summary>
        /// Writes the header for this frame to a stream.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="version">The ID3v2 version to use in writing the frame.</param>
        protected void WriteHeaderToStream(Stream stream, ID3Versions version)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if ((version & ID3Versions.V2) == ID3Versions.V2)
            {
                string frameIDString = FrameRegistry.GetFrameId(this.frameType, version);
                if (frameIDString == null)
                {
                    throw new UnsupportedVersionException(version);
                }

                EncodedString frameID = new EncodedString(TextEncodingType.ISO_8859_1, frameIDString);
                frameID.IsTerminated             = false;
                frameID.HasEncodingTypePrepended = false;
                frameID.WriteToStream(stream);
                WriteFrameSize(stream, version);
                WriteFlags(stream, version);
                stream.Flush();
            }
            else
            {
                throw new UnsupportedVersionException(version);
            }
        }
示例#8
0
        public override void Validate(ID3Versions version)
        {
            Exception innerException = null;

            if ((version & ID3Versions.V2) != ID3Versions.V2)
            {
                innerException = new UnsupportedVersionException(version);
            }
            else if (url.TextEncodingType != URLLinkFrame.UrlEncodingType)
            {
                innerException = new InvalidTextEncodingTypeException(
                    "URL not set with required TextEncodingType.", url.TextEncodingType);
            }
            else
            {
                try
                {
                    url.Validate(version);
                }
                catch (IOValidationException ex)
                {
                    innerException = ex;
                }
            }

            if (innerException != null)
            {
                throw new FrameValidationException("Validation failed.", this, innerException);
            }
        }
示例#9
0
        /// <summary>
        /// Writes the header flags for this frame to a stream.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="version">The ID3v2 version to use in writing the frame.</param>
        protected void WriteFlags(Stream stream, ID3Versions version)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            byte formatByte;
            byte statusByte;

            switch (version)
            {
            case ID3Versions.V2_2:
                break;

            case ID3Versions.V2_3:
                FrameHeaderFlagsV2_3 flags2_3 = ConvertFlags(this.HeaderFlags);
                formatByte = (byte)flags2_3;
                statusByte = (byte)(((int)flags2_3) >> 8);
                stream.WriteByte(statusByte);
                stream.WriteByte(formatByte);
                break;

            case ID3Versions.V2_4:
                formatByte = (byte)this.HeaderFlags;
                statusByte = (byte)(((int)this.HeaderFlags) >> 8);
                stream.WriteByte(statusByte);
                stream.WriteByte(formatByte);
                break;

            default:
                throw new UnsupportedVersionException(version);
            }
        }
示例#10
0
 /// <summary>
 /// Writes the composited frames to a stream.
 /// </summary>
 /// <param name="stream">The stream to write to.</param>
 /// <param name="version">The ID3v2 version to use in writing the frame.</param>
 public override void WriteToStream(Stream stream, ID3Versions version)
 {
     foreach (ID3v2Frame frame in frames)
     {
         frame.WriteToStream(stream, version);
     }
 }
示例#11
0
 /// <summary>
 /// Writes the tag to a file using the format specified by a particular ID3 version.
 /// </summary>
 /// <param name="filename">The name of the file to write the tag to.</param>
 /// <param name="version">The version to use.</param>
 public virtual void WriteTag(string filename, ID3Versions version)
 {
     using (Stream stream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite))
     {
         WriteTag(stream, version);
     }
 }
示例#12
0
        public override void Validate(ID3Versions version)
        {
            base.Validate(version);

            Exception innerException = null;

            if (version != ID3Versions.V2_4 && version != ID3Versions.V2_3)
            {
                innerException = new UnsupportedVersionException(version);
            }
            else
            {
                try
                {
                    description.Validate(version);
                }
                catch (IOValidationException ex)
                {
                    innerException = ex;
                }
            }

            if (innerException != null)
            {
                throw new FrameValidationException("Validation failed.", this, innerException);
            }
        }
示例#13
0
        /// <summary>
        /// Parses the frame header flags.
        /// </summary>
        /// <param name="flagBytes">The frame header flags.</param>
        /// <param name="version">The ID3 version of the tag being parsed.</param>
        private void ParseFlags(byte[] flagBytes, ID3Versions version)
        {
            int frameStatus;
            int frameFormat;

            switch (version)
            {
            case ID3Versions.V2_2:
                // do nothing - no flags in v2.2
                break;

            case ID3Versions.V2_3:
                frameStatus = (int)flagBytes[0];
                frameFormat = (int)flagBytes[1];
                frameStatus = frameStatus << 8;
                headerFlags = ConvertFlags((FrameHeaderFlagsV2_3)frameStatus + frameFormat);
                break;

            case ID3Versions.V2_4:
                frameStatus = (int)flagBytes[0];
                frameFormat = (int)flagBytes[1];
                frameStatus = frameStatus << 8;
                headerFlags = (FrameHeaderFlagsV2_4)frameStatus + frameFormat;
                break;

            default:
                throw new UnsupportedVersionException(version);
            }
        }
示例#14
0
        /// <summary>
        /// Reads and returns the tag header flags from a stream.
        /// </summary>
        /// <param name="stream">The stream to read.</param>
        /// <param name="version">The version of the ID3v2 tag being read.</param>
        /// <returns>The tag header flags read from the stream.</returns>
        private static TagHeaderFlagsV2 ReadFlags(Stream stream, ID3Versions version)
        {
            TagHeaderFlagsV2 flags = TagHeaderFlagsV2.None;

            stream.Seek(TAG_FLAGS_POSITION, SeekOrigin.Begin);
            switch (version)
            {
            case ID3Versions.V2_2:
                flags = ConvertFlags((TagHeaderFlagsV2_2)stream.ReadByte());
                break;

            case ID3Versions.V2_3:
                flags = ConvertFlags((TagHeaderFlagsV2_3)stream.ReadByte());
                break;

            case ID3Versions.V2_4:
                flags = ConvertFlags((TagHeaderFlagsV2_4)stream.ReadByte());
                break;

            default:
                throw new UnsupportedVersionException(version);
            }

            return(flags);
        }
示例#15
0
        /// <summary>
        /// Reads an ID3v2 tag from a stream. Returns null if no ID3v2 tag can be found
        /// in the stream.
        /// </summary>
        /// <param name="stream">The stream to read.</param>
        /// <returns>The tag read from the stream, or null if no ID3v2 tag can be found.</returns>
        public static ID3v2Tag ReadTag(Stream stream)
        {
            ID3Versions version = LookForTag(stream);
            ID3v2Tag    tag     = null;

            if ((version & ID3Versions.V2) == ID3Versions.V2)
            {
                tag = new ID3v2Tag();

                tag.headerFlags = ReadFlags(stream, version);

                int tagSize = ReadTagSize(stream);

                // Go to the first byte after the header
                stream.Seek(TAG_HEADER_LENGTH, SeekOrigin.Begin);

                while (stream.Position < tagSize)
                {
                    ID3v2Frame newFrame = ID3v2Frame.ReadFrame(stream, version);
                    if (newFrame != null)
                    {
                        tag.AddFrame(newFrame);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(tag);
        }
示例#16
0
        /// <summary>
        /// Writes the size field for this frame to a stream.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="version">The ID3v2 version to use in writing the frame.</param>
        protected void WriteFrameSize(Stream stream, ID3Versions version)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            switch (version)
            {
            case ID3Versions.V2_2:
                stream.Write(EncodedInteger.ToBytes(this.Size, ID3V2_2FrameSizeFieldLength), 0, ID3V2_2FrameSizeFieldLength);
                break;

            case ID3Versions.V2_3:
                stream.Write(EncodedInteger.ToBytes(this.Size, ID3V2_3FrameSizeFieldLength), 0, ID3V2_3FrameSizeFieldLength);
                break;

            case ID3Versions.V2_4:
                stream.Write(SynchsafeInteger.Synchsafe(this.Size), 0, ID3V2_4FrameSizeFieldLength);
                break;

            default:
                throw new UnsupportedVersionException(version);
            }
        }
示例#17
0
        /// <summary>
        /// Writes the tag to a stream using the format specified by a particular ID3 version.
        /// Only V2_2, V2_3 and V2_4 are supported.
        /// </summary>
        /// <param name="stream">The stream to write the tag to.</param>
        /// <param name="version">The version to use. Only V2_2, V2_3 and V2_4 are supported.</param>
        public override void WriteTag(Stream stream, ID3Versions version)
        {
            if ((version & ID3Versions.V2) != ID3Versions.V2)
            {
                throw new UnsupportedVersionException("Only versions 2.x are supported by this method.", version);
            }

            EnsureSpace(stream, version);
            stream.Position = 0;
            WriteHeader(stream, version);

            foreach (ID3v2Frame frame in frames.Values)
            {
                try
                {
                    frame.WriteToStream(stream, version);
                }
                catch (UnsupportedVersionException)
                {
                    //***
                }
            }

            WritePadding(stream);
        }
示例#18
0
 /// <summary>
 /// Writes the frame to a stream.
 /// </summary>
 /// <param name="stream">The stream to write to.</param>
 /// <param name="version">The ID3v2 version to use in writing the frame.</param>
 public override void WriteToStream(System.IO.Stream stream, ID3Versions version)
 {
     // "If the refinement should begin with a '(' character, it should be
     // replaced with '(('" [ID3 Spec.]
     if (this.ContentType != null && this.ContentType.StartsWith("("))
     {
         this.ContentType = this.ContentType.Insert(0, "(");
     }
     base.WriteToStream(stream, version);
 }
        protected UnsupportedVersionException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            version = (ID3Versions)info.GetInt32("version");
        }
示例#20
0
        /// <summary>
        /// Parses the raw frame data.
        /// </summary>
        /// <param name="frameData">The raw frame data.</param>
        /// <param name="version">The ID3v2 version of the tag being parsed.</param>
        protected override void ParseFrameData(byte[] frameData, ID3Versions version)
        {
            IList <EncodedString> strings = EncodedString.CreateStrings(frameData);

            if (strings.Count >= 1)
            {
                text = strings[0];                   //*** no support yet for multiple strings
                SetEncodedStringSettings();
            }
        }
示例#21
0
        /// <summary>
        /// Gets the total size of the frames in this tag.
        /// </summary>
        public virtual int GetFramesSize(ID3Versions version)
        {
            int size = 0;

            foreach (ID3v2Frame frame in frames.Values)
            {
                size += frame.GetTotalSize(version);
            }
            return(size);
        }
示例#22
0
        /// <summary>
        /// Gets the total size (in bytes, including headers) of all the frames contained in
        /// this composite.
        /// </summary>
        /// <param name="version">The format to be used in determing the frame size.</param>
        /// <returns>The total size (including headers) of all the frames contained in
        /// this composite.</returns>
        public override int GetTotalSize(ID3Versions version)
        {
            int size = 0;

            foreach (ID3v2Frame frame in frames)
            {
                size += frame.GetTotalSize(version);
            }
            return(size);
        }
示例#23
0
 /// <summary>
 /// Parses the raw frame data.
 /// </summary>
 /// <param name="frameData">The raw frame data.</param>
 /// <param name="version">The ID3 version of the tag being parsed.</param>
 protected override void ParseFrameData(byte[] frameData, ID3Versions version)
 {
     base.ParseFrameData(frameData, version);
     // "If the refinement should begin with a '(' character, it should be
     // replaced with '(('" [ID3 Spec.]
     if (this.ContentType != null && this.ContentType.StartsWith("(("))
     {
         this.ContentType = this.ContentType.Remove(0, 1);
     }
 }
示例#24
0
 /// <summary>
 /// Parses the raw frame data.
 /// </summary>
 /// <param name="frameData">The raw frame data.</param>
 /// <param name="version">The ID3v2 version of the tag being parsed.</param>
 protected override void ParseFrameData(byte[] frameData, ID3Versions version)
 {
     if (frameData.Length > 0)
     {
         IList <EncodedString> strings =
             EncodedString.CreateStrings(URLLinkFrame.UrlEncodingType, frameData);
         url = strings[0];                   // "If the text string is followed by a string
         // termination, all the following information should be ignored and not be displayed."
         SetEncodedStringSettings();
     }
 }
示例#25
0
        /// <summary>
        /// Parses the raw frame data.
        /// </summary>
        /// <param name="frameData">The raw frame data.</param>
        /// <param name="version">The ID3v2 version of the tag being parsed.</param>
        protected override void ParseFrameData(byte[] frameData, ID3Versions version)
        {
            IList <EncodedString> strings = EncodedString.CreateStrings(frameData);

            if (strings.Count >= 2)
            {
                description      = strings[0];
                base.EncodedText = strings[1];
                SetEncodedStringSettings();
            }
        }
示例#26
0
        /// <summary>
        /// Writes the frame to a stream.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="version">The ID3v2 version to use in writing the frame.</param>
        public override void WriteToStream(Stream stream, ID3Versions version)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            WriteHeaderToStream(stream, version);
            stream.Write(frameData, 0, frameData.Length);
            stream.Flush();
        }
示例#27
0
 /// <summary>
 /// Writes the flags to the specified stream.
 /// *** Flags are currently unsupported. ***
 /// </summary>
 /// <param name="stream">The stream to be written to.</param>
 /// <param name="version">The ID3v2 version of the tag to be written.</param>
 private void WriteFlags(Stream stream, ID3Versions version)
 {
     if ((version & ID3Versions.V2) == ID3Versions.V2)
     {
         //*** Doesn't support flags
         stream.WriteByte(0x00);
     }
     else
     {
         throw new UnsupportedVersionException(version);
     }
 }
示例#28
0
        /// <summary>
        /// Parses the raw frame data.
        /// </summary>
        /// <param name="frameData">The raw frame data.</param>
        /// <param name="version">The ID3v2 version of the tag being parsed.</param>
        protected override void ParseFrameData(byte[] frameData, ID3Versions version)
        {
            IList <EncodedString> strings =
                EncodedString.CreateStrings(TextEncodingType.ISO_8859_1, frameData, 1,
                                            delegate(byte[] leftoverBytes) { Identifier = leftoverBytes; });

            if (strings.Count == 1)
            {
                ownerIdentifier = strings[0];
                SetEncodedStringSettings();
            }
        }
示例#29
0
        /// <summary>
        /// Writes the frame to a stream.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="version">The ID3v2 version to use in writing the frame.</param>
        public override void WriteToStream(Stream stream, ID3Versions version)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            Validate(version);

            WriteHeaderToStream(stream, version);
            url.WriteToStream(stream);
            stream.Flush();
        }
示例#30
0
        /// <summary>
        /// Reads and returns a frame from a stream.
        /// </summary>
        /// <param name="stream">The stream to read from.</param>
        /// <param name="version">The ID3v2 version of the tag being parsed.</param>
        /// <returns>The frame read from the stream.</returns>
        public static ID3v2Frame ReadFrame(Stream stream, ID3Versions version)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            ID3v2Frame      frame      = null;
            FrameParameters parameters = new FrameParameters(version);

            byte[] header    = new byte[parameters.HeaderLength];
            char[] idChars   = new char[parameters.IDLength];
            byte[] sizeBytes = new byte[parameters.SizeLength];
            byte[] flags     = new byte[parameters.FlagsLength];
            byte[] frameData;
            string frameID;
            int    size;

            stream.Read(header, 0, header.Length);

            Array.Copy(header, 0, idChars, 0, idChars.Length);
            Array.Copy(header, parameters.IDLength, sizeBytes, 0, sizeBytes.Length);
            Array.Copy(header, parameters.IDLength + parameters.SizeLength, flags, 0, flags.Length);

            if (idChars[0] != 0x0)
            {
                frameID = new String(idChars);
                if (parameters.SizeIsSynchSafe)
                {
                    size = SynchsafeInteger.UnSynchsafe(sizeBytes);
                }
                else
                {
                    size = EncodedInteger.ToInt(sizeBytes);
                }

                frameData = new byte[size];
                stream.Read(frameData, 0, frameData.Length);

                FrameType frameType = FrameRegistry.GetFrameType(frameID, version);
                frame = FrameRegistry.GetNewFrame(frameType);

                frame.Initialize(flags, frameData, version);
            }
            else
            {
                frame = null;
            }

            return(frame);
        }