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; } }
/// <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)); }
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); } }
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)); } }
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)); }
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)); } }
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); } }
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; } }
/// <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); }
/// <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); } }
/// <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; } }
/// <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; } }