diff --git a/VisualCard.Calendar/Parsers/VCalendarParser.cs b/VisualCard.Calendar/Parsers/VCalendarParser.cs index f6bc2c3..168c3cf 100644 --- a/VisualCard.Calendar/Parsers/VCalendarParser.cs +++ b/VisualCard.Calendar/Parsers/VCalendarParser.cs @@ -181,7 +181,7 @@ public Parts.Calendar Parse() // Handle the part type, and extract the value string valueType = VcardCommonTools.GetFirstValue(splitArgs, defaultValueType, VcardConstants._valueArgumentSpecifier); - string finalValue = VcardParserTools.ProcessStringValue(value, valueType, calendarVersion.Major == 1 ? ';' : ','); + string finalValue = VcardCommonTools.ProcessStringValue(value, valueType, calendarVersion.Major == 1 ? ';' : ','); // Check for allowed values if (allowedValues.Length != 0) diff --git a/VisualCard/Parsers/VcardCommonTools.cs b/VisualCard/Parsers/VcardCommonTools.cs index af1d4bc..1f412f5 100644 --- a/VisualCard/Parsers/VcardCommonTools.cs +++ b/VisualCard/Parsers/VcardCommonTools.cs @@ -22,7 +22,9 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using VisualCard.Parsers.Arguments; +using VisualCard.Parsers.Recurrence; namespace VisualCard.Parsers { @@ -576,5 +578,95 @@ internal static DateTimeOffset ParsePosixRepresentation(string posixDateRepresen return date; throw new ArgumentException($"Can't parse date {posixDateRepresentation}"); } + + internal static string ProcessStringValue(string value, string valueType, char split = ';') + { + // Now, handle each type individually + string finalValue; + finalValue = Regex.Unescape(value); + foreach (string finalValuePart in finalValue.Split(split)) + { + switch (valueType.ToUpper()) + { + case "URI": + case "URL": + // Check the URI + if (!Uri.TryCreate(finalValue, UriKind.Absolute, out Uri uri)) + throw new InvalidDataException($"URL {finalValue} is invalid"); + finalValue = uri is not null ? uri.ToString() : finalValue; + break; + case "UTC-OFFSET": + // Check the UTC offset + VcardCommonTools.ParseUtcOffset(finalValue); + break; + case "DATE": + // Check the date + if (!VcardCommonTools.TryParsePosixDate(finalValue, out _)) + throw new InvalidDataException($"Date {finalValue} is invalid"); + break; + case "TIME": + // Check the time + if (!VcardCommonTools.TryParsePosixTime(finalValue, out _)) + throw new InvalidDataException($"Time {finalValue} is invalid"); + break; + case "DATE-TIME": + // Check the date and time + if (!VcardCommonTools.TryParsePosixDateTime(finalValue, out _)) + throw new InvalidDataException($"Date and time {finalValue} is invalid"); + break; + case "DATE-AND-OR-TIME": + // Check the date and/or time + if (!VcardCommonTools.TryParsePosixDateTime(finalValue, out _) && + !VcardCommonTools.TryParsePosixTime(finalValue, out _)) + throw new InvalidDataException($"Date and/or time {finalValue} is invalid"); + break; + case "TIMESTAMP": + // Check the timestamp + if (!VcardCommonTools.TryParsePosixTimestamp(finalValue, out _)) + throw new InvalidDataException($"Timestamp {finalValue} is invalid"); + break; + case "BOOLEAN": + // Check the boolean + if (!finalValue.Equals("true", StringComparison.OrdinalIgnoreCase) && + !finalValue.Equals("false", StringComparison.OrdinalIgnoreCase)) + throw new InvalidDataException($"Boolean {finalValue} is invalid"); + break; + case "INTEGER": + // Check the integer + if (!int.TryParse(finalValue, out _)) + throw new InvalidDataException($"Integer {finalValue} is invalid"); + break; + case "FLOAT": + // Check the float + string[] floatParts = finalValuePart.Split(split == ';' ? ',' : ';'); + foreach (var floatPart in floatParts) + if (!double.TryParse(floatPart, out _)) + throw new InvalidDataException($"Float {floatPart} in {finalValue} is invalid"); + break; + case "DURATION": + // Check the duration + VcardCommonTools.GetDurationSpan(finalValue); + break; + case "PERIOD": + // Check the period + VcardCommonTools.GetTimePeriod(finalValue); + break; + case "RECUR": + // Check the recursion rules + try + { + RecurrenceParser.ParseRuleV1(finalValue); + } + catch + { + RecurrenceParser.ParseRuleV2(finalValue); + } + break; + } + } + + // Return the result + return finalValue; + } } } diff --git a/VisualCard/Parsers/VcardParser.cs b/VisualCard/Parsers/VcardParser.cs index 40ae311..3f80e7a 100644 --- a/VisualCard/Parsers/VcardParser.cs +++ b/VisualCard/Parsers/VcardParser.cs @@ -185,7 +185,7 @@ public Card Parse() // Handle the part type string valueType = VcardCommonTools.GetFirstValue(splitArgs, defaultValueType, VcardConstants._valueArgumentSpecifier); - string finalValue = VcardParserTools.ProcessStringValue(value, valueType); + string finalValue = VcardCommonTools.ProcessStringValue(value, valueType); // Check for allowed values if (allowedValues.Length != 0) diff --git a/VisualCard/Parsers/VcardParserTools.cs b/VisualCard/Parsers/VcardParserTools.cs index bb165f1..a67f0dd 100644 --- a/VisualCard/Parsers/VcardParserTools.cs +++ b/VisualCard/Parsers/VcardParserTools.cs @@ -18,12 +18,9 @@ // using System; -using System.IO; using VisualCard.Parts.Enums; using VisualCard.Parts.Implementations; using VisualCard.Parts; -using System.Text.RegularExpressions; -using VisualCard.Parsers.Recurrence; using VisualCard.Parsers.Arguments; namespace VisualCard.Parsers @@ -286,95 +283,5 @@ internal static (PartType type, object enumeration, Type? enumType, Func (PartType.PartsArray, PartsArrayEnum.NonstandardNames, typeof(XNameInfo), XNameInfo.FromStringVcardStatic, "", "", "", [], []), _ => (PartType.PartsArray, PartsArrayEnum.IanaNames, typeof(ExtraInfo), ExtraInfo.FromStringVcardStatic, "", "", "", [], []), }; - - internal static string ProcessStringValue(string value, string valueType, char split = ';') - { - // Now, handle each type individually - string finalValue; - finalValue = Regex.Unescape(value); - foreach (string finalValuePart in finalValue.Split(split)) - { - switch (valueType.ToUpper()) - { - case "URI": - case "URL": - // Check the URI - if (!Uri.TryCreate(finalValue, UriKind.Absolute, out Uri uri)) - throw new InvalidDataException($"URL {finalValue} is invalid"); - finalValue = uri is not null ? uri.ToString() : finalValue; - break; - case "UTC-OFFSET": - // Check the UTC offset - VcardCommonTools.ParseUtcOffset(finalValue); - break; - case "DATE": - // Check the date - if (!VcardCommonTools.TryParsePosixDate(finalValue, out _)) - throw new InvalidDataException($"Date {finalValue} is invalid"); - break; - case "TIME": - // Check the time - if (!VcardCommonTools.TryParsePosixTime(finalValue, out _)) - throw new InvalidDataException($"Time {finalValue} is invalid"); - break; - case "DATE-TIME": - // Check the date and time - if (!VcardCommonTools.TryParsePosixDateTime(finalValue, out _)) - throw new InvalidDataException($"Date and time {finalValue} is invalid"); - break; - case "DATE-AND-OR-TIME": - // Check the date and/or time - if (!VcardCommonTools.TryParsePosixDateTime(finalValue, out _) && - !VcardCommonTools.TryParsePosixTime(finalValue, out _)) - throw new InvalidDataException($"Date and/or time {finalValue} is invalid"); - break; - case "TIMESTAMP": - // Check the timestamp - if (!VcardCommonTools.TryParsePosixTimestamp(finalValue, out _)) - throw new InvalidDataException($"Timestamp {finalValue} is invalid"); - break; - case "BOOLEAN": - // Check the boolean - if (!finalValue.Equals("true", StringComparison.OrdinalIgnoreCase) && - !finalValue.Equals("false", StringComparison.OrdinalIgnoreCase)) - throw new InvalidDataException($"Boolean {finalValue} is invalid"); - break; - case "INTEGER": - // Check the integer - if (!int.TryParse(finalValue, out _)) - throw new InvalidDataException($"Integer {finalValue} is invalid"); - break; - case "FLOAT": - // Check the float - string[] floatParts = finalValuePart.Split(split == ';' ? ',' : ';'); - foreach (var floatPart in floatParts) - if (!double.TryParse(floatPart, out _)) - throw new InvalidDataException($"Float {floatPart} in {finalValue} is invalid"); - break; - case "DURATION": - // Check the duration - VcardCommonTools.GetDurationSpan(finalValue); - break; - case "PERIOD": - // Check the period - VcardCommonTools.GetTimePeriod(finalValue); - break; - case "RECUR": - // Check the recursion rules - try - { - RecurrenceParser.ParseRuleV1(finalValue); - } - catch - { - RecurrenceParser.ParseRuleV2(finalValue); - } - break; - } - } - - // Return the result - return finalValue; - } } }