mirror of
https://github.com/claunia/plist-cil.git
synced 2025-12-16 11:04:26 +00:00
Performance improvements
- Set the capacity of the dictionary of known - Don't allocate a string to check whether a file is a valid binary property list
This commit is contained in:
@@ -119,20 +119,20 @@ namespace Claunia.PropertyList
|
||||
/// <exception cref="PropertyListFormatException">When the property list's format could not be parsed.</exception>
|
||||
private NSObject DoParse(ReadOnlySpan<byte> 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));
|
||||
|
||||
@@ -49,13 +49,24 @@ namespace Claunia.PropertyList
|
||||
// object remains constant accross calls to AssignIDs and ToBinary
|
||||
readonly Dictionary<string, NSString> keys;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new empty NSDictionary with a specific capacity.
|
||||
/// </summary>
|
||||
/// <param name="capacity">
|
||||
/// The capacity of the dictionary.
|
||||
/// </param>
|
||||
public NSDictionary(int capacity)
|
||||
{
|
||||
dict = new Dictionary<string, NSObject>(capacity);
|
||||
keys = new Dictionary<string, NSString>(capacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new empty NSDictionary.
|
||||
/// </summary>
|
||||
public NSDictionary()
|
||||
: this(0)
|
||||
{
|
||||
dict = new Dictionary<string, NSObject>();
|
||||
keys = new Dictionary<string, NSString>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -49,22 +49,34 @@ namespace Claunia.PropertyList
|
||||
/// </summary>
|
||||
/// <returns>The type of the property list</returns>
|
||||
/// <param name="dataBeginning">The very first bytes of data of the property list (minus any whitespace) as a string</param>
|
||||
static int DetermineType(string dataBeginning)
|
||||
static int DetermineTypeExact(ReadOnlySpan<byte> 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user