Пример #1
0
        public SprotoObject(object val)
        {
            string typename = SprotoObject.TypeOf(val);

            this.type = typename;
            this.val  = val;
        }
Пример #2
0
        public RpcPackage PackRequest(string proto, SprotoObject request = null, Int64 session = 0, SprotoObject ud = null)
        {
            //Console.WriteLine("PackRequest {0} {1} {2}",proto,request,session);
            SprotoProtocol protocol = this.C2S.GetProtocol(proto);
            UInt16         tag      = protocol.tag;
            SprotoObject   header   = this.NewPackageHeader(this.C2S, tag, session, ud);

            this.writer.Seek(0, SprotoStream.SEEK_BEGIN);            // clear stream
            SprotoStream writer = this.C2S.Encode(header, this.writer);

            if (request != null)
            {
                string expect = protocol.request;
                if (request.type != expect)
                {
                    SprotoHelper.Error("[SprotoRpc.Request] expect '{0}' got '{1}'", expect, request.type);
                }
                writer = this.C2S.Encode(request, writer);
            }
            RpcPackage package = new RpcPackage();

            package.data = this.C2S.Pack(writer.Buffer, 0, writer.Position, out package.size);
            if (session != 0)
            {
                SprotoHelper.Assert(!this.sessions.ContainsKey(session), String.Format("repeat session: {0}", session));
                RpcMessage message = new RpcMessage();
                message.session        = session;
                message.proto          = proto;
                message.request        = request;
                message.tag            = tag;
                this.sessions[session] = message;
            }
            return(package);
        }
Пример #3
0
        private Dictionary <T, SprotoObject> DecodeSprotoObjectDict <T> (SprotoMgr sprotomgr, SprotoType type, SprotoField field, SprotoStream reader)
        {
            Dictionary <T, SprotoObject> dict = new Dictionary <T, SprotoObject>();
            UInt32 size = this.ReadUInt32(reader);

            while (size > 0)
            {
                UInt32 elem_size = this.ReadUInt32(reader);
                UInt32 need_size = elem_size + SprotoCodec.SIZEOF_LENGTH;
                size = size - need_size;
                if (size < 0)
                {
                    SprotoHelper.Error("[SprotoCodec.DecodeSprotoObjectDict] fail");
                }
                SprotoObject elemobj = this.DecodeSprotoObject(sprotomgr, type, reader);
                SprotoObject keyobj  = elemobj.Get(field.key);
                T            key     = (T)keyobj.val;
                dict[key] = elemobj;
            }
            if (size != 0)
            {
                SprotoHelper.Error("[SprotoCodec.DecodeSprotoObjectDict] fail");
            }
            return(dict);
        }
Пример #4
0
        public SprotoObject NewSprotoObject(string typename, object val = null)
        {
            if (null == this.GetType(typename))
            {
                SprotoHelper.Error("[SprotoMgr.NewSprotoObject] unsupport type '{0}'", typename);
            }
            SprotoObject obj = new SprotoObject();

            obj.type = typename;
            obj.val  = val;
            return(obj);
        }
Пример #5
0
        public SprotoObject Decode(SprotoMgr sprotomgr, string typename, SprotoStream reader)
        {
            if (SprotoHelper.IsBuildInType(typename))
            {
                SprotoHelper.Error("[SprotoCodec.Decode] expect a 'non-buildin-type' got '{0}'", typename);
            }
            SprotoType type = sprotomgr.GetType(typename);

            if (null == type)
            {
                SprotoHelper.Error("[SprotoCodec.Decode] occur a unknow-type '{0}'", typename);
            }
            SprotoObject obj = this.DecodeSprotoObject(sprotomgr, type, reader);

            return(obj);
        }
Пример #6
0
        private UInt32 EncodeSprotoObjectList(SprotoMgr sprotomgr, List <SprotoObject> list, SprotoStream writer)
        {
            UInt32 size = 0;

            for (int i = 0; i < list.Count; i++)
            {
                SprotoObject elemobj      = list[i];
                SprotoType   elemtype     = sprotomgr.GetType(elemobj.type);
                int          elemsize_pos = writer.Position;
                writer.Seek(SprotoCodec.SIZEOF_LENGTH, SprotoStream.SEEK_CUR);
                UInt32 elemsize = this.EncodeSprotoObject(sprotomgr, elemtype, elemobj, writer);
                this.FillSize(writer, elemsize_pos, elemsize);
                size += (SprotoCodec.SIZEOF_LENGTH + elemsize);
            }
            return(size);
        }
Пример #7
0
 public void Set(string fieldname, object value)
 {
     if (value.GetType() == typeof(SprotoObject))
     {
         SprotoObject obj = value as SprotoObject;
         if (null == obj.type)
         {
             SprotoHelper.Error("[SprotoObject] uninitialize");
         }
         this.fields.Add(fieldname, obj);
     }
     else
     {
         SprotoObject obj = new SprotoObject(value);
         this.fields.Add(fieldname, obj);
     }
 }
Пример #8
0
        public SprotoStream Encode(SprotoMgr sprotomgr, SprotoObject obj, SprotoStream writer = null)
        {
            if (null == writer)
            {
                writer = new SprotoStream();
            }
            string typename = obj.type;

            if (SprotoHelper.IsBuildInType(typename))
            {
                SprotoHelper.Error("[SprotoCodec.Encode] expect a 'non-buildin-type sprotoobj' got '{0}'", typename);
            }
            SprotoType type = sprotomgr.GetType(typename);

            if (null == type)
            {
                SprotoHelper.Error("[SprotoCodec.Encode] occur a unknow-type '{0}'", typename);
            }

            this.EncodeSprotoObject(sprotomgr, type, obj, writer);
            return(writer);
        }
Пример #9
0
        private UInt32 EncodeSprotoObjectDict <T> (SprotoMgr sprotomgr, Dictionary <T, SprotoObject> dict, SprotoField field, SprotoStream writer)
        {
            UInt32   size = 0;
            List <T> keys = new List <T>(dict.Keys);

            keys.Sort();             // keep encode stable
            foreach (var key in keys)
            {
                SprotoObject elemobj = dict[key];
                if (elemobj.Get(field.key) == null)
                {
                    SprotoHelper.Error("[SprotoCodec.EncodeSprotoObjectDict] exist null mainindex '{0}' in field '{1}'", field.key, field.name);
                }
                SprotoType elemtype     = sprotomgr.GetType(elemobj.type);
                int        elemsize_pos = writer.Position;
                writer.Seek(SprotoCodec.SIZEOF_LENGTH, SprotoStream.SEEK_CUR);
                UInt32 elemsize = this.EncodeSprotoObject(sprotomgr, elemtype, elemobj, writer);
                this.FillSize(writer, elemsize_pos, elemsize);
                size += (SprotoCodec.SIZEOF_LENGTH + elemsize);
            }
            return(size);
        }
Пример #10
0
        private SprotoObject NewPackageHeader(SprotoMgr sprotomgr, UInt16 tag, Int64 session, SprotoObject ud = null)
        {
            SprotoObject header = sprotomgr.NewSprotoObject(this.package);

            if (tag != 0)               // tag == 0 mean : response header
            {
                header["type"] = tag;
            }
            else
            {
                SprotoHelper.Assert(session != 0, "response expect session");
            }
            if (session != 0)
            {
                header["session"] = session;
            }
            if (ud != null)
            {
                header["ud"] = ud;
            }
            return(header);
        }
Пример #11
0
        public RpcPackage PackResponse(string proto, SprotoObject response = null, Int64 session = 0, SprotoObject ud = null)
        {
            //Console.WriteLine("PackResponse {0} {1} {2}",proto,response,session);
            SprotoProtocol protocol = this.S2C.GetProtocol(proto);
            SprotoObject   header   = this.NewPackageHeader(this.S2C, 0, session, ud);

            this.writer.Seek(0, SprotoStream.SEEK_BEGIN);            // clear stream
            SprotoStream writer = this.S2C.Encode(header, this.writer);

            if (response != null)
            {
                string expect = protocol.response;
                if (response.type != expect)
                {
                    SprotoHelper.Error("[SprotoRpc.Response] expect '{0}' got '{1}'", expect, response.type);
                }
                writer = this.S2C.Encode(response, writer);
            }
            RpcPackage package = new RpcPackage();

            package.data = this.S2C.Pack(writer.Buffer, 0, writer.Position, out package.size);
            return(package);
        }
Пример #12
0
        private List <SprotoObject> DecodeSprotoObjectList(SprotoMgr sprotomgr, SprotoType type, SprotoStream reader)
        {
            List <SprotoObject> list = new List <SprotoObject>();
            UInt32 size = this.ReadUInt32(reader);

            while (size > 0)
            {
                UInt32 elem_size = this.ReadUInt32(reader);
                UInt32 need_size = elem_size + SprotoCodec.SIZEOF_LENGTH;
                size = size - need_size;
                if (size < 0)
                {
                    SprotoHelper.Error("[SprotoCodec.DecodeSprotoObjectList] fail");
                }
                SprotoObject elemobj = this.DecodeSprotoObject(sprotomgr, type, reader);
                list.Add(elemobj);
            }
            if (size != 0)
            {
                SprotoHelper.Error("[SprotoCodec.DecodeSprotoObjectList] fail");
            }
            return(list);
        }
Пример #13
0
        public byte[] PackEncode(SprotoObject obj, out int size, SprotoStream writer = null)
        {
            SprotoStream stream = this.Encode(obj, writer);

            return(this.Pack(stream.Buffer, 0, stream.Position, out size));
        }
Пример #14
0
 public SprotoStream Encode(SprotoObject obj, SprotoStream writer = null)
 {
     return(this.Codec.Encode(this, obj, writer));
 }
Пример #15
0
        private SprotoObject DecodeSprotoObject(SprotoMgr sprotomgr, SprotoType type, SprotoStream reader)
        {
            SprotoObject obj = sprotomgr.NewSprotoObject(type.name);
            // decode header part
            UInt16        fieldnum  = this.ReadUInt16(reader);
            List <UInt16> data_tags = new List <UInt16>();
            UInt16        curtag    = 0;

            for (UInt16 i = 0; i < fieldnum; i++)
            {
                UInt16 tag = this.ReadUInt16(reader);
                if (tag == 0)
                {
                    data_tags.Add(curtag);
                    curtag++;
                }
                else if (0 == (tag & 1))                      // even
                {
                    UInt16      val   = (UInt16)((tag / 2) - 1);
                    SprotoField field = type.GetField(curtag);
                    if (field != null)                          // for protocol version compatibility
                    {
                        if (field.type == "integer")
                        {
                            if (0 == field.digit)
                            {
                                Int64 number = (Int64)(val);
                                obj.Set(field.name, number);
                            }
                            else
                            {
                                double number = (double)val / MathPow(10, field.digit);
                                obj.Set(field.name, number);
                            }
                        }
                        else if (field.type == "boolean")
                        {
                            if (!(val == 0 || val == 1))
                            {
                                SprotoHelper.Error("[SprotoCodec.DecodeSprotoObject] type={0},field={1},boolean type expect value '0/1' got '{2}'", type.name, curtag, val);
                            }
                            bool ok = (val == 0) ? false : true;
                            obj.Set(field.name, ok);
                        }
                        else
                        {
                            SprotoHelper.Error("[SprotoCodec.DecodeSprotoObject] type={0},field={1},expect type 'integer/boolean' got '{2}'", type.name, curtag, field.type);
                        }
                    }
                    curtag++;
                }
                else                                                              // odd
                {
                    curtag += (UInt16)((tag + 1) / 2);
                }
            }
            // decode data part
            foreach (UInt16 tag in data_tags)
            {
                SprotoField field = type.GetField(tag);
                if (field != null)
                {
                    object fieldobj = null;
                    if (SprotoHelper.IsBuildInType(field.type))
                    {
                        fieldobj = this.DecodeBuildInType(field, reader);
                    }
                    else
                    {
                        SprotoType fieldtype = sprotomgr.GetType(field.type);
                        if (field.is_array)
                        {
                            if (field.key != null)
                            {
                                string keytype = fieldtype.GetField(field.key).type;
                                if (keytype == "integer")
                                {
                                    fieldobj = this.DecodeSprotoObjectDict <Int64>(sprotomgr, fieldtype, field, reader);
                                }
                                else if (keytype == "string")
                                {
                                    fieldobj = this.DecodeSprotoObjectDict <string>(sprotomgr, fieldtype, field, reader);
                                }
                                else if (keytype == "boolean")
                                {
                                    fieldobj = this.DecodeSprotoObjectDict <bool>(sprotomgr, fieldtype, field, reader);
                                }
                                else
                                {
                                    SprotoHelper.Error("[SprotoCodec.DecodeSprotoObject] keytype expect  'integer/boolean/string' got '{0}'", keytype);
                                }
                            }
                            else
                            {
                                fieldobj = this.DecodeSprotoObjectList(sprotomgr, fieldtype, reader);
                            }
                        }
                        else
                        {
                            this.ReadUInt32(reader);
                            fieldobj = this.DecodeSprotoObject(sprotomgr, fieldtype, reader);
                        }
                    }
                    obj.Set(field.name, fieldobj);
                }
                else
                {
                    // for protocol version compatibility
                    UInt32 fieldsize = this.ReadUInt32(reader);
                    this.IgnoreByte(reader, fieldsize);
                }
            }
            return(obj);
        }
Пример #16
0
        // not support recursive SprotoObject
        public override string ToString()
        {
            string val;

            if (null == this.val)
            {
                val = null;
            }
            else
            {
                string typename = SprotoObject.TypeOf(this.val);
                if (typename == "integer" ||
                    typename == "boolean" ||
                    typename == "string" ||
                    typename == "binary" ||
                    typename == "double")
                {
                    val = this.val.ToString();
                }
                else if (typename == "integer_list")
                {
                    val = SprotoHelper.DumpList <Int64>(this.val as List <Int64>);
                }
                else if (typename == "boolean_list")
                {
                    val = SprotoHelper.DumpList <bool>(this.val as List <bool>);
                }
                else if (typename == "string_list")
                {
                    val = SprotoHelper.DumpList <string>(this.val as List <string>);
                }
                else if (typename == "binary_list")
                {
                    val = SprotoHelper.DumpList <byte[]>(this.val as List <byte[]>);
                }
                else if (typename == "double_list")
                {
                    val = SprotoHelper.DumpList <double>(this.val as List <double>);
                }
                else if (typename == "object_list")
                {
                    val = SprotoHelper.DumpList <SprotoObject>(this.val as List <SprotoObject>);
                }
                else if (typename == "integer_object_dict")
                {
                    val = SprotoHelper.DumpDict <Int64, SprotoObject>(this.val as Dictionary <Int64, SprotoObject>);
                }
                else if (typename == "string_object_dict")
                {
                    val = SprotoHelper.DumpDict <string, SprotoObject>(this.val as Dictionary <string, SprotoObject>);
                }
                else if (typename == "boolean_object_dict")
                {
                    val = SprotoHelper.DumpDict <bool, SprotoObject>(this.val as Dictionary <bool, SprotoObject>);
                }
                else
                {
                    val = "unknow";
                }
            }
            string fields = SprotoHelper.DumpDict <string, SprotoObject>(this.fields);

            return("{" + String.Format("type={0},val={1},fields={2}", this.type, val, fields) + "}");
        }
Пример #17
0
        private UInt32 EncodeBuildInType(SprotoField field, SprotoObject fieldobj, SprotoStream writer)
        {
            UInt32 size = 0;

            switch (field.type)
            {
            case "integer":
                if (field.is_array)
                {
                    if (field.digit == 0)
                    {
                        List <Int64> list = fieldobj.val as List <Int64>;
                        size = this.EncodeIntegerList(list, writer);
                    }
                    else
                    {
                        List <double> double_list = fieldobj.val as List <double>;
                        List <Int64>  list        = new List <Int64>();
                        double_list.ForEach(v => list.Add((Int64)(Math.Round(v * MathPow(10, field.digit)))));
                        size = this.EncodeIntegerList(list, writer);
                    }
                }
                else
                {
                    Int64 val;
                    if (field.digit == 0)
                    {
                        val = (Int64)fieldobj.val;
                    }
                    else
                    {
                        val = (Int64)(Math.Round((double)fieldobj.val * MathPow(10, field.digit)));
                    }
                    size = this.EncodeInteger(val, writer);
                }
                break;

            case "boolean":
                if (field.is_array)
                {
                    List <bool> list = fieldobj.val as List <bool>;
                    size = this.EncodeBooleanList(list, writer);
                }
                else
                {
                    SprotoHelper.Error("[SprotoCodec.EncodeBuildInType] 'boolean' should encode in header part");
                    //bool val = (bool)fieldobj.val;
                    //return this.EncodeBoolean(val,writer);
                }
                break;

            case "string":
                if (field.is_array)
                {
                    List <string> list = fieldobj.val as List <string>;
                    size = this.EncodeStringList(list, writer);
                }
                else
                {
                    string val = fieldobj.val as string;
                    size = this.EncodeString(val, writer);
                }
                break;

            case "binary":
                if (field.is_array)
                {
                    List <byte[]> list = fieldobj.val as List <byte[]>;
                    size = this.EncodeBinaryList(list, writer);
                }
                else
                {
                    byte[] val = fieldobj.val as byte[];
                    size = this.EncodeBinary(val, writer);
                }
                break;

            default:
                SprotoHelper.Error("[SprotoCodec.EncodeBuildInType] invalid buildin-type '{0}'", field.type);
                break;
            }
            return(size);
        }
Пример #18
0
        private UInt32 EncodeSprotoObject(SprotoMgr sprotomgr, SprotoType type, SprotoObject obj, SprotoStream writer)
        {
            // encode header part
            List <UInt16> tags = new List <UInt16>(type.tagfields.Keys);

            tags.Sort();
            UInt16 fieldnum     = 0;
            Int16  lasttag      = -1;
            int    fieldnum_pos = writer.Position;

            writer.Seek(SprotoCodec.SIZEOF_FIELD, SprotoStream.SEEK_CUR);
            List <UInt16> data_tags = new List <UInt16>();

            for (int i = 0; i < tags.Count; i++)
            {
                UInt16       tag      = tags[i];
                SprotoField  field    = type.GetField(tag);
                SprotoObject fieldobj = obj.Get(field.name);
                if (fieldobj != null)
                {
                    UInt16 skiptag = (UInt16)(tag - lasttag);
                    //Console.WriteLine("skiptag: tag={0},lasttag={1},skiptag={2}",tag,lasttag,skiptag);
                    lasttag = (Int16)tag;
                    if (skiptag > 1)
                    {
                        skiptag = (UInt16)((skiptag - 1) * 2 - 1);
                        this.WriteTag(writer, skiptag);
                        fieldnum++;
                    }
                    fieldnum++;
                    bool encode_in_header = false;
                    if (!field.is_array)
                    {
                        if (field.type == "integer")
                        {
                            Int64 integer;
                            if (field.digit == 0)
                            {
                                integer = (Int64)fieldobj.val;
                            }
                            else
                            {
                                integer = (Int64)(Math.Round((double)fieldobj.val * MathPow(10, field.digit)));
                            }
                            if (this.IsSmallInteger(integer))
                            {
                                encode_in_header = true;
                                UInt16 number = (UInt16)((integer + 1) * 2);
                                this.WriteTag(writer, number);
                            }
                        }
                        else if (field.type == "boolean")
                        {
                            encode_in_header = true;
                            bool   ok      = (bool)fieldobj.val;
                            UInt16 integer = (UInt16)(ok ? 1 : 0);
                            UInt16 number  = (UInt16)((integer + 1) * 2);
                            this.WriteTag(writer, number);
                        }
                    }
                    if (!encode_in_header)
                    {
                        this.WriteTag(writer, 0);
                        data_tags.Add(tag);
                    }
                    else
                    {
                    }
                }
            }
            this.FillFieldNum(writer, fieldnum_pos, fieldnum);
            UInt32 size = SprotoCodec.SIZEOF_FIELD + fieldnum * SprotoCodec.SIZEOF_FIELD;

            // encode data part
            foreach (UInt16 tag in data_tags)
            {
                SprotoField  field         = type.GetField(tag);
                SprotoType   fieldtype     = sprotomgr.GetType(field.type);
                SprotoObject fieldobj      = obj.Get(field.name);
                int          fieldsize_pos = writer.Position;
                UInt32       fieldsize     = 0;
                writer.Seek(SprotoCodec.SIZEOF_LENGTH, SprotoStream.SEEK_CUR);
                if (SprotoHelper.IsBuildInType(field.type))
                {
                    fieldsize = this.EncodeBuildInType(field, fieldobj, writer);
                }
                else
                {
                    if (field.is_array)
                    {
                        if (field.key != null)
                        {
                            string keytype = fieldtype.GetField(field.key).type;
                            if (keytype == "integer")
                            {
                                Dictionary <Int64, SprotoObject> dict = fieldobj.val as Dictionary <Int64, SprotoObject>;
                                fieldsize = this.EncodeSprotoObjectDict <Int64>(sprotomgr, dict, field, writer);
                            }
                            else if (keytype == "string")
                            {
                                Dictionary <string, SprotoObject> dict = fieldobj.val as Dictionary <string, SprotoObject>;
                                fieldsize = this.EncodeSprotoObjectDict <string>(sprotomgr, dict, field, writer);
                            }
                            else if (keytype == "boolean")
                            {
                                Dictionary <bool, SprotoObject> dict = fieldobj.val as Dictionary <bool, SprotoObject>;
                                fieldsize = this.EncodeSprotoObjectDict <bool>(sprotomgr, dict, field, writer);
                            }
                            else
                            {
                                SprotoHelper.Error("[SprotoCodec.EncodeSprotoObject] keytype expect  'integer/boolean/string' got '{0}'", keytype);
                            }
                        }
                        else
                        {
                            List <SprotoObject> list = fieldobj.val as List <SprotoObject>;
                            fieldsize = this.EncodeSprotoObjectList(sprotomgr, list, writer);
                        }
                    }
                    else
                    {
                        fieldsize = this.EncodeSprotoObject(sprotomgr, fieldtype, fieldobj, writer);
                    }
                }
                this.FillSize(writer, fieldsize_pos, fieldsize);
                size += (fieldsize + SprotoCodec.SIZEOF_LENGTH);
            }
            return(size);
        }
Пример #19
0
        // Parser from binary(*.spb)
        private static void _ParseFromBinary(SprotoMgr sprotomgr, byte[] bytes, int length)
        {
            SprotoMgr    meta   = SprotoParser.Parse(meta_proto);
            SprotoStream reader = new SprotoStream();

            reader.Write(bytes, 0, length);
            reader.Seek(0, SprotoStream.SEEK_BEGIN);
            SprotoObject        group     = meta.Decode("group", reader);
            List <SprotoObject> types     = null;
            List <SprotoObject> protocols = null;

            if (group.Get("type") != null)
            {
                types = group.Get("type");
                foreach (SprotoObject meta_type in types)
                {
                    SprotoType type = new SprotoType();
                    type.name = meta_type["name"];
                    if (meta_type.Has("fields"))
                    {
                        List <SprotoObject> fields = meta_type["fields"];
                        foreach (SprotoObject meta_field in fields)
                        {
                            SprotoField field = new SprotoField();
                            field.name     = meta_field["name"];
                            field.tag      = (UInt16)meta_field["tag"];
                            field.is_array = false;
                            if (meta_field.Has("array"))
                            {
                                field.is_array = (bool)meta_field["array"];
                            }
                            Int64 type_id;
                            if (meta_field.Has("buildin"))
                            {
                                type_id    = meta_field["buildin"];
                                field.type = SprotoParser.BuildInTypeId2Name[type_id];
                                if (type_id == 0 && meta_field.Has("type"))
                                {
                                    // fixed float
                                    field.digit = (UInt16)meta_field["type"];
                                }
                                else if (type_id == 2 && meta_field.Has("type"))
                                {
                                    // binary
                                    field.type = "binary";
                                }
                            }
                            else
                            {
                                type_id = meta_field["type"];
                                SprotoObject t = types[(int)type_id];
                                field.type = t["name"];
                                // map
                                if (meta_field.Has("key"))
                                {
                                    SprotoHelper.Assert(field.is_array);
                                    UInt16 map_index             = (UInt16)meta_field["key"];
                                    List <SprotoObject> t_fields = t["fields"];
                                    string name = null;
                                    foreach (SprotoObject f in t_fields)
                                    {
                                        if (f["tag"] == map_index)
                                        {
                                            name = f["name"];
                                            break;
                                        }
                                    }
                                    SprotoHelper.Assert(name != null, String.Format("map index {0} cann't find in type '{1}'", map_index, field.type));
                                    field.key = name;
                                }
                            }
                            type.AddField(field);
                        }
                    }
                    sprotomgr.AddType(type);
                }
            }
            if (group.Get("protocol") != null)
            {
                protocols = group.Get("protocol");
                foreach (SprotoObject meta_protocol in protocols)
                {
                    SprotoProtocol protocol = new SprotoProtocol();
                    protocol.name = meta_protocol["name"];
                    protocol.tag  = (UInt16)meta_protocol["tag"];
                    if (meta_protocol["request"] != null)
                    {
                        Int64 request = meta_protocol["request"];
                        protocol.request = types[(int)request]["name"];
                    }
                    if (meta_protocol["response"] != null)
                    {
                        Int64 response = meta_protocol["response"];
                        protocol.response = types[(int)response]["name"];
                    }
                    bool confirm = meta_protocol["confirm"];
                    if (confirm)
                    {
                        protocol.response = null;
                    }
                    sprotomgr.AddProtocol(protocol);
                }
            }
        }
Пример #20
0
        public static byte[] DumpToBinary(SprotoMgr sprotomgr)
        {
            SprotoMgr    meta  = SprotoParser.Parse(meta_proto);
            SprotoObject group = meta.NewSprotoObject("group");
            // make result stable
            List <SprotoType> types = new List <SprotoType>(sprotomgr.Types.Values);

            types.Sort(delegate(SprotoType lhs, SprotoType rhs) {
                return(string.Compare(lhs.name, rhs.name));
            });
            if (sprotomgr.Types.Count != 0)
            {
                List <SprotoObject> meta_types = new List <SprotoObject>();
                foreach (SprotoType type in types)
                {
                    SprotoObject meta_type = meta.NewSprotoObject("type");
                    meta_type["name"] = type.name;
                    if (type.fields.Count != 0)
                    {
                        List <SprotoField> fields = new List <SprotoField>(type.fields.Values);
                        fields.Sort(delegate(SprotoField lhs, SprotoField rhs) {
                            return(lhs.tag < rhs.tag ? -1 : 1);
                        });
                        List <SprotoObject> meta_fields = new List <SprotoObject>();
                        foreach (SprotoField field in fields)
                        {
                            SprotoObject meta_field = meta.NewSprotoObject("type.field");
                            meta_field["name"] = field.name;
                            meta_field["tag"]  = field.tag;
                            if (SprotoParser.BuildInTypeName2Id.ContainsKey(field.type))
                            {
                                meta_field["buildin"] = SprotoParser.BuildInTypeName2Id[field.type];
                                if (field.type == "binary")
                                {
                                    meta_field["type"] = 1;
                                }
                                else if (field.type == "integer" && field.digit > 0)
                                {
                                    meta_field["type"] = field.digit;
                                }
                            }
                            else
                            {
                                meta_field["type"] = types.IndexOf(sprotomgr.Types[field.type]);
                            }
                            if (field.is_array)
                            {
                                meta_field["array"] = true;
                                if (field.key != null)
                                {
                                    SprotoType  t = sprotomgr.Types[field.type];
                                    SprotoField f = t.fields[field.key];
                                    meta_field["key"] = f.tag;
                                }
                            }
                            meta_fields.Add(meta_field);
                        }
                        meta_type["fields"] = meta_fields;
                    }
                    meta_types.Add(meta_type);
                }
                group["type"] = meta_types;
            }
            if (sprotomgr.Protocols.Count != 0)
            {
                // make result stable
                List <SprotoProtocol> protocols = new List <SprotoProtocol>(sprotomgr.Protocols.Values);
                protocols.Sort(delegate(SprotoProtocol lhs, SprotoProtocol rhs) {
                    return(lhs.tag < rhs.tag ? -1 : 1);
                });
                List <SprotoObject> meta_protocols = new List <SprotoObject>();
                foreach (SprotoProtocol protocol in protocols)
                {
                    SprotoObject meta_protocol = meta.NewSprotoObject("protocol");
                    meta_protocol["name"] = protocol.name;
                    meta_protocol["tag"]  = protocol.tag;
                    if (protocol.request != null)
                    {
                        meta_protocol["request"] = types.IndexOf(sprotomgr.Types[protocol.request]);
                    }
                    if (protocol.response != null)
                    {
                        meta_protocol["response"] = types.IndexOf(sprotomgr.Types[protocol.response]);
                    }
                    else
                    {
                        meta_protocol["confirm"] = true;
                    }
                    meta_protocols.Add(meta_protocol);
                }
                group["protocol"] = meta_protocols;
            }
            SprotoStream writer = new SprotoStream();

            meta.Encode(group, writer);
            byte[] result = new byte[writer.Position];
            for (int i = 0; i < writer.Position; i++)
            {
                result[i] = writer.Buffer[i];
            }
            return(result);
        }
Пример #21
0
        public RpcMessage UnpackMessage(byte[] bytes, int size)
        {
            RpcMessage message  = null;
            int        bin_size = 0;

            byte[] bin = this.S2C.Unpack(bytes, 0, size, out bin_size);
            this.reader.Seek(0, SprotoStream.SEEK_BEGIN);            // clear stream
            this.reader.Buffer = bin;

            SprotoObject header = this.S2C.Decode(this.package, this.reader);

            if (header["type"] != null)
            {
                // request
                UInt16         tag      = (UInt16)header["type"];
                SprotoProtocol protocol = this.S2C.GetProtocol(tag);
                SprotoObject   request  = null;
                if (protocol.request != null)
                {
                    request = this.S2C.Decode(protocol.request, this.reader);
                }

                message      = new RpcMessage();
                message.type = "request";
                if (header["session"] != null)
                {
                    message.session = header["session"];
                }
                if (header["ud"] != null)
                {
                    message.ud = header["ud"];
                }
                message.proto = protocol.name;
                message.tag   = protocol.tag;

                message.request = request;
            }
            else
            {
                // response
                SprotoHelper.Assert(header["session"] != null, "session not found");
                Int64 session = header["session"];
                if (this.sessions.TryGetValue(session, out message))
                {
                    //Console.WriteLine("remove session {0}",session);
                    this.sessions.Remove(session);
                }
                SprotoHelper.Assert(message != null, "unknow session");
                message.type = "response";
                if (header["ud"] != null)
                {
                    message.ud = header["ud"];
                }
                SprotoProtocol protocol = this.C2S.GetProtocol(message.tag);
                if (protocol.response != null)
                {
                    SprotoObject response = this.C2S.Decode(protocol.response, this.reader);
                    message.response = response;
                }
            }
            return(message);
        }