Пример #1
0
 public ProtoSpecClassDef(string className, string classBaseModule, string classBaseName, ProtoSpecSubset classBody)
 {
     ClassName       = className;
     ClassBaseModule = classBaseModule;
     ClassBaseName   = classBaseName;
     ClassBody       = classBody;
 }
Пример #2
0
        public ProtoSpecSubset GetFullSpec(ProtoSpecAction action)
        {
            ProtoSpecSubset resultSpec = new ProtoSpecSubset(action);

            if (ClassBaseName != null)
            {
                ProtoSpecClassDef classBaseDef = null;

                if (ClassBaseModule != null)
                {
                    classBaseDef = ParentModule.ParentDocument.GetClassDef(ClassBaseModule, ClassBaseName, true);
                }
                else
                {
                    classBaseDef = ParentModule.ParentDocument.GetClassDef(ParentModule.Name, ClassBaseName, true);
                }

                if (classBaseDef == null)
                {
                    if (ClassBaseModule != null)
                    {
                        throw new Exception("无法找到类型'" + ParentModule.Name + "." + ClassName + "'的基类'" + ClassBaseModule + "." + ClassBaseName + "'");
                    }
                    else
                    {
                        throw new Exception("无法找到类型'" + ParentModule.Name + "." + ClassName + "'的基类'" + ClassBaseName + "'");
                    }
                }

                ProtoSpecSubset classBaseSpec = classBaseDef.GetFullSpec(action);


                foreach (ProtoSpecColumn column in classBaseSpec.Columns)
                {
                    resultSpec.Columns.Add(column.Colon(action));
                }
            }

            foreach (ProtoSpecColumn column in ClassBody.Columns)
            {
                resultSpec.Columns.Add(column.Colon(action));
            }

            return(resultSpec);
        }
Пример #3
0
        public ProtoSpecColumn Colon(ProtoSpecAction parentAction)
        {
            ProtoSpecColumn result = new ProtoSpecColumn(Name, this.ColumnType);

            result.Values       = this.Values;
            result.ClassModule  = this.ClassModule;
            result.ClassName    = this.ClassName;
            result.ParentAction = parentAction;

            ProtoSpecSubset format = null;

            if (ClassName != null)
            {
                ProtoSpecClassDef classDef = GetClassDef(parentAction, ClassModule, ClassName);

                format = classDef.GetFullSpec(parentAction);
            }
            else
            {
                format = this.Format;
            }

            if (format != null)
            {
                ProtoSpecSubset newformat = new ProtoSpecSubset(parentAction);

                foreach (ProtoSpecColumn column in format.Columns)
                {
                    newformat.Columns.Add(column.Colon(parentAction));
                }

                result.Format = newformat;
            }

            return(result);
        }
Пример #4
0
        private static void ParseResponse(string module, byte[] data, ref int parseOffset, ProtoSpecSubset format, TestScriptValue recvValue)
        {
            foreach (ProtoSpecColumn column in format.Columns)
            {
                switch (column.ColumnType)
                {
                case ProtoSpecColumnType.Byte:
                {
                    byte value = data[parseOffset++];

                    recvValue.AddProperty(
                        column.Name,
                        new TestScriptValue(value, TestScriptValueType.Byte)
                        );
                }
                break;

                case ProtoSpecColumnType.Short:
                {
                    byte[] bytes = new byte[2];

                    bytes[1] = data[parseOffset++];
                    bytes[0] = data[parseOffset++];

                    short value = BitConverter.ToInt16(bytes, 0);

                    recvValue.AddProperty(
                        column.Name,
                        new TestScriptValue(value, TestScriptValueType.Short)
                        );
                }
                break;

                case ProtoSpecColumnType.Int:
                {
                    byte[] bytes = new byte[4];

                    bytes[3] = data[parseOffset++];
                    bytes[2] = data[parseOffset++];
                    bytes[1] = data[parseOffset++];
                    bytes[0] = data[parseOffset++];

                    int value = BitConverter.ToInt32(bytes, 0);

                    recvValue.AddProperty(
                        column.Name,
                        new TestScriptValue(value, TestScriptValueType.Integer)
                        );
                }
                break;

                case ProtoSpecColumnType.Long:
                {
                    byte[] bytes = new byte[8];

                    bytes[7] = data[parseOffset++];
                    bytes[6] = data[parseOffset++];
                    bytes[5] = data[parseOffset++];
                    bytes[4] = data[parseOffset++];
                    bytes[3] = data[parseOffset++];
                    bytes[2] = data[parseOffset++];
                    bytes[1] = data[parseOffset++];
                    bytes[0] = data[parseOffset++];

                    long value = BitConverter.ToInt64(bytes, 0);

                    recvValue.AddProperty(
                        column.Name,
                        new TestScriptValue(value, TestScriptValueType.Long)
                        );
                }
                break;

                case ProtoSpecColumnType.String:
                {
                    byte[] packhead = new byte[2];

                    packhead[1] = data[parseOffset++];
                    packhead[0] = data[parseOffset++];

                    short len = BitConverter.ToInt16(packhead, 0);

                    string text = Encoding.UTF8.GetString(data, parseOffset, len);

                    parseOffset += len;

                    recvValue.AddProperty(
                        column.Name,
                        new TestScriptValue(text, TestScriptValueType.String)
                        );
                }
                break;

                case ProtoSpecColumnType.List:
                {
                    byte[] packhead = new byte[2];

                    packhead[1] = data[parseOffset++];
                    packhead[0] = data[parseOffset++];

                    short len = BitConverter.ToInt16(packhead, 0);

                    TestScriptValue list = TestScriptValue.CreateList();

                    for (int i = 0; i < len; i++)
                    {
                        TestScriptValue item = TestScriptValue.CreateObject();

                        ParseResponse(module, data, ref parseOffset, column.Format, item);

                        list.AddItem(item);
                    }

                    recvValue.AddProperty(column.Name, list);
                }
                break;

                case ProtoSpecColumnType.Enum:
                {
                    byte value = data[parseOffset++];

                    recvValue.AddProperty(
                        column.Name,
                        TestScriptValue.CreateEnum(module, column.Values.GetNameByValue(value), value)
                        );
                }
                break;
                }
            }
        }
Пример #5
0
 public ProtoSpecColumn(string name, ProtoSpecColumnType columnType, ProtoSpecSubset format)
 {
     Name       = name;
     ColumnType = columnType;
     Format     = format;
 }
Пример #6
0
        private ProtoSpecSubset ParseSpecSubset(ProtoSpecAction action)
        {
            if (CurrentToken.Type != ProtoSpecTokenType.LeftBrace)
            {
                Error("规格定义起始位置,缺少'{'");
            }

            ProtoSpecSubset subset = new ProtoSpecSubset(action);

            while (true)
            {
                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                {
                    if (CurrentToken.Type != ProtoSpecTokenType.EndOfFile && CurrentToken.Type != ProtoSpecTokenType.RightBrace)
                    {
                        Error("缺少列名");
                    }

                    break;
                }

                string name = CurrentToken.Text;

                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Colon)
                {
                    Error("列名之后缺少':'");
                    break;
                }

                NextToken();

                if (IsColumnType(CurrentToken.Type) == false)
                {
                    Error("缺少类型定义");
                    break;
                }

                ProtoSpecColumnType type = (ProtoSpecColumnType)CurrentToken.Type;

                ProtoSpecColumn column = null;

                if (CurrentToken.Type == ProtoSpecTokenType.List)
                {
                    NextToken();

                    if (CurrentToken.Type == ProtoSpecTokenType.LeftAngular)
                    {
                        NextToken();

                        if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                        {
                            Error("列表类型缺少类型名");
                            break;
                        }

                        string part1 = CurrentToken.Text;

                        string part2 = null;

                        NextToken();

                        if (CurrentToken.Type == ProtoSpecTokenType.Dot)
                        {
                            NextToken();

                            if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                            {
                                Error("列表类型的模块名后缺少类型名");
                                break;
                            }

                            part2 = CurrentToken.Text;

                            NextToken();
                        }

                        if (CurrentToken.Type != ProtoSpecTokenType.RightAngular)
                        {
                            Error("列表类型后缺少闭合符号'>'");
                            break;
                        }

                        if (part2 == null)
                        {
                            column = new ProtoSpecColumn(name, type, part1);
                        }
                        else
                        {
                            column = new ProtoSpecColumn(name, type, part1, part2);
                        }
                    }
                    else
                    {
                        ProtoSpecSubset format = ParseSpecSubset(action);

                        column = new ProtoSpecColumn(name, type, format);
                    }
                }
                else if (CurrentToken.Type == ProtoSpecTokenType.TypeOf)
                {
                    NextToken();

                    if (CurrentToken.Type != ProtoSpecTokenType.LeftAngular)
                    {
                        Error("自定义类型前缺少起始符号'<'");
                        break;
                    }

                    NextToken();

                    if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                    {
                        Error("自定义类型的模块名后缺少类型名");
                        break;
                    }

                    string part1 = CurrentToken.Text;

                    string part2 = null;

                    NextToken();

                    if (CurrentToken.Type == ProtoSpecTokenType.Dot)
                    {
                        NextToken();

                        if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                        {
                            Error("自定义类型的模块名后缺少类型名");
                            break;
                        }

                        part2 = CurrentToken.Text;

                        NextToken();
                    }

                    if (CurrentToken.Type != ProtoSpecTokenType.RightAngular)
                    {
                        Error("自定义类型后缺少闭合符号'>'");
                        break;
                    }

                    if (part2 == null)
                    {
                        column = new ProtoSpecColumn(name, type, part1);
                    }
                    else
                    {
                        column = new ProtoSpecColumn(name, type, part1, part2);
                    }
                }
                else if (CurrentToken.Type == ProtoSpecTokenType.Enum)
                {
                    ProtoSpecEnumValueList values = ParseEnum();

                    column = new ProtoSpecColumn(name, type, values);
                }
                else
                {
                    column = new ProtoSpecColumn(name, type);
                }

                subset.Columns.Add(column);
            }

            if (CurrentToken.Type != ProtoSpecTokenType.RightBrace)
            {
                Error("规格定义结束位置,缺少'}'");
            }

            return(subset);
        }
Пример #7
0
        private ProtoSpecAction ParseAction(ProtoSpecModule module)
        {
            string name = CurrentToken.Text;

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Equal)
            {
                Error("接口名'" + name + "'后缺少'='");
                return(null);
            }

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Numeral)
            {
                Error("接口'" + name + "'的ID不是有效数值");
                return(null);
            }

            string actionId = CurrentToken.Text;

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.LeftBrace)
            {
                Error("操作'" + name + "'的主体起始位置,缺少'{'");
                return(null);
            }

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.In)
            {
                Error("接口'" + name + "'的主体,缺少'in'关键字");
                return(null);
            }

            ProtoSpecAction action = new ProtoSpecAction(name, actionId);

            NextToken();

            ProtoSpecSubset input = ParseSpecSubset(action);

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Out)
            {
                Error("接口'" + name + "'的主体,缺少'out'关键字");
                return(null);
            }

            NextToken();

            ProtoSpecSubset output = ParseSpecSubset(action);

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.RightBrace)
            {
                Error("接口'" + name + "'的主体结束位置,缺少'}'");
                return(null);
            }

            action.Input  = input;
            action.Output = output;

            return(action);
        }
Пример #8
0
        private ProtoSpecClassDef ParseClass(ProtoSpecModule module)
        {
            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
            {
                Error("缺少类名");
                return(null);
            }

            string name = CurrentToken.Text;

            string basePart1 = null;
            string basePart2 = null;

            NextToken();

            if (CurrentToken.Type == ProtoSpecTokenType.Colon)
            {
                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                {
                    Error("缺少基类名称");
                    return(null);
                }

                basePart1 = CurrentToken.Text;

                NextToken();

                if (CurrentToken.Type == ProtoSpecTokenType.Dot)
                {
                    NextToken();

                    if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                    {
                        Error("缺少基类名称");
                        return(null);
                    }

                    basePart2 = CurrentToken.Text;

                    NextToken();
                }
            }

            ProtoSpecSubset classBody = ParseSpecSubset(null);

            if (basePart1 == null)
            {
                return(new ProtoSpecClassDef(name, null, null, classBody));
            }
            else if (basePart2 == null)
            {
                return(new ProtoSpecClassDef(name, null, basePart1, classBody));
            }
            else
            {
                return(new ProtoSpecClassDef(name, basePart1, basePart2, classBody));
            }
        }