private void FillSize(SprotoStream writer, int pos, UInt32 size) { //Console.WriteLine("*FillSize: pos={0},size={1}",pos,size); int curpos = writer.Position; writer.Seek(pos, SprotoStream.SEEK_BEGIN); this.WriteUInt32(writer, size); writer.Seek(curpos, SprotoStream.SEEK_BEGIN); }
private void FillFieldNum(SprotoStream writer, int pos, UInt16 fieldnum) { //Console.WriteLine("*FillFieldNum: pos={0},fieldnum={1}",pos,fieldnum); int curpos = writer.Position; writer.Seek(pos, SprotoStream.SEEK_BEGIN); this.WriteUInt16(writer, fieldnum); writer.Seek(curpos, SprotoStream.SEEK_BEGIN); }
public byte[] Invoke <T>(SprotoTypeBase request = null, long?session = null) { int tag = protocol[typeof(T)]; ProtocolFunctionDictionary.MetaInfo info = protocol[tag]; #if (!INCLUDE_IL2CPP) if (request != null && request.GetType() != info.Request.Key) { throw new Exception("request type: " + request.GetType().ToString() + "not is expected. [" + info.Request.Key.GetType().ToString() + "]"); } #endif package.clear(); package.type = tag; if (session != null) { rpc.sessionDictionary.Add((long)session, info.Response.Value); package.session = (long)session; } stream.Seek(0, System.IO.SeekOrigin.Begin); int len = package.encode(stream); if (request != null) { len += request.encode(stream); } return(spack.pack(stream.Buffer, len)); }
private void test_array() { /* * .Test { * var1 0: *boolean * var2 4: *integer * var3 5: *string * } * */ SprotoTypeSerialize serialize = new SprotoTypeSerialize (20); List<Int64> data = new List<Int64> (); data.Add (4); data.Add (0x1123); data.Add (0x1122334455); data.Add (-0x778899aabb); data.Add (-6); List<bool> b_data = new List<bool> (); b_data.Add (true); b_data.Add (false); b_data.Add (true); List<string> str_data = new List<string> (); str_data.Add ("abc"); str_data.Add ("1234"); str_data.Add ("fgcbvb"); byte[] test_result_data = { 0X04, 0X00, 0X00, 0X00, 0X05, 0X00, 0X00, 0X00, 0X00, 0X00, 0X03, 0X00, 0X00, 0X00, 0X01, 0X00, 0X01, 0X29, 0X00, 0X00, 0X00, 0X08, 0X04, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X23, 0X11, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X55, 0X44, 0X33, 0X22, 0X11, 0X00, 0X00, 0X00, 0X45, 0X55, 0X66, 0X77, 0X88, 0Xff, 0Xff, 0Xff, 0Xfa, 0Xff, 0Xff, 0Xff, 0Xff, 0Xff, 0Xff, 0Xff, 0X19, 0X00, 0X00, 0X00, 0X03, 0X00, 0X00, 0X00, 0X61, 0X62, 0X63, 0X04, 0X00, 0X00, 0X00, 0X31, 0X32, 0X33, 0X34, 0X06, 0X00, 0X00, 0X00, 0X66, 0X67, 0X63, 0X62, 0X76, 0X62, }; SprotoStream stream = new SprotoStream (); serialize.open (stream); serialize.write_boolean (b_data, 0); serialize.write_integer (data, 4); serialize.write_string (str_data, 5); int len = serialize.close (); byte[] buffer = new byte[len]; stream.Seek (0, System.IO.SeekOrigin.Begin); stream.Read (buffer, 0, len); Console.Write ("====== array dump ========"); dump_bytes (buffer); assert(buffer, test_result_data); }
public byte[] encode () { SprotoStream stream = new SprotoStream (); this.encode (stream); int len = stream.Position; byte[] buffer = new byte[len]; stream.Seek (0, SeekOrigin.Begin); stream.Read (buffer, 0, len); return buffer; }
public byte[] encode() { SprotoStream stream = new SprotoStream(); this.encode(stream); int len = stream.Position; byte[] buffer = new byte[len]; stream.Seek(0, SeekOrigin.Begin); stream.Read(buffer, 0, len); return(buffer); }
private UInt32 EncodeBinaryList(List <byte[]> binary_list, SprotoStream writer) { UInt32 size = 0; for (int i = 0; i < binary_list.Count; i++) { byte[] binary = binary_list[i]; int length_pos = writer.Position; writer.Seek(SprotoCodec.SIZEOF_LENGTH, SprotoStream.SEEK_CUR); UInt32 length = this.EncodeBinary(binary, writer); this.FillSize(writer, length_pos, length); size += (SprotoCodec.SIZEOF_LENGTH + length); } return(size); }
private UInt32 EncodeStringList(List <string> string_list, SprotoStream writer) { UInt32 size = 0; for (int i = 0; i < string_list.Count; i++) { string str = string_list[i]; int length_pos = writer.Position; writer.Seek(SprotoCodec.SIZEOF_LENGTH, SprotoStream.SEEK_CUR); UInt32 length = this.EncodeString(str, writer); this.FillSize(writer, length_pos, length); size += (SprotoCodec.SIZEOF_LENGTH + length); } return(size); }
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); }
public RequestInfo Dispatch(byte[] buffer) { buffer = this.spack.unpack(buffer); PackageType.Package package = new PackageType.Package(); int offset = package.init(buffer); int tag = (int)package.type; ProtocolFunctionDictionary.ProtocolInfo pinfo = ProtocolFunctionDictionary.GetProtocolInfo(tag); RequestInfo info; info.Tag = tag; info.Obj = ProtocolFunctionDictionary.GenRequest((int)package.type, buffer, offset); info.Session = (int)package.session; if (pinfo.Response == null) { info.Response = null; } else { info.Response = delegate(SprotoProtocolBase protocol) { if (pinfo.Response != protocol.GetResponse().GetType()) { throw new Exception("response type: " + protocol.GetType().ToString() + " not is expected. [" + pinfo.Response.ToString() + "]"); } this.stream.Seek(0, System.IO.SeekOrigin.Begin); PackageType.Package pkg = new PackageType.Package(); pkg.session = package.session; pkg.encode(this.stream); protocol.GetResponse().encode(this.stream); int len = stream.Position; byte[] data = new byte[len]; stream.Seek(0, System.IO.SeekOrigin.Begin); stream.Read(data, 0, len); return(this.spack.pack(data)); }; } return(info); }
private void test_field() { SprotoTypeSerialize serialize = new SprotoTypeSerialize (20); /* * .Test { * var1 0: integer * var2 1: string * var3 5: intger * var4 7: boolean * var5 9: integer * var6 10: boolean * var7 12: intger * } * */ byte[] test_result_data = { 0X0b, 0X00, 0X00, 0X00, 0X00, 0X00, 0X05, 0X00, 0Xac, 0X88, 0X01, 0X00, 0X04, 0X00, 0X01, 0X00, 0X00, 0X00, 0X02, 0X00, 0X01, 0X00, 0X46, 0X22, 0X04, 0X00, 0X00, 0X00, 0Xde, 0Xff, 0Xff, 0Xff, 0X0b, 0X00, 0X00, 0X00, 0X74, 0X65, 0X73, 0X74, 0X5f, 0X73, 0X74, 0X72, 0X69, 0X6e, 0X67, 0X08, 0X00, 0X00, 0X00, 0X66, 0X55, 0X44, 0X33, 0X22, 0X11, 0X00, 0X00 }; SprotoStream stream = new SprotoStream (); serialize.open (stream); serialize.write_integer (-34, 0); serialize.write_string ("test_string", 1); serialize.write_integer (0x4455, 5); serialize.write_boolean (true, 7); serialize.write_integer (0x112233445566, 9); serialize.write_boolean (false, 10); serialize.write_integer (0x1122, 12); int len = serialize.close (); byte[] buffer = new byte[len]; stream.Seek (0, System.IO.SeekOrigin.Begin); stream.Read (buffer, 0, len); Console.WriteLine ("======== encode buffer ==========="); dump_bytes (buffer); assert(buffer, test_result_data); }
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); }
public RpcInfo Dispatch(byte[] buffer, int offset = 0) { buffer = this.spack.unpack(buffer, buffer.Length - offset); offset = this.package.init(buffer); RpcInfo info; // request if (this.package.HasType) { int tag = (int)this.package.type; info.session = null; info.tag = tag; info.responseObj = null; info.requestObj = (this.protocol != null)?(this.protocol.GenRequest(tag, buffer, offset)):(null); info.type = RpcType.REQUEST; info.Response = null; if (this.package.HasSession) { long session = this.package.session; info.Response = delegate(SprotoTypeBase response) { ProtocolFunctionDictionary.MetaInfo pinfo = this.protocol [tag]; #if (!INCLUDE_IL2CPP) if (response.GetType() != pinfo.Response.Key) { throw new Exception("response type: " + response.GetType().ToString() + "is not expected.(" + pinfo.Response.Key.ToString() + ")"); } #endif this.stream.Seek(0, System.IO.SeekOrigin.Begin); this.package.clear(); this.package.session = session; this.package.encode(this.stream); response.encode(this.stream); int len = stream.Position; byte[] data = new byte[len]; stream.Seek(0, System.IO.SeekOrigin.Begin); stream.Read(data, 0, len); return(this.spack.pack(data)); }; } } else // response { if (!this.package.HasSession) { throw new Exception("session not found"); } ProtocolFunctionDictionary.typeFunc response; if (!this.sessionDictionary.TryGetValue(this.package.session, out response)) { throw new Exception("Unknown session: " + this.package.session); } info.tag = null; info.session = this.package.session; info.requestObj = null; info.Response = null; info.type = RpcType.RESPONSE; info.responseObj = (response == null)?(null):(response(buffer, offset)); } return(info); }
// 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); } } }
private void test_array() { /* * .Test { * var1 0: *boolean * var2 4: *integer * var3 5: *string * } * */ SprotoTypeSerialize serialize = new SprotoTypeSerialize (20); List<Int64> data = new List<Int64> (); data.Add (4); data.Add (0x1123); data.Add (0x1122334455); data.Add (-0x778899aabb); data.Add (-6); List<bool> b_data = new List<bool> (); b_data.Add (true); b_data.Add (false); b_data.Add (true); List<string> str_data = new List<string> (); str_data.Add ("中文显示"); str_data.Add ("1234"); str_data.Add ("fgcbvb"); byte[] test_result_data = { 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x29, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x45, 0x55, 0x66, 0x77, 0x88, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87, 0xe6, 0x98, 0xbe, 0xe7, 0xa4, 0xba, 0x04, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x34, 0x06, 0x00, 0x00, 0x00, 0x66, 0x67, 0x63, 0x62, 0x76, 0x62, }; SprotoStream stream = new SprotoStream (); serialize.open (stream); serialize.write_boolean (b_data, 0); serialize.write_integer (data, 4); serialize.write_string (str_data, 5); int len = serialize.close (); byte[] buffer = new byte[len]; stream.Seek (0, System.IO.SeekOrigin.Begin); stream.Read (buffer, 0, len); Console.Write ("====== array dump ========"); dump_bytes (buffer); assert(buffer, test_result_data); }
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); }