Esempio n. 1
0
 /// <summary>
 ///    Constructs and initializes a new instance of <see
 ///    cref="PrivateFrame" /> by reading its raw data in a
 ///    specified ID3v2 version.
 /// </summary>
 /// <param name="data">
 ///    A <see cref="ByteVector" /> object containing the raw
 ///    representation of the new frame.
 /// </param>
 /// <param name="offset">
 ///    A <see cref="int" /> indicating at what offset in
 ///    <paramref name="data" /> the frame actually begins.
 /// </param>
 /// <param name="header">
 ///    A <see cref="FrameHeader" /> containing the header of the
 ///    frame found at <paramref name="offset" /> in the data.
 /// </param>
 /// <param name="version">
 ///    A <see cref="byte" /> indicating the ID3v2 version the
 ///    raw frame is encoded in.
 /// </param>
 protected internal PrivateFrame(ByteVector data, int offset,
                                 FrameHeader header,
                                 byte version) : base(header)
 {
     SetData(data, offset, version, false);
 }
Esempio n. 2
0
        /// <summary>
        ///    Extracts the field data from the raw data portion of an
        ///    ID3v2 frame.
        /// </summary>
        /// <param name="frameData">
        ///    A <see cref="ByteVector" /> object containing fraw frame
        ///    data.
        /// </param>
        /// <param name="offset">
        ///    A <see cref="int" /> value containing the index at which
        ///    the data is contained.
        /// </param>
        /// <param name="version">
        ///    A <see cref="byte" /> value containing the ID3v2 version
        ///    of the data.
        /// </param>
        /// <returns>
        ///    A <see cref="ByteVector" /> object containing the
        ///    extracted field data.
        /// </returns>
        /// <remarks>
        ///    This method is necessary for extracting extra data
        ///    prepended to the frame such as the grouping ID.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="frameData" /> is <see langword="null" />.
        /// </exception>
        protected ByteVector FieldData(ByteVector frameData,
                                       int offset, byte version)
        {
            if (frameData == null)
            {
                throw new ArgumentNullException("frameData");
            }

            int data_offset = offset + (int)FrameHeader.Size(version);
            int data_length = (int)Size;

            if ((Flags & (FrameFlags.Compression |
                          FrameFlags.DataLengthIndicator)) != 0)
            {
                data_offset += 4;
                data_length -= 4;
            }

            if ((Flags & FrameFlags.GroupingIdentity) != 0)
            {
                if (frameData.Count >= data_offset)
                {
                    throw new TagLib.CorruptFileException(
                              "Frame data incomplete.");
                }
                group_id = frameData [data_offset++];
                data_length--;
            }

            if ((Flags & FrameFlags.Encryption) != 0)
            {
                if (frameData.Count >= data_offset)
                {
                    throw new TagLib.CorruptFileException(
                              "Frame data incomplete.");
                }
                encryption_id = frameData [data_offset++];
                data_length--;
            }

            data_length = Math.Min(data_length, frameData.Count - data_offset);
            if (data_length < 0)
            {
                throw new CorruptFileException(
                          "Frame size less than zero.");
            }

            ByteVector data = frameData.Mid(data_offset,
                                            data_length);

            if ((Flags & FrameFlags.Unsynchronisation) != 0)
            {
                int before_length = data.Count;
                SynchData.ResynchByteVector(data);
                data_length -= (data.Count - before_length);
            }

            // FIXME: Implement encryption.
            if ((Flags & FrameFlags.Encryption) != 0)
            {
                throw new NotImplementedException();
            }

            // FIXME: Implement compression.
            if ((Flags & FrameFlags.Compression) != 0)
            {
                throw new NotImplementedException();
            }

            /*
             * if(d->header->compression()) {
             *      ByteVector data(frameDataLength);
             *      uLongf uLongTmp = frameDataLength;
             *      ::uncompress((Bytef *) data.data(),
             *      (uLongf *) &uLongTmp,
             *      (Bytef *) frameData.data() + frameDataOffset,
             *      size());
             *      return data;
             * }
             */

            return(data);
        }
Esempio n. 3
0
        /// <summary>
        ///    Creates a <see cref="Frame" /> object by reading it from
        ///    raw ID3v2 frame data.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing a raw ID3v2
        ///    frame.
        /// </param>
        /// <param name="offset">
        ///    A <see cref="int" /> value reference specifying at what
        ///    index in <paramref name="data" /> at which the frame
        ///    begins. After reading, it contains the offset of the next
        ///    frame to be read.
        /// </param>
        /// <param name="version">
        ///    A <see cref="byte" /> value specifying the ID3v2 version
        ///    the frame in <paramref name="data"/> is encoded in.
        /// </param>
        /// <param name="alreadyUnsynched">
        ///    A <see cref="bool" /> value specifying whether the entire
        ///    tag has already been unsynchronized.
        /// </param>
        /// <returns>
        ///    A <see cref="Frame" /> object read from the data, or <see
        ///    langword="null" /> if none is found.
        /// </returns>
        /// <exception cref="System.NotImplementedException">
        ///    The frame contained in the raw data could not be
        ///    converted to ID3v2 or uses encryption or compression.
        /// </exception>
        public static Frame CreateFrame(ByteVector data,
                                        ref int offset, byte version, bool alreadyUnsynched)
        {
            int position = offset;

            FrameHeader header = new FrameHeader(data.Mid(position,
                                                          (int)FrameHeader.Size(version)), version);

            offset += (int)(header.FrameSize + FrameHeader.Size(
                                version));

            if (header.FrameId == null)
            {
                throw new System.NotImplementedException();
            }

            foreach (byte b in header.FrameId)
            {
                char c = (char)b;
                if ((c < 'A' || c > 'Z') &&
                    (c < '1' || c > '9'))
                {
                    return(null);
                }
            }

            if (alreadyUnsynched)
            {
                // Mark the frame as not Unsynchronozed because the entire
                // tag has already been Unsynchronized
                header.Flags &= ~FrameFlags.Unsynchronisation;
            }

            // Windows Media Player may create zero byte frames.
            // Just send them off as unknown and delete them.
            if (header.FrameSize == 0)
            {
                header.Flags |= FrameFlags.TagAlterPreservation;
                return(new UnknownFrame(data, position, header,
                                        version));
            }

            // +TODO: Support Compression.
            if ((header.Flags & FrameFlags.Compression) != 0)
            {
                throw new System.NotImplementedException();
            }

            // +TODO: Support Encryption.
            if ((header.Flags & FrameFlags.Encryption) != 0)
            {
                throw new System.NotImplementedException();
            }

            foreach (FrameCreator creator in frame_creators)
            {
                Frame frame = creator(data, position, header,
                                      version);

                if (frame != null)
                {
                    return(frame);
                }
            }

            // This is where things get necissarily nasty.  Here we
            // determine which Frame subclass (or if none is found
            // simply an Frame) based on the frame ID. Since there
            // are a lot of possibilities, that means a lot of if
            // blocks.

            // Text Identification (frames 4.2)
            if (header.FrameId == FrameType.TXXX)
            {
                return(new UserTextInformationFrame(data,
                                                    position, header, version));
            }

            if (header.FrameId [0] == (byte)'T')
            {
                return(new TextInformationFrame(data, position,
                                                header, version));
            }

            // Unique File Identifier (frames 4.1)
            if (header.FrameId == FrameType.UFID)
            {
                return(new UniqueFileIdentifierFrame(data,
                                                     position, header, version));
            }

            // Music CD Identifier (frames 4.5)
            if (header.FrameId == FrameType.MCDI)
            {
                return(new MusicCdIdentifierFrame(data,
                                                  position, header, version));
            }

            // Unsynchronized Lyrics (frames 4.8)
            if (header.FrameId == FrameType.USLT)
            {
                return(new UnsynchronisedLyricsFrame(data,
                                                     position, header, version));
            }

            // Synchronized Lyrics (frames 4.9)
            if (header.FrameId == FrameType.SYLT)
            {
                return(new SynchronisedLyricsFrame(data,
                                                   position, header, version));
            }

            // Comments (frames 4.10)
            if (header.FrameId == FrameType.COMM)
            {
                return(new CommentsFrame(data, position,
                                         header, version));
            }

            // Relative Volume Adjustment (frames 4.11)
            if (header.FrameId == FrameType.RVA2)
            {
                return(new RelativeVolumeFrame(data, position,
                                               header, version));
            }

            // Attached Picture (frames 4.14)
            if (header.FrameId == FrameType.APIC)
            {
                return(new AttachedPictureFrame(data, position,
                                                header, version));
            }

            // General Encapsulated Object (frames 4.15)
            if (header.FrameId == FrameType.GEOB)
            {
                return(new GeneralEncapsulatedObjectFrame(data,
                                                          position, header, version));
            }

            // Play Count (frames 4.16)
            if (header.FrameId == FrameType.PCNT)
            {
                return(new PlayCountFrame(data, position,
                                          header, version));
            }

            // Play Count (frames 4.17)
            if (header.FrameId == FrameType.POPM)
            {
                return(new PopularimeterFrame(data, position,
                                              header, version));
            }

            // Terms of Use (frames 4.22)
            if (header.FrameId == FrameType.USER)
            {
                return(new TermsOfUseFrame(data, position,
                                           header, version));
            }

            // Private (frames 4.27)
            if (header.FrameId == FrameType.PRIV)
            {
                return(new PrivateFrame(data, position, header,
                                        version));
            }

            return(new UnknownFrame(data, position, header,
                                    version));
        }
Esempio n. 4
0
 /// <summary>
 ///    Constructs and initializes a new instance of <see
 ///    cref="Frame" /> with a specified header.
 /// </summary>
 /// <param name="header">
 ///    A <see cref="FrameHeader" /> value containing the header
 ///    to use for the new instance.
 /// </param>
 protected Frame(FrameHeader header)
 {
     this.header = header;
 }