Inherited FileStream arbitrarily sets position to end of buffer rather than actual position

  • Thread starter Thread starter primem0ver
  • Start date Start date
P

primem0ver

Guest
I inherited the FileStream class in my solution that is meant to copy the contents to a new file but give the user the ability to read, decompress, and analyze the stream before copying it in order to make changes along the way.

public class MixedCompressionStreamRewriter : FileStream

My first test of the code seemed to work just fine so I tried it on a few more files. With one file, the buffer has been cleared at position 203. It reads the start of the next record and determines what kind it is, advancing the the position to 207. At position 207 it then reads (another) Uint32 (using a BinaryReader). After reading the byte the position has advanced by 4092 bytes rather than 4 bytes. I don't think it is a coincidence that the buffer size is 4096 and the buffer is now full.

I can build a workaround into my Read method but this is a problem as it is NOT happening in my code. Why does it do this and how can I/we fix it? Below are the two methods (the one that reads the uint32 and the overridden code):

public static RecordHeaderBase FromFile(BinaryReader reader, uint internalIDMask = 0xFFFFFFFF)
{
RecordConsolidator consolidator = reader.BaseStream as RecordConsolidator;
if (consolidator != null)
consolidator.EnableParseMode = true;
RecordTypeInfo typeInfo = (RecordType)reader.ReadUInt32(); // THIS IS THE LINE THAT CALLS MY OVERRIDE
if (consolidator != null)
consolidator.EnableParseMode = false;
if (typeInfo == RecordType.TES4)
return new FileHeader(reader);
else if (typeInfo.isContainer)
return new GroupHeader(reader, typeInfo, internalIDMask);
else
return new RecordHeader(reader, typeInfo, internalIDMask);
}

Here is the overridden read method:

public override int Read(byte[] array, int offset, int count)
{
int result;
if (compressionHeaderStream == null) // TRUE IN THIS CASE
{
result = base.Read(array, offset, count); // HERE IS WHERE IT JUMPS TO 4299 rather than 207
if (!parseMode) // NOT TRUE IN THIS CASE
{
long equivalentBufferLocation = MemoryBufferStart + MemoryBuffer.Length;
if (Position > equivalentBufferLocation)
{
long bufferCopyBytes = Position - equivalentBufferLocation;
if (bufferCopyBytes > int.MaxValue)
throw new OverflowException();
offset += (count - (int)bufferCopyBytes);
MemoryBuffer.Write(array, offset, (int)bufferCopyBytes);
}
if (MaxBufferSize != 0)
if (MemoryBuffer.Length >= MaxBufferSize)
FlushToOutput();
}
}
else if (MemoryBuffer == null)
result = base.Read(array, offset, count);
else
result = MemoryBuffer.Read(array, offset, count);
return result;
}

Continue reading...
 
Back
Top