Add call to preprocessors in the plist parsers

This commit is contained in:
Johann Studanski
2025-01-21 19:58:45 +01:00
parent e4a29b7e2a
commit 9e53befd46
7 changed files with 36 additions and 29 deletions

View File

@@ -409,15 +409,15 @@ namespace Claunia.PropertyList
quotedString[4] == DATE_DATE_FIELD_DELIMITER) quotedString[4] == DATE_DATE_FIELD_DELIMITER)
try try
{ {
return new NSDate(quotedString); return new NSDate(ValuePreprocessor.Preprocess(quotedString, ValuePreprocessor.Types.DATE));
} }
catch(Exception) catch(Exception)
{ {
//not a date? --> return string //not a date? --> return string
return new NSString(quotedString); return new NSString(ValuePreprocessor.Preprocess(quotedString, ValuePreprocessor.Types.STRING));
} }
return new NSString(quotedString); return new NSString(ValuePreprocessor.Preprocess(quotedString, ValuePreprocessor.Types.STRING));
} }
default: default:
{ {
@@ -429,7 +429,7 @@ namespace Claunia.PropertyList
//non-numerical -> string or boolean //non-numerical -> string or boolean
string parsedString = ParseString(); string parsedString = ParseString();
return new NSString(parsedString); return new NSString(ValuePreprocessor.Preprocess(parsedString, ValuePreprocessor.Types.STRING));
} }
} }
} }
@@ -529,9 +529,9 @@ namespace Claunia.PropertyList
Expect(DATA_GSBOOL_TRUE_TOKEN, DATA_GSBOOL_FALSE_TOKEN); Expect(DATA_GSBOOL_TRUE_TOKEN, DATA_GSBOOL_FALSE_TOKEN);
if(Accept(DATA_GSBOOL_TRUE_TOKEN)) if(Accept(DATA_GSBOOL_TRUE_TOKEN))
obj = new NSNumber(true); obj = new NSNumber(ValuePreprocessor.Preprocess(true, ValuePreprocessor.Types.BOOL));
else else
obj = new NSNumber(false); obj = new NSNumber(ValuePreprocessor.Preprocess(false, ValuePreprocessor.Types.BOOL));
//Skip the parsed boolean token //Skip the parsed boolean token
Skip(); Skip();
@@ -541,14 +541,14 @@ namespace Claunia.PropertyList
//Date //Date
Skip(); Skip();
string dateString = ReadInputUntil(DATA_END_TOKEN); string dateString = ReadInputUntil(DATA_END_TOKEN);
obj = new NSDate(dateString); obj = new NSDate(ValuePreprocessor.Preprocess(dateString, ValuePreprocessor.Types.DATE));
} }
else if(Accept(DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN)) else if(Accept(DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN))
{ {
//Number //Number
Skip(); Skip();
string numberString = ReadInputUntil(DATA_END_TOKEN); string numberString = ReadInputUntil(DATA_END_TOKEN);
obj = new NSNumber(numberString); obj = new NSNumber(ValuePreprocessor.Preprocess(numberString, ValuePreprocessor.Types.UNDEFINED_NUMBER));
} }
//parse data end token //parse data end token
@@ -569,7 +569,7 @@ namespace Claunia.PropertyList
bytes[i] = (byte)byteValue; bytes[i] = (byte)byteValue;
} }
obj = new NSData(bytes); obj = new NSData(ValuePreprocessor.Preprocess(bytes, ValuePreprocessor.Types.DATA));
//skip end token //skip end token
Skip(); Skip();
@@ -586,18 +586,18 @@ namespace Claunia.PropertyList
if(numericalString.Length <= 4 || if(numericalString.Length <= 4 ||
numericalString[4] != DATE_DATE_FIELD_DELIMITER) numericalString[4] != DATE_DATE_FIELD_DELIMITER)
return new NSString(numericalString); return new NSString(ValuePreprocessor.Preprocess(numericalString, ValuePreprocessor.Types.STRING));
try try
{ {
return new NSDate(numericalString); return new NSDate(ValuePreprocessor.Preprocess(numericalString, ValuePreprocessor.Types.DATE));
} }
catch(Exception) catch(Exception)
{ {
//An exception occurs if the string is not a date but just a string //An exception occurs if the string is not a date but just a string
} }
return new NSString(numericalString); return new NSString(ValuePreprocessor.Preprocess(numericalString, ValuePreprocessor.Types.STRING));
} }
/// <summary> /// <summary>

View File

@@ -204,12 +204,12 @@ namespace Claunia.PropertyList
case 0x8: case 0x8:
{ {
//false //false
return new NSNumber(false); return new NSNumber(ValuePreprocessor.Preprocess(false, ValuePreprocessor.Types.BOOL));
} }
case 0x9: case 0x9:
{ {
//true //true
return new NSNumber(true); return new NSNumber(ValuePreprocessor.Preprocess(true, ValuePreprocessor.Types.BOOL));
} }
case 0xC: case 0xC:
{ {
@@ -267,7 +267,7 @@ namespace Claunia.PropertyList
//Data //Data
ReadLengthAndOffset(bytes, objInfo, offset, out int length, out int dataoffset); ReadLengthAndOffset(bytes, objInfo, offset, out int length, out int dataoffset);
return new NSData(CopyOfRange(bytes, offset + dataoffset, offset + dataoffset + length)); return new NSData(ValuePreprocessor.Preprocess(CopyOfRange(bytes, offset + dataoffset, offset + dataoffset + length), ValuePreprocessor.Types.DATA));
} }
case 0x5: case 0x5:
{ {

View File

@@ -52,7 +52,7 @@ namespace Claunia.PropertyList
public NSDate(ReadOnlySpan<byte> bytes) => public NSDate(ReadOnlySpan<byte> bytes) =>
//dates are 8 byte big-endian double, seconds since the epoch //dates are 8 byte big-endian double, seconds since the epoch
Date = EPOCH.AddSeconds(BinaryPropertyListParser.ParseDouble(bytes)); Date = EPOCH.AddSeconds(ValuePreprocessor.Preprocess(BinaryPropertyListParser.ParseDouble(bytes), ValuePreprocessor.Types.DATE));
/// <summary> /// <summary>
/// Parses a date from its textual representation. That representation has the following pattern: /// Parses a date from its textual representation. That representation has the following pattern:

View File

@@ -69,13 +69,13 @@ namespace Claunia.PropertyList
switch(type) switch(type)
{ {
case INTEGER: case INTEGER:
doubleValue = longValue = BinaryPropertyListParser.ParseLong(bytes); doubleValue = longValue = ValuePreprocessor.Preprocess(BinaryPropertyListParser.ParseLong(bytes), ValuePreprocessor.Types.INTEGER);
break; break;
case REAL: case REAL:
doubleValue = BinaryPropertyListParser.ParseDouble(bytes); doubleValue = ValuePreprocessor.Preprocess(BinaryPropertyListParser.ParseDouble(bytes), ValuePreprocessor.Types.FLOATING_POINT);
longValue = (long)Math.Round(doubleValue); longValue = ValuePreprocessor.Preprocess((long)Math.Round(doubleValue), ValuePreprocessor.Types.INTEGER);
break; break;

View File

@@ -48,9 +48,9 @@ namespace Claunia.PropertyList
public NSString(ReadOnlySpan<byte> bytes, Encoding encoding) public NSString(ReadOnlySpan<byte> bytes, Encoding encoding)
{ {
#if NATIVE_SPAN #if NATIVE_SPAN
Content = encoding.GetString(bytes); Content = ValuePreprocessor.Preprocess(encoding.GetString(bytes), ValuePreprocessor.Types.STRING);
#else #else
Content = encoding.GetString(bytes.ToArray()); Content = ValuePreprocessor.Preprocess(encoding.GetString(bytes.ToArray()), ValuePreprocessor.Types.STRING);
#endif #endif
} }

View File

@@ -1,4 +1,4 @@
// plist-cil - An open source library to parse and generate property lists for .NET // plist-cil - An open source library to parse and generate property lists for .NET
// Copyright (C) 2015 Natalia Portillo // Copyright (C) 2015 Natalia Portillo
// //
// This code is based on: // This code is based on:
@@ -147,6 +147,12 @@ namespace Claunia.PropertyList
return type; return type;
} }
/// <summary>Register preprocessing functions for for plist values.</summary>
/// <param name="preprocessor">A function that preprocesses the passed string and returns the adjusted value.</param>
/// <param name="type">The type of value preprocessor to use.</param>
public static void RegisterValuePreprocessor<T>(Func<T, T> preprocessor, ValuePreprocessor.Types type) =>
ValuePreprocessor.Register(preprocessor, type);
/// <summary>Reads all bytes from an Stream and stores them in an array, up to a maximum count.</summary> /// <summary>Reads all bytes from an Stream and stores them in an array, up to a maximum count.</summary>
/// <param name="fs">The Stream pointing to the data that should be stored in the array.</param> /// <param name="fs">The Stream pointing to the data that should be stored in the array.</param>
internal static byte[] ReadAll(Stream fs) internal static byte[] ReadAll(Stream fs)

View File

@@ -23,6 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -173,13 +174,13 @@ namespace Claunia.PropertyList
return array; return array;
} }
case "true": return new NSNumber(true); case "true": return new NSNumber(ValuePreprocessor.Preprocess(true, ValuePreprocessor.Types.BOOL));
case "false": return new NSNumber(false); case "false": return new NSNumber(ValuePreprocessor.Preprocess(false, ValuePreprocessor.Types.BOOL));
case "integer": return new NSNumber(GetNodeTextContents(n), NSNumber.INTEGER); case "integer": return new NSNumber(ValuePreprocessor.Preprocess(GetNodeTextContents(n), ValuePreprocessor.Types.INTEGER));
case "real": return new NSNumber(GetNodeTextContents(n), NSNumber.REAL); case "real": return new NSNumber(ValuePreprocessor.Preprocess(GetNodeTextContents(n), ValuePreprocessor.Types.FLOATING_POINT));
case "string": return new NSString(GetNodeTextContents(n)); case "string": return new NSString(ValuePreprocessor.Preprocess(GetNodeTextContents(n), ValuePreprocessor.Types.STRING));
case "data": return new NSData(GetNodeTextContents(n)); case "data": return new NSData(ValuePreprocessor.Preprocess(GetNodeTextContents(n), ValuePreprocessor.Types.DATA));
default: return n.Name.Equals("date") ? new NSDate(GetNodeTextContents(n)) : null; default: return n.Name.Equals("date") ? new NSDate(ValuePreprocessor.Preprocess(GetNodeTextContents(n), ValuePreprocessor.Types.DATE)) : null;
} }
} }