public SpStream Encode(SpType type, SpObject obj) { SpStream stream = new SpStream(); if (Encode(type, obj, stream) == false) { if (stream.IsOverflow()) { if (stream.Position > MAX_SIZE) { return(null); } int size = stream.Position; size = ((size + 7) / 8) * 8; stream = new SpStream(size); if (Encode(type, obj, stream) == false) { return(null); } } else { return(null); } } return(stream); }
public bool Request(string proto, SpObject args, int session, SpStream stream) { SpStream encode_stream = EncodeRequest(proto, args, session); encode_stream.Position = 0; return(SpPacker.Pack(encode_stream, stream)); }
public SpRpcResult Dispatch(SpStream stream) { SpStream unpack_stream = SpPacker.Unpack(stream); unpack_stream.Position = 0; SpObject header = mHostTypeManager.Codec.Decode(mHeaderType, unpack_stream); int session = 0; if (header["session"] != null) { session = header["session"].AsInt(); } int ud = 0; if (header["ud"] != null) { ud = header["ud"].AsInt(); } if (header["type"] != null) { // handle request SpProtocol protocol = mHostTypeManager.GetProtocolByTag(header["type"].AsInt()); SpObject obj = mHostTypeManager.Codec.Decode(protocol.Request, unpack_stream); if (session != 0) { mSessions[session] = protocol; } return(new SpRpcResult(session, protocol, SpRpcOp.Request, obj, ud)); } else { // handle response if (mSessions.ContainsKey(session) == false) { return(new SpRpcResult()); } SpProtocol protocol = mSessions[session]; mSessions.Remove(session); if (protocol == null) { return(new SpRpcResult()); } if (protocol.Response == null) { return(new SpRpcResult(session, protocol, SpRpcOp.Response, null, ud)); } SpObject obj = mAttachTypeManager.Codec.Decode(protocol.Response, unpack_stream); return(new SpRpcResult(session, protocol, SpRpcOp.Response, obj, ud)); } }
public static bool Unpack(SpStream input, SpStream output) { int src_size = input.Tail; int src_offset = input.Offset; byte[] src = input.Buffer; while (src_offset < src_size) { byte header = src[src_offset]; src_offset++; if (header == 0xff) { if (src_offset > src_size) { return(false); } int n = (src[src_offset] + 1) * 8; if (src_size - src_offset < n + 1) { return(false); } src_offset++; output.Write(src, src_offset, n); src_offset += n; } else { for (int i = 0; i < 8; i++) { int nz = (header >> i) & 1; if (nz != 0) { if (src_offset > src_size) { return(false); } output.Write(src[src_offset]); src_offset++; } else { output.Write((byte)0); } } } } return(output.IsOverflow() == false); }
public bool Encode(SpType type, SpObject obj, SpStream stream) { if (type == null || obj == null || stream == null) { return(false); } //mStream = stream; bool success = EncodeInternal(type, obj, stream); return(success && stream.IsOverflow() == false); }
public static void WriteFF(byte[] src, int src_offset, SpStream output, int n, int correctPos) { int align8_n = (n + 7) & (~7); output.Write((byte)0xff); output.Write((byte)(align8_n / 8 - 1)); output.Write(src, src_offset, n); for (int i = 0; i < align8_n - n; i++) { output.Write((byte)0); } output.CorrectLength(correctPos); }
private static int PackSeg(byte[] src, int src_offset, SpStream output, int n) { byte header = 0; int notzero = 0; int dest_begin = output.Position; output.Position++; for (int i = 0; i < 8; i++) { if (src[src_offset + i] != 0) { notzero++; header |= (byte)(1 << i); output.Write(src[src_offset + i]); } } if ((notzero == 7 || notzero == 6) && n > 0) { notzero = 8; } if (notzero == 8) { if (n > 0) { return(8); } else { return(10); } } int dest_end = output.Position; output.Position = dest_begin; output.Write(header); output.Position = dest_end; return(notzero + 1); }
public static SpStream Unpack(SpStream input) { SpStream stream = new SpStream(); int pos = input.Position; if (Unpack(input, stream) == false) { stream = new SpStream(stream.Position); input.Position = pos; if (Unpack(input, stream) == false) { return(null); } } return(stream); }
public static SpStream Pack(SpStream input) { SpStream stream = new SpStream(); int pos = input.Position; if (Pack(input, stream) == false) { int size = stream.Position; size = ((size + 7) / 8) * 8; stream = new SpStream(size); input.Position = pos; // do we need this check? it's not possible it will return false this time if (Pack(input, stream) == false) { return(null); } } return(stream); }
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); }
public static bool Pack(SpStream input, SpStream output) { int src_size = input.Length; if (src_size % 8 != 0) { int new_size = ((src_size + 7) / 8) * 8; if (input.Capacity < new_size) { SpStream new_input = new SpStream(new_size); Array.Copy(input.Buffer, input.Offset, new_input.Buffer, new_input.Offset, input.Length); new_input.Position = new_input.Offset; input = new_input; src_size = new_size; } else { int pos = input.Position; input.Position = input.Tail; for (int i = src_size; i < new_size; i++) { input.Write((byte)0); } input.Position = pos; } } int src_start = input.Offset; int src_offset = input.Offset; byte[] src = input.Buffer; int ff_n = 0; int ff_src_start = 0; int ff_dest_start = 0; for (; src_offset < src_size; src_offset += 8) { int pos = output.Position; int n = PackSeg(src, src_offset, output, ff_n); if (n == 10) { ff_src_start = src_offset; ff_dest_start = pos; ff_n = 1; } else if (n == 8 && ff_n > 0) { ff_n++; if (ff_n == 256) { output.Position = ff_dest_start; WriteFF(src, ff_src_start, output, 256 * 8, n); ff_n = 0; } } else { if (ff_n > 0) { output.Position = ff_dest_start; WriteFF(src, ff_src_start, output, ff_n * 8, n); ff_n = 0; } } output.Position = pos + n; } if (ff_n == 1) { output.Position = ff_dest_start; WriteFF(src, ff_src_start, output, 8, 0); } else if (ff_n > 1) { output.Position = ff_dest_start; WriteFF(src, ff_src_start, output, src_size - (ff_src_start - src_start), 0); } return(output.IsOverflow() == false); }
private bool EncodeInternal(SpType type, SpObject obj, SpStream mStream) { if (mStream == null || type == null || obj == null) { return(false); } // buildin type decoding should not be here if (mTypeManager.IsBuildinType(type)) { return(false); } int begin = mStream.Position; // fn. will be update later short fn = 0; mStream.Write(fn); List <KeyValuePair <SpObject, SpField> > objs = new List <KeyValuePair <SpObject, SpField> >(); int current_tag = -1; Dictionary <int, SpField> .ValueCollection.Enumerator en = type.Fields.Values.GetEnumerator(); while (en.MoveNext()) { SpField f = en.Current; if (f == null) { return(false); } SpObject o = obj[f.Name]; if (o == null || IsTypeMatch(f, o) == false) { continue; } if (f.Tag <= current_tag) { return(false); } if (f.Tag - current_tag > 1) { mStream.Write((short)(2 * (f.Tag - current_tag - 1) - 1)); fn++; } bool standalone = true; if (f.IsTable == false) { if (f.Type == mTypeManager.Boolean) { int value = o.AsBoolean() ? 1 : 0; mStream.Write((short)((value + 1) * 2)); standalone = false; } else if (f.Type == mTypeManager.Integer) { long value = o.AsLong(); if (value >= 0 && value < 0x7fff) { mStream.Write((short)((value + 1) * 2)); standalone = false; } } } if (standalone) { objs.Add(new KeyValuePair <SpObject, SpField>(o, f)); mStream.Write((short)0); } fn++; current_tag = f.Tag; } List <KeyValuePair <SpObject, SpField> > .Enumerator e = objs.GetEnumerator(); while (e.MoveNext()) { KeyValuePair <SpObject, SpField> entry = e.Current; if (entry.Value.IsTable) { int array_begin = mStream.Position; int size = 0; mStream.Write(size); if (entry.Value.Type == mTypeManager.Integer) { byte len = 4; Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; if (o.IsLong()) { len = 8; break; } } mStream.Write(len); enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; if (len == 4) { mStream.Write(o.AsInt()); } else { mStream.Write(o.AsLong()); } } } else if (entry.Value.Type == mTypeManager.Boolean) { Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; mStream.Write((byte)(o.AsBoolean() ? 1 : 0)); } } else if (entry.Value.Type == mTypeManager.String) { Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; byte[] b = Encoding.UTF8.GetBytes(o.AsString()); mStream.Write(b.Length); mStream.Write(b); } } else { Dictionary <object, SpObject> .Enumerator enumerator = entry.Key.AsTable().GetEnumerator(); while (enumerator.MoveNext()) { SpObject o = enumerator.Current.Value; int obj_begin = mStream.Position; int obj_size = 0; mStream.Write(obj_size); if (EncodeInternal(entry.Value.Type, o, mStream) == false) { return(false); } int obj_end = mStream.Position; obj_size = (int)(obj_end - obj_begin - 4); mStream.Position = obj_begin; mStream.Write(obj_size); mStream.Position = obj_end; } } int array_end = mStream.Position; size = (int)(array_end - array_begin - 4); mStream.Position = array_begin; mStream.Write(size); mStream.Position = array_end; } else { if (entry.Key.IsString()) { byte[] b = Encoding.UTF8.GetBytes(entry.Key.AsString()); mStream.Write(b.Length); mStream.Write(b); } else if (entry.Key.IsInt()) { mStream.Write((int)4); mStream.Write(entry.Key.AsInt()); } else if (entry.Key.IsLong()) { mStream.Write((int)8); mStream.Write(entry.Key.AsLong()); } else if (entry.Key.IsBoolean()) { // boolean should not be here return(false); } else { int obj_begin = mStream.Position; int obj_size = 0; mStream.Write(obj_size); if (EncodeInternal(entry.Value.Type, entry.Key, mStream) == false) { return(false); } int obj_end = mStream.Position; obj_size = (int)(obj_end - obj_begin - 4); mStream.Position = obj_begin; mStream.Write(obj_size); mStream.Position = obj_end; } } } int end = mStream.Position; mStream.Position = begin; mStream.Write(fn); mStream.Position = end; return(true); }
public bool Encode(string proto, SpObject obj, SpStream stream) { return(Encode(mTypeManager.GetType(proto), obj, stream)); }
public SpObject Decode(SpType type, SpStream mStream) { 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) { continue; } 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 { continue; } current_tag++; } else { //System.Console.WriteLine(string.Format("decode value: {0}",value)); 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) { continue; } if (f.IsTable) { int size = mStream.ReadInt32(); if (size == 0) { continue; //empty table } 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 = Decode(f.Type, mStream); 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: continue; } } 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, Decode(f.Type, mStream)); } } } return(obj); }
public SpObject Decode(string proto, SpStream stream) { return(Decode(mTypeManager.GetType(proto), stream)); }