예제 #1
0
        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;
        }
예제 #2
0
            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
                    });
                }
            }
예제 #3
0
            /// <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);
                }
            }
예제 #4
0
        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);
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
            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);
            }
예제 #8
0
 public MemberComponent(string name, DataType type, PathComponent parent = null) : base(type, parent)
 {
     Name = name;
 }
예제 #9
0
        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);
        }
예제 #10
0
 public PathComponent(DataType type, PathComponent parent = null)
 {
     Type   = type;
     Parent = parent;
 }
예제 #11
0
 public IndexComponent(int[] indices, DataType type, PathComponent parent = null) : base(type, parent)
 {
     Indices = (int[])indices.Clone();
 }
예제 #12
0
 public XmlNode AddEnableType(PathComponent path)
 {
     int[] indices;
     return(AddPathEnable(type_section, path, out indices));
 }