Skip to content

Commit

Permalink
Rework the handling of FMTID0 in OLEPropertiesContainer
Browse files Browse the repository at this point in the history
  • Loading branch information
Numpsy committed Sep 3, 2024
1 parent 64b5278 commit 7d1a772
Showing 1 changed file with 54 additions and 21 deletions.
75 changes: 54 additions & 21 deletions sources/OpenMcdf.Extensions/OLEProperties/OLEPropertiesContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ public class OLEPropertiesContainer

public bool HasUserDefinedProperties { get; private set; }

public ContainerType ContainerType { get; internal set; }
private Guid? FmtID0 { get; }
/// <summary>
/// Gets the type of the container.
/// </summary>
public ContainerType ContainerType { get; }

/// <summary>
/// Gets the FMTID of the properties container.
/// </summary>
public Guid FMTID0 { get; }

public PropertyContext Context { get; private set; }

Expand Down Expand Up @@ -69,6 +76,11 @@ public static OLEPropertiesContainer CreateNewSummaryInfo(SummaryInfoProperties
return null;
}

/// <summary>
/// Create a new instance of <see cref="OLEPropertiesContainer"/> with the specified code page and container type.
/// </summary>
/// <param name="codePage">The code page to use for the new container.</param>
/// <param name="containerType">The type of the new container.</param>
public OLEPropertiesContainer(int codePage, ContainerType containerType)
{
Context = new PropertyContext
Expand All @@ -78,6 +90,7 @@ public OLEPropertiesContainer(int codePage, ContainerType containerType)
};

this.ContainerType = containerType;
this.FMTID0 = FmtIdFromContainerType(containerType);
}

internal OLEPropertiesContainer(CFStream cfStream)
Expand All @@ -87,20 +100,8 @@ internal OLEPropertiesContainer(CFStream cfStream)
this.cfStream = cfStream;
pStream.Read(new BinaryReader(new StreamDecorator(cfStream)));

switch (pStream.FMTID0.ToString("B").ToUpperInvariant())
{
case WellKnownFMTID.FMTID_SummaryInformation:
this.ContainerType = ContainerType.SummaryInfo;
break;
case WellKnownFMTID.FMTID_DocSummaryInformation:
this.ContainerType = ContainerType.DocumentSummaryInfo;
break;
default:
this.ContainerType = ContainerType.AppSpecific;
break;
}

this.FmtID0 = pStream.FMTID0;
this.FMTID0 = pStream.FMTID0;
this.ContainerType = ContainerTypeFromFmtId(pStream.FMTID0);

this.PropertyNames = (Dictionary<uint, string>)pStream.PropertySet0.Properties
.Where(p => p.PropertyType == PropertyType.DictionaryProperty).FirstOrDefault()?.Value;
Expand Down Expand Up @@ -135,8 +136,6 @@ internal OLEPropertiesContainer(CFStream cfStream)
UserDefinedProperties = new OLEPropertiesContainer(pStream.PropertySet1.PropertyContext.CodePage, ContainerType.UserDefinedProperties);
this.HasUserDefinedProperties = true;

UserDefinedProperties.ContainerType = ContainerType.UserDefinedProperties;

for (int i = 0; i < pStream.PropertySet1.Properties.Count; i++)
{
if (pStream.PropertySet1.PropertyIdentifierAndOffsets[i].PropertyIdentifier == 0) continue;
Expand Down Expand Up @@ -239,8 +238,6 @@ public void Save(CFStream cfStream)
Stream s = new StreamDecorator(cfStream);
BinaryWriter bw = new BinaryWriter(s);

Guid fmtId0 = this.FmtID0 ?? (this.ContainerType == ContainerType.SummaryInfo ? new Guid(WellKnownFMTID.FMTID_SummaryInformation) : new Guid(WellKnownFMTID.FMTID_DocSummaryInformation));

PropertySetStream ps = new PropertySetStream
{
ByteOrder = 0xFFFE,
Expand All @@ -250,7 +247,7 @@ public void Save(CFStream cfStream)

NumPropertySets = 1,

FMTID0 = fmtId0,
FMTID0 = this.FMTID0,
Offset0 = 0,

FMTID1 = Guid.Empty,
Expand Down Expand Up @@ -314,5 +311,41 @@ public void Save(CFStream cfStream)

ps.Write(bw);
}

// Determine the type of the container from the FMTID0 property.
private static ContainerType ContainerTypeFromFmtId(Guid fmtId0)
{
if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_SummaryInformation))
return ContainerType.SummaryInfo;
else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_DocSummaryInformation))
return ContainerType.DocumentSummaryInfo;
else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_GlobalInfo))
return ContainerType.GlobalInfo;
else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_ImageInfo))
return ContainerType.ImageInfo;
else if (fmtId0 == Guid.Parse(WellKnownFMTID.FMTID_ImageContents))
return ContainerType.ImageContents;

return ContainerType.AppSpecific;
}

// Determine the FMTID property from the container type.
// Note: Uses FMTID_DocSummaryInformation by default to match the previous behavior.
private static Guid FmtIdFromContainerType(ContainerType containerType)
{
switch (containerType)
{
case ContainerType.SummaryInfo:
return Guid.Parse(WellKnownFMTID.FMTID_SummaryInformation);
case ContainerType.GlobalInfo:
return Guid.Parse(WellKnownFMTID.FMTID_GlobalInfo);
case ContainerType.ImageContents:
return Guid.Parse(WellKnownFMTID.FMTID_ImageContents);
case ContainerType.ImageInfo:
return Guid.Parse(WellKnownFMTID.FMTID_ImageInfo);
default:
return Guid.Parse(WellKnownFMTID.FMTID_DocSummaryInformation);
}
}
}
}

0 comments on commit 7d1a772

Please sign in to comment.