public static Outcome <Iban> TryParse(string value, IbanStyles styles, IbanValidationLevels levels) { if (value == null) { return(Outcome <Iban> .FromError(Format.Current(Strings.InvalidIbanValue, value))); } string input = PreprocessInput(value, styles); return(from val in IbanParts.TryParse(input) where IbanValidator.TryValidate(val, levels) select new Iban(val, levels)); }
public static Iban?Parse(string value, IbanStyles styles, IbanValidationLevels levels) { if (value == null) { return(null); } var val = PreprocessInput(value, styles); var parts = IbanParts.Parse(val); if (!parts.HasValue) { return(null); } if (!IbanValidator.Validate(parts.Value, levels)) { return(null); } return(new Iban(parts.Value, levels)); }
public static Iban?Parse(string value, IbanStyles styles) => Parse(value, styles, IbanValidationLevels.Default);
// NB: Normally, there is either a single whitespace char every four chars or no whitespace // char at all. Here we are more permissive: multiple whitespaces are ok, and position check // is not enforced. private static string PreprocessInput(string text, IbanStyles styles) { Debug.Assert(text != null); // Fast track. if (styles == IbanStyles.None) { return(text); } if (text.Length == 0) { return(String.Empty); } int len = text.Length; int start = 0; if (styles.Contains(IbanStyles.AllowLeadingWhite)) { // Ignore leading whitespaces. while (start < len) { if (text[start] != WHITESPACE_CHAR) { break; } start++; } } // The input contains only whitespaces. if (start == len) { return(String.Empty); } int end = len - 1; if (styles.Contains(IbanStyles.AllowTrailingWhite)) { // Ignore trailing whitespaces. while (end > start) { if (text[end] != WHITESPACE_CHAR) { break; } end--; } } // removespaces is really remove **inner** spaces. bool removespaces = styles.Contains(IbanStyles.AllowInnerWhite); if (styles.Contains(IbanStyles.AllowHeader) && text.Length >= start + 5 && text.Substring(start, 5) == IbanParts.HumanHeader) { start += 5; if (removespaces) { // Ignore leading whitespaces. // By removing an IBAN prefix, we might have white spaces // again at the beginning of the loop. while (start < len) { if (text[start] != WHITESPACE_CHAR) { break; } start++; } } } bool transformcase = styles.Contains(IbanStyles.AllowLowercaseLetter); // NB: If end - start + 1 < MinLength, the input is clearly invalid, nevertheless // we continue to process the input until we completely fulfill the method's contract: // cleanup the input according to the user provided rules. var output = new char[end - start + 1]; int k = 0; for (var i = start; i <= end; i++) { char ch = text[i]; if (removespaces && i != 0 && i != end && ch == WHITESPACE_CHAR) { continue; } if (transformcase && ch >= 'a' && ch <= 'z') { // NB: We use a known property of the ASCII charset; for instance // 01100001 = 0x61 = 'a' // AND 11011111 = 0xDF = ~0x20 // -------- // 01000001 = 0x41 = 'A' output[k] = (char)(ch & 0xDF); } else { output[k] = ch; } k++; } return(new String(output, 0, k)); }
public static Outcome <Iban> TryParse(string value, IbanStyles styles) => TryParse(value, styles, IbanValidationLevels.Default);
// WARNING: This always returns false for IbanStyles.None. public static bool Contains(this IbanStyles @this, IbanStyles styles) => (@this & styles) != 0;