/// <summary> /// Creates a known property /// </summary> /// <param name="identifier">Identifier of the property</param> /// <param name="parser">Property values parser</param> /// <param name="valueMultiplicity">Multiplicity of the values</param> /// <param name="type">Type of the property</param> public SgfKnownProperty(string identifier, SgfPropertyType type, SgfValueMultiplicity valueMultiplicity = SgfValueMultiplicity.None, SgfPropertyValueParser parser = null) { if (identifier == null) { throw new ArgumentNullException(nameof(identifier)); } if (valueMultiplicity != SgfValueMultiplicity.None && parser == null) { throw new ArgumentNullException(nameof(parser), $"Property value parser cannot be null unless value multiplicity is None (identifier {identifier})"); } Type = type; Identifier = identifier; Parser = parser; ValueMultiplicity = valueMultiplicity; }
/// <summary> /// Parses a compose given the types of both values /// </summary> /// <param name="value">SGF serialized value to parse</param> /// <param name="leftValueParser">Parser of the left value</param> /// <param name="rightValueParser">Parser of the right value</param> /// <returns>Instance of SGF Compose</returns> public static SgfComposePropertyValue <TLeft, TRight> Parse (string value, SgfPropertyValueParser leftValueParser, SgfPropertyValueParser rightValueParser) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (leftValueParser == null) { throw new ArgumentNullException(nameof(leftValueParser)); } if (rightValueParser == null) { throw new ArgumentNullException(nameof(rightValueParser)); } bool escapePreceded = false; int separatorPosition = -1; for (int i = 0; i < value.Length; i++) { var currentCharacter = value[i]; if (currentCharacter == EscapeCharacter) { escapePreceded = !escapePreceded; } else if (currentCharacter == ComposeSeparator) { if (i == 0 || !escapePreceded) { if (separatorPosition != -1) { throw new SgfParseException($"Two or more unescaped colons in Compose value '{value}'"); } separatorPosition = i; } escapePreceded = false; } else { escapePreceded = false; } } if (separatorPosition == -1) { throw new SgfParseException($"No colon found in Compose value '{value}'"); } var leftPart = value.Substring(0, separatorPosition); var rightPart = value.Substring(separatorPosition + 1, value.Length - separatorPosition - 1); var leftValue = leftValueParser(leftPart) as SgfSimplePropertyValueBase <TLeft>; if (leftValue == null) { throw new SgfParseException($"Unexpected result type of the left value parse"); } var rightValue = rightValueParser(rightPart) as SgfSimplePropertyValueBase <TRight>; if (rightValue == null) { throw new SgfParseException($"Unexpected result type of the right value parse"); } return(new SgfComposePropertyValue <TLeft, TRight>(leftValue, rightValue)); }
/// <summary> /// Generates SGF Property Value parser for compose values /// </summary> /// <typeparam name="TLeft">Type of the left value</typeparam> /// <typeparam name="TRight">Type of the right value</typeparam> /// <param name="left">Left value parser</param> /// <param name="right">Right value parser</param> /// <returns></returns> private static SgfPropertyValueParser Compose <TLeft, TRight>(SgfPropertyValueParser left, SgfPropertyValueParser right) { //create a parser function using closure return((value) => SgfComposePropertyValue <TLeft, TRight> .Parse(value, left, right)); }
/// <summary> /// Parses given values using a parser /// </summary> /// <param name="values">Values to parse</param> /// <param name="parser">Parser to use</param> /// <returns>Parsed SGF property values</returns> private static IEnumerable <ISgfPropertyValue> ParseValues(string[] values, SgfPropertyValueParser parser) => values.Select(value => parser(value));