Exemplo n.º 1
0
        public static void OverwriteSequenceNumbers(File file,
                                                    long position,
                                                    IDictionary <uint, int> shiftTable)
        {
            bool done = true;

            foreach (KeyValuePair <uint, int> pair in shiftTable)
            {
                if (pair.Value != 0)
                {
                    done = false;
                    break;
                }
            }

            if (done)
            {
                return;
            }

            while (position < file.Length)
            {
                PageHeader header = new PageHeader(file, position);
                int        size   = (int)(header.Size + header.DataSize);

                if (shiftTable.ContainsKey(header.StreamSerialNumber) &&
                    shiftTable [header.StreamSerialNumber] != 0)
                {
                    file.Seek(position);
                    ByteVector page_data = file.ReadBlock(size);

                    ByteVector new_data = ByteVector.FromUInt(
                        (uint)(header.PageSequenceNumber +
                               shiftTable [header.StreamSerialNumber]),
                        false);

                    for (int i = 18; i < 22; i++)
                    {
                        page_data [i] = new_data [i - 18];
                    }
                    for (int i = 22; i < 26; i++)
                    {
                        page_data [i] = 0;
                    }

                    new_data.Add(ByteVector.FromUInt(
                                     page_data.Checksum, false));
                    file.Seek(position + 18);
                    file.WriteBlock(new_data);
                }
                position += size;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="Page" /> by reading a raw Ogg page from a specified
        ///    position in a specified file.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="File" /> object containing the file from
        ///    which the contents of the new instance are to be read.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specify at what position to
        ///    read.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///    <paramref name="position" /> is less than zero or greater
        ///    than the size of the file.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    The Ogg identifier could not be found at the correct
        ///    location.
        /// </exception>
        public Page(File file, long position)
            : this(new PageHeader (file, position))
        {
            file.Seek (position + header.Size);

            foreach (int packet_size in header.PacketSizes)
                packets.Add (file.ReadBlock (packet_size));
        }
Exemplo n.º 3
0
        public PageHeader(File file, long position)
        {
            file.Seek(position);

            // An Ogg page header is at least 27 bytes, so we'll go ahead and read that
            // much and then get the rest when we're ready for it.

            ByteVector data = file.ReadBlock(27);

            if (data.Count < 27 || !data.StartsWith("OggS"))
            {
                throw new CorruptFileException("Error reading page header");
            }

            _version = data [4];
            _flags   = (PageFlags)data [5];
            _absolute_granular_position = data.Mid(6, 8).ToULong(false);
            _stream_serial_number       = data.Mid(14, 4).ToUInt(false);
            _page_sequence_number       = data.Mid(18, 4).ToUInt(false);

            // Byte number 27 is the number of page segments, which is the only variable
            // length portion of the page header.  After reading the number of page
            // segments we'll then read in the coresponding data for this count.
            int        page_segment_count = data [26];
            ByteVector page_segments      = file.ReadBlock(page_segment_count);

            // Another sanity check.
            if (page_segment_count < 1 || page_segments.Count != page_segment_count)
            {
                throw new CorruptFileException("Incorrect number of page segments");
            }

            // The base size of an Ogg page 27 bytes plus the number of lacing values.
            _size         = (uint)(27 + page_segment_count);
            _packet_sizes = new List <int> ();

            int packet_size = 0;

            _data_size = 0;

            for (int i = 0; i < page_segment_count; i++)
            {
                _data_size  += page_segments [i];
                packet_size += page_segments [i];

                if (page_segments [i] < 255)
                {
                    _packet_sizes.Add(packet_size);
                    packet_size = 0;
                }
            }

            if (packet_size > 0)
            {
                _packet_sizes.Add(packet_size);
            }
        }
Exemplo n.º 4
0
 public Page(File file, long position) :
     this(new PageHeader(file, position))
 {
     file.Seek(position + header.Size);
     foreach (int packet_size in header.PacketSizes)
     {
         packets.Add(file.ReadBlock(packet_size));
     }
 }
Exemplo n.º 5
0
 public Page (File file, long position) : this (new PageHeader (file, position))
 {
    if (file == null)
       throw new ArgumentNullException ("file");
    
    file.Seek (position + header.Size);
    
    foreach (int packet_size in header.PacketSizes)
       packets.Add (file.ReadBlock (packet_size));
 }
Exemplo n.º 6
0
        public Page(File file, long position) : this(new PageHeader(file, position))
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            file.Seek(position + header.Size);

            foreach (int packet_size in header.PacketSizes)
            {
                packets.Add(file.ReadBlock(packet_size));
            }
        }
Exemplo n.º 7
0
        public PageHeader(File file, long position)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
            if (position < 0 || position > file.Length - 27)
            {
                throw new ArgumentOutOfRangeException("position");
            }
            file.Seek(position);
            ByteVector data = file.ReadBlock(27);

            if (data.Count < 27 || !data.StartsWith("OggS"))
            {
                throw new CorruptFileException("Error reading page header");
            }
            version    = data[4];
            this.flags = (PageFlags)data[5];
            absolute_granular_position = data.Mid(6, 8).ToULong(false);
            stream_serial_number       = data.Mid(14, 4).ToUInt(false);
            page_sequence_number       = data.Mid(18, 4).ToUInt(false);
            int        page_segment_count = data[26];
            ByteVector page_segments      = file.ReadBlock(page_segment_count);

            if (page_segment_count < 1 || page_segments.Count != page_segment_count)
            {
                throw new CorruptFileException("Incorrect number of page segments");
            }
            size         = (uint)(27 + page_segment_count);
            packet_sizes = new List <int>();
            int packet_size = 0;

            data_size = 0;
            for (int i = 0; i < page_segment_count; i++)
            {
                data_size   += page_segments[i];
                packet_size += page_segments[i];
                if (page_segments[i] < 255)
                {
                    packet_sizes.Add(packet_size);
                    packet_size = 0;
                }
            }
            if (packet_size > 0)
            {
                packet_sizes.Add(packet_size);
            }
        }
Exemplo n.º 8
0
		public static void OverwriteSequenceNumbers (File file,
		                                             long position,
		                                             IDictionary<uint, int> shiftTable)
		{
			bool done = true;
			foreach (KeyValuePair<uint, int> pair in shiftTable)
				if (pair.Value != 0) {
					done = false;
					break;
				}
			
			if (done)
				return;
			
			while (position < file.Length) {
				PageHeader header = new PageHeader (file, position);
				int size = (int) (header.Size + header.DataSize);
				
				if (shiftTable.ContainsKey (header.StreamSerialNumber)
					&& shiftTable [header.StreamSerialNumber] != 0) {
					file.Seek (position);
					ByteVector page_data = file.ReadBlock (size);
					
					ByteVector new_data = ByteVector.FromUInt (
						(uint)(header.PageSequenceNumber +
						shiftTable [header.StreamSerialNumber]),
						false);
					
					for (int i = 18; i < 22; i ++)
						page_data [i] = new_data [i - 18];
					for (int i = 22; i < 26; i++)
						page_data [i] = 0;
					
					new_data.Add (ByteVector.FromUInt (
						page_data.Checksum, false));
					file.Seek (position + 18);
					file.WriteBlock (new_data);
				}
				position += size;
			}
		}
Exemplo n.º 9
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="PageHeader" /> by reading a raw Ogg page header
        ///    from a specified position in a specified file.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="File" /> object containing the file from
        ///    which the contents of the new instance are to be read.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specify at what position to
        ///    read.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///    <paramref name="position" /> is less than zero or greater
        ///    than the size of the file.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    The Ogg identifier could not be found at the correct
        ///    location.
        /// </exception>
        public PageHeader(File file, long position)
        {
            if (file == null)
                throw new ArgumentNullException ("file");

            if (position < 0 || position > file.Length - 27)
                throw new ArgumentOutOfRangeException (
                    "position");

            file.Seek (position);

            // An Ogg page header is at least 27 bytes, so we'll go
            // ahead and read that much and then get the rest when
            // we're ready for it.

            ByteVector data = file.ReadBlock (27);
            if (data.Count < 27 || !data.StartsWith ("OggS"))
                System.Console.WriteLine(
                    "Error reading page header");

            version = data [4];
            this.flags = (PageFlags) data [5];
            absolute_granular_position = data.Mid(6, 8).ToULong (
                false);
            stream_serial_number = data.Mid(14, 4).ToUInt (false);
            page_sequence_number = data.Mid(18, 4).ToUInt (false);

            // Byte number 27 is the number of page segments, which
            // is the only variable length portion of the page
            // header. After reading the number of page segments
            // we'll then read in the coresponding data for this
            // count.
            int page_segment_count = data [26];
            ByteVector page_segments =
                file.ReadBlock (page_segment_count);

            // Another sanity check.
            if (page_segment_count < 1 ||
                page_segments.Count != page_segment_count)
                System.Console.WriteLine(
                    "Incorrect number of page segments");

            // The base size of an Ogg page 27 bytes plus the number
            // of lacing values.
            size = (uint)(27 + page_segment_count);
            packet_sizes = new List<int> ();

            int packet_size = 0;
            data_size = 0;

            for (int i = 0; i < page_segment_count; i++) {
                data_size += page_segments [i];
                packet_size += page_segments [i];

                if (page_segments [i] < 255) {
                    packet_sizes.Add (packet_size);
                    packet_size = 0;
                }
            }

            if (packet_size > 0)
                packet_sizes.Add (packet_size);
        }
Exemplo n.º 10
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="PageHeader" /> by reading a raw Ogg page header
        ///    from a specified position in a specified file.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="File" /> object containing the file from
        ///    which the contents of the new instance are to be read.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specify at what position to
        ///    read.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///    <paramref name="position" /> is less than zero or greater
        ///    than the size of the file.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    The Ogg identifier could not be found at the correct
        ///    location.
        /// </exception>
        public PageHeader(File file, long position)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (position < 0 || position > file.Length - 27)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            file.Seek(position);

            // An Ogg page header is at least 27 bytes, so we'll go
            // ahead and read that much and then get the rest when
            // we're ready for it.

            ByteVector data = file.ReadBlock(27);

            if (data.Count < 27 || !data.StartsWith("OggS"))
            {
                throw new CorruptFileException("Error reading page header");
            }

            version = data[4];
            Flags   = (PageFlags)data[5];
            absolute_granular_position = data.Mid(6, 8).ToULong(false);
            StreamSerialNumber         = data.Mid(14, 4).ToUInt(false);
            PageSequenceNumber         = data.Mid(18, 4).ToUInt(false);

            // Byte number 27 is the number of page segments, which
            // is the only variable length portion of the page
            // header. After reading the number of page segments
            // we'll then read in the coresponding data for this
            // count.
            int        page_segment_count = data[26];
            ByteVector page_segments      = file.ReadBlock(page_segment_count);

            // Another sanity check.
            if (page_segment_count < 1 || page_segments.Count != page_segment_count)
            {
                throw new CorruptFileException("Incorrect number of page segments");
            }

            // The base size of an Ogg page 27 bytes plus the number
            // of lacing values.
            Size         = (uint)(27 + page_segment_count);
            packet_sizes = new List <int> ();

            int packet_size = 0;

            DataSize = 0;

            for (int i = 0; i < page_segment_count; i++)
            {
                DataSize    += page_segments[i];
                packet_size += page_segments[i];

                if (page_segments[i] < 255)
                {
                    packet_sizes.Add(packet_size);
                    packet_size = 0;
                }
            }

            if (packet_size > 0)
            {
                packet_sizes.Add(packet_size);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        ///    Overwrites all page headers in a file starting at a
        ///    specified position, shifting the page sequence numbers
        ///    a set amount.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="File" /> object containing the file to
        ///    update.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value specify at what position to
        ///    start updating.
        /// </param>
        /// <param name="shiftTable">
        ///    A <see cref="T:System.Collections.Generic.IDictionary`2"
        ///    /> object where the key is the serial number of the
        ///    stream to update and the value is the amount to offset
        ///    the page sequence numbers in the stream.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> or <paramref name="shiftTable"
        ///    /> is <see langword="null" />.
        /// </exception>
        /// <remarks>
        ///    When the number of pages in a stream changes, all
        ///    subsequent pages in the stream need to have their page
        ///    sequence number update in order to remain valid.
        ///    Additionally, when the page sequence number changes, the
        ///    page needs to have its checksum recomputed. This makes
        ///    for a costly recalculation if large comment data is
        ///    added.
        /// </remarks>
        public static void OverwriteSequenceNumbers(File file,
                                                    long position,
                                                    IDictionary <uint, int> shiftTable)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

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

            // Check to see if there are no changes to be made.
            bool done = true;

            foreach (KeyValuePair <uint, int> pair in shiftTable)
            {
                if (pair.Value != 0)
                {
                    done = false;
                    break;
                }
            }

            // If the file is fine, quit.
            if (done)
            {
                return;
            }

            while (position < file.Length - 27)
            {
                PageHeader header = new PageHeader(file, position);
                int        size   = (int)(header.Size + header.DataSize);

                if (shiftTable.ContainsKey(header.StreamSerialNumber) &&
                    shiftTable [header.StreamSerialNumber] != 0)
                {
                    file.Seek(position);
                    ByteVector page_data = file.ReadBlock(size);

                    ByteVector new_data = ByteVector.FromUInt(
                        (uint)(header.PageSequenceNumber +
                               shiftTable [header.StreamSerialNumber]),
                        false);

                    for (int i = 18; i < 22; i++)
                    {
                        page_data [i] = new_data [i - 18];
                    }
                    for (int i = 22; i < 26; i++)
                    {
                        page_data [i] = 0;
                    }

                    new_data.Add(ByteVector.FromUInt(
                                     page_data.Checksum, false));
                    file.Seek(position + 18);
                    file.WriteBlock(new_data);
                }
                position += size;
            }
        }
Exemplo n.º 12
0
		/// <summary>
		///    Overwrites all page headers in a file starting at a
		///    specified position, shifting the page sequence numbers
		///    a set amount.
		/// </summary>
		/// <param name="file">
		///    A <see cref="File" /> object containing the file to
		///    update.
		/// </param>
		/// <param name="position">
		///    A <see cref="long" /> value specify at what position to
		///    start updating.
		/// </param>
		/// <param name="shiftTable">
		///    A <see cref="T:System.Collections.Generic.IDictionary`2"
		///    /> object where the key is the serial number of the
		///    stream to update and the value is the amount to offset
		///    the page sequence numbers in the stream.
		/// </param>
		/// <exception cref="ArgumentNullException">
		///    <paramref name="file" /> or <paramref name="shiftTable"
		///    /> is <see langword="null" />.
		/// </exception>
		/// <remarks>
		///    When the number of pages in a stream changes, all
		///    subsequent pages in the stream need to have their page
		///    sequence number update in order to remain valid.
		///    Additionally, when the page sequence number changes, the
		///    page needs to have its checksum recomputed. This makes
		///    for a costly recalculation if large comment data is
		///    added.
		/// </remarks>
		public static void OverwriteSequenceNumbers (File file,
		                                             long position,
		                                             IDictionary<uint, int> shiftTable)
		{
			if (file == null)
				throw new ArgumentNullException ("file");
			
			if (shiftTable == null)
				throw new ArgumentNullException ("shiftTable");
			
			// Check to see if there are no changes to be made.
			bool done = true;
			foreach (KeyValuePair<uint, int> pair in shiftTable)
				if (pair.Value != 0) {
					done = false;
					break;
				}
			
			// If the file is fine, quit.
			if (done)
				return;
			
			while (position < file.Length - 27) {
				PageHeader header = new PageHeader (file, position);
				int size = (int) (header.Size + header.DataSize);
				
				if (shiftTable.ContainsKey (header.StreamSerialNumber)
					&& shiftTable [header.StreamSerialNumber] != 0) {
					file.Seek (position);
					ByteVector page_data = file.ReadBlock (size);
					
					ByteVector new_data = ByteVector.FromUInt (
						(uint)(header.PageSequenceNumber +
						shiftTable [header.StreamSerialNumber]),
						false);
					
					for (int i = 18; i < 22; i ++)
						page_data [i] = new_data [i - 18];
					for (int i = 22; i < 26; i++)
						page_data [i] = 0;
					
					new_data.Add (ByteVector.FromUInt (
						page_data.Checksum, false));
					file.Seek (position + 18);
					file.WriteBlock (new_data);
				}
				position += size;
			}
		}