Permalink
Browse files

Fix object ref sizing issue in BinaryPlistWriter.

The top level object offset (always 8) was not being taken into account when
calculating the object reference integer size.
  • Loading branch information...
ChadBurggraf committed Sep 15, 2011
1 parent ae095b1 commit 53ffdedf22599892d4599785860d1b8d6ad71f4c
View
@@ -3,6 +3,7 @@
*.snk
.DS_Store
StyleCop.Cache
+Artifacts/
bin/
obj/
Build/
@@ -2,6 +2,7 @@
<TestRunConfiguration name="Local Test Run" id="4c6ea626-eb6d-4822-a3c7-905de6cf1311" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2006">
<Description>This is a default test run configuration for a local test run.</Description>
<Deployment>
+ <DeploymentItem filename="System.Runtime.Serialization.Plists.Test\Profile2.plist" />
<DeploymentItem filename="System.Runtime.Serialization.Plists.Test\Nested.plist" />
<DeploymentItem filename="System.Runtime.Serialization.Plists.Test\Calculator.plist" />
<DeploymentItem filename="System.Runtime.Serialization.Plists.Test\Types.plist" />
View
@@ -17,7 +17,7 @@
[assembly: AssemblyCulture("")]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.3.0.1")]
-[assembly: AssemblyFileVersion("1.3.0.1")]
+[assembly: AssemblyVersion("1.3.0.2")]
+[assembly: AssemblyFileVersion("1.3.0.2")]
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "Signed during a release build.")][assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "Assembly", Target = "System.Runtime.Serialization.Plists.dll", Justification = "The spelling is correct.")]
@@ -32,6 +32,12 @@ public static class Paths
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "The spelling is correct.")]
public const string ProfilePlistPath = "Profile.plist";
+ /// <summary>
+ /// Gets the path of the profile 2 plist file.
+ /// </summary>
+ [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "The spelling is correct.")]
+ public const string Profile2PlistPath = "Profile2.plist";
+
/// <summary>
/// Gets the path of the types plist file.
/// </summary>
Binary file not shown.
@@ -101,5 +101,59 @@ public void ReaderReadObjectTypes()
Assert.AreEqual("World", dictionary["Hello"]);
Assert.AreEqual(72, ((object[])dictionary["LongArray"]).Length);
}
+
+ /// <summary>
+ /// Read Profile2.plist tests.
+ /// </summary>
+ [TestMethod]
+ public void ReaderReadProfile2()
+ {
+ BinaryPlistReader reader = new BinaryPlistReader();
+ IDictionary dictionary;
+
+ using (Stream stream = File.OpenRead(Paths.Profile2PlistPath))
+ {
+ dictionary = reader.ReadObject(stream);
+ }
+
+ Assert.AreEqual(2, dictionary.Count);
+
+ object[] disorders = (object[])dictionary["disorders"];
+ object[] educationLevels = (object[])dictionary["educationLevels"];
+
+ Assert.AreEqual(1, disorders.Length);
+ Assert.AreEqual(6, educationLevels.Length);
+
+ IDictionary obj = (IDictionary)disorders[0];
+ Assert.AreEqual((short)1, obj["id"]);
+ Assert.AreEqual(false, obj["isAlias"]);
+ Assert.AreEqual("Autism", obj["name"]);
+ Assert.AreEqual((short)1, obj["order"]);
+
+ obj = (IDictionary)educationLevels[1];
+ Assert.AreEqual((short)2, obj["id"]);
+ Assert.AreEqual("Elementary School", obj["name"]);
+ Assert.AreEqual((short)2, obj["order"]);
+
+ obj = (IDictionary)educationLevels[2];
+ Assert.AreEqual((short)3, obj["id"]);
+ Assert.AreEqual("Middle School", obj["name"]);
+ Assert.AreEqual((short)3, obj["order"]);
+
+ obj = (IDictionary)educationLevels[3];
+ Assert.AreEqual((short)4, obj["id"]);
+ Assert.AreEqual("High School", obj["name"]);
+ Assert.AreEqual((short)4, obj["order"]);
+
+ obj = (IDictionary)educationLevels[4];
+ Assert.AreEqual((short)5, obj["id"]);
+ Assert.AreEqual("Post High School", obj["name"]);
+ Assert.AreEqual((short)5, obj["order"]);
+
+ obj = (IDictionary)educationLevels[5];
+ Assert.AreEqual((short)6, obj["id"]);
+ Assert.AreEqual("Higher Education", obj["name"]);
+ Assert.AreEqual((short)6, obj["order"]);
+ }
}
}
@@ -61,9 +61,11 @@
<None Include="Calculator.plist" />
<None Include="Nested.plist" />
<None Include="Profile.plist" />
+ <None Include="Profile2.plist" />
<None Include="Types.plist" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\StyleCop\v4.5\StyleCop.Targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
@@ -28,7 +28,7 @@ public void WriterWriteEmptyString()
string outputPath = Guid.NewGuid().ToString() + ".plist";
IDictionary dict = new Dictionary<string, object>();
- dict["Empty"] = String.Empty;
+ dict["Empty"] = string.Empty;
BinaryPlistWriter writer = new BinaryPlistWriter();
writer.WriteObject(outputPath, dict);
@@ -37,7 +37,7 @@ public void WriterWriteEmptyString()
dict = reader.ReadObject(outputPath);
Assert.IsTrue(dict.Contains("Empty"));
- Assert.AreEqual(String.Empty, dict["Empty"]);
+ Assert.AreEqual(string.Empty, dict["Empty"]);
}
/// <summary>
@@ -205,7 +205,7 @@ public T ReadObject<T>(Stream stream) where T : IPlistSerializable, new()
private static string ReadAsciiString(BinaryReader reader, long index, int size)
{
byte[] buffer = ReadData(reader, index, size);
- return buffer.Length > 0 ? Encoding.ASCII.GetString(buffer) : String.Empty;
+ return buffer.Length > 0 ? Encoding.ASCII.GetString(buffer) : string.Empty;
}
/// <summary>
@@ -131,6 +131,8 @@ public void WriteObject(Stream stream, IDictionary dictionary)
// Reset the state and then build the object table.
this.Reset();
this.AddDictionary(dictionary);
+
+ this.topLevelObjectOffset = 8;
this.CalculateObjectRefSize();
using (BinaryWriter writer = new BinaryWriter(stream))
@@ -140,7 +142,6 @@ public void WriteObject(Stream stream, IDictionary dictionary)
writer.Write(HeaderVersionNumber.ToBigEndianConditional());
// Write the object table.
- this.topLevelObjectOffset = 8;
long offsetTableOffset = this.topLevelObjectOffset + this.WriteObjectTable(writer);
// Write the offset table.
@@ -195,11 +196,11 @@ private static byte[] GetIntegerBytes(long value)
{
return new byte[] { (byte)value };
}
- else if (value >= Int16.MinValue && value <= Int16.MaxValue)
+ else if (value >= short.MinValue && value <= short.MaxValue)
{
return BitConverter.GetBytes(((short)value).ToBigEndianConditional());
}
- else if (value >= Int32.MinValue && value <= Int32.MaxValue)
+ else if (value >= int.MinValue && value <= int.MaxValue)
{
return BitConverter.GetBytes(((int)value).ToBigEndianConditional());
}
@@ -525,7 +526,7 @@ private int AddObject(object value)
index = this.AddPrimitive(null);
break;
case TypeCode.Int16:
- index = this.AddInteger((long)(int)value);
+ index = this.AddInteger((long)(short)value);
break;
case TypeCode.Int32:
index = this.AddInteger((long)(int)value);
@@ -676,26 +677,26 @@ private int AddString(string value)
/// </summary>
private void CalculateObjectRefSize()
{
- while (this.objectTableSize + (this.objectRefCount * this.objectRefSize) > this.maxObjectRefValue)
+ while (this.objectTableSize + this.topLevelObjectOffset + (this.objectRefCount * this.objectRefSize) > this.maxObjectRefValue)
{
switch (this.objectRefSize)
{
case 1:
this.objectRefSize = 2;
- this.maxObjectRefValue = Int16.MaxValue;
+ this.maxObjectRefValue = short.MaxValue;
break;
case 2:
this.objectRefSize = 4;
- this.maxObjectRefValue = Int32.MaxValue;
+ this.maxObjectRefValue = int.MaxValue;
break;
case 4:
this.objectRefSize = 8;
- this.maxObjectRefValue = Int64.MaxValue;
+ this.maxObjectRefValue = long.MaxValue;
break;
case 8:
break;
default:
- throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Failed to calculate the required object reference size with an object table size of {0} and an object reference count of {1}.", this.objectTableSize, this.objectRefCount));
+ throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Failed to calculate the required object reference size with an object table size of {0} and an object reference count of {1}.", this.objectTableSize, this.objectRefCount));
}
}
}
@@ -84,7 +84,7 @@ public void WriteObject(Stream stream, object graph)
if (!this.rootType.IsAssignableFrom(type))
{
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The object specified is of type {0}, which is not assignable to this instance's root type, {1}.", type, this.rootType));
+ throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The object specified is of type {0}, which is not assignable to this instance's root type, {1}.", type, this.rootType));
}
IDictionary dict = this.GetWritablePlistObject(type, graph) as IDictionary;
@@ -42,7 +42,7 @@ public static Type GetConcreteTypeIfNullable(this Type type)
/// <returns>True if the string contains only ASCII characters, false otherwise.</returns>
public static bool IsAscii(this string value)
{
- if (!String.IsNullOrEmpty(value))
+ if (!string.IsNullOrEmpty(value))
{
foreach (char c in value)
{
@@ -61,6 +61,7 @@
<Compile Include="UniqueValueCache.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\StyleCop\v4.5\StyleCop.Targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
@@ -88,7 +88,7 @@ select new
IsRequired = false
};
- member.Name = !String.IsNullOrEmpty(member.Name) ? member.Name : tuple.Info.Name;
+ member.Name = !string.IsNullOrEmpty(member.Name) ? member.Name : tuple.Info.Name;
this.FieldMembers.Add(member);
this.Fields.Add(tuple.Info);
@@ -127,7 +127,7 @@ select new
IsRequired = false
};
- member.Name = !String.IsNullOrEmpty(member.Name) ? member.Name : tuple.Info.Name;
+ member.Name = !string.IsNullOrEmpty(member.Name) ? member.Name : tuple.Info.Name;
this.PropertyMembers.Add(member);
this.Properties.Add(tuple.Info);
Binary file not shown.
Binary file not shown.
Oops, something went wrong.

0 comments on commit 53ffded

Please sign in to comment.