示例#1
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);
                 }
             }
         }
     }
 }
示例#2
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);
        }
示例#3
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);
        }