public PresetDB(string block_name, Constant array_length, XmlDocument doc = null) { has_remanence_attr = true; if (doc == null) { doc = new XmlDocument(); doc.LoadXml(Resources.InitialPresetDB); } this.doc = doc; static_section = (XmlElement)doc.SelectSingleNode("/Document/SW.Blocks.GlobalDB/AttributeList/Interface/if:Sections/if:Section[@Name='Static']", nsmgr); if (static_section == null) { throw new Exception("No section named 'Static' in XML"); } ARRAY array_type = new ARRAY(); array_type.Limits.Add(new ArrayLimits(new IntegerLiteral(1), array_length)); array_type.MemberType = new STRUCT(); int[] preset_index = new int[1] { 1 }; PathComponent preset_member = new MemberComponent("Preset", array_type); preset_prefix = new IndexComponent(preset_index, array_type.MemberType, preset_member); PathComponent enable_member = new MemberComponent("Enable", array_type); enable_prefix = new IndexComponent(preset_index, array_type.MemberType, enable_member); enable_selected_prefix = new MemberComponent("EnableSelected", new STRUCT()); preset_selected_prefix = new MemberComponent("PresetSelected", new STRUCT()); XmlElement name_elem = (XmlElement)doc.SelectSingleNode("/Document/SW.Blocks.GlobalDB/AttributeList/Name", nsmgr); name_elem.InnerText = block_name; }
protected void readSubelement(XmlElement subelement, PathComponent parent) { string indices_str = subelement.GetAttribute("Path"); string[] index_strings = indices_str.Split(path_sep); int[] indices = new int[index_strings.Length]; for (int i = 0; i < index_strings.Length; i++) { indices[i] = int.Parse(index_strings[i]); } PathComponent subs; int subs_count = SubstituteIndices(parent, out subs, (indices as IList <int>).GetEnumerator()); if (subs_count != indices.Length) { if (!(subs is IndexComponent) || (subs_count != (indices.Length + ((IndexComponent)subs).Indices.Length))) { throw new Exception("Length of path in subelement doesn't match number of indices in path"); } // It's the path of the array itself not an array item. subs = subs.Parent; } XmlElement comment_elem = subelement.SelectSingleNode("if:Comment", XMLUtil.nameSpaces) as XmlElement; MultilingualText comment = null; if (comment_elem != null) { comment = readComment(comment_elem); } if (((options & Options.AllowNoComment) != 0) || comment != null) { handle_tag(new HandleTagEventArgs() { Path = subs, Comment = comment }); } }
/// <summary> /// Makes a copy of the path with the indices substitutes /// </summary> /// <param name="path">Original path</param> /// <param name="substituted">Copy of path with new indices</param> /// <param name="indices">Indices to substitute</param> /// <returns>Number of indices in path</returns> protected static int SubstituteIndices(PathComponent path, out PathComponent substituted, IEnumerator <int> indices) { PathComponent parent_copy; int subs_count; if (path.Parent != null) { subs_count = SubstituteIndices(path.Parent, out parent_copy, indices); } else { parent_copy = null; subs_count = 0; } if (path is IndexComponent) { IndexComponent ic = (IndexComponent)path; IndexComponent copy = new IndexComponent(new int[ic.Indices.Length], ic.Type, parent_copy); for (int i = 0; i < ic.Indices.Length; i++) { if (!indices.MoveNext()) { break; } copy.Indices[i] = indices.Current; } subs_count += ic.Indices.Length; substituted = copy; return(subs_count); } else { MemberComponent member = (MemberComponent)path; substituted = new MemberComponent(member.Name, member.Type, parent_copy); return(subs_count); } }
public static void SetPathValues(XmlElement tag_element, PathComponent path, ConstantLookup constants, object [] values) { List <Limits> limits = new List <Limits>(); XmlElement elem = GetPathElement(tag_element, ref limits, path, constants); int[] lengths = limits.Select(x => (x.High - x.Low + 1)).ToArray(); int[] lower = limits.Select(x => x.Low).ToArray(); if (limits.Count < values.Rank) { throw new Exception("Path " + path + " has " + limits.Count + " indices but the supplied values has " + values.Rank); } DataType value_type = DataTypeParser.Parse(elem.GetAttribute("Datatype"), out string _); if (value_type is ARRAY value_array) { value_type = value_array.MemberType; } int[] indices = new int[lengths.Count()]; int v_index = 0; SetStartValues(elem, values, value_type, indices, limits, 0, ref v_index); }
public static XmlElement GetPathElement(XmlElement tag_element, ref List <Limits> limits, PathComponent path, ConstantLookup constants) { XmlElement elem = tag_element; if (path.Parent != null) { elem = GetPathElement(tag_element, ref limits, path.Parent, constants); if (elem == null) { return(null); } } if (path is MemberComponent member_path) { if (!(elem.SelectSingleNode("./if:Member[@Name='" + member_path.Name + "'] | ./if:Sections/if:Section/if:Member[@Name='" + member_path.Name + "']", XMLUtil.nameSpaces) is XmlElement child_elem)) { throw new Exception("Unable to find path " + member_path + " in element " + (elem?.GetAttribute("Name") ?? "<Unknown>")); } DataType type = DataTypeParser.Parse(child_elem.GetAttribute("Datatype"), out string _); if (type is ARRAY array) { limits.AddRange(array.Limits.Select(x => new Limits() { Low = x.LowLimit.ResolveInt(constants), High = x.HighLimit.ResolveInt(constants) })); } return(child_elem); } else if (path is IndexComponent index_path) { limits.RemoveRange(limits.Count - index_path.Indices.Count(), index_path.Indices.Count()); limits.AddRange(index_path.Indices.Select(x => new Limits() { Low = x, High = x })); return(elem); } else { return(null); } }
public static Array GetPathValues(XmlElement tag_element, PathComponent path, ConstantLookup constants) { List <Limits> limits = new List <Limits>(); XmlElement elem = GetPathElement(tag_element, ref limits, path, constants); XmlNodeList start_values = elem.SelectNodes(".//if:Subelement/if:StartValue", XMLUtil.nameSpaces); int[] lengths = limits.Select(x => (x.High - x.Low + 1)).ToArray(); int[] lower = limits.Select(x => x.Low).ToArray(); DataType value_type = DataTypeParser.Parse(elem.GetAttribute("Datatype"), out string _); if (value_type is ARRAY value_array) { value_type = value_array.MemberType; } Type array_type; if (value_type is BitString bits) { array_type = typeof(int); } else if (value_type is Integer) { array_type = typeof(int); } else if (value_type is Float) { array_type = typeof(double); } else if (value_type is BOOL) { array_type = typeof(bool); } else if (value_type is STRING) { array_type = typeof(string); } else { throw new NotImplementedException("Unhandled value type " + value_type.ToString()); } Array array = Array.CreateInstance(array_type, lengths, lower); foreach (XmlElement start_value in start_values) { string subpath = ((XmlElement)start_value.ParentNode).GetAttribute("Path"); int[] indices = subpath.Split(new char[] { ',' }).Select(x => int.Parse(x)).ToArray(); string value_str = start_value.InnerText.Trim(new char[1] { '\'' }); Object value = ParseValue(value_str, value_type); if (indices.Length != limits.Count) { throw new IndexOutOfRangeException("Wrong number of dimensions for " + path + " (expected " + limits.Count + " got " + indices.Length); } int i; // Check if indices are within limits for (i = 0; i < indices.Length; i++) { if (indices[i] < limits[i].Low || indices[i] > limits[i].High) { break; } } if (i == indices.Length) { array.SetValue(value, indices); } } return(array); }
protected MemberComponent readMember(XmlElement member_elem, PathComponent parent) { string name = member_elem.GetAttribute("Name"); string type_str = member_elem.GetAttribute("Datatype"); string left; DataType type = DataTypeParser.Parse(type_str, out left); MemberComponent member = new MemberComponent(name, type, parent); PathComponent child_path = member; if (type is ARRAY) { ARRAY array = (ARRAY)type; child_path = new IndexComponent(new int[array.Limits.Count], array.MemberType, member); if ((options & Options.NoSubelement) != 0) { if (member != child_path) { handle_tag(new HandleTagEventArgs() { Path = SubstituteIndicesLow(child_path), Comment = null }); } } } XmlElement comment_elem = member_elem.SelectSingleNode("if:Comment", XMLUtil.nameSpaces) as XmlElement; MultilingualText comment = null; if (comment_elem != null) { comment = readComment(comment_elem); } if (((options & Options.AllowNoComment) != 0) || comment != null) { handle_tag(new HandleTagEventArgs() { Path = SubstituteIndicesLow(member), Comment = comment }); } XmlNodeList member_elems = member_elem.SelectNodes("if:Member", XMLUtil.nameSpaces); foreach (XmlNode m in member_elems) { MemberComponent submember = readMember((XmlElement)m, child_path); if (child_path.Type is STRUCT) { STRUCT struct_type = (STRUCT)child_path.Type; struct_type.Members.Add(new StructMember() { Name = submember.Name, MemberType = submember.Type }); } } if ((options & Options.NoSubelement) == 0) { XmlNodeList sub_elems = member_elem.SelectNodes("if:Subelement", XMLUtil.nameSpaces); foreach (XmlNode s in sub_elems) { readSubelement(s as XmlElement, child_path); } } return(member); }
public MemberComponent(string name, DataType type, PathComponent parent = null) : base(type, parent) { Name = name; }
public static PathComponent ParsePath(string str) { int pos = 0; PathComponent path = null; string name; while (pos < str.Length) { if (str[pos] == '"') { if (pos + 1 >= str.Length) { throw new ParseException("Path ends with '\"'"); } int end = str.IndexOf('"', pos + 1); if (end == -1) { throw new ParseException("No terminating '\"'"); } name = str.Substring(pos + 1, end - pos - 1); pos = end + 1; } else { int start = pos; pos = str.IndexOfAny(MemberComponent.ESCAPED_CHARS, pos); if (pos == -1) { pos = str.Length; } name = str.Substring(start, pos - start); } path = new MemberComponent(name, null, path); if (pos == str.Length) { break; } if (str[pos] == '[') { if (pos + 1 >= str.Length) { throw new ParseException("Path ends with '['"); } int end = str.IndexOf(']', pos + 1); if (end == -1) { throw new ParseException("No terminating ']'"); } string indices = str.Substring(pos + 1, end - pos - 1); string[] index_str = indices.Split(','); path = new IndexComponent(index_str.Select(s => int.Parse(s)).ToArray <int>(), null, path); pos = end + 1; } if (pos == str.Length) { break; } if (str[pos] != '.') { throw new ParseException("Expected '.'"); } pos++; } return(path); }
public PathComponent(DataType type, PathComponent parent = null) { Type = type; Parent = parent; }
public IndexComponent(int[] indices, DataType type, PathComponent parent = null) : base(type, parent) { Indices = (int[])indices.Clone(); }
public XmlNode AddEnableType(PathComponent path) { int[] indices; return(AddPathEnable(type_section, path, out indices)); }