private CtfPropertyBag GetPropertyBag(string str, int start, int stop) { Debug.Assert(str[start] == '{'); CtfPropertyBag result = new CtfPropertyBag(); foreach (string rawStatement in EnumerateStatements(str, start + 1, stop)) { string statement = StripComments(rawStatement); int i = statement.IndexOf('='); if (i <= 0) { continue; } if (statement[i - 1] == ':') { string name = statement.Substring(0, i - 1).Trim(); int open = statement.IndexOf('{', i + 1); int close = FindCloseBrace(statement, open); if (close > stop || close == -1) { string[] structNameParts = statement.Substring(i + 1).Trim().Split(' '); if (structNameParts.Length != 2 || structNameParts[0] != "struct") { throw new InvalidOperationException(); } CtfUnresolvedType unresolved = new CtfUnresolvedType(structNameParts[1]); result.AddValue(name, unresolved); } else { CtfField[] fields = ParseStructFields(statement, open, close).ToArray(); result.AddValue(name, new CtfStruct(null, fields)); } } else { string name = statement.Substring(0, i).Trim(); string value = statement.Substring(i + 1).Trim(); if (value.Length > 2 && value[0] == '\"' && value[value.Length - 1] == '\"') { value = value.Substring(1, value.Length - 2); } result.AddValue(name, value); } } return(result); }
private CtfMetadataType ParseOneType(string statement, out int index) { CtfMetadataType type = null; Match match; if ((match = s_integer.Match(statement)).Success) { Group group = match.Groups[1]; CtfPropertyBag bag = GetPropertyBag(group.ToString()); type = new CtfInteger(bag); index = group.Index + group.Length; } else if ((match = s_struct.Match(statement)).Success) { var group = match.Groups[1]; if (group.ToString() != "{") { throw new InvalidOperationException(); } int open = group.Index; int close = FindCloseBrace(statement, open); CtfField[] fields = ParseStructFields(statement, open, close).ToArray(); type = new CtfStruct(null, fields); index = close + 1; } else if ((match = s_float.Match(statement)).Success) { int open = match.Index + match.Length - 1; int close = FindCloseBrace(statement, open); CtfPropertyBag bag = GetPropertyBag(statement, open, close); type = new CtfFloat(bag); index = close + 1; } else if ((match = s_variant.Match(statement)).Success) { string switchVariable = match.Groups[1].ToString(); int open = statement.IndexOf('{'); int close = FindCloseBrace(statement, open); if (close == -1) { throw new InvalidOperationException(); } CtfField[] fields = ParseStructFields(statement, open, close).ToArray(); type = new CtfVariant(switchVariable, fields); index = close + 1; } else if ((match = s_variable.Match(statement)).Success) { var typeGroup = match.Groups[1]; string typeName = typeGroup.ToString().Trim(); if (typeName == "string") { type = new CtfString(); } else { type = new CtfUnresolvedType(typeName); } index = typeGroup.Index + typeGroup.Length; } else if ((match = s_enum.Match(statement)).Success) { var groups = match.Groups; string typeName = groups[1].ToString().Trim(); int open = statement.IndexOf('{'); int close = FindCloseBrace(statement, open); if (close == -1) { throw new InvalidOperationException(); } CtfNamedRange[] ranges = ParseNamedRanges(statement, open + 1, close).ToArray(); // TODO: Can enums just be an inline defined integer? type = new CtfEnum(new CtfUnresolvedType(typeName), ranges); index = close + 1; } else { // TODO: Floating point index = 0; return(null); } return(type); }