/// <summary> /// Searches for a top-level chunk with a given id inside of the given container chunk. /// This method assumes that starting with the offset given, there is nothing in the container chunk besides /// chunks written one after another. Any stray data between chunks is unexpected. /// </summary> /// <param name="container">The chunk to search within.</param> /// <param name="id">The id of the chunk to look for.</param> /// <param name="start">The starting offset from the beginning of the container chunk data to apply.</param> /// <returns>The header of the chunk found, or a header with an offset of -1 if none is found.</returns> public MDFChunkHeader findNextChunk(MDFChunkHeader container, UInt32 id, long start) { long origPos = reader.BaseStream.Position; long curPos = start + container.offset + sizeof(UInt32) + sizeof(UInt32); MDFChunkHeader temp; while (curPos < container.offset + container.size) { reader.BaseStream.Seek(curPos, SeekOrigin.Begin); if ((temp = peekChunkHeader()).id == id) { reader.BaseStream.Seek(origPos, SeekOrigin.Begin); return(temp); } else { curPos = temp.offset + temp.size; } } reader.BaseStream.Seek(origPos, SeekOrigin.Begin); temp.offset = -1; temp.id = 0; temp.size = 0; return(temp); }
/// <summary> /// Writes the chunk header and returns a new header with an offset field marking the place where the header was written. /// </summary> /// <param name="header"></param> public MDFChunkHeader writeChunkHeader(MDFChunkHeader header) { header.offset = writer.BaseStream.Position; writer.Write(header.id); writer.Write(header.size); return(header); }
/// <summary> /// Calculates the size of the chunk from the current file position back to the start of the chunk header and writes that size into the chunk header. /// The size is corrected straight into the file, and the file position is reset back to the end of the chunk. /// </summary> /// <param name="header">The chunk header of this chunk.</param> /// <returns>The updated chunk header structure, with the new corrected size field (just in case anyone needs it).</returns> public MDFChunkHeader writeCalculatedChunkSize(MDFChunkHeader header) { long curPos = writer.BaseStream.Position; header.size = (UInt32)(curPos - header.offset); writer.BaseStream.Seek(header.offset, SeekOrigin.Begin); header = writeChunkHeader(header); writer.BaseStream.Seek(curPos, SeekOrigin.Begin); return(header); }
/// <summary> /// Returns true if the given chunk is empty. /// </summary> /// <param name="header">The header of the chunk to test.</param> /// <returns>true if the given chunk is completely empty (in which the size field only accounts for the header), false otherwise.</returns> public bool isEmpty(MDFChunkHeader header) { if (header.size == sizeof(UInt32) + sizeof(UInt32)) { return(true); } else { return(false); } }
/// <summary> /// Skips the current chunk by seeking past its size. /// </summary> /// <param name="chunk">The header of the chunk to skip over.</param> public void skipChunk(MDFChunkHeader chunk) { reader.BaseStream.Seek(chunk.offset + chunk.size, SeekOrigin.Begin); }
/// <summary> /// Skips over the given chunk header, positioning the file position at the beginning of the chunk's data. /// </summary> /// <param name="header">The chunk header of the chunk to enter.</param> public void enterChunk(MDFChunkHeader header) { reader.BaseStream.Seek(header.offset + sizeof(UInt32) + sizeof(UInt32), SeekOrigin.Begin); }
/// <summary> /// Searches for a top-level chunk with a given id inside of the given container chunk. /// This method assumes that starting with the offset given, there is nothing in the container chunk besides /// chunks written one after another. Any stray data between chunks is unexpected. /// </summary> /// <param name="container">The chunk to search within.</param> /// <param name="id">The id of the chunk to look for.</param> /// <param name="start">The starting offset from the beginning of the container chunk data to apply.</param> /// <returns>The header of the chunk found, or a header with an offset of -1 if none is found.</returns> public MDFChunkHeader findNextChunk(MDFChunkHeader container, UInt32 id, long start) { long origPos = reader.BaseStream.Position; long curPos = start + container.offset + sizeof(UInt32) + sizeof(UInt32); MDFChunkHeader temp; while (curPos < container.offset + container.size) { reader.BaseStream.Seek(curPos, SeekOrigin.Begin); if ((temp = peekChunkHeader()).id == id) { reader.BaseStream.Seek(origPos, SeekOrigin.Begin); return temp; } else { curPos = temp.offset + temp.size; } } reader.BaseStream.Seek(origPos, SeekOrigin.Begin); temp.offset = -1; temp.id = 0; temp.size = 0; return temp; }
/// <summary> /// Calculates the size of the chunk from the current file position back to the start of the chunk header and writes that size into the chunk header. /// The size is corrected straight into the file, and the file position is reset back to the end of the chunk. /// </summary> /// <param name="header">The chunk header of this chunk.</param> /// <returns>The updated chunk header structure, with the new corrected size field (just in case anyone needs it).</returns> public MDFChunkHeader writeCalculatedChunkSize(MDFChunkHeader header) { long curPos = writer.BaseStream.Position; header.size = (UInt32)(curPos - header.offset); writer.BaseStream.Seek(header.offset, SeekOrigin.Begin); header = writeChunkHeader(header); writer.BaseStream.Seek(curPos, SeekOrigin.Begin); return header; }
/// <summary> /// Writes the chunk header and returns a new header with an offset field marking the place where the header was written. /// </summary> /// <param name="header"></param> public MDFChunkHeader writeChunkHeader(MDFChunkHeader header) { header.offset = writer.BaseStream.Position; writer.Write(header.id); writer.Write(header.size); return header; }
/// <summary> /// Skips the current chunk by seeking past its size. /// </summary> /// <param name="chunk">The header of the chunk to skip over.</param> public void skipChunk(MDFChunkHeader chunk) { reader.BaseStream.Seek(chunk.offset + chunk.size, SeekOrigin.Begin); }
/// <summary> /// Skips over the given chunk header, positioning the file position at the beginning of the chunk's data. /// </summary> /// <param name="header">The chunk header of the chunk to enter.</param> public void enterChunk(MDFChunkHeader header) { reader.BaseStream.Seek(header.offset + sizeof(UInt32) + sizeof(UInt32), SeekOrigin.Begin); }
/// <summary> /// Returns true if the given chunk is empty. /// </summary> /// <param name="header">The header of the chunk to test.</param> /// <returns>true if the given chunk is completely empty (in which the size field only accounts for the header), false otherwise.</returns> public bool isEmpty(MDFChunkHeader header) { if (header.size == sizeof(UInt32) + sizeof(UInt32)) return true; else return false; }