Skip to content

Commit

Permalink
Merge branch '3.0-poc' into 3.0-poc-draft
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-visionaid committed Oct 20, 2024
2 parents 80ecf5e + 812d582 commit e3dd49d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 32 deletions.
22 changes: 17 additions & 5 deletions OpenMcdf3/CfbBinaryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,34 @@ namespace OpenMcdf3;
/// </summary>
internal sealed class CfbBinaryReader : BinaryReader
{
readonly byte[] guidBuffer = new byte[16];
readonly byte[] buffer = new byte[DirectoryEntry.NameFieldLength];

public CfbBinaryReader(Stream input)
: base(input, Encoding.Unicode, true)
{
}

public Guid ReadGuid() => new(ReadBytes(16));
public Guid ReadGuid()
{
int bytesRead = 0;
do
{
int n = Read(guidBuffer, bytesRead, guidBuffer.Length - bytesRead);
if (n == 0)
throw new EndOfStreamException();
bytesRead += n;
} while (bytesRead < guidBuffer.Length);

return new Guid(guidBuffer);
}

public DateTime ReadFileTime()
{
long fileTime = ReadInt64();
return DateTime.FromFileTimeUtc(fileTime);
}

private void ReadBytes(byte[] buffer) => Read(buffer, 0, buffer.Length);

public Header ReadHeader()
{
Header header = new();
Expand Down Expand Up @@ -90,8 +101,9 @@ public DirectoryEntry ReadDirectoryEntry(Version version)

DirectoryEntry entry = new();
Read(buffer, 0, DirectoryEntry.NameFieldLength);
int nameLength = Math.Max(0, ReadUInt16() - 2);
entry.Name = Encoding.Unicode.GetString(buffer, 0, nameLength);
ushort nameLength = ReadUInt16();
int clampedNameLength = Math.Max(0, Math.Min(ushort.MaxValue, nameLength - 2));
entry.Name = Encoding.Unicode.GetString(buffer, 0, clampedNameLength);
entry.Type = ReadStorageType();
entry.Color = ReadColor();
entry.LeftSiblingId = ReadUInt32();
Expand Down
21 changes: 20 additions & 1 deletion OpenMcdf3/FatSectorChainEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public bool MoveNext()
}
else if (!current.IsEndOfChain)
{
uint sectorId = fatEnumerator.GetNextFatSectorId(current.Id);
uint sectorId = GetNextFatSectorId(current.Id);
current = new(sectorId, ioContext.Header.SectorSize);
Index++;
}
Expand Down Expand Up @@ -98,4 +98,23 @@ public void Reset()
current = Sector.EndOfChain;
Index = uint.MaxValue;
}

/// <summary>
/// Gets the next sector ID in the FAT chain.
/// </summary>
uint GetNextFatSectorId(uint id)
{
if (id > SectorType.Maximum)
throw new ArgumentException("Invalid sector ID", nameof(id));

int elementCount = ioContext.Header.SectorSize / sizeof(uint);
uint sectorId = (uint)Math.DivRem(id, elementCount, out long sectorOffset);
if (!fatEnumerator.MoveTo(sectorId))
throw new ArgumentException("Invalid sector ID", nameof(id));

long position = fatEnumerator.Current.Position + sectorOffset * sizeof(uint);
ioContext.Reader.Seek(position);
uint nextId = ioContext.Reader.ReadUInt32();
return nextId;
}
}
21 changes: 3 additions & 18 deletions OpenMcdf3/FatSectorEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ public bool MoveNext()
return true;
}

/// <inheritdoc/>
/// <summary>
/// Moves the enumerator to the specified sector.
/// </summary>
public bool MoveTo(uint sectorId)
{
if (sectorId < id)
Expand All @@ -107,21 +109,4 @@ public void Reset()
difatSectorElementIndex = 0;
current = Sector.EndOfChain;
}

/// <inheritdoc/>
public uint GetNextFatSectorId(uint id)
{
if (id > SectorType.Maximum)
throw new ArgumentException("Invalid sector ID", nameof(id));

int elementCount = ioContext.Header.SectorSize / sizeof(uint);
uint sectorId = (uint)Math.DivRem(id, elementCount, out long sectorOffset);
if (!MoveTo(sectorId))
throw new ArgumentException("Invalid sector ID", nameof(id));

long position = Current.Position + sectorOffset * sizeof(uint);
ioContext.Reader.Seek(position);
uint nextId = ioContext.Reader.ReadUInt32();
return nextId;
}
}
8 changes: 4 additions & 4 deletions OpenMcdf3/FatStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ public override int Read(byte[] buffer, int offset, int count)
if (count == 0)
return 0;

uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
if (!chain.MoveTo(chainIndex))
return 0;

int maxCount = (int)Math.Min(Math.Max(length - position, 0), int.MaxValue);
if (maxCount == 0)
return 0;

uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
if (!chain.MoveTo(chainIndex))
return 0;

int realCount = Math.Min(count, maxCount);
int readCount = 0;
do
Expand Down
8 changes: 4 additions & 4 deletions OpenMcdf3/MiniFatStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ public override int Read(byte[] buffer, int offset, int count)
if (count == 0)
return 0;

uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
if (!chain.MoveTo(chainIndex))
return 0;

int maxCount = (int)Math.Min(Math.Max(length - position, 0), int.MaxValue);
if (maxCount == 0)
return 0;

uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
if (!chain.MoveTo(chainIndex))
return 0;

int realCount = Math.Min(count, maxCount);
int readCount = 0;
do
Expand Down

0 comments on commit e3dd49d

Please sign in to comment.