public SpStream Response(int session, SpObject args) { SpObject header = new SpObject(); header.Insert("session", session); SpStream encode_stream = new SpStream(); mHostTypeManager.Codec.Encode(mHeaderType, header, encode_stream); if (session != 0 && mSessions.ContainsKey(session)) { mHostTypeManager.Codec.Encode(mSessions[session].Response, args, encode_stream); } SpStream pack_stream = new SpStream(); encode_stream.Position = 0; SpPacker.Pack(encode_stream, pack_stream); pack_stream.Position = 0; return(pack_stream); }
private SpStream EncodeRequest(string proto, SpObject args, int session) { if (mAttachTypeManager == null || mHostTypeManager == null || mHeaderType == null) { return(null); } SpProtocol protocol = mAttachTypeManager.GetProtocolByName(proto); if (protocol == null) { return(null); } SpObject header = new SpObject(); header.Insert("type", protocol.Tag); if (session != 0) { header.Insert("session", session); } SpStream stream = mHostTypeManager.Codec.Encode(mHeaderType, header); if (stream == null) { return(null); } if (args != null) { if (mAttachTypeManager.Codec.Encode(protocol.Request, args, stream) == false) { if (stream.IsOverflow()) { if (stream.Position > SpCodec.MAX_SIZE) { return(null); } int size = stream.Position; size = ((size + 7) / 8) * 8; stream = new SpStream(size); if (mAttachTypeManager.Codec.Encode(protocol.Request, args, stream) == false) { return(null); } } else { return(null); } } } if (session != 0) { mSessions[session] = protocol; } return(stream); }
private SpObject DecodeInternal(SpType type) { if (mStream == null || type == null) { return(null); } // buildin type decoding should not be here if (mTypeManager.IsBuildinType(type)) { return(null); } SpObject obj = new SpObject(); List <int> tags = new List <int>(); int current_tag = 0; short fn = mStream.ReadInt16(); for (short i = 0; i < fn; i++) { int value = (int)mStream.ReadUInt16(); if (value == 0) { tags.Add(current_tag); current_tag++; } else { if (value % 2 == 0) { SpField f = type.GetFieldByTag(current_tag); if (f == null) { return(null); } value = value / 2 - 1; if (f.Type == mTypeManager.Integer) { obj.Insert(f.Name, value); } else if (f.Type == mTypeManager.Boolean) { obj.Insert(f.Name, (value == 0 ? false : true)); } else { return(null); } current_tag++; } else { current_tag += (value + 1) / 2; } } } for (int c = 0; c < tags.Count; c++) { int tag = tags[c]; SpField f = type.GetFieldByTag(tag); if (f == null) { return(null); } if (f.IsTable) { int size = mStream.ReadInt32(); if (f.Type == mTypeManager.Integer) { byte n = mStream.ReadByte(); int count = (size - 1) / n; SpObject tbl = new SpObject(); for (int i = 0; i < count; i++) { switch (n) { case 4: tbl.Insert(i, mStream.ReadInt32()); break; case 8: tbl.Insert(i, mStream.ReadInt64()); break; default: return(null); } } obj.Insert(f.Name, tbl); } else if (f.Type == mTypeManager.Boolean) { SpObject tbl = new SpObject(); for (int i = 0; i < size; i++) { tbl.Insert(i, mStream.ReadBoolean()); } obj.Insert(f.Name, tbl); } else if (f.Type == mTypeManager.String) { SpObject tbl = new SpObject(); int k = 0; while (size > 0) { int str_len = mStream.ReadInt32(); size -= 4; tbl.Insert(k, Encoding.UTF8.GetString(mStream.ReadBytes(str_len), 0, str_len)); k++; size -= str_len; } obj.Insert(f.Name, tbl); } else if (f.Type == null) { // unknown type mStream.ReadBytes(size); } else { SpObject tbl = new SpObject(); int k = 0; while (size > 0) { int obj_len = mStream.ReadInt32(); size -= 4; SpObject o = DecodeInternal(f.Type); if (f.KeyName != null) { tbl.Insert(o.AsTable()[f.KeyName].Value, o); } else { tbl.Insert(k, o); } k++; size -= obj_len; } obj.Insert(f.Name, tbl); } } else { int size = mStream.ReadInt32(); if (f.Type == mTypeManager.Integer) { switch (size) { case 4: obj.Insert(f.Name, mStream.ReadInt32()); break; case 8: obj.Insert(f.Name, mStream.ReadInt64()); break; default: return(null); } } else if (f.Type == mTypeManager.Boolean) { // boolean should not be here return(null); } else if (f.Type == mTypeManager.String) { obj.Insert(f.Name, Encoding.UTF8.GetString(mStream.ReadBytes(size), 0, size)); } else if (f.Type == null) { // unknown type mStream.ReadBytes(size); } else { obj.Insert(f.Name, DecodeInternal(f.Type)); } } } return(obj); }