static object ParseWAngle(string fieldName, Type fieldType, string value, MemberInfo field) { if (Exts.TryParseIntegerInvariant(value, out var res)) { return(new WAngle(res)); } return(InvalidValueAction(value, fieldType, fieldName)); }
static object ParseWRot(string fieldName, Type fieldType, string value, MemberInfo field) { if (value != null) { var parts = value.Split(SplitComma); if (parts.Length == 3) { if (Exts.TryParseIntegerInvariant(parts[0], out var rr) && Exts.TryParseIntegerInvariant(parts[1], out var rp) && Exts.TryParseIntegerInvariant(parts[2], out var ry)) { return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry))); } } } return(InvalidValueAction(value, fieldType, fieldName)); }
public static bool TryParse(string s, out WDist result) { result = Zero; if (string.IsNullOrEmpty(s)) { return(false); } s = s.ToLowerInvariant(); var components = s.Split('c'); var cell = 0; var subcell = 0; switch (components.Length) { case 2: if (!Exts.TryParseIntegerInvariant(components[0], out cell) || !Exts.TryParseIntegerInvariant(components[1], out subcell)) { return(false); } break; case 1: if (!Exts.TryParseIntegerInvariant(components[0], out subcell)) { return(false); } break; default: return(false); } // Propagate sign to fractional part if (cell < 0) { subcell = -subcell; } result = new WDist(1024 * cell + subcell); return(true); }
public static object GetValue(string fieldName, Type fieldType, MiniYaml yaml, MemberInfo field) { var value = yaml.Value?.Trim(); if (fieldType == typeof(int)) { if (Exts.TryParseIntegerInvariant(value, out var res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(ushort)) { if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out var res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } if (fieldType == typeof(long)) { if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out var res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float)) { if (value != null && float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var res)) { return(res * (value.Contains('%') ? 0.01f : 1f)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(decimal)) { if (value != null && decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var res)) { return(res * (value.Contains('%') ? 0.01m : 1m)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(string)) { if (field != null && MemberHasTranslateAttribute[field] && value != null) { return(Regex.Replace(value, "@[^@]+@", m => Translate(m.Value.Substring(1, m.Value.Length - 2)), RegexOptions.Compiled)); } return(value); } else if (fieldType == typeof(Color)) { if (value != null && Color.TryParse(value, out var color)) { return(color); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Hotkey)) { if (Hotkey.TryParse(value, out var res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(HotkeyReference)) { return(Game.ModData.Hotkeys[value]); } else if (fieldType == typeof(WDist)) { if (WDist.TryParse(value, out var res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { if (WDist.TryParse(parts[0], out var rx) && WDist.TryParse(parts[1], out var ry) && WDist.TryParse(parts[2], out var rz)) { return(new WVec(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 3 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new WVec[parts.Length / 3]; for (var i = 0; i < vecs.Length; ++i) { if (WDist.TryParse(parts[3 * i], out var rx) && WDist.TryParse(parts[3 * i + 1], out var ry) && WDist.TryParse(parts[3 * i + 2], out var rz)) { vecs[i] = new WVec(rx, ry, rz); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WPos)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { if (WDist.TryParse(parts[0], out var rx) && WDist.TryParse(parts[1], out var ry) && WDist.TryParse(parts[2], out var rz)) { return(new WPos(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WAngle)) { if (Exts.TryParseIntegerInvariant(value, out var res)) { return(new WAngle(res)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WRot)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { if (Exts.TryParseIntegerInvariant(parts[0], out var rr) && Exts.TryParseIntegerInvariant(parts[1], out var rp) && Exts.TryParseIntegerInvariant(parts[2], out var ry)) { return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry))); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CPos)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CPos(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CVec(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 2 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new CVec[parts.Length / 2]; for (var i = 0; i < vecs.Length; i++) { if (int.TryParse(parts[2 * i], out var rx) && int.TryParse(parts[2 * i + 1], out var ry)) { vecs[i] = new CVec(rx, ry); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(BooleanExpression)) { if (value != null) { try { return(BooleanExpressionCache[value]); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(IntegerExpression)) { if (value != null) { try { return(IntegerExpressionCache[value]); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsEnum) { try { return(Enum.Parse(fieldType, value, true)); } catch (ArgumentException) { return(InvalidValueAction(value, fieldType, fieldName)); } } else if (fieldType == typeof(bool)) { if (bool.TryParse(value.ToLowerInvariant(), out var result)) { return(result); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(int2[])) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length % 2 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var ints = new int2[parts.Length / 2]; for (var i = 0; i < ints.Length; i++) { ints[i] = new int2(Exts.ParseIntegerInvariant(parts[2 * i]), Exts.ParseIntegerInvariant(parts[2 * i + 1])); } return(ints); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsArray && fieldType.GetArrayRank() == 1) { if (value == null) { return(Array.CreateInstance(fieldType.GetElementType(), 0)); } var options = field != null && field.HasAttribute <AllowEmptyEntriesAttribute>() ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries; var parts = value.Split(new char[] { ',' }, options); var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length); for (var i = 0; i < parts.Length; i++) { ret.SetValue(GetValue(fieldName, fieldType.GetElementType(), parts[i].Trim(), field), i); } return(ret); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(HashSet <>)) { var set = Activator.CreateInstance(fieldType); if (value == null) { return(set); } var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var addMethod = fieldType.GetMethod("Add", fieldType.GetGenericArguments()); for (var i = 0; i < parts.Length; i++) { addMethod.Invoke(set, new[] { GetValue(fieldName, fieldType.GetGenericArguments()[0], parts[i].Trim(), field) }); } return(set); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var dict = Activator.CreateInstance(fieldType); var arguments = fieldType.GetGenericArguments(); var addMethod = fieldType.GetMethod("Add", arguments); foreach (var node in yaml.Nodes) { var key = GetValue(fieldName, arguments[0], node.Key, field); var val = GetValue(fieldName, arguments[1], node.Value, field); addMethod.Invoke(dict, new[] { key, val }); } return(dict); } else if (fieldType == typeof(Size)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Size(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(int2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 2) { return(InvalidValueAction(value, fieldType, fieldName)); } return(new int2(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float xx = 0; float yy = 0; if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var res)) { xx = res * (parts[0].Contains('%') ? 0.01f : 1f); } if (float.TryParse(parts[1].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { yy = res * (parts[1].Contains('%') ? 0.01f : 1f); } return(new float2(xx, yy)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float3)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var x); float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out var y); // z component is optional for compatibility with older float2 definitions float z = 0; if (parts.Length > 2) { float.TryParse(parts[2], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out z); } return(new float3(x, y, z)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Rectangle)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Rectangle( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]), Exts.ParseIntegerInvariant(parts[2]), Exts.ParseIntegerInvariant(parts[3]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(BitSet <>)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var ctor = fieldType.GetConstructor(new[] { typeof(string[]) }); return(ctor.Invoke(new object[] { parts.Select(p => p.Trim()).ToArray() })); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>)) { if (string.IsNullOrEmpty(value)) { return(null); } var innerType = fieldType.GetGenericArguments().First(); var innerValue = GetValue("Nullable<T>", innerType, value, field); return(fieldType.GetConstructor(new[] { innerType }).Invoke(new[] { innerValue })); } else if (fieldType == typeof(DateTime)) { if (DateTime.TryParseExact(value, "yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var dt)) { return(dt); } return(InvalidValueAction(value, fieldType, fieldName)); } else { var conv = TypeDescriptor.GetConverter(fieldType); if (conv.CanConvertFrom(typeof(string))) { try { return(conv.ConvertFromInvariantString(value)); } catch { return(InvalidValueAction(value, fieldType, fieldName)); } } } UnknownFieldAction("[Type] {0}".F(value), fieldType); return(null); }
public static object GetValue(string fieldName, Type fieldType, MiniYaml yaml, MemberInfo field) { var value = yaml.Value; if (value != null) { value = value.Trim(); } if (fieldType == typeof(int)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(ushort)) { ushort res; if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } if (fieldType == typeof(long)) { long res; if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float)) { float res; if (value != null && float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01f : 1f)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(decimal)) { decimal res; if (value != null && decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01m : 1m)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(string)) { if (field != null && MemberHasTranslateAttribute[field] && value != null) { return(Regex.Replace(value, "@[^@]+@", m => Translate(m.Value.Substring(1, m.Value.Length - 2)), RegexOptions.Compiled)); } return(value); } else if (fieldType == typeof(Color)) { Color color; if (value != null && HSLColor.TryParseRGB(value, out color)) { return(color); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Color[])) { if (value != null) { var parts = value.Split(','); var colors = new Color[parts.Length]; for (var i = 0; i < colors.Length; i++) { if (!HSLColor.TryParseRGB(parts[i], out colors[i])) { return(InvalidValueAction(value, fieldType, fieldName)); } } return(colors); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(HSLColor)) { if (value != null) { Color rgb; if (HSLColor.TryParseRGB(value, out rgb)) { return(new HSLColor(rgb)); } // Allow old HSLColor/ColorRamp formats to be parsed as HSLColor var parts = value.Split(','); if (parts.Length == 3 || parts.Length == 4) { return(new HSLColor( (byte)Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255))); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Hotkey)) { Hotkey res; if (Hotkey.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WDist)) { WDist res; if (WDist.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { WDist rx, ry, rz; if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz)) { return(new WVec(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 3 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new WVec[parts.Length / 3]; for (var i = 0; i < vecs.Length; ++i) { WDist rx, ry, rz; if (WDist.TryParse(parts[3 * i], out rx) && WDist.TryParse(parts[3 * i + 1], out ry) && WDist.TryParse(parts[3 * i + 2], out rz)) { vecs[i] = new WVec(rx, ry, rz); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WPos)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { WDist rx, ry, rz; if (WDist.TryParse(parts[0], out rx) && WDist.TryParse(parts[1], out ry) && WDist.TryParse(parts[2], out rz)) { return(new WPos(rx, ry, rz)); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WAngle)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(new WAngle(res)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WRot)) { if (value != null) { var parts = value.Split(','); if (parts.Length == 3) { int rr, rp, ry; if (Exts.TryParseIntegerInvariant(parts[0], out rr) && Exts.TryParseIntegerInvariant(parts[1], out rp) && Exts.TryParseIntegerInvariant(parts[2], out ry)) { return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry))); } } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CPos)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CPos(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CVec(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CVec[])) { if (value != null) { var parts = value.Split(','); if (parts.Length % 2 != 0) { return(InvalidValueAction(value, fieldType, fieldName)); } var vecs = new CVec[parts.Length / 2]; for (var i = 0; i < vecs.Length; i++) { int rx, ry; if (int.TryParse(parts[2 * i], out rx) && int.TryParse(parts[2 * i + 1], out ry)) { vecs[i] = new CVec(rx, ry); } } return(vecs); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(BooleanExpression)) { if (value != null) { try { return(new BooleanExpression(value)); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(IntegerExpression)) { if (value != null) { try { return(new IntegerExpression(value)); } catch (InvalidDataException e) { throw new YamlException(e.Message); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsEnum) { try { return(Enum.Parse(fieldType, value, true)); } catch (ArgumentException) { return(InvalidValueAction(value, fieldType, fieldName)); } } else if (fieldType == typeof(ImageFormat)) { if (value != null) { switch (value.ToLowerInvariant()) { case "bmp": return(ImageFormat.Bmp); case "gif": return(ImageFormat.Gif); case "jpg": case "jpeg": return(ImageFormat.Jpeg); case "tif": case "tiff": return(ImageFormat.Tiff); default: return(ImageFormat.Png); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(bool)) { return(ParseYesNo(value, fieldType, fieldName)); } else if (fieldType.IsArray && fieldType.GetArrayRank() == 1) { if (value == null) { return(Array.CreateInstance(fieldType.GetElementType(), 0)); } var options = field != null && field.HasAttribute <AllowEmptyEntriesAttribute>() ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries; var parts = value.Split(new char[] { ',' }, options); var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length); for (var i = 0; i < parts.Length; i++) { ret.SetValue(GetValue(fieldName, fieldType.GetElementType(), parts[i].Trim(), field), i); } return(ret); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(HashSet <>)) { var set = Activator.CreateInstance(fieldType); if (value == null) { return(set); } var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var addMethod = fieldType.GetMethod("Add", fieldType.GetGenericArguments()); for (var i = 0; i < parts.Length; i++) { addMethod.Invoke(set, new[] { GetValue(fieldName, fieldType.GetGenericArguments()[0], parts[i].Trim(), field) }); } return(set); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var dict = Activator.CreateInstance(fieldType); var arguments = fieldType.GetGenericArguments(); var addMethod = fieldType.GetMethod("Add", arguments); foreach (var node in yaml.Nodes) { var key = GetValue(fieldName, arguments[0], node.Key, field); var val = GetValue(fieldName, arguments[1], node.Value, field); addMethod.Invoke(dict, new[] { key, val }); } return(dict); } else if (fieldType == typeof(Size)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Size(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(int2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new int2(Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float2)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float xx = 0; float yy = 0; float res; if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { xx = res * (parts[0].Contains('%') ? 0.01f : 1f); } if (float.TryParse(parts[1].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { yy = res * (parts[1].Contains('%') ? 0.01f : 1f); } return(new float2(xx, yy)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float3)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float x = 0; float y = 0; float z = 0; float.TryParse(parts[0], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out x); float.TryParse(parts[1], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out y); // z component is optional for compatibility with older float2 definitions if (parts.Length > 2) { float.TryParse(parts[2], NumberStyles.Float, NumberFormatInfo.InvariantInfo, out z); } return(new float3(x, y, z)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Rectangle)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Rectangle( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]), Exts.ParseIntegerInvariant(parts[2]), Exts.ParseIntegerInvariant(parts[3]))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bits <>)) { if (value != null) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var argTypes = new Type[] { typeof(string[]) }; var argValues = new object[] { parts }; return(fieldType.GetConstructor(argTypes).Invoke(argValues)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>)) { var innerType = fieldType.GetGenericArguments().First(); var innerValue = GetValue("Nullable<T>", innerType, value, field); return(fieldType.GetConstructor(new[] { innerType }).Invoke(new[] { innerValue })); } else if (fieldType == typeof(DateTime)) { DateTime dt; if (DateTime.TryParseExact(value, "yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt)) { return(dt); } return(InvalidValueAction(value, fieldType, fieldName)); } else { var conv = TypeDescriptor.GetConverter(fieldType); if (conv.CanConvertFrom(typeof(string))) { try { return(conv.ConvertFromInvariantString(value)); } catch { return(InvalidValueAction(value, fieldType, fieldName)); } } } UnknownFieldAction("[Type] {0}".F(value), fieldType); return(null); }
public static object GetValue(string fieldName, Type fieldType, string value, MemberInfo field) { if (value != null) { value = value.Trim(); } if (fieldType == typeof(int)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(ushort)) { ushort res; if (ushort.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } if (fieldType == typeof(long)) { long res; if (long.TryParse(value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(float)) { float res; if (float.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01f : 1f)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(decimal)) { decimal res; if (decimal.TryParse(value.Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { return(res * (value.Contains('%') ? 0.01m : 1m)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(string)) { if (field != null && field.HasAttribute <TranslateAttribute>()) { return(Regex.Replace(value, "@[^@]+@", m => Translate(m.Value.Substring(1, m.Value.Length - 2)), RegexOptions.Compiled)); } return(value); } else if (fieldType == typeof(Color)) { var parts = value.Split(','); if (parts.Length == 3) { return(Color.FromArgb( Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255), Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255), Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255))); } if (parts.Length == 4) { return(Color.FromArgb( Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255), Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255), Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255), Exts.ParseIntegerInvariant(parts[3]).Clamp(0, 255))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(HSLColor)) { var parts = value.Split(','); // Allow old ColorRamp format to be parsed as HSLColor if (parts.Length == 3 || parts.Length == 4) { return(new HSLColor( (byte)Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255), (byte)Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255))); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(Hotkey)) { Hotkey res; if (Hotkey.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WRange)) { WRange res; if (WRange.TryParse(value, out res)) { return(res); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WVec)) { var parts = value.Split(','); if (parts.Length == 3) { WRange rx, ry, rz; if (WRange.TryParse(parts[0], out rx) && WRange.TryParse(parts[1], out ry) && WRange.TryParse(parts[2], out rz)) { return(new WVec(rx, ry, rz)); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WPos)) { var parts = value.Split(','); if (parts.Length == 3) { WRange rx, ry, rz; if (WRange.TryParse(parts[0], out rx) && WRange.TryParse(parts[1], out ry) && WRange.TryParse(parts[2], out rz)) { return(new WPos(rx, ry, rz)); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WAngle)) { int res; if (Exts.TryParseIntegerInvariant(value, out res)) { return(new WAngle(res)); } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(WRot)) { var parts = value.Split(','); if (parts.Length == 3) { int rr, rp, ry; if (Exts.TryParseIntegerInvariant(value, out rr) && Exts.TryParseIntegerInvariant(value, out rp) && Exts.TryParseIntegerInvariant(value, out ry)) { return(new WRot(new WAngle(rr), new WAngle(rp), new WAngle(ry))); } } return(InvalidValueAction(value, fieldType, fieldName)); } else if (fieldType == typeof(CPos)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CPos( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } else if (fieldType == typeof(CVec)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new CVec( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } else if (fieldType.IsEnum) { try { return(Enum.Parse(fieldType, value, true)); } catch (ArgumentException) { return(InvalidValueAction(value, fieldType, fieldName)); } } else if (fieldType == typeof(bool)) { return(ParseYesNo(value, fieldType, fieldName)); } else if (fieldType.IsArray) { if (value == null) { return(Array.CreateInstance(fieldType.GetElementType(), 0)); } var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length); for (int i = 0; i < parts.Length; i++) { ret.SetValue(GetValue(fieldName, fieldType.GetElementType(), parts[i].Trim(), field), i); } return(ret); } else if (fieldType == typeof(Size)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Size( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } else if (fieldType == typeof(int2)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new int2( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]))); } else if (fieldType == typeof(float2)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); float xx = 0; float yy = 0; float res; if (float.TryParse(parts[0].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { xx = res * (parts[0].Contains('%') ? 0.01f : 1f); } if (float.TryParse(parts[1].Replace("%", ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out res)) { yy = res * (parts[1].Contains('%') ? 0.01f : 1f); } return(new float2(xx, yy)); } else if (fieldType == typeof(Rectangle)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(new Rectangle( Exts.ParseIntegerInvariant(parts[0]), Exts.ParseIntegerInvariant(parts[1]), Exts.ParseIntegerInvariant(parts[2]), Exts.ParseIntegerInvariant(parts[3]))); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Bits <>)) { var parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var argTypes = new Type[] { typeof(string[]) }; var argValues = new object[] { parts }; return(fieldType.GetConstructor(argTypes).Invoke(argValues)); } else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>)) { var innerType = fieldType.GetGenericArguments().First(); var innerValue = GetValue("Nullable<T>", innerType, value, field); return(fieldType.GetConstructor(new[] { innerType }).Invoke(new[] { innerValue })); } else if (fieldType == typeof(DateTime)) { DateTime dt; if (DateTime.TryParseExact(value, "yyyy-MM-dd HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt)) { return(dt); } return(InvalidValueAction(value, fieldType, fieldName)); } UnknownFieldAction("[Type] {0}".F(value), fieldType); return(null); }