public void WriteStruct(int type, Struct s)
        {
            if (s == null)
            {
                s = Struct.Create(type);
            }

            int width = s.GetSizeWidth();
            int pos   = -1;

            if (width > 0)
            {
                pos = BeginSize(width);
            }

            if (type > 0)
            {
                WriteUint16(type);
            }

            s.Write(this);

            if (width > 0)
            {
                EndSize(width, pos);
            }
        }
        public Struct ReadStruct32()
        {
            long size = ReadUint32();

            if (size == 0)
            {
                return(null);
            }
            int    type   = ReadUint16();
            Struct result = Struct.Create(type);

            result.Read(this);
            return(result);
        }
Пример #3
0
        static Scanner()
        {
            _matchObjs.Add(Struct.Create(_cmmReg, new Func <Match, Token>(m => new Token(TokenType.COMM, m.Value))));
            _matchObjs.Add(Struct.Create(_strReg, new Func <Match, Token>(m => new Token(TokenType.STR, m.Value))));
            _matchObjs.Add(Struct.Create(_funcReg, new Func <Match, Token>(m => new Token(TokenType.FUNC, m.Value))));
            _matchObjs.Add(Struct.Create(_forReg, new Func <Match, Token>(m => new Token(TokenType.FOR, m.Value))));
            _matchObjs.Add(Struct.Create(_foreachReg, new Func <Match, Token>(m => new Token(TokenType.FOREACH, m.Value))));
            _matchObjs.Add(Struct.Create(_inReg, new Func <Match, Token>(m => new Token(TokenType.IN, m.Value))));
            _matchObjs.Add(Struct.Create(_ifReg, new Func <Match, Token>(m => new Token(TokenType.IF, m.Value))));
            _matchObjs.Add(Struct.Create(_elseReg, new Func <Match, Token>(m => new Token(TokenType.ELSE, m.Value))));
            _matchObjs.Add(Struct.Create(_breakReg, new Func <Match, Token>(m => new Token(TokenType.BREAK, m.Value))));
            _matchObjs.Add(Struct.Create(_retReg, new Func <Match, Token>(m => new Token(TokenType.RET, m.Value))));
            _matchObjs.Add(Struct.Create(_whileReg, new Func <Match, Token>(m => new Token(TokenType.WHILE, m.Value))));
            _matchObjs.Add(Struct.Create(_trueReg, new Func <Match, Token>(m => new Token(TokenType.TRUE, m.Value))));
            _matchObjs.Add(Struct.Create(_falseReg, new Func <Match, Token>(m => new Token(TokenType.FALSE, m.Value))));
            _matchObjs.Add(Struct.Create(_catchReg, new Func <Match, Token>(m => new Token(TokenType.CATCH, m.Value))));
            _matchObjs.Add(Struct.Create(_wordReg, new Func <Match, Token>(m => new Token(TokenType.WORD, m.Value))));
            _matchObjs.Add(Struct.Create(_numReg, new Func <Match, Token>(m => new Token(TokenType.NUM, m.Value))));

            _markerMap.Add('(', TokenType.LS);
            _markerMap.Add(')', TokenType.RS);
            _markerMap.Add('[', TokenType.LM);
            _markerMap.Add(']', TokenType.RM);
            _markerMap.Add('{', TokenType.LB);
            _markerMap.Add('}', TokenType.RB);
            _markerMap.Add(',', TokenType.CMA);
            _markerMap.Add('=', TokenType.EQ);
            _markerMap.Add('!', TokenType.EX);
            _markerMap.Add('+', TokenType.PLUS);
            _markerMap.Add('-', TokenType.SUB);
            _markerMap.Add('*', TokenType.MUL);
            _markerMap.Add('/', TokenType.DIV);
            _markerMap.Add('.', TokenType.DOT);
            _markerMap.Add(':', TokenType.COL);
            _markerMap.Add('>', TokenType.GT);
            _markerMap.Add('<', TokenType.LT);
            _markerList = _markerMap.Keys.ToArray();

            _rangeMap.Add(TokenType.LS, Struct.Create(TokenType.RS, TokenType.SS));
            _rangeMap.Add(TokenType.LM, Struct.Create(TokenType.RM, TokenType.MM));
            _rangeMap.Add(TokenType.LB, Struct.Create(TokenType.RB, TokenType.BB));
            _rangeOpens = new HashSet <TokenType>(_rangeMap.Keys);
        }
        public Struct ReadStruct(int type)
        {
            Struct st    = Struct.Create(type);
            int    width = st.GetSizeWidth();

            if (width > 0)
            {
                long size = ReadSize(width);
                if (size == 0)
                {
                    return(null);
                }
            }
            if (type > 0)
            {
                int code = ReadUint16();
                Debug.Assert(code == type);
            }
            st.Read(this);
            return(st);
        }
Пример #5
0
        /// <summary>
        /// 创建结构体
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <param name="address"></param>
        /// <param name="canPostfix"></param>
        /// <returns></returns>
        public static Struct Create <TEntity>(TEntity entity, UInt32 address, Boolean canPostfix) where TEntity : EntityBase <TEntity>, new()
        {
            Type type = typeof(TEntity);

            // 类名作为结构体名字
            String name = type.Name;

            // 检查是否已存在
            //UInt32 id = Struct.GetStructID(name);
            //if (id != Bytes.BadAddress)
            //{
            //    KernelWin.WriteLine("结构体{0}(ID={1:X}h)已存在!", name, id);
            //    return Struct.FindStructByID(id);
            //}

            Struct st = Struct.FindStructByName(name);
            //if (st != null)
            //{
            //    KernelWin.WriteLine("结构体{0}(ID={1:X}h)已存在!", name, st.ID);
            //    return st;
            //}

            Int32  n     = 0;
            String name2 = name;

            while (st == null)
            {
                st = Struct.Create(name2, Bytes.BadAddress, false);

                n++;
                if (st == null)
                {
                    if (n > 10 || !canPostfix)
                    {
                        throw new Exception("创建结构体失败!");
                    }
                    name2 = name + "_" + n;
                }
            }

            Dictionary <String, DataFieldItem> dic = DataFieldItem.GetFields(type);

            foreach (DataFieldItem item in dic.Values)
            {
                name = item.Property.Name;
                DataType dt;
                UInt32   size = 0;

                if (item.Attribute.RefType == null)
                {
                    #region 普通成员
                    if (item.Property.PropertyType == typeof(String))
                    {
                        dt = DataType.ASCI;
                        if (!String.IsNullOrEmpty(item.Attribute.SizeField))
                        {
                            size = Convert.ToUInt32(entity[item.Attribute.SizeField]);
                        }
                        if (size <= 0)
                        {
                            size = (UInt32)item.Attribute.Size;
                        }
                    }
                    else if (item.Property.PropertyType == typeof(Byte[]))
                    {
                        // 字节数组也可以当作字符串一样处理
                        dt = DataType.ASCI;
                        if (!String.IsNullOrEmpty(item.Attribute.SizeField))
                        {
                            size = Convert.ToUInt32(entity[item.Attribute.SizeField]);
                        }
                        if (size <= 0)
                        {
                            size = (UInt32)item.Attribute.Size;
                        }
                    }
                    else if (item.Property.PropertyType == typeof(Byte))
                    {
                        dt   = DataType.BYTE;
                        size = 1;
                    }
                    else if (item.Property.PropertyType == typeof(Int16))
                    {
                        dt   = DataType.WORD;
                        size = 2;
                    }
                    else if (item.Property.PropertyType == typeof(Int32))
                    {
                        dt   = DataType.DWRD;
                        size = 4;
                    }
                    else
                    {
                        throw new Exception("不支持的类型:" + type.Name);
                    }

                    //KernelWin.WriteLine("创建普通成员:{0} {1} {2} ", name, dt, size);
                    st.Add(name, dt, size);

                    #endregion
                }
                else
                {
                    #region 引用成员
                    if (item.Property.PropertyType == typeof(Int16))
                    {
                        dt   = DataType.WORD | DataType.F0OFF;
                        size = 2;
                    }
                    else if (item.Property.PropertyType == typeof(Int32))
                    {
                        dt   = DataType.DWRD | DataType.F0OFF;
                        size = 4;
                    }
                    else
                    {
                        throw new Exception("不支持的类型:" + type.Name);
                    }

                    UInt32 addr = 0;
                    switch (item.Attribute.RefKind)
                    {
                    case RefKinds.Virtual:
                        addr = 0;
                        break;

                    case RefKinds.Relative:
                        addr = address;
                        break;

                    case RefKinds.Auto:
                        // 先直接取地址
                        addr = Convert.ToUInt32(item.Property.GetValue(entity, null));
                        // 如果小于基址,可能是相对地址
                        if (addr < entity.Info.ImageBase && addr > 0)
                        {
                            addr = address;
                        }
                        else
                        {
                            addr = 0;
                        }
                        break;

                    case RefKinds.Absolute:
                        throw new Exception("不支持的类型:" + item.Attribute.RefKind);
                    }

                    //KernelWin.WriteLine("创建引用成员:{0} {1} 0x{2:X} {3}", name, dt, addr, size);
                    st.Add(name, Bytes.BadAddress, dt, addr, size);

                    #endregion
                }
            }

            return(st);
        }