Beispiel #1
0
        /// <summary>
        ///    Loads the children of the current instance from a
        ///    specified file using the internal data position and size.
        /// </summary>
        /// <param name="file">
        ///    The <see cref="TagLib.File" /> from which the current
        ///    instance was read and from which to read the children.
        /// </param>
        /// <returns>
        ///    A <see cref="T:System.Collections.Generic.IEnumerable`1" /> object enumerating the
        ///    boxes read from the file.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        protected IEnumerable <Box> LoadChildren(TagLib.File file)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            List <Box> children = new List <Box> ();

            long position = DataPosition;
            long end      = position + DataSize;

            header.Box = this;
            while (position < end)
            {
                Box child = BoxFactory.CreateBox(file,
                                                 position, header, handler,
                                                 children.Count);
                children.Add(child);
                position += child.Size;
            }
            header.Box = null;

            return(children);
        }
        /// <summary>
        ///    Parses boxes for a specified range, looking for tags.
        /// </summary>
        /// <param name="start">
        ///    A <see cref="long" /> value specifying the seek position
        ///    at which to start reading.
        /// </param>
        /// <param name="end">
        ///    A <see cref="long" /> value specifying the seek position
        ///    at which to stop reading.
        /// </param>
        private void ParseTag(long start, long end,
                              List <BoxHeader> parents)
        {
            BoxHeader header;

            for (long position = start; position < end;
                 position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);

                if (header.BoxType == BoxType.Moov)
                {
                    ParseTag(header.HeaderSize + position,
                             header.TotalBoxSize + position,
                             AddParent(parents, header));
                }
                else if (header.BoxType == BoxType.Mdia ||
                         header.BoxType == BoxType.Minf ||
                         header.BoxType == BoxType.Stbl ||
                         header.BoxType == BoxType.Trak)
                {
                    ParseTag(header.HeaderSize + position,
                             header.TotalBoxSize + position,
                             AddParent(parents, header));
                }
                else if (header.BoxType == BoxType.Udta)
                {
                    IsoUserDataBox udtaBox = BoxFactory.CreateBox(file,
                                                                  header) as IsoUserDataBox;

                    // Since we can have multiple udta boxes, save the parent for each one
                    List <BoxHeader> new_parents = AddParent(
                        parents, header);
                    udtaBox.ParentTree = new_parents.ToArray();

                    udta_boxes.Add(udtaBox);
                }
                else if (header.BoxType == BoxType.Mdat)
                {
                    mdat_start = position;
                    mdat_end   = position + header.TotalBoxSize;
                }

                if (header.TotalBoxSize == 0)
                {
                    break;
                }
            }
        }
        /// <summary>
        ///    Parses boxes for a specified range, looking for chunk
        ///    offset boxes.
        /// </summary>
        /// <param name="start">
        ///    A <see cref="long" /> value specifying the seek position
        ///    at which to start reading.
        /// </param>
        /// <param name="end">
        ///    A <see cref="long" /> value specifying the seek position
        ///    at which to stop reading.
        /// </param>
        private void ParseChunkOffsets(long start, long end)
        {
            BoxHeader header;

            for (long position = start; position < end;
                 position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);

                if (header.BoxType == BoxType.Moov)
                {
                    ParseChunkOffsets(
                        header.HeaderSize + position,
                        header.TotalBoxSize + position);
                }
                else if (header.BoxType == BoxType.Moov ||
                         header.BoxType == BoxType.Mdia ||
                         header.BoxType == BoxType.Minf ||
                         header.BoxType == BoxType.Stbl ||
                         header.BoxType == BoxType.Trak)
                {
                    ParseChunkOffsets(
                        header.HeaderSize + position,
                        header.TotalBoxSize + position);
                }
                else if (header.BoxType == BoxType.Stco ||
                         header.BoxType == BoxType.Co64)
                {
                    stco_boxes.Add(BoxFactory.CreateBox(
                                       file, header));
                }
                else if (header.BoxType == BoxType.Mdat)
                {
                    mdat_start = position;
                    mdat_end   = position + header.TotalBoxSize;
                }

                if (header.TotalBoxSize == 0)
                {
                    break;
                }
            }
        }
        /// <summary>
        ///    Parses boxes for a specified range, looking for tags and
        ///    properties.
        /// </summary>
        /// <param name="start">
        ///    A <see cref="long" /> value specifying the seek position
        ///    at which to start reading.
        /// </param>
        /// <param name="end">
        ///    A <see cref="long" /> value specifying the seek position
        ///    at which to stop reading.
        /// </param>
        /// <param name="handler">
        ///    A <see cref="IsoHandlerBox" /> object that applied to the
        ///    range being searched.
        /// </param>
        private void ParseTagAndProperties(long start, long end,
                                           IsoHandlerBox handler, List <BoxHeader> parents)
        {
            BoxHeader header;

            for (long position = start; position < end;
                 position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);
                ByteVector type = header.BoxType;

                if (type == BoxType.Moov)
                {
                    ParseTagAndProperties(header.HeaderSize + position,
                                          header.TotalBoxSize + position,
                                          handler,
                                          AddParent(parents, header));
                }
                else if (type == BoxType.Mdia ||
                         type == BoxType.Minf ||
                         type == BoxType.Stbl ||
                         type == BoxType.Trak)
                {
                    ParseTagAndProperties(
                        header.HeaderSize + position,
                        header.TotalBoxSize + position,
                        handler,
                        AddParent(parents, header));
                }
                else if (type == BoxType.Stsd)
                {
                    stsd_boxes.Add(BoxFactory.CreateBox(
                                       file, header, handler));
                }
                else if (type == BoxType.Hdlr)
                {
                    handler = BoxFactory.CreateBox(file,
                                                   header, handler) as
                              IsoHandlerBox;
                }
                else if (mvhd_box == null &&
                         type == BoxType.Mvhd)
                {
                    mvhd_box = BoxFactory.CreateBox(file,
                                                    header, handler) as
                               IsoMovieHeaderBox;
                }
                else if (type == BoxType.Udta)
                {
                    IsoUserDataBox udtaBox = BoxFactory.CreateBox(file,
                                                                  header, handler) as
                                             IsoUserDataBox;

                    // Since we can have multiple udta boxes, save the parent for each one
                    List <BoxHeader> new_parents = AddParent(
                        parents, header);
                    udtaBox.ParentTree = new_parents.ToArray();

                    udta_boxes.Add(udtaBox);
                }
                else if (type == BoxType.Mdat)
                {
                    mdat_start = position;
                    mdat_end   = position + header.TotalBoxSize;
                }

                if (header.TotalBoxSize == 0)
                {
                    break;
                }
            }
        }