Esempio n. 1
0
        /// <summary>
        ///     Populates the current instance by reading in a raw APEv2
        ///     item.
        /// </summary>
        /// <param name="data">
        ///     A <see cref="ByteVector" /> object containing the item to
        ///     read.
        /// </param>
        /// <param name="offset">
        ///     A <see cref="int" /> value specifying the offset in
        ///     <paramref name="data" /> at which the item data begins.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     <paramref name="offset" /> is less than zero.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///     A complete item could not be read.
        /// </exception>
        protected void Parse(ByteVector data, int offset)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            // 11 bytes is the minimum size for an APE item
            if (data.Count < offset + 11)
            {
                throw new CorruptFileException(
                          "Not enough data for APE Item");
            }

            var value_length = data.Mid(offset, 4)
                               .ToUInt(false);

            var flags = data.Mid(offset + 4, 4)
                        .ToUInt(false);

            ReadOnly = (flags & 1) == 1;
            Type     = (ItemType)((flags >> 1) & 3);

            var pos = data.Find(ByteVector.TextDelimiter(
                                    StringType.UTF8), offset + 8);

            Key = data.ToString(StringType.UTF8,
                                offset + 8, pos - offset - 8);

            if (value_length > data.Count - pos - 1)
            {
                throw new CorruptFileException(
                          "Invalid data length.");
            }

            Size = pos + 1 + (int)value_length - offset;

            if (Type == ItemType.Binary)
            {
                this.data = new ReadOnlyByteVector(
                    data.Mid(pos + 1, (int)value_length));
            }
            else
            {
                text = data.Mid(pos + 1,
                                (int)value_length)
                       .ToStrings(
                    StringType.UTF8, 0);
            }
        }