Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the readonly version #87

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions sources/OpenMcdf/DirectoryEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public int SID
}

internal static Int32 NOSTREAM
= unchecked((int)0xFFFFFFFF);
=> unchecked((int)0xFFFFFFFF);

internal static Int32 ZERO
= 0;
=> 0;

private DirectoryEntry(String name, StgType stgType, IList<IDirectoryEntry> dirRepository)
{
Expand All @@ -71,13 +71,13 @@ private DirectoryEntry(String name, StgType stgType, IList<IDirectoryEntry> dirR
}
}

private byte[] entryName = new byte[64];
private byte[] entryName;//= new byte[64];

public byte[] EntryName
{
get
{
return entryName;
return entryName ?? new byte[64];
}
//set
//{
Expand Down Expand Up @@ -214,27 +214,27 @@ public Int32 StateBits
set { stateBits = value; }
}

private byte[] creationDate = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private byte[] creationDate;//= new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

public byte[] CreationDate
{
get
{
return creationDate;
return creationDate ?? new byte[8];
}
set
{
creationDate = value;
}
}

private byte[] modifyDate = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private byte[] modifyDate;//= new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

public byte[] ModifyDate
{
get
{
return modifyDate;
return modifyDate ?? new byte[8];
}
set
{
Expand Down Expand Up @@ -331,14 +331,14 @@ private static ulong fnv_hash(byte[] buffer)

public override int GetHashCode()
{
return (int)fnv_hash(this.entryName);
return (int)fnv_hash(this.EntryName);
}

public void Write(Stream stream)
{
StreamRW rw = new StreamRW(stream);

rw.Write(entryName);
rw.Write(EntryName);
rw.Write(nameLength);
rw.Write((byte)stgType);
rw.Write((byte)stgColor);
Expand All @@ -347,8 +347,8 @@ public void Write(Stream stream)
rw.Write(child);
rw.Write(storageCLSID.ToByteArray());
rw.Write(stateBits);
rw.Write(creationDate);
rw.Write(modifyDate);
rw.Write(CreationDate);
rw.Write(ModifyDate);
rw.Write(startSetc);
rw.Write(size);

Expand Down Expand Up @@ -384,7 +384,7 @@ public void Write(Stream stream)

public void Read(Stream stream, CFSVersion ver = CFSVersion.Ver_3)
{
StreamRW rw = new StreamRW(stream);
IStreamReader rw = stream.ToStreamReader();

entryName = rw.ReadBytes(64);
nameLength = rw.ReadUInt16();
Expand All @@ -405,8 +405,8 @@ public void Read(Stream stream, CFSVersion ver = CFSVersion.Ver_3)

storageCLSID = new Guid(rw.ReadBytes(16));
stateBits = rw.ReadInt32();
creationDate = rw.ReadBytes(8);
modifyDate = rw.ReadBytes(8);
CreationDate = rw.ReadBytes(8);
ModifyDate = rw.ReadBytes(8);
startSetc = rw.ReadInt32();

if (ver == CFSVersion.Ver_3)
Expand All @@ -415,7 +415,7 @@ public void Read(Stream stream, CFSVersion ver = CFSVersion.Ver_3)
// where most significant bits are not initialized to zero

size = rw.ReadInt32();
rw.ReadBytes(4); //discard most significant 4 (possibly) dirty bytes
rw.ReadInt32(); //rw.ReadBytes(4); //discard most significant 4 (possibly) dirty bytes
}
else
{
Expand Down
58 changes: 33 additions & 25 deletions sources/OpenMcdf/Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ namespace OpenMcdf
{
internal class Header
{
/// <summary>
/// Number of DIFAT entries in the header
/// </summary>
private const int HEADER_DIFAT_ENTRIES_COUNT = 109;

//0 8 Compound document file identifier: D0H CFH 11H E0H A1H B1H 1AH E1H
private byte[] headerSignature
= new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };

public byte[] HeaderSignature
{
get { return headerSignature; }
get => _headerSignature ??= new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };
private set => _headerSignature = value;
}

//8 16 Unique identifier (UID) of this file (not of interest in the following, may be all 0)
Expand Down Expand Up @@ -63,7 +67,7 @@ public ushort ByteOrder
public ushort SectorShift
{
get { return sectorShift; }

}

//32 2 Size of a short-sector in the short-stream container stream (➜6.1) in power-of-two (sssz),
Expand Down Expand Up @@ -171,7 +175,8 @@ public uint DIFATSectorsNumber
}

//76 436 First part of the master sector allocation table (➜5.1) containing 109 SecIDs
private int[] difat = new int[109];
private int[] difat = new int[HEADER_DIFAT_ENTRIES_COUNT];
private byte[] _headerSignature;

public int[] DIFAT
{
Expand Down Expand Up @@ -207,19 +212,17 @@ public Header(ushort version)

}

for (int i = 0; i < 109; i++)
for (int i = 0; i < HEADER_DIFAT_ENTRIES_COUNT; i++)
{
difat[i] = Sector.FREESECT;
}


}

public void Write(Stream stream)
{
StreamRW rw = new StreamRW(stream);

rw.Write(headerSignature);
rw.Write(HeaderSignature);
rw.Write(clsid);
rw.Write(minorVersion);
rw.Write(majorVersion);
Expand Down Expand Up @@ -253,10 +256,12 @@ public void Write(Stream stream)

public void Read(Stream stream)
{
StreamRW rw = new StreamRW(stream);
var rw = stream.ToStreamReader();

var headerSignature = rw.ReadBytes(8);
CheckSignature(headerSignature);
HeaderSignature = headerSignature;

headerSignature = rw.ReadBytes(8);
CheckSignature();
clsid = rw.ReadBytes(16);
minorVersion = rw.ReadUInt16();
majorVersion = rw.ReadUInt16();
Expand All @@ -275,32 +280,35 @@ public void Read(Stream stream)
firstDIFATSectorID = rw.ReadInt32();
difatSectorsNumber = rw.ReadUInt32();

for (int i = 0; i < 109; i++)
for (int i = 0; i < HEADER_DIFAT_ENTRIES_COUNT; i++)
{
this.DIFAT[i] = rw.ReadInt32();
}

rw.Close();
}


private void CheckVersion()
{
if (this.majorVersion != 3 && this.majorVersion != 4)
throw new CFFileFormatException("Unsupported Binary File Format version: OpenMcdf only supports Compound Files with major version equal to 3 or 4 ");
}

/// <summary>
/// Structured Storage signature
/// </summary>
private byte[] OLE_CFS_SIGNATURE = new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };

private void CheckSignature()
private static void CheckSignature(byte[] headerSignature)
{
for (int i = 0; i < headerSignature.Length; i++)
var success = headerSignature.Length == 8;
success = success
//var oleCfsSignature = new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 };
&& headerSignature[0] == 0xD0
&& headerSignature[1] == 0xCF
&& headerSignature[2] == 0x11
&& headerSignature[3] == 0xE0
&& headerSignature[4] == 0xA1
&& headerSignature[5] == 0xB1
&& headerSignature[6] == 0x1A
&& headerSignature[7] == 0xE1;

if (!success)
{
if (headerSignature[i] != OLE_CFS_SIGNATURE[i])
throw new CFFileFormatException("Invalid OLE structured storage file");
throw new CFFileFormatException("Invalid OLE structured storage file");
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions sources/OpenMcdf/OpenMcdf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -90,9 +91,8 @@
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<None Include="OpenMcdf.snk" />
Expand Down
42 changes: 42 additions & 0 deletions sources/OpenMcdf/Readonly/ByteArrayPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace OpenMcdf
{
class ByteArrayPool : IByteArrayPool
{
public byte[] Rent(int minimumLength)
{
for (var i = 0; i < _bufferList.Length; i++)
{
var buffer = _bufferList[i];

if (buffer != null && buffer.Length >= minimumLength)
{
_bufferList[i] = null;
return buffer;
}
}

return new byte[minimumLength];
}

public void Return(byte[] byteList)
{
if (byteList == null || byteList.Length >= MaxBufferLength)
{
return;
}

for (var i = 0; i < _bufferList.Length; i++)
{
var buffer = _bufferList[i];
if (buffer is null || byteList.Length > buffer.Length)
{
buffer = byteList;
_bufferList[i] = buffer;
}
}
}

private readonly byte[][] _bufferList = new byte[4][];
private const int MaxBufferLength = 8 * 1024;
}
}
8 changes: 8 additions & 0 deletions sources/OpenMcdf/Readonly/IByteArrayPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace OpenMcdf
{
public interface IByteArrayPool
{
byte[] Rent(int minimumLength);
void Return(byte[] byteList);
}
}
16 changes: 16 additions & 0 deletions sources/OpenMcdf/Readonly/IStreamReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace OpenMcdf
{
internal interface IStreamReader
{
long Seek(long offset);
byte ReadByte();
ushort ReadUInt16();
int ReadInt32();
uint ReadUInt32();
long ReadInt64();
ulong ReadUInt64();
byte[] ReadBytes(int count);
byte[] ReadBytes(int count, out int readCount);
void Close();
}
}
Loading