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

Rework the handling of FMTID0 in OLEPropertiesContainer #142

Closed
wants to merge 1 commit into from
Closed
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
68 changes: 54 additions & 14 deletions sources/OpenMcdf.Extensions/OLEProperties/OLEPropertiesContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,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 @@ -68,6 +75,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 @@ -77,6 +89,7 @@ public OLEPropertiesContainer(int codePage, ContainerType containerType)
};

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

internal OLEPropertiesContainer(CFStream cfStream)
Expand All @@ -86,13 +99,8 @@ internal OLEPropertiesContainer(CFStream cfStream)
this.cfStream = cfStream;
pStream.Read(new BinaryReader(new StreamDecorator(cfStream)));

ContainerType = pStream.FMTID0.ToString("B").ToUpperInvariant() switch
{
WellKnownFMTID.FMTID_SummaryInformation => ContainerType.SummaryInfo,
WellKnownFMTID.FMTID_DocSummaryInformation => ContainerType.DocumentSummaryInfo,
_ => ContainerType.AppSpecific,
};
FmtID0 = pStream.FMTID0;
FMTID0 = pStream.FMTID0;
ContainerType = ContainerTypeFromFmtId(pStream.FMTID0);

PropertyNames = (Dictionary<uint, string>)pStream.PropertySet0.Properties
.Where(p => p.PropertyType == PropertyType.DictionaryProperty).FirstOrDefault()?.Value;
Expand Down Expand Up @@ -126,8 +134,6 @@ internal OLEPropertiesContainer(CFStream cfStream)
UserDefinedProperties = new OLEPropertiesContainer(pStream.PropertySet1.PropertyContext.CodePage, ContainerType.UserDefinedProperties);
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 @@ -227,8 +233,6 @@ public void Save(CFStream cfStream)
Stream s = new StreamDecorator(cfStream);
BinaryWriter bw = new BinaryWriter(s);

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

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

NumPropertySets = 1,

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

FMTID1 = Guid.Empty,
Expand Down Expand Up @@ -312,5 +316,41 @@ private void AddDictionaryPropertyToPropertySet(Dictionary<uint, string> propert
propertySet.Properties.Add(dictionaryProperty);
propertySet.PropertyIdentifierAndOffsets.Add(new PropertyIdentifierAndOffset() { PropertyIdentifier = 0, Offset = 0 });
}

// 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);
}
}
}
}