Пример #1
0
        private static StatementBlock ParseStatementBlock(BinaryReader reader, Encoding encoding, BinaryWriter lineOffestWriter, BinaryWriter blockOffestWriter)
        {
            var block = new StatementBlock();

            while (!(reader.BaseStream.Position == reader.BaseStream.Length))
            {
                var type = reader.ReadByte();
                while (Array.BinarySearch(KnownTypeId, type) < 0)
                {
                    // 尝试跳过未知信息
                    type = reader.ReadByte();
                }
                var startOffest = (int)reader.BaseStream.Position - 1; // typeId到代码数据开头的偏移位置
                if (lineOffestWriter != null)
                {
                    if (true && // 部分数据不需要将位置写入LineOffest(一般为在IDE无显示的数据)
                        type != 0x50 && // 否则
                        type != 0x51 && // 如果结束
                        type != 0x52 && // 如果真结束
                        type != 0x55 && // 循环块结束标识:0x71前
                        type != 0x54 && // .判断结束
                        type != 0x53 && // .判断 某Case结束
                        type != 0x6D && // .判断开始(紧接着就是 0x6E)
                        type != 0x6F)    // .默认)
                    {
                        lineOffestWriter.Write(startOffest);
                    }
                }
                switch (type)
                {
                case 0x50:     // 否则
                case 0x51:     // 如果结束
                case 0x52:     // 如果真结束
                case 0x53:     // .判断 某Case结束
                case 0x54:     // .判断结束
                case 0x6F:     // .默认
                case 0x71:     // 循环结束语句:XX循环尾(参数...)
                    reader.BaseStream.Position = startOffest;
                    return(block);

                case 0x55:     // 循环体结束标识(0x71前)
                    continue;

                case 0x6D:     // .判断开始(紧接着就是 0x6E)
                {
                    blockOffestWriter.Write((byte)4);
                    blockOffestWriter.Write(startOffest);
                    long posToFillEndOffest = blockOffestWriter.BaseStream.Position;
                    blockOffestWriter.Write(0);
                    var s = new SwitchStatement();
                    if (reader.ReadByte() != 0x6E)         // .判断 某Case开始
                    {
                        throw new Exception();
                    }
                    byte switch_type;
                    do
                    {
                        lineOffestWriter.Write((int)reader.BaseStream.Position - 1);
                        var caseInfo = new SwitchStatement.CaseInfo();
                        caseInfo.Condition      = ParseCallExpressionWithoutType(reader, encoding, out var caseInfo_UnexaminedCode, out var caseInfo_Comment, out var caseInfo_Mask).ParamList.ElementAtOrDefault(0);
                        caseInfo.UnexaminedCode = caseInfo_UnexaminedCode;
                        caseInfo.Comment        = caseInfo_Comment;
                        caseInfo.Mask           = caseInfo_Mask;
                        caseInfo.Block          = ParseStatementBlock(reader, encoding, lineOffestWriter, blockOffestWriter);
                        s.Case.Add(caseInfo);
                        if (reader.ReadByte() != 0x53)
                        {
                            throw new Exception();
                        }
                    } while ((switch_type = reader.ReadByte()) == 0x6E);
                    if (switch_type != 0x6F)         // .默认
                    {
                        throw new Exception();
                    }
                    s.DefaultBlock = ParseStatementBlock(reader, encoding, lineOffestWriter, blockOffestWriter);
                    if (reader.ReadByte() != 0x54)         // .判断结束
                    {
                        throw new Exception();
                    }
                    int endOffest = (int)reader.BaseStream.Position;
                    blockOffestWriter.BaseStream.Position = posToFillEndOffest;
                    blockOffestWriter.Write(endOffest);
                    blockOffestWriter.BaseStream.Seek(0, SeekOrigin.End);
                    reader.ReadByte();         // 0x74
                    block.Add(s);
                }
                    continue;
                }
                var exp = ParseCallExpressionWithoutType(reader, encoding, out string unexaminedCode, out string comment, out bool mask);
                switch (type)
                {
                case 0x70:     // 循环开始语句:XX循环首(参数...)
                {
                    blockOffestWriter.Write((byte)3);
                    blockOffestWriter.Write(startOffest);
                    long posToFillEndOffest = blockOffestWriter.BaseStream.Position;
                    blockOffestWriter.Write(0);

                    var            loopblock = ParseStatementBlock(reader, encoding, lineOffestWriter, blockOffestWriter);
                    CallExpression endexp    = null;

                    var endOffest = (int)reader.BaseStream.Position;
                    blockOffestWriter.BaseStream.Position = posToFillEndOffest;
                    blockOffestWriter.Write(endOffest);
                    blockOffestWriter.BaseStream.Seek(0, SeekOrigin.End);

                    string endexp_unexaminedCode;
                    string endexp_comment;
                    bool   endexp_mask;
                    switch (reader.ReadByte())
                    {
                    case 0x71:
                        endexp = ParseCallExpressionWithoutType(reader, encoding, out endexp_unexaminedCode, out endexp_comment, out endexp_mask);
                        break;

                    default:
                        throw new Exception();
                    }
                    if (exp.LibraryId != 0)
                    {
                        throw new Exception();
                    }
                    LoopStatement s = null;
                    switch (exp.MethodId)
                    {
                    case 3:
                        s = new WhileStatement()
                        {
                            Condition      = exp.ParamList.ElementAtOrDefault(0),
                            Block          = loopblock,
                            UnexaminedCode = unexaminedCode
                        };
                        break;

                    case 5:
                        s = new DoWhileStatement()
                        {
                            Condition      = endexp.ParamList.ElementAtOrDefault(0),
                            Block          = loopblock,
                            UnexaminedCode = endexp_unexaminedCode
                        };
                        break;

                    case 7:
                        s = new CounterStatement()
                        {
                            Count          = exp.ParamList.ElementAtOrDefault(0),
                            Var            = exp.ParamList.ElementAtOrDefault(1),
                            Block          = loopblock,
                            UnexaminedCode = unexaminedCode
                        };
                        break;

                    case 9:
                        s = new ForStatement()
                        {
                            Start          = exp.ParamList.ElementAtOrDefault(0),
                            End            = exp.ParamList.ElementAtOrDefault(1),
                            Step           = exp.ParamList.ElementAtOrDefault(2),
                            Var            = exp.ParamList.ElementAtOrDefault(3),
                            Block          = loopblock,
                            UnexaminedCode = unexaminedCode
                        };
                        break;

                    default:
                        throw new Exception();
                    }

                    s.CommentOnStart = comment;
                    s.CommentOnEnd   = endexp_comment;

                    s.MaskOnStart = mask;
                    s.MaskOnEnd   = endexp_mask;

                    block.Add(s);
                }
                break;

                case 0x6C:     // 如果真
                {
                    blockOffestWriter.Write((byte)2);
                    blockOffestWriter.Write(startOffest);
                    long posToFillEndOffest = blockOffestWriter.BaseStream.Position;
                    blockOffestWriter.Write(0);

                    var s = new IfStatement()
                    {
                        Condition      = exp.ParamList.ElementAtOrDefault(0),
                        UnexaminedCode = unexaminedCode,
                        Block          = ParseStatementBlock(reader, encoding, lineOffestWriter, blockOffestWriter),
                        Comment        = comment,
                        Mask           = mask
                    };
                    if (reader.ReadByte() != 0x52)
                    {
                        throw new Exception();
                    }

                    var endOffest = (int)reader.BaseStream.Position;
                    blockOffestWriter.BaseStream.Position = posToFillEndOffest;
                    blockOffestWriter.Write(endOffest);
                    blockOffestWriter.BaseStream.Seek(0, SeekOrigin.End);

                    reader.ReadByte();         // 0x73

                    block.Add(s);
                }
                break;

                case 0x6B:     // 如果
                {
                    var s = new IfElseStatement()
                    {
                        Condition      = exp.ParamList.ElementAtOrDefault(0),
                        UnexaminedCode = unexaminedCode,
                        Comment        = comment,
                        Mask           = mask
                    };
                    blockOffestWriter.Write((byte)1);
                    blockOffestWriter.Write(startOffest);
                    long posToFillEndOffest = blockOffestWriter.BaseStream.Position;
                    blockOffestWriter.Write(0);

                    s.BlockOnTrue = ParseStatementBlock(reader, encoding, lineOffestWriter, blockOffestWriter);
                    if (reader.ReadByte() != 0x50)
                    {
                        throw new Exception();
                    }
                    s.BlockOnFalse = ParseStatementBlock(reader, encoding, lineOffestWriter, blockOffestWriter);
                    if (reader.ReadByte() != 0x51)
                    {
                        throw new Exception();
                    }
                    var endOffest = (int)reader.BaseStream.Position;

                    blockOffestWriter.BaseStream.Position = posToFillEndOffest;
                    blockOffestWriter.Write(endOffest);
                    blockOffestWriter.BaseStream.Seek(0, SeekOrigin.End);

                    reader.ReadByte();         // 0x72

                    block.Add(s);
                }
                break;

                case 0x6A:     // 常规Call
                {
                    if (unexaminedCode != null)
                    {
                        block.Add(new UnexaminedStatement()
                            {
                                UnexaminedCode = unexaminedCode,
                                Mask           = mask
                            });
                    }
                    else
                    {
                        if (exp.LibraryId == -1)
                        {
                            block.Add(new ExpressionStatement()
                                {
                                    Expression = null,
                                    Comment    = comment
                                });
                        }
                        else
                        {
                            block.Add(new ExpressionStatement()
                                {
                                    Expression = exp,
                                    Comment    = comment,
                                    Mask       = mask
                                });
                        }
                    }
                }
                break;
                }
            }
            return(block);
        }