private static void WriteEnumValue(Compiler.CompilerContext ctx, ProtoTypeCode typeCode, Compiler.CodeLabel handler, Compiler.CodeLabel @continue, object value, Compiler.Local local) { ctx.MarkLabel(handler); WriteEnumValue(ctx, typeCode, value); ctx.StoreValue(local); ctx.Branch(@continue, false); // "continue" }
private static void WriteEnumValue(Compiler.CompilerContext ctx, ProtoTypeCode typeCode, object value) { switch (typeCode) { case ProtoTypeCode.Byte: ctx.LoadValue((int)(byte)value); break; case ProtoTypeCode.SByte: ctx.LoadValue((int)(sbyte)value); break; case ProtoTypeCode.Int16: ctx.LoadValue((int)(short)value); break; case ProtoTypeCode.Int32: ctx.LoadValue((int)(int)value); break; case ProtoTypeCode.Int64: ctx.LoadValue((long)(long)value); break; case ProtoTypeCode.UInt16: ctx.LoadValue((int)(ushort)value); break; case ProtoTypeCode.UInt32: ctx.LoadValue((int)(uint)value); break; case ProtoTypeCode.UInt64: ctx.LoadValue((long)(ulong)value); break; default: throw new InvalidOperationException(); } }
void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { ProtoTypeCode typeCode = GetTypeCode(); if (map == null) { ctx.LoadValue(valueFrom); ctx.ConvertToInt32(typeCode, false); ctx.EmitBasicWrite("WriteInt32", null); } else { using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) { Compiler.CodeLabel @continue = ctx.DefineLabel(); for (int i = 0; i < map.Length; i++) { Compiler.CodeLabel tryNextValue = ctx.DefineLabel(), processThisValue = ctx.DefineLabel(); ctx.LoadValue(loc); WriteEnumValue(ctx, typeCode, map[i].RawValue); ctx.BranchIfEqual(processThisValue, true); ctx.Branch(tryNextValue, true); ctx.MarkLabel(processThisValue); ctx.LoadValue(map[i].WireValue); ctx.EmitBasicWrite("WriteInt32", null); ctx.Branch(@continue, false); ctx.MarkLabel(tryNextValue); } ctx.LoadReaderWriter(); ctx.LoadValue(loc); ctx.CastToObject(ExpectedType); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("ThrowEnumException")); ctx.MarkLabel(@continue); } } }
private WireType GetWireType(ProtoTypeCode code, DataFormat format, ref Type type, out int modelKey) { modelKey = -1; if (Helpers.IsEnum(type)) { modelKey = GetKey(ref type); return(WireType.Variant); } switch (code) { default: if ((uint)(code - 100) <= 3u) { goto case ProtoTypeCode.Decimal; } break; case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: if (format != DataFormat.FixedSize) { return(WireType.Variant); } return(WireType.Fixed64); case ProtoTypeCode.Boolean: case ProtoTypeCode.Char: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: if (format != DataFormat.FixedSize) { return(WireType.Variant); } return(WireType.Fixed32); case ProtoTypeCode.Double: return(WireType.Fixed64); case ProtoTypeCode.Single: return(WireType.Fixed32); case ProtoTypeCode.Decimal: case ProtoTypeCode.DateTime: case ProtoTypeCode.String: return(WireType.String); case (ProtoTypeCode)17: break; } if ((modelKey = GetKey(ref type)) >= 0) { return(WireType.String); } return(WireType.None); }
/// <summary> /// 构造函数 /// </summary> /// <param name="modifier">字段修饰符</param> /// <param name="typeCode">字段类型</param> /// <param name="name">字段名字</param> /// <param name="nestTypeName">嵌套类型的名字</param> private fieldDescriptor(EFieldModifier modifier, ProtoTypeCode typeCode, string name, string nestedTypeName = "") { this.modifier = modifier; this.typeCode = typeCode; this.name = name; wireType = luaProtoHelper.getWireType(typeCode); this.nestedTypeName = nestedTypeName; }
private WireType GetWireType(ProtoTypeCode code, DataFormat format, ref Type type, out int modelKey) { modelKey = -1; if (Helpers.IsEnum(type)) { modelKey = GetKey(ref type); return(WireType.Variant); } switch (code) { case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: if (format != DataFormat.FixedSize) { return(WireType.Variant); } return(WireType.Fixed64); case ProtoTypeCode.Boolean: case ProtoTypeCode.Char: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: if (format != DataFormat.FixedSize) { return(WireType.Variant); } return(WireType.Fixed32); case ProtoTypeCode.Double: return(WireType.Fixed64); case ProtoTypeCode.Single: return(WireType.Fixed32); case ProtoTypeCode.Decimal: case ProtoTypeCode.DateTime: case ProtoTypeCode.String: case ProtoTypeCode.TimeSpan: case ProtoTypeCode.ByteArray: case ProtoTypeCode.Guid: case ProtoTypeCode.Uri: return(WireType.String); default: if ((modelKey = GetKey(ref type)) >= 0) { return(WireType.String); } return(WireType.None); } }
private static void WriteEnumValue(CompilerContext ctx, ProtoTypeCode typeCode, object value) { switch (typeCode) { case ProtoTypeCode.SByte: { ctx.LoadValue((sbyte)value); return; } case ProtoTypeCode.Byte: { ctx.LoadValue((int)value); return; } case ProtoTypeCode.Int16: { ctx.LoadValue((short)value); return; } case ProtoTypeCode.UInt16: { ctx.LoadValue((int)value); return; } case ProtoTypeCode.Int32: { ctx.LoadValue((int)value); return; } case ProtoTypeCode.UInt32: { ctx.LoadValue((int)value); return; } case ProtoTypeCode.Int64: { ctx.LoadValue((long)value); return; } case ProtoTypeCode.UInt64: { ctx.LoadValue((long)value); return; } } throw new InvalidOperationException(); }
///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// 获取对应类型的工厂 /// </summary> /// <param name="typeCode"></param> /// <returns></returns> static internal IValueFactory getFactory(ProtoTypeCode typeCode) { IValueFactory value = null; if (_factories.TryGetValue(typeCode, out value)) { return(value); } return(null); }
/// <summary> /// 创建描述信息 /// </summary> /// <param name="modifier">字段修饰符</param> /// <param name="typeCode">字段类型</param> /// <param name="name">字段名字</param> /// <param name="nestedTypeName">嵌套类型的名字</param> /// <returns></returns> public static fieldDescriptor createDescriptor(EFieldModifier modifier, ProtoTypeCode typeCode, string name, string nestedTypeName = "") { if (modifier == EFieldModifier.none || typeCode == ProtoTypeCode.Empty || string.IsNullOrEmpty(name)) { return(null); } return(new fieldDescriptor(modifier, typeCode, name, nestedTypeName)); }
/////////////////////////////////////////////////////////////////////////// /// <summary> /// 写入消息字段 /// </summary> /// <param name="number">字段索引</param> /// <param name="wireType">WireType代码</param> /// <param name="typeCode">类型代码</param> /// <param name="value">要写入的值</param> private void writeField(int number, WireType wireType, ProtoTypeCode typeCode, object value) { if (value == null) { return; } //字段头 writeFieldHeader(number, wireType); //值 writeLuaObject(typeCode, value, wireType); }
internal void ConvertFromInt32(ProtoTypeCode typeCode, bool uint32Overflow) { switch (typeCode) { case ProtoTypeCode.SByte: { this.Emit(OpCodes.Conv_Ovf_I1); return; } case ProtoTypeCode.Byte: { this.Emit(OpCodes.Conv_Ovf_U1); return; } case ProtoTypeCode.Int16: { this.Emit(OpCodes.Conv_Ovf_I2); return; } case ProtoTypeCode.UInt16: { this.Emit(OpCodes.Conv_Ovf_U2); return; } case ProtoTypeCode.Int32: { return; } case ProtoTypeCode.UInt32: { this.Emit((uint32Overflow ? OpCodes.Conv_Ovf_U4 : OpCodes.Conv_U4)); return; } case ProtoTypeCode.Int64: { this.Emit(OpCodes.Conv_I8); return; } case ProtoTypeCode.UInt64: { this.Emit(OpCodes.Conv_U8); return; } } throw new InvalidOperationException(); }
/// <summary> /// 根据message生成table /// </summary> internal static void createLuaTable(LuaState state, luaMessage msg) { //压入消息表 LuaDLL.lua_newtable(state.L); fieldDataInfo field = null; for (int idx = 1; idx <= msg.fieldsCount(); idx++) { field = (fieldDataInfo)msg[idx]; if (field.Value == null) { continue; } string key = field.descriptor.name; ProtoTypeCode typeCode = field.descriptor.typeCode; if (field.descriptor.isRepeated()) { LuaDLL.lua_pushstring(state.L, key); LuaDLL.lua_newtable(state.L); for (int j = 0; j < field.Value.count(); j++) { if (field.descriptor.haveNestedType()) { createLuaTable(state, (luaMessage)field.Value[j]); } else { object luaValue = field.Value[j]; pushLuaValue(typeCode, state, luaValue); } LuaDLL.lua_rawseti(state.L, -2, j + 1); } LuaDLL.lua_settable(state.L, -3); } else { LuaDLL.lua_pushstring(state.L, key); if (field.descriptor.haveNestedType()) { createLuaTable(state, (luaMessage)field.Value.valueL); } else { object luaValue = field.Value.valueL; pushLuaValue(typeCode, state, luaValue); } LuaDLL.lua_settable(state.L, -3); } } }
/// <summary> /// lua中的数据类型转换为C#中的具体数据类型 /// </summary> internal static object luaType2CType(ProtoTypeCode typeCode, object luaValue) { if (luaValue == null) { return(null); } switch (typeCode) { case ProtoTypeCode.Boolean: return((bool)luaValue); case ProtoTypeCode.UInt16: return((ushort)((double)luaValue)); case ProtoTypeCode.Int16: return((short)((double)luaValue)); case ProtoTypeCode.Int32: return((int)((double)luaValue)); case ProtoTypeCode.UInt32: return((uint)((double)luaValue)); case ProtoTypeCode.Int64: return((long)((double)luaValue)); case ProtoTypeCode.UInt64: return((ulong)((double)luaValue)); case ProtoTypeCode.Single: return((float)((double)luaValue)); case ProtoTypeCode.Double: return((double)luaValue); case ProtoTypeCode.String: return((string)luaValue); case ProtoTypeCode.ByteArray: var str = (string)luaValue; byte[] bts = System.Text.Encoding.UTF8.GetBytes(str); return(bts); case ProtoTypeCode.Type: return((LuaTable)luaValue); default: return(null); } }
///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// 添加工厂类 /// </summary> /// <param name="typeCode"></param> /// <param name="factory"></param> static internal void addFactory(ProtoTypeCode typeCode, IValueFactory factory) { if (factory == null) { return; } if (_factories.ContainsKey(typeCode)) { return; } _factories[typeCode] = factory; }
/////////////////////////////////////////////////////////////////////////// /// <summary> /// 从流中读取lua消息 /// </summary> /// <param name="idMsg">配置表中的消息索引</param> /// <returns></returns> public luaMessage readLuaMessage(object idMsg) { luaMessage msg = (luaMessage)luaMessageCache.createTypeInstance(idMsg); if (msg == null) { return(null); } int fieldCount = msg.fieldsCount(); fieldDataInfo fieldData = null; for (int idx = 1; idx <= fieldCount; idx++) { fieldData = (fieldDataInfo)msg[idx]; if (fieldData == null) { continue; } WireType wireType = fieldData.descriptor.wireType; ProtoTypeCode typeCode = fieldData.descriptor.typeCode; string nestedTypeName = fieldData.descriptor.nestedTypeName; if (tryReadFieldHeader(idx, wireType)) { //创建值字段 if (!fieldData.appendValue()) { continue; } if (fieldData.descriptor.isRepeated()) { do { var obj = readLuaObject(typeCode, wireType, nestedTypeName); fieldData.Value.addChild(obj); } while (tryReadFieldHeader(idx, wireType)); } else { fieldData.Value.valueL = readLuaObject(typeCode, wireType, nestedTypeName); } } } return(msg); }
/// <summary> /// 获取wireType /// </summary> internal static WireType getWireType(ProtoTypeCode typeCode) { WireType wireType = WireType.None; switch (typeCode) { case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: wireType = WireType.Variant; break; case ProtoTypeCode.String: wireType = WireType.String; break; case ProtoTypeCode.Single: wireType = WireType.Fixed32; break; case ProtoTypeCode.Double: wireType = WireType.Fixed64; break; case ProtoTypeCode.Boolean: wireType = WireType.Variant; break; case ProtoTypeCode.Decimal: wireType = WireType.String; break; case ProtoTypeCode.ByteArray: wireType = WireType.String; break; case ProtoTypeCode.Char: wireType = WireType.Variant; break; case ProtoTypeCode.Type: wireType = WireType.String; break; } return(wireType); }
/// <summary> /// 压入一个lua值到LuaState中 /// </summary> /// <param name="typeCode"></param> /// <param name="state"></param> /// <param name="luaValue"></param> private static void pushLuaValue(ProtoTypeCode typeCode, LuaState state, object luaValue) { switch (typeCode) { case ProtoTypeCode.Boolean: LuaDLL.lua_pushboolean(state.L, (bool)luaValue); break; case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: LuaDLL.lua_pushinteger(state.L, (int)luaValue); break; case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: LuaDLL.lua_pushinteger(state.L, (int)(uint)luaValue); break; case ProtoTypeCode.Int64: LuaDLL.lua_pushnumber(state.L, (long)luaValue); break; case ProtoTypeCode.UInt64: LuaDLL.lua_pushnumber(state.L, (ulong)luaValue); break; case ProtoTypeCode.Single: LuaDLL.lua_pushnumber(state.L, (float)luaValue); break; case ProtoTypeCode.Double: LuaDLL.lua_pushnumber(state.L, (double)luaValue); break; case ProtoTypeCode.String: LuaDLL.lua_pushstring(state.L, (string)luaValue); break; case ProtoTypeCode.ByteArray: var str = System.Text.Encoding.UTF8.GetString((byte[])luaValue); LuaDLL.lua_pushstring(state.L, str); break; default: LuaDLL.lua_pushnil(state.L); break; } }
// no need for special handling of !Nullable.HasValue - when boxing they will be applied NetObjectValueDecorator(Type type, bool asReference, bool asLateReference, bool allowNullWireType, RuntimeTypeModel model) { if (type == null) { throw new ArgumentNullException(nameof(type)); } _allowNullWireType = allowNullWireType; _options = BclHelpers.NetObjectOptions.UseConstructor; if (asReference) { _options |= BclHelpers.NetObjectOptions.AsReference; if (asLateReference) { _options |= BclHelpers.NetObjectOptions.WriteAsLateReference; } } else if (asLateReference) { throw new ArgumentException("Can't serialize as late reference when asReference = false", nameof(asReference)); } int baseKey = model.GetKey(type, false, true); int key = model.GetKey(type, false, false); if (!Helpers.IsValueType(type) && key >= 0 && baseKey >= 0 && ValueSerializerBuilder.CanTypeBeAsLateReferenceOnBuildStage(key, model, true)) { _lateReferenceTail = new LateReferenceSerializer(type, key, baseKey, model); } else if (asLateReference) { throw new ArgumentException("Can't use late reference with non-model or value type " + type.Name); } ProtoTypeCode typeCode = Helpers.GetTypeCode(type); // mind that this is set not for AsReference only // because AsReference may be switched in another version if (typeCode == ProtoTypeCode.String || typeCode == ProtoTypeCode.Type || typeCode == ProtoTypeCode.Uri) { _options |= BclHelpers.NetObjectOptions.LateSet; } // if this type is nullable it's ok // we'll unwrap it // and for non emit it's already boxed as not nullable this.ExpectedType = type; }
private static string GenBaseTypeReadCode(ProtoTypeCode typecode, string varName) { string userVar = " var "+ varName; switch (typecode) { case ProtoTypeCode.Int16: return(userVar + " = source.ReadInt16();"); case ProtoTypeCode.Int32: return(userVar + " = source.ReadInt32();"); case ProtoTypeCode.Int64: return(userVar + " = source.ReadInt64();"); case ProtoTypeCode.UInt16: return(userVar + " = source.ReadUInt16();"); case ProtoTypeCode.UInt32: return(userVar + " = source.ReadUInt32();"); case ProtoTypeCode.UInt64: return(userVar + " = source.ReadUInt64();"); case ProtoTypeCode.Boolean: return(userVar + " = source.ReadBoolean();"); case ProtoTypeCode.SByte: return(userVar + " = source.ReadSByte();"); case ProtoTypeCode.Byte: return(userVar + " = source.ReadByte();"); case ProtoTypeCode.Char: return(userVar + " = source.ReadUInt16();"); case ProtoTypeCode.Double: return(userVar + " = source.ReadDouble();"); case ProtoTypeCode.Single: return(userVar + " = source.ReadSingle();"); case ProtoTypeCode.DateTime: return(userVar + " = source.ReadDateTime();"); case ProtoTypeCode.Decimal: return(userVar + " = source.ReadDecimal();"); case ProtoTypeCode.String: return(userVar + " = source.ReadString();"); case ProtoTypeCode.ByteArray: return(userVar + " = ProtoReader.AppendBytes(null, source)"); case ProtoTypeCode.TimeSpan: return(userVar + " = BclHelpers.ReadTimeSpan(source);"); case ProtoTypeCode.Guid: return(userVar + " = BclHelpers.ReadGuid(source);"); case ProtoTypeCode.Uri: return(userVar + " = source.ReadString();"); } return(""); }
public static WireType GetWireType(ProtoTypeCode code, BinaryDataFormat format) { switch (code) { case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: { return(format == BinaryDataFormat.FixedSize ? WireType.Fixed64 : WireType.Variant); } case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: case ProtoTypeCode.Boolean: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Char: { return(format == BinaryDataFormat.FixedSize ? WireType.Fixed32 : WireType.Variant); } case ProtoTypeCode.Double: { return(WireType.Fixed64); } case ProtoTypeCode.Single: { return(WireType.Fixed32); } case ProtoTypeCode.String: case ProtoTypeCode.DateTime: case ProtoTypeCode.Decimal: case ProtoTypeCode.ByteArray: case ProtoTypeCode.TimeSpan: case ProtoTypeCode.Guid: case ProtoTypeCode.Uri: case ProtoTypeCode.Type: { return(WireType.String); } } return(WireType.None); }
private bool CanSerialize(Type type, bool allowBasic, bool allowContract, bool allowLists) { if (type == null) { throw new ArgumentNullException("type"); } Type underlyingType = Helpers.GetUnderlyingType(type); if (underlyingType != null) { type = underlyingType; } ProtoTypeCode typeCode = Helpers.GetTypeCode(type); if ((uint)typeCode > 1u) { return(allowBasic); } if (GetKey(ref type) >= 0) { return(allowContract); } if (allowLists) { Type type2 = null; if (type.IsArray) { if (type.GetArrayRank() == 1) { type2 = type.GetElementType(); } } else { type2 = GetListItemType(this, type); } if (type2 != null) { return(CanSerialize(type2, allowBasic, allowContract, allowLists: false)); } } return(false); }
internal void ConvertToInt32(ProtoTypeCode typeCode, bool uint32Overflow) { switch (typeCode) { case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: { this.Emit(OpCodes.Conv_I4); return; } case ProtoTypeCode.Int32: { return; } case ProtoTypeCode.UInt32: { this.Emit((uint32Overflow ? OpCodes.Conv_Ovf_I4_Un : OpCodes.Conv_Ovf_I4)); return; } case ProtoTypeCode.Int64: { this.Emit(OpCodes.Conv_Ovf_I4); return; } case ProtoTypeCode.UInt64: { this.Emit(OpCodes.Conv_Ovf_I4_Un); return; } } throw new InvalidOperationException(string.Concat("ConvertToInt32 not implemented for: ", typeCode.ToString())); }
void IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom) { ProtoTypeCode typeCode = this.GetTypeCode(); if (this.map == null) { ctx.LoadValue(valueFrom); ctx.ConvertToInt32(typeCode, false); ctx.EmitBasicWrite("WriteInt32", null); } else { using (Local local = ctx.GetLocalWithValue(this.ExpectedType, valueFrom)) { CodeLabel label = ctx.DefineLabel(); for (int i = 0; i < this.map.Length; i++) { CodeLabel label2 = ctx.DefineLabel(); CodeLabel label3 = ctx.DefineLabel(); ctx.LoadValue(local); WriteEnumValue(ctx, typeCode, this.map[i].RawValue); ctx.BranchIfEqual(label3, true); ctx.Branch(label2, true); ctx.MarkLabel(label3); ctx.LoadValue(this.map[i].WireValue); ctx.EmitBasicWrite("WriteInt32", null); ctx.Branch(label, false); ctx.MarkLabel(label2); } ctx.LoadReaderWriter(); ctx.LoadValue(local); ctx.CastToObject(this.ExpectedType); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("ThrowEnumException")); ctx.MarkLabel(label); } } }
void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { ProtoTypeCode typeCode = GetTypeCode(); if (map == null) { ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); ctx.ConvertFromInt32(typeCode, false); } else { int[] wireValues = new int[map.Length]; object[] values = new object[map.Length]; for (int i = 0; i < map.Length; i++) { wireValues[i] = map[i].WireValue; values[i] = map[i].RawValue; } using (Compiler.Local result = new Compiler.Local(ctx, ExpectedType)) using (Compiler.Local wireValue = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) { ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); ctx.StoreValue(wireValue); Compiler.CodeLabel @continue = ctx.DefineLabel(); foreach (BasicList.Group group in BasicList.GetContiguousGroups(wireValues, values)) { Compiler.CodeLabel tryNextGroup = ctx.DefineLabel(); int groupItemCount = group.Items.Count; if (groupItemCount == 1) { // discreet group; use an equality test ctx.LoadValue(wireValue); ctx.LoadValue(group.First); Compiler.CodeLabel processThisValue = ctx.DefineLabel(); ctx.BranchIfEqual(processThisValue, true); ctx.Branch(tryNextGroup, false); WriteEnumValue(ctx, typeCode, processThisValue, @continue, group.Items[0], @result); } else { // implement as a jump-table-based switch ctx.LoadValue(wireValue); ctx.LoadValue(group.First); ctx.Subtract(); // jump-tables are zero-based Compiler.CodeLabel[] jmp = new Compiler.CodeLabel[groupItemCount]; for (int i = 0; i < groupItemCount; i++) { jmp[i] = ctx.DefineLabel(); } ctx.Switch(jmp); // write the default... ctx.Branch(tryNextGroup, false); for (int i = 0; i < groupItemCount; i++) { WriteEnumValue(ctx, typeCode, jmp[i], @continue, group.Items[i], @result); } } ctx.MarkLabel(tryNextGroup); } // throw source.CreateEnumException(ExpectedType, wireValue); ctx.LoadReaderWriter(); ctx.LoadValue(ExpectedType); ctx.LoadValue(wireValue); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ThrowEnumException")); ctx.MarkLabel(@continue); ctx.LoadValue(result); } } }
internal void ConvertToInt32(ProtoTypeCode typeCode, bool uint32Overflow) { switch (typeCode) { case ProtoTypeCode.Byte: case ProtoTypeCode.SByte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: Emit(OpCodes.Conv_I4); break; case ProtoTypeCode.Int32: break; case ProtoTypeCode.Int64: Emit(OpCodes.Conv_Ovf_I4); break; case ProtoTypeCode.UInt32: Emit(uint32Overflow ? OpCodes.Conv_Ovf_I4_Un : OpCodes.Conv_Ovf_I4); break; case ProtoTypeCode.UInt64: Emit(OpCodes.Conv_Ovf_I4_Un); break; default: throw new InvalidOperationException("ConvertToInt32 not implemented for: " + typeCode); } }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { #if !NO_GENERICS { Type tmp = Helpers.GetUnderlyingType(type); if (tmp != null) { type = tmp; } } #endif if (Helpers.IsEnum(type)) { if (allowComplexTypes && model != null) { // need to do this before checking the typecode; an int enum will report Int32 etc defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } else { // enum is fine for adding as a meta-type defaultWireType = WireType.None; return(null); } } ProtoTypeCode code = Helpers.GetTypeCode(type); switch (code) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); case ProtoTypeCode.String: defaultWireType = WireType.String; if (asReference) { return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } return(new StringSerializer(model)); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new DecimalSerializer(model)); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer(model)); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(model)); case ProtoTypeCode.Guid: defaultWireType = WireType.String; return(new GuidSerializer(model)); case ProtoTypeCode.Uri: defaultWireType = WireType.String; return(new StringSerializer(model)); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); } IProtoSerializer parseable = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; if (parseable != null) { defaultWireType = WireType.String; return(parseable); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, false, true); if (asReference || dynamicType) { defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None; if (asReference) { options |= BclHelpers.NetObjectOptions.AsReference; } if (dynamicType) { options |= BclHelpers.NetObjectOptions.DynamicType; } if (key >= 0) { // exists if (asReference && Helpers.IsValueType(type)) { string message = "AsReference cannot be used with value-types"; if (type.Name == "KeyValuePair`2") { message += "; please see http://stackoverflow.com/q/14436606/"; } else { message += ": " + type.FullName; } throw new InvalidOperationException(message); } MetaType meta = model[type]; if (asReference && meta.IsAutoTuple) { options |= BclHelpers.NetObjectOptions.LateSet; } if (meta.UseConstructor) { options |= BclHelpers.NetObjectOptions.UseConstructor; } } return(new NetObjectSerializer(model, type, key, options)); } if (key >= 0) { defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); }
IProtoSerializerWithWireType TryGetBasicTypeSerializer(BinaryDataFormat dataFormat, Type type, out WireType defaultWireType, bool overwriteList) { ProtoTypeCode code = Helpers.GetTypeCode(type); switch (code) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new Int32Serializer(_model))); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new UInt32Serializer(_model))); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new WireTypeDecorator(defaultWireType, new Int64Serializer(_model))); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new WireTypeDecorator(defaultWireType, new UInt64Serializer(_model))); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new WireTypeDecorator(defaultWireType, new SingleSerializer(_model))); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new WireTypeDecorator(defaultWireType, new DoubleSerializer(_model))); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new WireTypeDecorator(defaultWireType, new BooleanSerializer(_model))); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new WireTypeDecorator(defaultWireType, new DateTimeSerializer(_model))); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new DecimalSerializer(_model))); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new ByteSerializer(_model))); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new SByteSerializer(_model))); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new WireTypeDecorator(defaultWireType, new CharSerializer(_model))); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new Int16Serializer(_model))); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new UInt16Serializer(_model))); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new WireTypeDecorator(defaultWireType, new TimeSpanSerializer(_model))); case ProtoTypeCode.Guid: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new GuidSerializer(_model))); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new BlobSerializer(_model, overwriteList))); case ProtoTypeCode.Uri: // treat uri as string; wrapped in decorator later case ProtoTypeCode.String: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new StringSerializer(_model))); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new SystemTypeSerializer(_model))); } defaultWireType = WireType.None; return(null); }
internal void ConvertFromInt32(ProtoTypeCode typeCode, bool uint32Overflow) { switch (typeCode) { case ProtoTypeCode.SByte: Emit(OpCodes.Conv_Ovf_I1); break; case ProtoTypeCode.Byte: Emit(OpCodes.Conv_Ovf_U1); break; case ProtoTypeCode.Int16: Emit(OpCodes.Conv_Ovf_I2); break; case ProtoTypeCode.UInt16: Emit(OpCodes.Conv_Ovf_U2); break; case ProtoTypeCode.Int32: break; case ProtoTypeCode.UInt32: Emit(uint32Overflow ? OpCodes.Conv_Ovf_U4 : OpCodes.Conv_U4); break; case ProtoTypeCode.Int64: Emit(OpCodes.Conv_I8); break; case ProtoTypeCode.UInt64: Emit(OpCodes.Conv_U8); break; default: throw new InvalidOperationException(); } }
internal void ConvertToInt32(ProtoTypeCode typeCode) { switch (typeCode) { case ProtoTypeCode.Byte: case ProtoTypeCode.SByte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: Emit(OpCodes.Conv_I4); break; case ProtoTypeCode.Int32: break; case ProtoTypeCode.Int64: Emit(OpCodes.Conv_Ovf_I4); break; case ProtoTypeCode.UInt32: case ProtoTypeCode.UInt64: Emit(OpCodes.Conv_Ovf_I4_Un); break; default: throw new InvalidOperationException(); } }
// Token: 0x06000389 RID: 905 RVA: 0x00013428 File Offset: 0x00011628 internal string GetSchemaTypeName(Type effectiveType, DataFormat dataFormat, bool asReference, bool dynamicType, ref bool requiresBclImport) { Type underlyingType = Helpers.GetUnderlyingType(effectiveType); if (underlyingType != null) { effectiveType = underlyingType; } if (effectiveType == base.MapType(typeof(byte[]))) { return("bytes"); } WireType wireType; IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(this, dataFormat, effectiveType, out wireType, false, false, false, false); if (protoSerializer == null) { if (asReference || dynamicType) { requiresBclImport = true; return("bcl.NetObjectProxy"); } return(this[effectiveType].GetSurrogateOrBaseOrSelf(true).GetSchemaTypeName()); } else { if (!(protoSerializer is ParseableSerializer)) { ProtoTypeCode typeCode = Helpers.GetTypeCode(effectiveType); switch (typeCode) { case ProtoTypeCode.Boolean: return("bool"); case ProtoTypeCode.Char: case ProtoTypeCode.Byte: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: if (dataFormat == DataFormat.FixedSize) { return("fixed32"); } return("uint32"); case ProtoTypeCode.SByte: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: if (dataFormat == DataFormat.ZigZag) { return("sint32"); } if (dataFormat != DataFormat.FixedSize) { return("int32"); } return("sfixed32"); case ProtoTypeCode.Int64: if (dataFormat == DataFormat.ZigZag) { return("sint64"); } if (dataFormat != DataFormat.FixedSize) { return("int64"); } return("sfixed64"); case ProtoTypeCode.UInt64: if (dataFormat == DataFormat.FixedSize) { return("fixed64"); } return("uint64"); case ProtoTypeCode.Single: return("float"); case ProtoTypeCode.Double: return("double"); case ProtoTypeCode.Decimal: requiresBclImport = true; return("bcl.Decimal"); case ProtoTypeCode.DateTime: requiresBclImport = true; return("bcl.DateTime"); case (ProtoTypeCode)17: break; case ProtoTypeCode.String: if (asReference) { requiresBclImport = true; } if (!asReference) { return("string"); } return("bcl.NetObjectProxy"); default: if (typeCode == ProtoTypeCode.TimeSpan) { requiresBclImport = true; return("bcl.TimeSpan"); } if (typeCode == ProtoTypeCode.Guid) { requiresBclImport = true; return("bcl.Guid"); } break; } throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName); } if (asReference) { requiresBclImport = true; } if (!asReference) { return("string"); } return("bcl.NetObjectProxy"); } }
private static string GenTypeReadCode(MemberInfo memberInfo, Type type, string fieldName, int fieldNumber) { string getCode = fieldName; ProtoSupportGetAttribute supportGetAttribute = memberInfo.GetAttribute <ProtoSupportGetAttribute>(); if (supportGetAttribute != null) { getCode = string.Format("{0}({1})", supportGetAttribute.FunctionName, supportGetAttribute.FunctionParam); } if (type.IsArray) { if (type == typeof(byte[])) { string bytesCode = BYTES_TEMP; bytesCode = bytesCode.Replace("$MemberName$", getCode); return(bytesCode); } else { string arrayCode = ARRAY_TEMP; arrayCode = arrayCode.Replace("$CaseNum$", fieldNumber.ToString()); Type subItemType = type.GetElementType(); arrayCode = arrayCode.Replace("$SubItemType$", GetTypeFullName(subItemType)); if (subItemType.IsArray) { //TODO error } else if (subItemType.IsGenericType) { //TODO error } else { ProtoTypeCode typecode = Helpers.GetTypeCode(subItemType); if (typecode != ProtoTypeCode.Unknown) { string subItemCode = "\t" + GenBaseTypeReadCode(typecode, "subValue"); return(arrayCode.Replace("$SubItem$", subItemCode)); } else if (subItemType.GetAttribute <ProtoContractAttribute>() != null) { string subItemCode = SUBITEM_TEMP; subItemType = GetBaseType(subItemType); subItemCode = subItemCode.Replace("$MemberType$", subItemType.Name); subItemCode = subItemCode.Replace("$MemberObj$", subItemType.IsValueType ? "new " + GetTypeFullName(subItemType) + "()" : "null"); subItemCode = subItemCode.Replace("$VarName$", "subValue"); subItemCode = "\t" + subItemCode.Replace("\n", "\n\t"); return(arrayCode.Replace("$SubItem$", subItemCode)); } } } } else if (type.IsGenericType) { string code = ""; if (type.GetGenericTypeDefinition() == typeof(List <>)) { code = LIST_TEMP; } else { code = HASHSET_TEMP; } if (!string.IsNullOrEmpty(code)) { code = code.Replace("$CaseNum$", fieldNumber.ToString()); code = code.Replace("$MemberName$", getCode); Type subItemType = type.GetGenericArguments()[0]; code = code.Replace("$SubItemType$", GetTypeFullName(subItemType)); if (subItemType.IsArray) { //TODO error } else if (subItemType.IsGenericType) { //TODO error } else { ProtoTypeCode typecode = Helpers.GetTypeCode(subItemType); if (typecode != ProtoTypeCode.Unknown) { string subItemCode = "\t" + GenBaseTypeReadCode(typecode, "subValue"); return(code.Replace("$SubItem$", subItemCode)); } else if (subItemType.GetAttribute <ProtoContractAttribute>() != null) { string subItemCode = SUBITEM_TEMP; subItemType = GetBaseType(subItemType); subItemCode = subItemCode.Replace("$MemberType$", subItemType.Name); subItemCode = subItemCode.Replace("$MemberObj$", subItemType.IsValueType ? "new " + GetTypeFullName(subItemType) + "()" : "null"); subItemCode = subItemCode.Replace("$VarName$", "subValue"); subItemCode = "\t" + subItemCode.Replace("\n", "\n\t"); return(code.Replace("$SubItem$", subItemCode)); } } } else { //TODO error } } else { ProtoTypeCode typecode = Helpers.GetTypeCode(type); if (typecode != ProtoTypeCode.Unknown) { return(GenBaseTypeReadCode(typecode, "value")); } else if (type.GetAttribute <ProtoContractAttribute>() != null) { string subItemCode = SUBITEM_TEMP; type = GetBaseType(type); subItemCode = subItemCode.Replace("$MemberType$", type.Name); subItemCode = subItemCode.Replace("$MemberObj$", type.IsValueType ? "new " + GetTypeFullName(type) + "()" : "obj." + fieldName); subItemCode = subItemCode.Replace("$VarName$", "value"); return(subItemCode); } } return(""); }
/// <summary> /// 初始化消息定义 /// </summary> static internal void init() { LuaTable protoCfgTbl = luaSvrManager.getInstance().LuaProtoDefTbl; if (protoCfgTbl == null) { return; } object key = 0; foreach (LuaTable.TablePair kvp in protoCfgTbl) { key = luaProtoHelper.regualarKey(kvp.key); if (key == null || kvp.value.GetType() != typeof(LuaTable)) { continue; } //LogSys.Log("***************************** << " + kvp.key.ToString() + " >> ***********************************"); //创建消息实体 var luaMsg = new luaMessage(key); //读取消息定义 var msgTbl = (LuaTable)kvp.value; foreach (LuaTable.TablePair field in msgTbl) { var fieldInfo = (LuaTable)field.value; if (fieldInfo == null) { continue; } int idx = (int)luaProtoHelper.regualarKey(field.key); EFieldModifier modifier = (EFieldModifier)luaProtoHelper.regualarKey(fieldInfo[1]); //类型信息 ProtoTypeCode typeCode = ProtoTypeCode.Empty; string nestedTypeName = null; if (fieldInfo[2].GetType() == typeof(double)) { typeCode = (ProtoTypeCode)luaProtoHelper.regualarKey(fieldInfo[2]); } else { typeCode = ProtoTypeCode.Type; nestedTypeName = (string)fieldInfo[2]; } string name = (string)fieldInfo[3]; //创建field var descriptor = fieldDescriptor.createDescriptor(modifier, typeCode, name, nestedTypeName); if (descriptor != null) { var info = fieldDataInfo.createFieldData(idx, descriptor); if (info != null) { luaMsg.addField(idx, info); } } //调试信息 string fieldLog = string.Format("idx={0}, modifier={1}, typeCode={2}[{3}], name={4}", idx, modifier, typeCode, nestedTypeName, name); //LogSys.Log(fieldLog); } //加入消息缓存 luaMessageCache.add(key, luaMsg); } }
public void Write(object value, ProtoWriter dest) { if (_allowNullWireType && value == null) { ProtoWriter.WriteFieldHeaderComplete(WireType.Null, dest); return; } bool write; int dynamicTypeKey; var options = _options; if ((options & BclHelpers.NetObjectOptions.WriteAsLateReference) != 0 && !ProtoWriter.CheckIsOnHalfToRecursionDepthLimit(dest)) { options &= ~BclHelpers.NetObjectOptions.WriteAsLateReference; } SubItemToken token = NetObjectHelpers.WriteNetObject_Start(value, dest, options, out dynamicTypeKey, out write); if (write) { // field header written! if ((options & BclHelpers.NetObjectOptions.DynamicType) != 0) { if (dynamicTypeKey < 0) { ProtoTypeCode typeCode = HelpersInternal.GetTypeCode(value.GetType()); WireType wireType = HelpersInternal.GetWireType(typeCode, _dataFormatForDynamicBuiltins); if (wireType != WireType.None) { ProtoWriter.WriteFieldHeaderComplete(wireType, dest); if (!ProtoWriter.TryWriteBuiltinTypeValue(value, typeCode, true, dest)) { throw new ProtoException("Dynamic type is not a contract-type: " + value.GetType().Name); } } else { throw new ProtoException("Dynamic type is not a contract-type: " + value.GetType().Name); } } else { ProtoWriter.WriteRecursionSafeObject(value, dynamicTypeKey, dest); } } else { if ((options & BclHelpers.NetObjectOptions.WriteAsLateReference) != 0) { _lateReferenceTail.Write(value, dest); } else if (_tail != null) { _tail.Write(value, dest); } else { Debug.Assert(_baseKey >= 0); if (_baseKeySerializer != null) { _baseKeySerializer.Write(value, dest); } else { ProtoWriter.WriteRecursionSafeObject(value, _baseKey, dest); } } } } ProtoWriter.EndSubItem(token, dest); }