diff --git a/VisualCard/Parsers/BaseVcardParser.cs b/VisualCard/Parsers/BaseVcardParser.cs
index 62643fd..0bc257a 100644
--- a/VisualCard/Parsers/BaseVcardParser.cs
+++ b/VisualCard/Parsers/BaseVcardParser.cs
@@ -56,13 +56,8 @@ public abstract class BaseVcardParser : IVcardParser
/// A strongly-typed instance holding information about the card
public virtual Card Parse()
{
- // Check the version to ensure that we're really dealing with the correct vCard version
- if (CardVersion != ExpectedCardVersion)
- throw new InvalidDataException($"Card version {CardVersion} doesn't match expected \"2.1\".");
-
- // Check the content to ensure that we really have data
- if (string.IsNullOrEmpty(CardContent))
- throw new InvalidDataException($"Card content is empty.");
+ // Verify the card data
+ VerifyCardData();
// Now, make a stream out of card content
byte[] CardContentData = Encoding.Default.GetBytes(CardContent);
@@ -72,24 +67,6 @@ public virtual Card Parse()
// Make a new vCard
var card = new Card(this);
- // Track the required fields
- List expectedFields = [];
- List actualFields = [];
- switch (CardVersion.ToString(2))
- {
- case "2.1":
- expectedFields.Add(VcardConstants._nameSpecifier);
- break;
- case "4.0":
- expectedFields.Add(VcardConstants._fullNameSpecifier);
- break;
- case "3.0":
- case "5.0":
- expectedFields.Add(VcardConstants._nameSpecifier);
- expectedFields.Add(VcardConstants._fullNameSpecifier);
- break;
- }
-
// Iterate through all the lines
int lineNumber = 0;
while (!CardContentReader.EndOfStream)
@@ -144,7 +121,7 @@ public virtual Card Parse()
// The name (N:Sanders;John;;;)
// ALTID is supported.
- if (StartsWithPrefix(VcardConstants._nameSpecifier) && !actualFields.Contains(VcardConstants._nameSpecifier))
+ if (StartsWithPrefix(VcardConstants._nameSpecifier))
{
// Get the name
var partInfo =
@@ -152,15 +129,11 @@ public virtual Card Parse()
NameInfo.FromStringVcardWithTypeStatic(_value, [.. finalArgs], altId, CardVersion, CardContentReader) :
NameInfo.FromStringVcardStatic(_value, altId, CardVersion, CardContentReader);
card.AddPartToArray(PartsArrayEnum.Names, partInfo);
-
- // Set flag to indicate that the required field is spotted
- if (expectedFields.Contains(VcardConstants._nameSpecifier))
- actualFields.Add(VcardConstants._nameSpecifier);
}
// Full name (FN:John Sanders)
// Here, we don't support ALTID.
- if (StartsWithPrefix(VcardConstants._fullNameSpecifier) && !actualFields.Contains(VcardConstants._fullNameSpecifier))
+ if (StartsWithPrefix(VcardConstants._fullNameSpecifier))
{
// Get the value
string fullNameValue = _value.Substring(VcardConstants._fullNameSpecifier.Length + 1);
@@ -168,10 +141,6 @@ public virtual Card Parse()
// Populate field
card.SetString(StringsEnum.FullName, fullNameValue);
-
- // Set flag to indicate that the required field is spotted
- if (expectedFields.Contains(VcardConstants._fullNameSpecifier))
- actualFields.Add(VcardConstants._fullNameSpecifier);
}
// Telephone (TEL;CELL;HOME:495-522-3560 or TEL;TYPE=cell,home:495-522-3560 or TEL:495-522-3560)
@@ -597,13 +566,8 @@ public virtual Card Parse()
}
}
- // Requirement checks
- actualFields.Sort();
- expectedFields.Sort();
- if (!actualFields.SequenceEqual(expectedFields))
- throw new InvalidDataException($"The following keys [{string.Join(", ", expectedFields)}] are required. Got [{string.Join(", ", actualFields)}].");
-
- // Return this card
+ // Validate this card before returning it.
+ ValidateCard(card);
return card;
}
@@ -829,5 +793,46 @@ partsEnum switch
_ =>
throw new InvalidOperationException("Invalid parts enumeration type"),
};
+
+ internal void ValidateCard(Card card)
+ {
+ // Track the required fields
+ List expectedFields = [];
+ List actualFields = [];
+ switch (CardVersion.ToString(2))
+ {
+ case "2.1":
+ expectedFields.Add(VcardConstants._nameSpecifier);
+ break;
+ case "4.0":
+ expectedFields.Add(VcardConstants._fullNameSpecifier);
+ break;
+ case "3.0":
+ case "5.0":
+ expectedFields.Add(VcardConstants._nameSpecifier);
+ expectedFields.Add(VcardConstants._fullNameSpecifier);
+ break;
+ }
+
+ // Requirement checks
+ if (expectedFields.Contains(VcardConstants._nameSpecifier))
+ {
+ var names = card.GetPartsArray(PartsArrayEnum.Names);
+ bool exists = names is not null && names.Length > 0;
+ if (exists)
+ actualFields.Add(VcardConstants._nameSpecifier);
+ }
+ if (expectedFields.Contains(VcardConstants._fullNameSpecifier))
+ {
+ string fullName = card.GetString(StringsEnum.FullName);
+ bool exists = !string.IsNullOrEmpty(fullName);
+ if (exists)
+ actualFields.Add(VcardConstants._fullNameSpecifier);
+ }
+ expectedFields.Sort();
+ actualFields.Sort();
+ if (!actualFields.SequenceEqual(expectedFields))
+ throw new InvalidDataException($"The following keys [{string.Join(", ", expectedFields)}] are required. Got [{string.Join(", ", actualFields)}].");
+ }
}
}