public void Remove()
        {
            ByteVectorCollection list = BuildList();

            list.Remove("DEF");
            Assert.AreEqual("ABCGHI", list.ToByteVector("").ToString());
        }
示例#2
0
        /// <summary>
        ///    Replaces the comment packet in a collection of packets
        ///    with the rendered version of a Xiph comment or inserts a
        ///    comment packet if the stream lacks one.
        /// </summary>
        /// <param name="packets">
        ///    A <see cref="ByteVectorCollection" /> object containing
        ///    a collection of packets.
        /// </param>
        /// <param name="comment">
        ///    A <see cref="XiphComment" /> object to store the rendered
        ///    version of in <paramref name="packets" />.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="packets" /> or <paramref name="comment"
        ///    /> is <see langword="null" />.
        /// </exception>
        public override void SetCommentPacket(ByteVectorCollection packets,
                                              XiphComment comment)
        {
            if (packets == null)
            {
                throw new ArgumentNullException("packets");
            }

            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            ByteVector data = new ByteVector((byte)0x03);

            data.Add(id);
            data.Add(comment.Render(true));
            if (packets.Count > 1 && PacketType(packets [1]) == 0x03)
            {
                if (data.Count < packets [1].Count)
                {
                    data.Add(new ByteVector(packets [1].Count - data.Count, 0));
                }
                packets [1] = data;
            }
            else
            {
                packets.Insert(1, data);
            }
        }
示例#3
0
        /// <summary>
        ///    Replaces the comment packet in a collection of packets
        ///    with the rendered version of a Xiph comment or inserts a
        ///    comment packet if the stream lacks one.
        /// </summary>
        /// <param name="packets">
        ///    A <see cref="ByteVectorCollection" /> object containing
        ///    a collection of packets.
        /// </param>
        /// <param name="comment">
        ///    A <see cref="XiphComment" /> object to store the rendered
        ///    version of in <paramref name="packets" />.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="packets" /> or <paramref name="comment"
        ///    /> is <see langword="null" />.
        /// </exception>
        public override void SetCommentPacket(ByteVectorCollection packets,
                                              XiphComment comment)
        {
            if (packets == null)
            {
                throw new ArgumentNullException("packets");
            }

            if (comment == null)
            {
                throw new ArgumentNullException("comment");
            }

            ByteVector data = new ByteVector();

            data.Add(magic_signature_comment);
            data.Add(comment.Render(true));
            if (packets.Count > 1 && MagicSignature(packets [1])
                == magic_signature_comment)
            {
                packets [1] = data;
            }
            else
            {
                packets.Insert(1, data);
            }
        }
示例#4
0
 public Page(ByteVectorCollection packets, PageHeader header) : this(header)
 {
     if (packets == null)
     {
         throw new ArgumentNullException("packets");
     }
     this.packets = new ByteVectorCollection(packets);
     List<int> list = new List<int>();
     IEnumerator<ByteVector> enumerator = packets.GetEnumerator();
     try
     {
         while (enumerator.MoveNext())
         {
             ByteVector current = enumerator.Current;
             list.Add(current.Count);
         }
     }
     finally
     {
         if (enumerator == null)
         {
         }
         enumerator.Dispose();
     }
     header.PacketSizes = list.ToArray();
 }
示例#5
0
        /// <summary>
        ///    Gets the number of lacing value bytes that would be
        ///    required for a given packet.
        /// </summary>
        /// <param name="packets">
        ///    A <see cref="ByteVectorCollection" /> object containing
        ///    the packet.
        /// </param>
        /// <param name="index">
        ///    A <see cref="int" /> value containing the index of the
        ///    packet to compute.
        /// </param>
        /// <returns>
        ///    A <see cref="int" /> value containing the number of bytes
        ///    needed to store the length.
        /// </returns>
        static int GetLacingValueLength(ByteVectorCollection packets, int index)
        {
            int size = packets[index].Count;

            return(size / 0xff + ((index + 1 < packets.Count ||
                                   size % 0xff > 0) ? 1 : 0));
        }
        public void Insert()
        {
            ByteVectorCollection list = BuildList();

            list.Insert(1, "QUACK");
            Assert.AreEqual("ABC,QUACK,DEF,GHI", list.ToByteVector(",").ToString());
        }
 private static ByteVectorCollection BuildList()
 {
     ByteVectorCollection list = new ByteVectorCollection();
     list.Add("ABC");
     list.Add("DEF");
     list.Add("GHI");
     return list;
 }
        public void Contains()
        {
            ByteVectorCollection list = BuildList();

            Assert.IsTrue(list.Contains("DEF"));
            Assert.IsFalse(list.Contains("CDEFG"));
            Assert.AreEqual(2, list.ToByteVector("").Find("CDEFG"));
        }
        private static ByteVectorCollection BuildList()
        {
            ByteVectorCollection list = new ByteVectorCollection();

            list.Add("ABC");
            list.Add("DEF");
            list.Add("GHI");
            return(list);
        }
        static ByteVectorCollection BuildList()
        {
            var list = new ByteVectorCollection {
                "ABC",
                "DEF",
                "GHI"
            };

            return(list);
        }
示例#11
0
        protected override void ParseFields(ByteVector data, byte version)
        {
            ByteVectorCollection fields = ByteVectorCollection.Split(data, (byte)0);

            if (fields.Count != 2)
            {
                return;
            }
            owner      = fields[0].ToString(StringType.Latin1);
            identifier = fields[1];
        }
示例#12
0
        public void SetText(ByteVector type, string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                ilst_box.RemoveChild(FixId(type));
                return;
            }
            ByteVectorCollection l = new ByteVectorCollection();

            l.Add(ByteVector.FromString(text, StringType.UTF8));
            SetData(type, l, (uint)AppleDataBox.FlagType.ContainsText);
        }
示例#13
0
 public void SetValue(ByteVector id, ByteVectorCollection value)
 {
     if (id == null)
     {
         throw new ArgumentNullException("id");
     }
     if (id.Count != 4)
     {
         throw new ArgumentException("ID must be 4 bytes long.", "id");
     }
     fields.SetValue(id, value);
 }
示例#14
0
 public void SetData(ByteVector type, ByteVectorCollection data, uint flags)
 {
     if (data == null || data.Count == 0)
     {
         ClearData(type);
         return;
     }
     AppleDataBox[] boxes = new AppleDataBox[data.Count];
     for (int i = 0; i < data.Count; i++)
     {
         boxes[i] = new AppleDataBox(data[i], flags);
     }
     SetData(type, boxes);
 }
示例#15
0
        /// <summary>
        ///    Populates the values in the current instance by parsing
        ///    its field data in a specified version.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the
        ///    extracted field data.
        /// </param>
        /// <param name="version">
        ///    A <see cref="byte" /> indicating the ID3v2 version the
        ///    field data is encoded in.
        /// </param>
        protected override void ParseFields(ByteVector data, byte version)
        {
            if (data.Count < 1)
            {
                throw new CorruptFileException("A private frame must contain at least 1 byte.");
            }

            var l = ByteVectorCollection.Split(data, ByteVector.TextDelimiter(StringType.Latin1), 1, 2);

            if (l.Count == 2)
            {
                Owner       = l[0].ToString(StringType.Latin1);
                PrivateData = l[1];
            }
        }
示例#16
0
 public Page(ByteVectorCollection packets, PageHeader header) :
     this(header)
 {
     if (packets == null)
     {
         throw new ArgumentNullException("packets");
     }
     this.packets = new ByteVectorCollection(packets);
     List <int> packet_sizes = new List <int>();
     foreach (ByteVector v in packets)
     {
         packet_sizes.Add(v.Count);
     }
     header.PacketSizes = packet_sizes.ToArray();
 }
示例#17
0
      public Page (ByteVectorCollection packets, PageHeader header) : this (header)
      {
         if (packets == null)
            throw new ArgumentNullException ("packets");
         
         this.packets = packets;

         List<int> packet_sizes = new List<int> ();

         // Build a page from the list of packets.
         foreach (ByteVector v in packets)
            packet_sizes.Add (v.Count);
         
         header.PacketSizes = packet_sizes.ToArray ();
      }
示例#18
0
 public override void SetCommentPacket (ByteVectorCollection packets, XiphComment comment)
 {
    if (packets == null)
       throw new ArgumentNullException ("packets");
    
    if (comment == null)
       throw new ArgumentNullException ("comment");
    
    ByteVector data = new ByteVector ((byte) 0x03);
    data.Add (id);
    data.Add (comment.Render (true));
    if (packets.Count > 1 && PacketType (packets [1]) == 0x03)
       packets [1] = data;
    else
       packets.Insert (1, data);
 }
示例#19
0
      //////////////////////////////////////////////////////////////////////////
      // public methods
      //////////////////////////////////////////////////////////////////////////
		public OggPage(OggFile file, long pageOffset)
		{
			this.file = file;
			this.fileOffset = pageOffset;
			//packetOffset = 0;
			//dataSize = 0;
			header = new OggPageHeader(file, pageOffset);
			firstPacketIndex = -1;
			packets = new ByteVectorCollection();
         
			if (file != null)
			{
				packetOffset = fileOffset + header.Size;
				dataSize = header.DataSize;
			}
		}
示例#20
0
        /// <summary>
        ///     Constructs and initializes a new instance of
        ///     <see
        ///         cref="Page" />
        ///     with a specified header and packets.
        /// </summary>
        /// <param name="packets">
        ///     A <see cref="ByteVectorCollection" /> object containing
        ///     packets to use for the new instance.
        /// </param>
        /// <param name="header">
        ///     A <see cref="PageHeader" /> object to use as the header of
        ///     the new instance.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="packets" /> is <see langword="null" />.
        /// </exception>
        public Page(ByteVectorCollection packets, PageHeader header)
            : this(header)
        {
            if (packets == null)
            {
                throw new ArgumentNullException(nameof(packets));
            }

            this.packets = new ByteVectorCollection(packets);

            var packet_sizes = new List <int>();

            // Build a page from the list of packets.
            foreach (var v in packets)
            {
                packet_sizes.Add(v.Count);
            }

            header.PacketSizes = packet_sizes.ToArray();
        }
示例#21
0
        /// <summary>
        ///    Sets the text for a specified box type.
        /// </summary>
        /// <param name="type">
        ///    A <see cref="ByteVector" /> object containing the type to
        ///    add to the new instance.
        /// </param>
        /// <param name="text">
        ///    A <see cref="string[]" /> containing text to store.
        /// </param>
        public void SetText(ByteVector type, string [] text)
        {
            // Remove empty data and return.
            if (text == null)
            {
                ilst_box.RemoveChild(FixId(type));
                return;
            }

            // Create a list...
            ByteVectorCollection l = new ByteVectorCollection();

            // and populate it with the ByteVectorized strings.
            foreach (string value in text)
            {
                l.Add(ByteVector.FromString(value,
                                            StringType.UTF8));
            }

            // Send our final byte vectors to SetData
            SetData(type, l, (uint)
                    AppleDataBox.FlagType.ContainsText);
        }
示例#22
0
 public override void SetCommentPacket(ByteVectorCollection packets, XiphComment comment)
 {
     if (packets == null)
     {
         throw new ArgumentNullException("packets");
     }
     if (comment == null)
     {
         throw new ArgumentNullException("comment");
     }
     byte[] data = new byte[] { 0x81 };
     ByteVector item = new ByteVector(data) {
         id,
         comment.Render(1)
     };
     if ((packets.Count > 1) && (PacketType(packets[1]) == 0x81))
     {
         packets[1] = item;
     }
     else
     {
         packets.Insert(1, item);
     }
 }
示例#23
0
        /// <summary>
        ///    Repaginates the pages passed into the current instance to
        ///    handle changes made to the Xiph comment.
        /// </summary>
        /// <param name="change">
        ///    A <see cref="int" /> value reference containing the
        ///    the difference between the number of pages returned and
        ///    the number of pages that were added to the class.
        /// </param>
        /// <returns>
        ///    A <see cref="T:Page[]" /> containing the new page
        ///    collection.
        /// </returns>
        public Page [] Paginate(out int change)
        {
            // Ogg Pagination: Welcome to sucksville!
            // If you don't understand this, you're not alone.
            // It is confusing as Hell.

            // TODO: Document this method, in the mean time, there
            // is always http://xiph.org/ogg/doc/framing.html

            if (pages_read == 0)
            {
                change = 0;
                return(new Page [0]);
            }

            int count = pages_read;
            ByteVectorCollection packets = new ByteVectorCollection(
                this.packets);
            PageHeader  first_header = (PageHeader)first_page_header;
            List <Page> pages        = new List <Page> ();
            uint        index        = 0;
            bool        bos          = first_header.PageSequenceNumber == 0;

            if (bos)
            {
                pages.Add(new Page(new ByteVectorCollection(packets [0]), first_header));
                index++;
                packets.RemoveAt(0);
                count--;
            }

            int lacing_per_page = 0xfc;

            if (count > 0)
            {
                int total_lacing_bytes = 0;

                for (int i = 0; i < packets.Count; i++)
                {
                    total_lacing_bytes += GetLacingValueLength(
                        packets, i);
                }

                lacing_per_page = Math.Min(total_lacing_bytes / count + 1, lacing_per_page);
            }

            int lacing_bytes_used             = 0;
            ByteVectorCollection page_packets = new ByteVectorCollection();
            bool first_packet_continued       = false;

            while (packets.Count > 0)
            {
                int  packet_bytes = GetLacingValueLength(packets, 0);
                int  remaining    = lacing_per_page - lacing_bytes_used;
                bool whole_packet = packet_bytes <= remaining;
                if (whole_packet)
                {
                    page_packets.Add(packets [0]);
                    lacing_bytes_used += packet_bytes;
                    packets.RemoveAt(0);
                }
                else
                {
                    page_packets.Add(packets [0].Mid(0, remaining * 0xff));
                    packets [0]        = packets [0].Mid(remaining * 0xff);
                    lacing_bytes_used += remaining;
                }

                if (lacing_bytes_used == lacing_per_page)
                {
                    pages.Add(new Page(page_packets,
                                       new PageHeader(first_header,
                                                      index, first_packet_continued ?
                                                      PageFlags.FirstPacketContinued :
                                                      PageFlags.None)));
                    page_packets      = new ByteVectorCollection();
                    lacing_bytes_used = 0;
                    index++;
                    count--;
                    first_packet_continued = !whole_packet;
                }
            }

            if (page_packets.Count > 0)
            {
                pages.Add(new Page(page_packets,
                                   new PageHeader(
                                       first_header.StreamSerialNumber,
                                       index, first_packet_continued ?
                                       PageFlags.FirstPacketContinued :
                                       PageFlags.None)));
                index++;
                count--;
            }
            change = -count;
            return(pages.ToArray());
        }
示例#24
0
 private static int GetLacingValueLength(ByteVectorCollection packets, int index)
 {
     int count = packets[index].Count;
     return ((count / 0xff) + ((((index + 1) >= packets.Count) && ((count % 0xff) <= 0)) ? 0 : 1));
 }
示例#25
0
 protected Page (PageHeader header)
 {
    this.header = header;
    packets = new ByteVectorCollection ();
 }
示例#26
0
 public Page[] Paginate(out int change)
 {
     if (this.pages_read == 0)
     {
         change = 0;
         return new Page[0];
     }
     int num = this.pages_read;
     ByteVectorCollection packets = new ByteVectorCollection(this.packets);
     PageHeader header = this.first_page_header.Value;
     List<Page> list = new List<Page>();
     uint offset = 0;
     if (header.PageSequenceNumber == 0)
     {
         ByteVector[] vectorArray1 = new ByteVector[] { packets[0] };
         list.Add(new Page(new ByteVectorCollection(vectorArray1), header));
         offset++;
         packets.RemoveAt(0);
         num--;
     }
     int num3 = 0xfc;
     if (num > 0)
     {
         int num4 = 0;
         for (int i = 0; i < packets.Count; i++)
         {
             num4 += GetLacingValueLength(packets, i);
         }
         num3 = Math.Min((num4 / num) + 1, num3);
     }
     int num6 = 0;
     ByteVectorCollection vectors2 = new ByteVectorCollection();
     bool flag2 = false;
     while (packets.Count > 0)
     {
         int lacingValueLength = GetLacingValueLength(packets, 0);
         int num8 = num3 - num6;
         bool flag3 = lacingValueLength <= num8;
         if (flag3)
         {
             vectors2.Add(packets[0]);
             num6 += lacingValueLength;
             packets.RemoveAt(0);
         }
         else
         {
             vectors2.Add(packets[0].Mid(0, num8 * 0xff));
             packets[0] = packets[0].Mid(num8 * 0xff);
             num6 += num8;
         }
         if (num6 == num3)
         {
             list.Add(new Page(vectors2, new PageHeader(header, offset, !flag2 ? PageFlags.None : PageFlags.FirstPacketContinued)));
             vectors2 = new ByteVectorCollection();
             num6 = 0;
             offset++;
             num--;
             flag2 = !flag3;
         }
     }
     if (vectors2.Count > 0)
     {
         list.Add(new Page(vectors2, new PageHeader(header.StreamSerialNumber, offset, !flag2 ? PageFlags.None : PageFlags.FirstPacketContinued)));
         offset++;
         num--;
     }
     change = -num;
     return list.ToArray();
 }
示例#27
0
		/// <summary>
		///    Replaces the comment packet in a collection of packets
		///    with the rendered version of a Xiph comment or inserts a
		///    comment packet if the stream lacks one.
		/// </summary>
		/// <param name="packets">
		///    A <see cref="ByteVectorCollection" /> object containing
		///    a collection of packets.
		/// </param>
		/// <param name="comment">
		///    A <see cref="XiphComment" /> object to store the rendered
		///    version of in <paramref name="packets" />.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///    <paramref name="packets" /> or <paramref name="comment"
		///    /> is <see langword="null" />.
		/// </exception>
		public override void SetCommentPacket (ByteVectorCollection packets,
		                                       XiphComment comment)
		{
			if (packets == null)
				throw new ArgumentNullException ("packets");

			if (comment == null)
				throw new ArgumentNullException ("comment");

			ByteVector data = new ByteVector ();
			data.Add (magic_signature_comment);
			data.Add (comment.Render (true));
			if (packets.Count > 1 && MagicSignature (packets [1])
						  == magic_signature_comment)
				packets [1] = data;
			else
				packets.Insert (1, data);
		}
示例#28
0
 public void SetValue(ByteVector id, ByteVectorCollection value)
 {
     fields.SetValue(id, value);
 }
示例#29
0
 /// <summary>
 ///    Gets the number of lacing value bytes that would be
 ///    required for a given packet.
 /// </summary>
 /// <param name="packets">
 ///    A <see cref="ByteVectorCollection" /> object containing
 ///    the packet.
 /// </param>
 /// <param name="index">
 ///    A <see cref="int" /> value containing the index of the
 ///    packet to compute.
 /// </param>
 /// <returns>
 ///    A <see cref="int" /> value containing the number of bytes
 ///    needed to store the length.
 /// </returns>
 private static int GetLacingValueLength(ByteVectorCollection packets,
                                          int index)
 {
     int size = packets[index].Count;
     return size / 0xff + ((index + 1 < packets.Count ||
         size % 0xff > 0) ? 1 : 0);
 }
示例#30
0
		/// <summary>
		///    Replaces the comment packet in a collection of packets
		///    with the rendered version of a Xiph comment or inserts a
		///    comment packet if the stream lacks one.
		/// </summary>
		/// <param name="packets">
		///    A <see cref="ByteVectorCollection" /> object containing
		///    a collection of packets.
		/// </param>
		/// <param name="comment">
		///    A <see cref="XiphComment" /> object to store the rendered
		///    version of in <paramref name="packets" />.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///    <paramref name="packets" /> or <paramref name="comment"
		///    /> is <see langword="null" />.
		/// </exception>
		public abstract void SetCommentPacket (ByteVectorCollection packets,
		                                       XiphComment comment);
示例#31
0
        public Page[] Paginate(out int change)
        {
            if (pages_read == 0)
            {
                change = 0;
                return(new Page[0]);
            }
            int count = pages_read;
            ByteVectorCollection packets      = new ByteVectorCollection(this.packets);
            PageHeader           first_header = (PageHeader)first_page_header;
            List <Page>          pages        = new List <Page>();
            uint index = 0;
            bool bos   = first_header.PageSequenceNumber == 0;

            if (bos)
            {
                pages.Add(new Page(new ByteVectorCollection(packets[0]), first_header));
                index++;
                packets.RemoveAt(0);
                count--;
            }
            int lacing_per_page = 0xfc;

            if (count > 0)
            {
                int total_lacing_bytes = 0;
                for (int i = 0; i < packets.Count; i++)
                {
                    total_lacing_bytes += GetLacingValueLength(packets, i);
                }
                lacing_per_page = Math.Min(total_lacing_bytes / count + 1, lacing_per_page);
            }
            int lacing_bytes_used             = 0;
            ByteVectorCollection page_packets = new ByteVectorCollection();
            bool first_packet_continued       = false;

            while (packets.Count > 0)
            {
                int  packet_bytes = GetLacingValueLength(packets, 0);
                int  remaining    = lacing_per_page - lacing_bytes_used;
                bool whole_packet = packet_bytes <= remaining;
                if (whole_packet)
                {
                    page_packets.Add(packets[0]);
                    lacing_bytes_used += packet_bytes;
                    packets.RemoveAt(0);
                }
                else
                {
                    page_packets.Add(packets[0].Mid(0, remaining * 0xff));
                    packets[0]         = packets[0].Mid(remaining * 0xff);
                    lacing_bytes_used += remaining;
                }
                if (lacing_bytes_used == lacing_per_page)
                {
                    pages.Add(new Page(page_packets, new PageHeader(first_header, index, first_packet_continued?PageFlags.FirstPacketContinued:PageFlags.None)));
                    page_packets      = new ByteVectorCollection();
                    lacing_bytes_used = 0;
                    index++;
                    count--;
                    first_packet_continued = !whole_packet;
                }
            }
            if (page_packets.Count > 0)
            {
                pages.Add(new Page(page_packets, new PageHeader(first_header.StreamSerialNumber, index, first_packet_continued?PageFlags.FirstPacketContinued:PageFlags.None)));
                index++;
                count--;
            }
            change = -count;
            return(pages.ToArray());
        }
示例#32
0
 public void SetValue(ByteVector id, ByteVectorCollection value)
 {
     if (id == null)
     {
         throw new ArgumentNullException("id");
     }
     if (id.Count != 4)
     {
         throw new ArgumentException("ID must be 4 bytes long.", "id");
     }
     this.fields.SetValue(id, value);
 }
示例#33
0
		public static OggPage[] Paginate(ByteVectorCollection packets, PaginationStrategy strategy, uint streamSerialNumber,
			int firstPage, bool firstPacketContinued, bool lastPacketCompleted, bool containsLastPacket)
		{
			ArrayList l = new ArrayList();

			int totalSize = 0;
         
			foreach (ByteVector b in packets)
				totalSize += b.Count;

			if (strategy == PaginationStrategy.Repaginate || totalSize + packets.Count > 255 * 256)
			{
				TagLibDebugger.Debug ("Ogg.Page.Paginate() -- Sorry!  Repagination is not yet implemented.");
				return (OggPage[]) l.ToArray(typeof(OggPage));
			}

			// TODO: Handle creation of multiple pages here with appropriate pagination.

			OggPage p = new OggPage(packets, streamSerialNumber, firstPage, firstPacketContinued,
                            lastPacketCompleted, containsLastPacket);
			l.Add (p);

			return (OggPage[]) l.ToArray(typeof(OggPage));
		}
示例#34
0
 protected OggPage (ByteVectorCollection packets,     uint stream_serial_number,
                   int page_number)
          : this (packets, stream_serial_number, page_number, false)
 {
 }
示例#35
0
 protected OggPage (ByteVectorCollection packets,     uint stream_serial_number,
                   int page_number,            bool first_packet_continued)
          : this (packets, stream_serial_number, page_number,
                   first_packet_continued, true)
 {
 }
示例#36
0
      protected OggPage (ByteVectorCollection packets,     uint stream_serial_number,
                      int page_number,            bool first_packet_continued,
                      bool last_packet_completed, bool contains_last_packet)
      {
         //file = null;
         fileOffset = -1;
         //packetOffset = 0;
         //dataSize = 0;
         header = new OggPageHeader();
         firstPacketIndex = -1;
         this.packets = packets;

         ByteVector data = new ByteVector();
         ArrayList packet_sizes = new ArrayList();

         header.FirstPageOfStream    = (page_number == 0 && !first_packet_continued);
         header.LastPageOfStream     = contains_last_packet;
         header.FirstPacketContinued = first_packet_continued;
         header.LastPacketCompleted  = last_packet_completed;
         header.StreamSerialNumber   = stream_serial_number;
         header.PageSequenceNumber   = page_number;

         // Build a page from the text of packets.
         foreach (ByteVector v in packets)
         {
            packet_sizes.Add (v.Count);
            data.Add (v);
         }
         
         header.SetPacketSizes((int[]) packet_sizes.ToArray(typeof(int)));
      }
示例#37
0
 public void SetValue (ByteVector id, ByteVectorCollection value)
 {
    fields.SetValue (id, value);
 }
示例#38
0
        /// <summary>
        ///    Repaginates the pages passed into the current instance to
        ///    handle changes made to the Xiph comment.
        /// </summary>
        /// <param name="change">
        ///    A <see cref="int" /> value reference containing the
        ///    the difference between the number of pages returned and
        ///    the number of pages that were added to the class.
        /// </param>
        /// <returns>
        ///    A <see cref="Page[]" /> containing the new page
        ///    collection.
        /// </returns>
        public Page[] Paginate(out int change)
        {
            // Ogg Pagination: Welcome to sucksville!
            // If you don't understand this, you're not alone.
            // It is confusing as Hell.

            // TODO: Document this method, in the mean time, there
            // is always http://xiph.org/ogg/doc/framing.html

            if (pages_read == 0)
            {
                change = 0;
                return new Page[0];
            }

            int count = pages_read;
            ByteVectorCollection packets = new ByteVectorCollection(
                this.packets);
            PageHeader first_header = (PageHeader)first_page_header;
            List<Page> pages = new List<Page>();
            uint index = 0;
            bool bos = first_header.PageSequenceNumber == 0;

            if (bos)
            {
                pages.Add(new Page(new ByteVectorCollection(packets[0]), first_header));
                index++;
                packets.RemoveAt(0);
                count--;
            }

            int lacing_per_page = 0xfc;
            if (count > 0)
            {
                int total_lacing_bytes = 0;

                for (int i = 0; i < packets.Count; i++)
                    total_lacing_bytes += GetLacingValueLength(
                        packets, i);

                lacing_per_page = Math.Min(total_lacing_bytes / count + 1, lacing_per_page);
            }

            int lacing_bytes_used = 0;
            ByteVectorCollection page_packets = new ByteVectorCollection();
            bool first_packet_continued = false;

            while (packets.Count > 0)
            {
                int packet_bytes = GetLacingValueLength(packets, 0);
                int remaining = lacing_per_page - lacing_bytes_used;
                bool whole_packet = packet_bytes <= remaining;
                if (whole_packet)
                {
                    page_packets.Add(packets[0]);
                    lacing_bytes_used += packet_bytes;
                    packets.RemoveAt(0);
                }
                else
                {
                    page_packets.Add(packets[0].Mid(0, remaining * 0xff));
                    packets[0] = packets[0].Mid(remaining * 0xff);
                    lacing_bytes_used += remaining;
                }

                if (lacing_bytes_used == lacing_per_page)
                {
                    pages.Add(new Page(page_packets,
                        new PageHeader(first_header,
                            index, first_packet_continued ?
                            PageFlags.FirstPacketContinued :
                            PageFlags.None)));
                    page_packets = new ByteVectorCollection();
                    lacing_bytes_used = 0;
                    index++;
                    count--;
                    first_packet_continued = !whole_packet;
                }
            }

            if (page_packets.Count > 0)
            {
                pages.Add(new Page(page_packets,
                    new PageHeader(
                        first_header.StreamSerialNumber,
                        index, first_packet_continued ?
                        PageFlags.FirstPacketContinued :
                        PageFlags.None)));
                index++;
                count--;
            }
            change = -count;
            return pages.ToArray();
        }
示例#39
0
		private void WritePageGroup(IntCollection page_group)
		{
			if (page_group.IsEmpty)
				return;

			ByteVectorCollection packets = new ByteVectorCollection();

			// If the first page of the group isn'type dirty, append its partial content here.

			if (!dirtyPages.Contains(((OggPage)this.pages[page_group[0]]).FirstPacketIndex))
				packets.Add(((OggPage)this.pages[page_group[0]]).Packets[0]);

			int previous_packet = -1;
			int original_size = 0;

			for (int i = 0; i < page_group.Count; i++)
			{
				int page = page_group[i];

				uint first_packet = (uint)((OggPage)this.pages[page]).FirstPacketIndex;
				uint last_packet = first_packet + ((OggPage)this.pages[page]).PacketCount - 1;

				for (uint j = first_packet; j <= last_packet; j++)
				{

					if (i == page_group.Count - 1 && j == last_packet && !dirtyPages.Contains((int)j))
						packets.Add(((OggPage)this.pages[page]).Packets[((OggPage)this.pages[page]).Packets.Count - 1]);
					else if ((int)j != previous_packet)
					{
						previous_packet = (int)j;
						packets.Add(GetPacket(j));
					}
				}
				original_size += ((OggPage)this.pages[page]).Size;
			}

			bool continued = ((OggPage)this.pages[page_group[0]]).Header.FirstPacketContinued;
			bool completed = ((OggPage)this.pages[page_group[page_group.Count - 1]]).Header.LastPacketCompleted;

			// TODO: This pagination method isn'type accurate for what'field being done here.
			// This should account for real possibilities like non-aligned packets and such.

			OggPage[] pages = OggPage.Paginate(packets, PaginationStrategy.SinglePagePerGroup,
										   streamSerialNumber, page_group[0],
										   continued, completed);

			ByteVector data = new ByteVector();

			foreach (OggPage p in pages)
				data.Add(p.Render());

			// The insertion algorithms could also be improve to queue and prioritize data
			// on the way out.  Currently it requires rewriting the file for every page
			// group rather than just once; however, for tagging applications there will
			// generally only be one page group, so it'field not worth the time for the
			// optimization at the moment.

			Insert(data, ((OggPage)this.pages[page_group[0]]).FileOffset, original_size);

			// Update the page index to include the pages we just created and to delete the
			// old pages.

			foreach (OggPage p in pages)
			{
				int index = p.Header.PageSequenceNumber;
				this.pages[index] = p;
			}
		}		
示例#40
0
		public ByteVector GetPacket(uint index)
		{
			// Check to see if we're called setPacket() for this packet since the last
			// save:

			if (dirtyPackets.ContainsKey(index))
				return dirtyPackets[index];

			// If we haven'type indexed the page where the packet we're interested in starts,
			// begin reading pages until we have.

			while (packetToPageMap.Count <= index)
				if (!NextPage())
				{
					TagLibDebugger.Debug("Ogg.File.Packet() -- Could not find the requested packet.");
					return null;
				}

			// Start reading at the first page that contains part (or all) of this packet.
			// If the last read stopped at the packet that we're interested in, don'type
			// reread its packet text.  (This should make sequential packet reads fast.)

			int pageIndex = ((IntCollection)packetToPageMap[(int)index])[0];
			if (currentPacketPage != pages[pageIndex])
			{
				currentPacketPage = pages[pageIndex];
				currentPackets = currentPacketPage.Packets;
			}

			// If the packet is completely contained in the first page that it'field in, then
			// just return it now.

			if ((currentPacketPage.ContainsPacket((int)index) & ContainsPacketSettings.CompletePacket) != 0)
				return currentPackets[(int)(index - currentPacketPage.FirstPacketIndex)];

			// If the packet is *not* completely contained in the first page that it'field a
			// part of then that packet trails off the end of the page.  Continue appending
			// the pages' packet data until we hit a page that either does not end with the
			// packet that we're fetching or where the last packet is complete.

			ByteVector packet = currentPackets[currentPackets.Count - 1];
			while ((currentPacketPage.ContainsPacket((int)index) & ContainsPacketSettings.EndsWithPacket) != 0
				&& !currentPacketPage.Header.LastPacketCompleted)
			{
				pageIndex++;
				if (pageIndex == pages.Count && !NextPage())
				{
					TagLibDebugger.Debug("Ogg.File.Packet() -- Could not find the requested packet.");
					return null;
				}

				currentPacketPage = (OggPage)pages[pageIndex];
				currentPackets = currentPacketPage.Packets;
				packet.Add(currentPackets[0]);
			}

			return packet;
		}
示例#41
0
文件: Page.cs 项目: juschubut/kenos
 /// <summary>
 ///    Constructs and intializes a new instance of <see
 ///    cref="Page" /> with a specified header and no packets.
 /// </summary>
 /// <param name="header">
 ///    A <see cref="PageHeader"/> object to use as the header of
 ///    the new instance.
 /// </param>
 protected Page(PageHeader header)
 {
     this.header = header;
     packets     = new ByteVectorCollection();
 }
示例#42
0
		public static OggPage[] Paginate(ByteVectorCollection packets, PaginationStrategy strategy, uint streamSerialNumber,
			int firstPage, bool firstPacketContinued)
		{
			return Paginate(packets, strategy, streamSerialNumber, firstPage,
				firstPacketContinued, true);
		}
示例#43
0
		protected void ClearPageData()
		{
			streamSerialNumber = 0;
			pages = new List<OggPage>(); //new ArrayList ();
			firstPageHeader = null;
			lastPageHeader = null;
			packetToPageMap = new List<IntCollection>(); //new ArrayList();
			dirtyPackets = new Dictionary<uint, ByteVector>(); //new Hashtable ();
			dirtyPages = new IntCollection();
			currentPage = null;
			currentPacketPage = null;
			currentPackets = null;
		}
示例#44
0
 public abstract void SetCommentPacket(ByteVectorCollection packets, XiphComment comment);
示例#45
0
		public static OggPage[] Paginate(ByteVectorCollection packets, PaginationStrategy strategy, uint streamSerialNumber,
			int firstPage)
		{
			return Paginate(packets, strategy, streamSerialNumber, firstPage, false);
		}