Skip to content

Commit e3dd49d

Browse files
Merge branch '3.0-poc' into 3.0-poc-draft
2 parents 80ecf5e + 812d582 commit e3dd49d

File tree

5 files changed

+48
-32
lines changed

5 files changed

+48
-32
lines changed

OpenMcdf3/CfbBinaryReader.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,34 @@ namespace OpenMcdf3;
77
/// </summary>
88
internal sealed class CfbBinaryReader : BinaryReader
99
{
10+
readonly byte[] guidBuffer = new byte[16];
1011
readonly byte[] buffer = new byte[DirectoryEntry.NameFieldLength];
1112

1213
public CfbBinaryReader(Stream input)
1314
: base(input, Encoding.Unicode, true)
1415
{
1516
}
1617

17-
public Guid ReadGuid() => new(ReadBytes(16));
18+
public Guid ReadGuid()
19+
{
20+
int bytesRead = 0;
21+
do
22+
{
23+
int n = Read(guidBuffer, bytesRead, guidBuffer.Length - bytesRead);
24+
if (n == 0)
25+
throw new EndOfStreamException();
26+
bytesRead += n;
27+
} while (bytesRead < guidBuffer.Length);
28+
29+
return new Guid(guidBuffer);
30+
}
1831

1932
public DateTime ReadFileTime()
2033
{
2134
long fileTime = ReadInt64();
2235
return DateTime.FromFileTimeUtc(fileTime);
2336
}
2437

25-
private void ReadBytes(byte[] buffer) => Read(buffer, 0, buffer.Length);
26-
2738
public Header ReadHeader()
2839
{
2940
Header header = new();
@@ -90,8 +101,9 @@ public DirectoryEntry ReadDirectoryEntry(Version version)
90101

91102
DirectoryEntry entry = new();
92103
Read(buffer, 0, DirectoryEntry.NameFieldLength);
93-
int nameLength = Math.Max(0, ReadUInt16() - 2);
94-
entry.Name = Encoding.Unicode.GetString(buffer, 0, nameLength);
104+
ushort nameLength = ReadUInt16();
105+
int clampedNameLength = Math.Max(0, Math.Min(ushort.MaxValue, nameLength - 2));
106+
entry.Name = Encoding.Unicode.GetString(buffer, 0, clampedNameLength);
95107
entry.Type = ReadStorageType();
96108
entry.Color = ReadColor();
97109
entry.LeftSiblingId = ReadUInt32();

OpenMcdf3/FatSectorChainEnumerator.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public bool MoveNext()
5656
}
5757
else if (!current.IsEndOfChain)
5858
{
59-
uint sectorId = fatEnumerator.GetNextFatSectorId(current.Id);
59+
uint sectorId = GetNextFatSectorId(current.Id);
6060
current = new(sectorId, ioContext.Header.SectorSize);
6161
Index++;
6262
}
@@ -98,4 +98,23 @@ public void Reset()
9898
current = Sector.EndOfChain;
9999
Index = uint.MaxValue;
100100
}
101+
102+
/// <summary>
103+
/// Gets the next sector ID in the FAT chain.
104+
/// </summary>
105+
uint GetNextFatSectorId(uint id)
106+
{
107+
if (id > SectorType.Maximum)
108+
throw new ArgumentException("Invalid sector ID", nameof(id));
109+
110+
int elementCount = ioContext.Header.SectorSize / sizeof(uint);
111+
uint sectorId = (uint)Math.DivRem(id, elementCount, out long sectorOffset);
112+
if (!fatEnumerator.MoveTo(sectorId))
113+
throw new ArgumentException("Invalid sector ID", nameof(id));
114+
115+
long position = fatEnumerator.Current.Position + sectorOffset * sizeof(uint);
116+
ioContext.Reader.Seek(position);
117+
uint nextId = ioContext.Reader.ReadUInt32();
118+
return nextId;
119+
}
101120
}

OpenMcdf3/FatSectorEnumerator.cs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ public bool MoveNext()
8383
return true;
8484
}
8585

86-
/// <inheritdoc/>
86+
/// <summary>
87+
/// Moves the enumerator to the specified sector.
88+
/// </summary>
8789
public bool MoveTo(uint sectorId)
8890
{
8991
if (sectorId < id)
@@ -107,21 +109,4 @@ public void Reset()
107109
difatSectorElementIndex = 0;
108110
current = Sector.EndOfChain;
109111
}
110-
111-
/// <inheritdoc/>
112-
public uint GetNextFatSectorId(uint id)
113-
{
114-
if (id > SectorType.Maximum)
115-
throw new ArgumentException("Invalid sector ID", nameof(id));
116-
117-
int elementCount = ioContext.Header.SectorSize / sizeof(uint);
118-
uint sectorId = (uint)Math.DivRem(id, elementCount, out long sectorOffset);
119-
if (!MoveTo(sectorId))
120-
throw new ArgumentException("Invalid sector ID", nameof(id));
121-
122-
long position = Current.Position + sectorOffset * sizeof(uint);
123-
ioContext.Reader.Seek(position);
124-
uint nextId = ioContext.Reader.ReadUInt32();
125-
return nextId;
126-
}
127112
}

OpenMcdf3/FatStream.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ public override int Read(byte[] buffer, int offset, int count)
7373
if (count == 0)
7474
return 0;
7575

76-
uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
77-
if (!chain.MoveTo(chainIndex))
78-
return 0;
79-
8076
int maxCount = (int)Math.Min(Math.Max(length - position, 0), int.MaxValue);
8177
if (maxCount == 0)
8278
return 0;
8379

80+
uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
81+
if (!chain.MoveTo(chainIndex))
82+
return 0;
83+
8484
int realCount = Math.Min(count, maxCount);
8585
int readCount = 0;
8686
do

OpenMcdf3/MiniFatStream.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ public override int Read(byte[] buffer, int offset, int count)
7171
if (count == 0)
7272
return 0;
7373

74-
uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
75-
if (!chain.MoveTo(chainIndex))
76-
return 0;
77-
7874
int maxCount = (int)Math.Min(Math.Max(length - position, 0), int.MaxValue);
7975
if (maxCount == 0)
8076
return 0;
8177

78+
uint chainIndex = (uint)Math.DivRem(position, ioContext.Header.SectorSize, out long sectorOffset);
79+
if (!chain.MoveTo(chainIndex))
80+
return 0;
81+
8282
int realCount = Math.Min(count, maxCount);
8383
int readCount = 0;
8484
do

0 commit comments

Comments
 (0)