예제 #1
0
        /// <summary>Initializes a new instance of the <see cref="ID3v2Frame" /> class.</summary>
        /// <param name="header">The header.</param>
        /// <param name="reader">The reader.</param>
        /// <exception cref="ArgumentNullException">Header.</exception>
        /// <exception cref="NotSupportedException"></exception>
        public ID3v2Frame(ID3v2Header header, DataFrameReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("Reader");
            }

            m_Header = new ID3v2FrameHeader(header, reader);

            // prepare content (has to be decoded, decrypted, decompressed, ...
            m_Content = reader.Read(m_Header.HeaderSize, m_Header.ContentSize);

            switch (header.Version)
            {
            case 2: /*nothing to do, raw plain content data*/ break;

            case 3: ParseVersion3(reader); break;

            case 4: ParseVersion4(reader); break;

            default: throw new NotSupportedException(string.Format("ID3v2.{0} is not supported!", header.Version));
            }

            // copy raw data and remove from reader
            m_Data = reader.GetBuffer(m_Header.HeaderSize + m_Header.ContentSize);
        }
예제 #2
0
        bool ParseVersion3(DataFrameReader reader)
        {
            if (!reader.EnsureBuffer(4))
            {
                return false;
            }

            // calc size
            byte[] sizeBytes = reader.Read(0, 4);
            int size = 0;
            for (int i = 0; i < 4; i++)
            {
                size = (size << 8) | sizeBytes[i];
            }

            size += 4;

            // get data
            if (!reader.EnsureBuffer(size))
            {
                return false;
            }

            m_Data = reader.GetBuffer(size);

            // get flags
            m_Flags = ID3v2ExtendedHeaderFlags.FromID3v23(m_Data);
            return true;
        }
예제 #3
0
        /// <summary>
        /// Reads the header (check <see cref="State"/> before usage).
        /// </summary>
        /// <returns></returns>
        public ID3v2Header ReadHeader(out byte[] tagData)
        {
            if (State != ID3v2ReaderState.ReadHeader)
            {
                throw new InvalidOperationException(string.Format("Cannot read header at state {0}", State));
            }

            var header = new ID3v2Header();

            if (!header.Parse(m_Reader))
            {
                tagData = null;
                return(null);
            }
            m_BodyBytes = header.BodySize;
            if ((header.Flags & ID3v2HeaderFlags.Footer) != 0)
            {
                m_BodyBytes -= 10;
            }
            State++;
            if (header.Version < 2)
            {
                tagData = null;
                return(null);
            }

            tagData = m_Reader.GetBuffer(header.HeaderSize + header.BodySize);
            var bodyData = tagData.GetRange(header.HeaderSize);

            // need to unsync whole tag?
            if ((header.Flags & ID3v2HeaderFlags.Unsynchronisation) != 0)
            {
                bodyData    = ID3v2DeUnsync.Buffer(bodyData);
                m_BodyBytes = bodyData.Length;
            }

            // update reader (use cached data)
            m_Header = header;
            m_Reader = new DataFrameReader(bodyData);
            return(header);
        }
예제 #4
0
        bool ParseVersion4(DataFrameReader reader)
        {
            if (!reader.EnsureBuffer(4))
            {
                return false;
            }

            // calc size
            int size = ID3v2DeUnsync.Int32(reader.Read(0, 4), 0);

            // get data
            if (!reader.EnsureBuffer(size))
            {
                return false;
            }

            m_Data = reader.GetBuffer(size);

            // get flags
            m_Flags = ID3v2ExtendedHeaderFlags.FromID3v24(m_Data);
            return true;
        }
예제 #5
0
        /// <summary>
        /// uses the <see cref="Search"/> class to find the next id3 / mp3 frame start at the buffer.
        /// </summary>
        /// <returns>Returns the search result.</returns>
        Search FindFrame()
        {
            // initialize the search and run it at the buffer
            var search = new Search();

            while (true)
            {
                // fill the buffer
                if (!m_Reader.EnsureBuffer(1024) && (m_Reader.Available < 4))
                {
                    if (m_Reader.Available == 0)
                    {
                        return(null);
                    }

                    // end of stream
                    var buffer = m_Reader.GetBuffer(m_Reader.Available);
                    InvalidData(buffer);
                    return(null);
                }

                // run the search
                {
                    if (m_Reader.Contains(search))
                    {
                        return(search);
                    }

                    // nothing found, enqueue invalid data...
                    var buffer = m_Reader.GetBuffer(m_Reader.Available - 2);
                    InvalidData(buffer);

                    // .. and start new search
                    search = new Search();
                }
            }
        }