예제 #1
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);
        }
예제 #2
0
        private void check_protocol()
        {
            Dictionary <UInt16, bool> defined_tag = new Dictionary <UInt16, bool>();

            foreach (var protocol in this.Protocols.Values)
            {
                UInt16 tag      = protocol.tag;
                string name     = protocol.name;
                string request  = protocol.request;
                string response = protocol.response;
                if (defined_tag.ContainsKey(tag))
                {
                    SprotoHelper.Error("redefined protocol tag '{0}' at '{1}'", tag, name);
                }
                if (request != null && this.GetType(request) == null)
                {
                    SprotoHelper.Error("undefined request type '{0}' in protocol '{1}'", request, name);
                }
                if (response != null && this.GetType(response) == null)
                {
                    SprotoHelper.Error("undefined response type '{0}' in protocol '{1}'", response, name);
                }
                defined_tag.Add(tag, true);
            }
        }
예제 #3
0
        private string check_type(string ptype, string fieldtype)
        {
            if (SprotoHelper.IsBuildInType(fieldtype))
            {
                return(fieldtype);
            }
            string fullname = ptype + "." + fieldtype;

            if (this.GetType(fullname) != null)
            {
                return(fullname);
            }
            // backtrace find
            List <string> list = new List <string>(ptype.Split('.'));

            list.RemoveAt(list.Count - 1);
            if (list.Count > 0)
            {
                string pptype = String.Join(".", list.ToArray());
                return(this.check_type(pptype, fieldtype));
            }
            else if (this.GetType(fieldtype) != null)
            {
                return(fieldtype);
            }
            else
            {
                return(null);
            }
        }
예제 #4
0
        private List <Int64> DecodeIntegerList(SprotoStream reader)
        {
            List <Int64> list = new List <Int64>();
            UInt32       size = this.ReadUInt32(reader);

            if (size == 0)
            {
                return(list);
            }
            UInt32 sizeof_integer = (UInt32)reader.ReadByte();

            size--;
            for (; size > 0; size = size - sizeof_integer)
            {
                Int64 integer;
                if (sizeof_integer == sizeof(UInt32))
                {
                    Int32 number = (Int32)this.ReadUInt32(reader);
                    integer = (Int64)number;
                }
                else
                {
                    integer = (Int64)this.ReadUInt64(reader);
                }
                list.Add(integer);
            }
            if (size != 0)
            {
                SprotoHelper.Error("[SprotoCodec.DecodeIntegerList] fail");
            }
            return(list);
        }
예제 #5
0
        private static void _Parse(SprotoMgr sprotomgr, string proto, string filename)
        {
            Lexer lexer = new Lexer(proto, filename);

            while (lexer.tokens.Count > 0)
            {
                Token token = lexer.tokens[0];
                if ("eof" == token.type)
                {
                    break;
                }
                switch (token.type)
                {
                case "word":
                    SprotoProtocol protocol = parse_protocol(lexer, sprotomgr);
                    sprotomgr.AddProtocol(protocol);
                    break;

                case "point":
                    lexer.pop_token();
                    SprotoType type = parse_type(lexer);
                    sprotomgr.AddType(type);
                    break;

                case "space":
                    ignore(lexer, "space");
                    break;

                default:
                    SprotoHelper.Error(lexer.error_pos(token.line, token.column) + "invalid token:<{0},{1}>", token.type, token.val);
                    break;
                }
            }
        }
예제 #6
0
        /*
         * public void seek (int pos) {
         *      if (pos < 0 || pos >= this.length)
         *              SprotoHelper.Error("{0}: seek invalid pos: {1}",this.filename,pos);
         *      this.pos = pos;
         * }
         */

        public void check_word_size(string word, int max_size, int line, int column)
        {
            if (word.Length >= max_size)
            {
                SprotoHelper.Error(this.error_pos(line, column) + "word '{0}' size > {0}", word, max_size);
            }
        }
예제 #7
0
        private static SprotoField parse_field(Lexer lexer, SprotoType type)
        {
            SprotoField field = new SprotoField();
            Token       token = expect(lexer, "word", "space");

            field.name = token.val;
            // allow colon follow by tag,eg: field tag: type
            token = expect(lexer, "tag");
            ignore(lexer, "space");
            field.tag = Convert.ToUInt16(token.val);
            if (field.tag >= SprotoParser.MAX_FIELD_TAG)
            {
                SprotoHelper.Error(lexer.error_pos(token.line, token.column, type) + "{0} field's tag {1} >= {2}", field.name, field.tag, SprotoParser.MAX_FIELD_TAG);
            }
            expect(lexer, "colon", "space");
            token = optional(lexer, "star");
            if (token != null)
            {
                field.is_array = true;
            }
            token      = expect(lexer, "word");
            field.type = token.val;
            string fieldtype = field.type;

            token = optional(lexer, "key_start");
            if (token != null)
            {
                // allow field tag : type(space+key+space)
                ignore(lexer, "space");
                token = expect(lexer, "word|tag");
                if ("tag" == token.type)
                {
                    if (fieldtype != "integer")
                    {
                        SprotoHelper.Error(lexer.error_pos(token.line, token.column, type) + "decimal index expect 'integer' got '{0}'", fieldtype);
                    }
                    field.digit = Convert.ToUInt16(token.val);
                    if (field.digit > SprotoParser.MAX_DECIMAL)
                    {
                        SprotoHelper.Error(lexer.error_pos(token.line, token.column, type) + "decimal index {0} > {1}", field.digit, SprotoParser.MAX_DECIMAL);
                    }
                }
                else
                {
                    if (SprotoHelper.IsBuildInType(fieldtype))
                    {
                        SprotoHelper.Error(lexer.error_pos(token.line, token.column, type) + "map index expect 'usertype' got '{0}'", fieldtype);
                    }
                    field.key = token.val;
                }
                ignore(lexer, "space");
                expect(lexer, "key_end", "space");
            }
            else
            {
                expect(lexer, "space");
                ignore(lexer, "space");
            }
            return(field);
        }
예제 #8
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);
        }
예제 #9
0
 public void AddType(SprotoType type)
 {
     if (this.GetType(type.name) != null)
     {
         SprotoHelper.Error("redefined type '{0}'", type.name);
     }
     this.Types.Add(type.name, type);
 }
예제 #10
0
        public void AddType(SprotoType type)
        {
            string name = type.name;

            if (this.nest_types.ContainsKey(name))
            {
                SprotoHelper.Error("redefined nest_type '{0} in type '{1}", name, this.name);
            }
            this.nest_types.Add(name, type);
        }
예제 #11
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);
        }
예제 #12
0
 public RpcPackage PackMessage(RpcMessage message)
 {
     if (message.type == "request")
     {
         return(this.PackRequest(message.proto, message.request, message.session, message.ud));
     }
     else
     {
         SprotoHelper.Assert(message.type == "response", String.Format("invalid message type: {0}", message.type));
         return(this.PackResponse(message.proto, message.response, message.session, message.ud));
     }
 }
예제 #13
0
 public void AddProtocol(SprotoProtocol protocol)
 {
     if (this.Protocols.ContainsKey(protocol.name))
     {
         SprotoHelper.Error("redefined protocol name '{0}' tag is '{1}'", protocol.name, protocol.tag);
     }
     if (this.TagProtocols.ContainsKey(protocol.tag))
     {
         SprotoHelper.Error("redefined protocol tag '{0}' name is '{1}'", protocol.tag, protocol.name);
     }
     this.Protocols.Add(protocol.name, protocol);
     this.TagProtocols.Add(protocol.tag, protocol);
 }
예제 #14
0
        public void AddField(SprotoField field)
        {
            string name = field.name;
            UInt16 tag  = field.tag;

            if (this.fields.ContainsKey(name))
            {
                SprotoHelper.Error("redefined field name '{0} {1}' in type '{2}'", name, tag, this.name);
            }
            if (this.tagfields.ContainsKey(tag))
            {
                SprotoHelper.Error("redefined field tag '{0} {1}' in type '{2}'", name, tag, this.name);
            }
            this.fields.Add(name, field);
            this.tagfields.Add(tag, field);
        }
예제 #15
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);
        }
예제 #16
0
        private List <bool> DecodeBooleanList(SprotoStream reader)
        {
            List <bool> list = new List <bool>();
            UInt32      size = this.ReadUInt32(reader);

            for (; size > 0; size--)
            {
                bool ok = this.DecodeBoolean(reader);
                list.Add(ok);
            }
            if (size != 0)
            {
                SprotoHelper.Error("[SprotoCodec.DecodeBooleanList] fail");
            }
            return(list);
        }
예제 #17
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);
     }
 }
예제 #18
0
        public byte[] Unpack(byte[] src, int start, int length, out int size, byte[] dest = null)
        {
            if (null == dest)
            {
                int dest_length = SprotoPacker.NeedBufferSize("unpack", length);
                dest = new byte[dest_length];
            }
            int srcpos  = start;
            int destpos = 0;

            while (srcpos < start + length)
            {
                int  n;
                byte header = src[srcpos++];
                if (0xff == header)
                {
                    n = src[srcpos++];
                    n = (n + 1) * 8;
                    this.memcpy(dest, destpos, src, srcpos, n);
                    srcpos  += n;
                    destpos += n;
                }
                else
                {
                    for (int i = 0; i < 8; i++)
                    {
                        bool notzero = ((header >> i) & 1) == 1 ? true : false;
                        if (notzero)
                        {
                            byte b = src[srcpos++];
                            dest[destpos++] = b;
                        }
                        else
                        {
                            dest[destpos++] = 0;
                        }
                    }
                }
            }
            if (srcpos != start + length)
            {
                SprotoHelper.Error("[SprotoPacker.UnPack] fail");
            }
            size = destpos;
            return(dest);
        }
예제 #19
0
        private static Token expect(Lexer lexer, string need, string need_and_ignore = null)
        {
            string[] types = need.Split('|');
            Token    token = lexer.pop_token();

            if (-1 == Array.IndexOf(types, token.type))
            {
                SprotoHelper.Error(lexer.error_pos(token.line, token.column) + "token expect type '{0}',got '{1}' {2}", need, token.type, token.val);
            }
            if (need_and_ignore != null)
            {
                // expect at least one
                expect(lexer, need_and_ignore);
                ignore(lexer, need_and_ignore);
            }
            return(token);
        }
예제 #20
0
 private void _flattypename(SprotoType type)
 {
     foreach (var nest_type in type.nest_types.Values)
     {
         string fullname = String.Format("{0}.{1}", type.name, nest_type.name);
         nest_type.name = fullname;
         this.AddType(nest_type);
         this._flattypename(nest_type);
     }
     foreach (var field in type.fields.Values)
     {
         string fieldtype = field.type;
         string fullname  = this.check_type(type.name, fieldtype);
         if (null == fullname)
         {
             SprotoHelper.Error("undefined type '{0}' in field '{1}.{2}'", fieldtype, type.name, field.name);
         }
         field.type = fullname;
     }
 }
예제 #21
0
        private Int64 DecodeInteger(SprotoStream reader)
        {
            UInt32 sizeof_integer = this.ReadUInt32(reader);
            Int64  integer;

            if (sizeof_integer == 4)
            {
                Int32 number = (Int32)this.ReadUInt32(reader);
                integer = (Int64)number;
            }
            else
            {
                if (sizeof_integer != 8)
                {
                    SprotoHelper.Error("[SprotoCodec.DecodeInteger] invalid integer size '{0}'", sizeof_integer);
                }
                integer = (Int64)this.ReadUInt64(reader);
            }
            return(integer);
        }
예제 #22
0
 private void check_type()
 {
     foreach (var type in this.Types.Values)
     {
         foreach (var field in type.fields.Values)
         {
             if (!SprotoHelper.IsBuildInType(field.type) && (null == this.GetType(field.type)))
             {
                 SprotoHelper.Error("undefined type '{0}' in field '{1}.{2}'", field.type, type.name, field.name);
             }
             if (field.key != null)
             {
                 SprotoType fieldtype = this.GetType(field.type);
                 if (null == fieldtype.GetField(field.key))
                 {
                     SprotoHelper.Error("map index '{0}' cann't found in type '{1}'", field.key, field.type);
                 }
             }
         }
     }
 }
예제 #23
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);
        }
예제 #24
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);
        }
예제 #25
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);
        }
예제 #26
0
        private List <byte[]> DecodeBinaryList(SprotoStream reader)
        {
            List <byte[]> list = new List <byte[]>();
            UInt32        size = this.ReadUInt32(reader);

            while (size > 0)
            {
                byte[] bytes     = this.DecodeBinary(reader);
                UInt32 elem_size = (UInt32)(bytes.Length + SprotoCodec.SIZEOF_LENGTH);
                size = size - elem_size;
                if (size < 0)
                {
                    SprotoHelper.Error("[SprotoCodec.DecodeBinaryList] fail");
                }
                list.Add(bytes);
            }
            if (size != 0)
            {
                SprotoHelper.Error("[SprotoCodec.DecodeBinaryList] fail");
            }
            return(list);
        }
예제 #27
0
 public void Expand(int size)
 {
     if (this.Capcity - this.pos < size)
     {
         int old_capcity = this.Capcity;
         int capcity     = this.Capcity;
         while (capcity - this.pos < size)
         {
             capcity = capcity * 2;
         }
         if (capcity >= SprotoStream.MAX_SIZE)
         {
             SprotoHelper.Error("object is too large(>{0})", SprotoStream.MAX_SIZE);
         }
         byte [] new_buffer = new byte[capcity];
         for (int i = 0; i < old_capcity; i++)
         {
             new_buffer[i] = this.buffer[i];
         }
         this.buffer = new_buffer;
     }
 }
예제 #28
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);
        }
예제 #29
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);
        }
예제 #30
0
        public int Seek(int offset, int whence)
        {
            switch (whence)
            {
            case SprotoStream.SEEK_BEGIN:
                this.pos = 0 + offset;
                break;

            case SprotoStream.SEEK_CUR:
                this.pos = this.pos + offset;
                break;

            case SprotoStream.SEEK_END:
                this.pos = this.Capcity + offset;
                break;

            default:
                SprotoHelper.Error("[Sproto.Stream.Seek] invalid whence:{0}", whence);
                break;
            }
            this.Expand(0);
            return(this.pos);
        }