diff --git a/plist-cil/BinaryPropertyListParser.cs b/plist-cil/BinaryPropertyListParser.cs
index b4c4462..33818e8 100644
--- a/plist-cil/BinaryPropertyListParser.cs
+++ b/plist-cil/BinaryPropertyListParser.cs
@@ -119,20 +119,20 @@ namespace Claunia.PropertyList
/// When the property list's format could not be parsed.
private NSObject DoParse(ReadOnlySpan bytes)
{
- string magic = Encoding.ASCII.GetString(
-#if NATIVE_SPAN
- bytes.Slice(0, 8));
-#else
- bytes.Slice(0, 8).ToArray());
-#endif
-
- if (!magic.StartsWith("bplist", StringComparison.Ordinal))
+ if(bytes.Length < 8
+ || bytes[0] != 'b'
+ || bytes[1] != 'p'
+ || bytes[2] != 'l'
+ || bytes[3] != 'i'
+ || bytes[4] != 's'
+ || bytes[5] != 't')
{
+ var magic = Encoding.ASCII.GetString(bytes.Slice(0, 8).ToArray());
throw new PropertyListFormatException("The given data is no binary property list. Wrong magic bytes: " + magic);
}
- majorVersion = magic[6] - 0x30; //ASCII number
- minorVersion = magic[7] - 0x30; //ASCII number
+ majorVersion = bytes[6] - 0x30; //ASCII number
+ minorVersion = bytes[7] - 0x30; //ASCII number
// 0.0 - OS X Tiger and earlier
// 0.1 - Leopard
@@ -366,7 +366,7 @@ namespace Claunia.PropertyList
ReadLengthAndOffset(bytes, objInfo, offset, out int length, out int contentOffset);
//System.out.println("Parsing dictionary #"+obj);
- NSDictionary dict = new NSDictionary();
+ NSDictionary dict = new NSDictionary(length);
for (int i = 0; i < length; i++)
{
int keyRef = (int)ParseUnsignedInt(bytes.Slice(offset + contentOffset + i * objectRefSize, objectRefSize));
diff --git a/plist-cil/NSDictionary.cs b/plist-cil/NSDictionary.cs
index 8d76a67..721dd4f 100644
--- a/plist-cil/NSDictionary.cs
+++ b/plist-cil/NSDictionary.cs
@@ -49,13 +49,24 @@ namespace Claunia.PropertyList
// object remains constant accross calls to AssignIDs and ToBinary
readonly Dictionary keys;
+ ///
+ /// Creates a new empty NSDictionary with a specific capacity.
+ ///
+ ///
+ /// The capacity of the dictionary.
+ ///
+ public NSDictionary(int capacity)
+ {
+ dict = new Dictionary(capacity);
+ keys = new Dictionary(capacity);
+ }
+
///
/// Creates a new empty NSDictionary.
///
public NSDictionary()
+ : this(0)
{
- dict = new Dictionary();
- keys = new Dictionary();
}
///
diff --git a/plist-cil/PropertyListParser.cs b/plist-cil/PropertyListParser.cs
index ac7f572..bfce752 100644
--- a/plist-cil/PropertyListParser.cs
+++ b/plist-cil/PropertyListParser.cs
@@ -49,22 +49,34 @@ namespace Claunia.PropertyList
///
/// The type of the property list
/// The very first bytes of data of the property list (minus any whitespace) as a string
- static int DetermineType(string dataBeginning)
+ static int DetermineTypeExact(ReadOnlySpan dataBeginning)
{
- dataBeginning = dataBeginning.Trim();
if (dataBeginning.Length == 0)
{
return TYPE_ERROR_BLANK;
}
- if (dataBeginning.StartsWith("bplist"))
- {
- return TYPE_BINARY;
- }
- if (dataBeginning.StartsWith("(") || dataBeginning.StartsWith("{") || dataBeginning.StartsWith("/"))
+ else if (dataBeginning[0] == '(' || dataBeginning[0] == '{' || dataBeginning[0] == '/')
{
return TYPE_ASCII;
}
- return dataBeginning.StartsWith("<") ? TYPE_XML : TYPE_ERROR_UNKNOWN;
+ else if (dataBeginning[0] == '<')
+ {
+ return TYPE_XML;
+ }
+ else if (dataBeginning.Length >= 6
+ && dataBeginning[0] == 'b'
+ && dataBeginning[1] == 'p'
+ && dataBeginning[2] == 'l'
+ && dataBeginning[3] == 'i'
+ && dataBeginning[4] == 's'
+ && dataBeginning[5] == 't')
+ {
+ return TYPE_BINARY;
+ }
+ else
+ {
+ return TYPE_ERROR_UNKNOWN;
+ }
}
///
@@ -90,11 +102,7 @@ namespace Claunia.PropertyList
}
var header = bytes.Slice(offset, Math.Min(8, bytes.Length - offset));
-#if NATIVE_SPAN
- return DetermineType(Encoding.ASCII.GetString(header));
-#else
- return DetermineType(Encoding.ASCII.GetString(header.ToArray(), 0, header.Length));
-#endif
+ return DetermineTypeExact(header);
}
///
@@ -138,7 +146,7 @@ namespace Claunia.PropertyList
magicBytes[0] = (byte)b;
int read = fs.Read(magicBytes, 1, 7);
- int type = DetermineType(Encoding.ASCII.GetString(magicBytes, 0, read));
+ int type = DetermineTypeExact(magicBytes.AsSpan(0, read));
fs.Seek(mark, SeekOrigin.Begin);
return type;
}