Skip to content

Commit

Permalink
Merge pull request #137 from Numpsy/users/rw/app_specific_property_names
Browse files Browse the repository at this point in the history
When saving an OLEProperties container of type 'AppSpecific' which ha…
  • Loading branch information
ironfede authored Sep 15, 2024
2 parents 86b3355 + 62036c1 commit 278146a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ public void Save(CFStream cfStream)
}
};

// If we're writing an AppSpecific property set and have property names, then add a dictionary property
if (this.ContainerType == ContainerType.AppSpecific && this.PropertyNames != null && this.PropertyNames.Count > 0)
{
AddDictionaryPropertyToPropertySet(this.PropertyNames, ps.PropertySet0);
ps.PropertySet0.NumProperties += 1;
}

PropertyFactory factory =
this.ContainerType == ContainerType.DocumentSummaryInfo ? DocumentSummaryInfoPropertyFactory.Instance : DefaultPropertyFactory.Instance;

Expand All @@ -270,8 +277,6 @@ public void Save(CFStream cfStream)
ps.PropertySet0.PropertyIdentifierAndOffsets.Add(new PropertyIdentifierAndOffset() { PropertyIdentifier = op.PropertyIdentifier, Offset = 0 });
}

ps.PropertySet0.NumProperties = (uint)this.Properties.Count();

if (HasUserDefinedProperties)
{
ps.NumPropertySets = 2;
Expand All @@ -289,12 +294,7 @@ public void Save(CFStream cfStream)
ps.Offset1 = 0;

// Add the dictionary containing the property names
IDictionaryProperty dictionaryProperty = new DictionaryProperty(ps.PropertySet1.PropertyContext.CodePage)
{
Value = this.UserDefinedProperties.PropertyNames
};
ps.PropertySet1.Properties.Add(dictionaryProperty);
ps.PropertySet1.PropertyIdentifierAndOffsets.Add(new PropertyIdentifierAndOffset() { PropertyIdentifier = 0, Offset = 0 });
AddDictionaryPropertyToPropertySet(this.UserDefinedProperties.PropertyNames, ps.PropertySet1);

// Add the properties themselves
foreach (var op in this.UserDefinedProperties.Properties)
Expand All @@ -308,5 +308,15 @@ public void Save(CFStream cfStream)

ps.Write(bw);
}

private void AddDictionaryPropertyToPropertySet(Dictionary<uint, string> propertyNames, PropertySet propertySet)
{
IDictionaryProperty dictionaryProperty = new DictionaryProperty(propertySet.PropertyContext.CodePage)
{
Value = propertyNames
};
propertySet.Properties.Add(dictionaryProperty);
propertySet.PropertyIdentifierAndOffsets.Add(new PropertyIdentifierAndOffset() { PropertyIdentifier = 0, Offset = 0 });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -531,5 +531,47 @@ public void Test_ADD_USER_DEFINED_PROPERTIES_SECTION()
Assert.AreEqual(VTPropertyType.VT_LPSTR, propArray[1].VTType);
}
}

// A test for the issue described in https://github.com/ironfede/openmcdf/issues/134 where modifying an AppSpecific stream
// removes any already-existing Dictionary property
[TestMethod]
public void Test_Retain_Dictionary_Property_In_AppSpecific_Streams()
{
File.Delete("Issue134RoundTrip.cfs");

using (CompoundFile cf = new CompoundFile("Issue134.cfs"))
{
var testStream = cf.RootStorage.GetStream("Issue134");
var co = testStream.AsOLEPropertiesContainer();

// Test initial contents are as expected
AssertExpectedProperties(co.PropertyNames);

// Write test file
co.Save(testStream);
cf.SaveAs("Issue134RoundTrip.cfs");
}

// Open test file, and check that the property names are still as expected.
using (CompoundFile cf = new CompoundFile("Issue134RoundTrip.cfs", CFSUpdateMode.ReadOnly, CFSConfiguration.Default))
{
var co = cf.RootStorage.GetStream("Issue134").AsOLEPropertiesContainer();
AssertExpectedProperties(co.PropertyNames);
}

void AssertExpectedProperties(Dictionary<uint, string> actual)
{
Assert.IsNotNull(actual);

var expected = new Dictionary<uint, string>()
{
[2] = "Document Number",
[3] = "Revision",
[4] = "Project Name"
};

CollectionAssert.AreEqual(expected, actual);
}
}
}
}
Binary file added sources/Test/TestFiles/Issue134.cfs
Binary file not shown.

0 comments on commit 278146a

Please sign in to comment.