From 496f574e1e92165146d10f4225ea37358303c580 Mon Sep 17 00:00:00 2001 From: Henri Hein Date: Sun, 1 Dec 2024 18:56:35 -0800 Subject: [PATCH 1/2] QuotedPrintable support, including handling multi-line values. --- VisualCard.sln | 8 ++++++- VisualCard/CardTools.cs | 8 +++++++ VisualCard/Parsers/Arguments/PropertyInfo.cs | 25 +++++++++++++++++++- VisualCard/Parsers/VcardConstants.cs | 3 +++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/VisualCard.sln b/VisualCard.sln index 2bec0af0..df3accc2 100644 --- a/VisualCard.sln +++ b/VisualCard.sln @@ -25,7 +25,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Public", "Public", "{F07A71 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualCard.ShowCalendars", "VisualCard.ShowCalendars\VisualCard.ShowCalendars.csproj", "{80A3B32A-F96E-4E87-837F-94E6EB188547}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualCard.Extras", "VisualCard.Extras\VisualCard.Extras.csproj", "{A06611BC-20E0-4990-B907-83C2979E5AE8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualCard.Extras", "VisualCard.Extras\VisualCard.Extras.csproj", "{A06611BC-20E0-4990-B907-83C2979E5AE8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualCardTester", "VisualCardTester\VisualCardTester.csproj", "{D38D9034-43C2-4584-97AE-D19B8F558F39}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -57,6 +59,10 @@ Global {A06611BC-20E0-4990-B907-83C2979E5AE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {A06611BC-20E0-4990-B907-83C2979E5AE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {A06611BC-20E0-4990-B907-83C2979E5AE8}.Release|Any CPU.Build.0 = Release|Any CPU + {D38D9034-43C2-4584-97AE-D19B8F558F39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D38D9034-43C2-4584-97AE-D19B8F558F39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D38D9034-43C2-4584-97AE-D19B8F558F39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D38D9034-43C2-4584-97AE-D19B8F558F39}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VisualCard/CardTools.cs b/VisualCard/CardTools.cs index 44224a9d..5f673f37 100644 --- a/VisualCard/CardTools.cs +++ b/VisualCard/CardTools.cs @@ -103,6 +103,14 @@ public static Card[] GetCards(StreamReader stream) var prop = new PropertyInfo(CardLine); prefix = prop.Prefix; value = prop.Value; + while (prop.Continue) + { + string nextLine = stream.ReadLine(); + + prop.AddLine(nextLine); + //Add it to the current line for later processing + CardLine += nextLine; + } } catch { diff --git a/VisualCard/Parsers/Arguments/PropertyInfo.cs b/VisualCard/Parsers/Arguments/PropertyInfo.cs index 1549a219..3d14d486 100644 --- a/VisualCard/Parsers/Arguments/PropertyInfo.cs +++ b/VisualCard/Parsers/Arguments/PropertyInfo.cs @@ -33,6 +33,7 @@ namespace VisualCard.Parsers.Arguments public class PropertyInfo : IEquatable { private readonly string rawValue = ""; + private string tailValue = ""; private readonly string prefix = ""; private readonly string group = ""; private readonly ArgumentInfo[] arguments = []; @@ -41,7 +42,7 @@ public class PropertyInfo : IEquatable /// Raw value /// public string Value => - rawValue; + rawValue + tailValue; /// /// Property prefix @@ -67,6 +68,11 @@ public class PropertyInfo : IEquatable public ArgumentInfo[] Arguments => arguments; + /// + /// Specifies if this property spans multiple lines + /// + public bool Multiline { get; set; } + /// /// Checks to see if both the property info instances are equal /// @@ -117,6 +123,19 @@ public override int GetHashCode() public static bool operator !=(PropertyInfo? left, PropertyInfo? right) => !(left == right); + internal static string Encoding(ArgumentInfo[] args) + => VcardCommonTools.GetValuesString(args, "", VcardConstants._encodingArgumentSpecifier); + + /// + public bool Continue + => Multiline ? (0 < Value?.Length ? '=' == Value[Value.Length - 1] : false) : false; + + /// + public void AddLine(string line) + { + tailValue += line; + } + internal PropertyInfo(string line) { // Now, parse this value @@ -142,6 +161,10 @@ internal PropertyInfo(string line) this.rawValue = value; this.prefix = prefix; this.arguments = finalArgs; + if (VcardConstants._quotedPrintable == Encoding(this.arguments)) + Multiline = true; + else + Multiline = false; this.group = group.Trim(); } } diff --git a/VisualCard/Parsers/VcardConstants.cs b/VisualCard/Parsers/VcardConstants.cs index 59915a1b..55e13867 100644 --- a/VisualCard/Parsers/VcardConstants.cs +++ b/VisualCard/Parsers/VcardConstants.cs @@ -35,6 +35,9 @@ internal static class VcardConstants internal const string _spaceBreak = " "; internal const string _tabBreak = "\x0009"; + //Encodings + internal const string _quotedPrintable = "QUOTED-PRINTABLE"; + // Available in vCard 2.1, 3.0, 4.0, and 5.0 internal const char _fieldDelimiter = ';'; internal const char _valueDelimiter = ','; From f18a61b87311bf0012071a7d030635103138a460 Mon Sep 17 00:00:00 2001 From: Henri Hein Date: Mon, 23 Dec 2024 21:47:48 -0800 Subject: [PATCH 2/2] Revert unneeded changes to solution file. --- VisualCard.sln | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/VisualCard.sln b/VisualCard.sln index df3accc2..2bec0af0 100644 --- a/VisualCard.sln +++ b/VisualCard.sln @@ -25,9 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Public", "Public", "{F07A71 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualCard.ShowCalendars", "VisualCard.ShowCalendars\VisualCard.ShowCalendars.csproj", "{80A3B32A-F96E-4E87-837F-94E6EB188547}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisualCard.Extras", "VisualCard.Extras\VisualCard.Extras.csproj", "{A06611BC-20E0-4990-B907-83C2979E5AE8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualCardTester", "VisualCardTester\VisualCardTester.csproj", "{D38D9034-43C2-4584-97AE-D19B8F558F39}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualCard.Extras", "VisualCard.Extras\VisualCard.Extras.csproj", "{A06611BC-20E0-4990-B907-83C2979E5AE8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -59,10 +57,6 @@ Global {A06611BC-20E0-4990-B907-83C2979E5AE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {A06611BC-20E0-4990-B907-83C2979E5AE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {A06611BC-20E0-4990-B907-83C2979E5AE8}.Release|Any CPU.Build.0 = Release|Any CPU - {D38D9034-43C2-4584-97AE-D19B8F558F39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D38D9034-43C2-4584-97AE-D19B8F558F39}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D38D9034-43C2-4584-97AE-D19B8F558F39}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D38D9034-43C2-4584-97AE-D19B8F558F39}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE