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); }
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); } }
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); } }
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); }
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; } } }
/* * 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); } }
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); }
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); }
public void AddType(SprotoType type) { if (this.GetType(type.name) != null) { SprotoHelper.Error("redefined type '{0}'", type.name); } this.Types.Add(type.name, type); }
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); }
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); }
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)); } }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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; } }
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); }
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); } } } } }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }
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); }