mirror of
https://github.com/claunia/plist-cil.git
synced 2025-12-16 19:14: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>
|
/// <exception cref="PropertyListFormatException">When the property list's format could not be parsed.</exception>
|
||||||
private NSObject DoParse(ReadOnlySpan<byte> bytes)
|
private NSObject DoParse(ReadOnlySpan<byte> bytes)
|
||||||
{
|
{
|
||||||
string magic = Encoding.ASCII.GetString(
|
if(bytes.Length < 8
|
||||||
#if NATIVE_SPAN
|
|| bytes[0] != 'b'
|
||||||
bytes.Slice(0, 8));
|
|| bytes[1] != 'p'
|
||||||
#else
|
|| bytes[2] != 'l'
|
||||||
bytes.Slice(0, 8).ToArray());
|
|| bytes[3] != 'i'
|
||||||
#endif
|
|| bytes[4] != 's'
|
||||||
|
|| bytes[5] != 't')
|
||||||
if (!magic.StartsWith("bplist", StringComparison.Ordinal))
|
|
||||||
{
|
{
|
||||||
|
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);
|
throw new PropertyListFormatException("The given data is no binary property list. Wrong magic bytes: " + magic);
|
||||||
}
|
}
|
||||||
|
|
||||||
majorVersion = magic[6] - 0x30; //ASCII number
|
majorVersion = bytes[6] - 0x30; //ASCII number
|
||||||
minorVersion = magic[7] - 0x30; //ASCII number
|
minorVersion = bytes[7] - 0x30; //ASCII number
|
||||||
|
|
||||||
// 0.0 - OS X Tiger and earlier
|
// 0.0 - OS X Tiger and earlier
|
||||||
// 0.1 - Leopard
|
// 0.1 - Leopard
|
||||||
@@ -366,7 +366,7 @@ namespace Claunia.PropertyList
|
|||||||
ReadLengthAndOffset(bytes, objInfo, offset, out int length, out int contentOffset);
|
ReadLengthAndOffset(bytes, objInfo, offset, out int length, out int contentOffset);
|
||||||
|
|
||||||
//System.out.println("Parsing dictionary #"+obj);
|
//System.out.println("Parsing dictionary #"+obj);
|
||||||
NSDictionary dict = new NSDictionary();
|
NSDictionary dict = new NSDictionary(length);
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
int keyRef = (int)ParseUnsignedInt(bytes.Slice(offset + contentOffset + i * objectRefSize, objectRefSize));
|
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
|
// object remains constant accross calls to AssignIDs and ToBinary
|
||||||
readonly Dictionary<string, NSString> keys;
|
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>
|
/// <summary>
|
||||||
/// Creates a new empty NSDictionary.
|
/// Creates a new empty NSDictionary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NSDictionary()
|
public NSDictionary()
|
||||||
|
: this(0)
|
||||||
{
|
{
|
||||||
dict = new Dictionary<string, NSObject>();
|
|
||||||
keys = new Dictionary<string, NSString>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -49,22 +49,34 @@ namespace Claunia.PropertyList
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The type of the property list</returns>
|
/// <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>
|
/// <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)
|
if (dataBeginning.Length == 0)
|
||||||
{
|
{
|
||||||
return TYPE_ERROR_BLANK;
|
return TYPE_ERROR_BLANK;
|
||||||
}
|
}
|
||||||
if (dataBeginning.StartsWith("bplist"))
|
else if (dataBeginning[0] == '(' || dataBeginning[0] == '{' || dataBeginning[0] == '/')
|
||||||
{
|
|
||||||
return TYPE_BINARY;
|
|
||||||
}
|
|
||||||
if (dataBeginning.StartsWith("(") || dataBeginning.StartsWith("{") || dataBeginning.StartsWith("/"))
|
|
||||||
{
|
{
|
||||||
return TYPE_ASCII;
|
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>
|
/// <summary>
|
||||||
@@ -90,11 +102,7 @@ namespace Claunia.PropertyList
|
|||||||
}
|
}
|
||||||
|
|
||||||
var header = bytes.Slice(offset, Math.Min(8, bytes.Length - offset));
|
var header = bytes.Slice(offset, Math.Min(8, bytes.Length - offset));
|
||||||
#if NATIVE_SPAN
|
return DetermineTypeExact(header);
|
||||||
return DetermineType(Encoding.ASCII.GetString(header));
|
|
||||||
#else
|
|
||||||
return DetermineType(Encoding.ASCII.GetString(header.ToArray(), 0, header.Length));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -138,7 +146,7 @@ namespace Claunia.PropertyList
|
|||||||
magicBytes[0] = (byte)b;
|
magicBytes[0] = (byte)b;
|
||||||
int read = fs.Read(magicBytes, 1, 7);
|
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);
|
fs.Seek(mark, SeekOrigin.Begin);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user