public static void SyncObject(Serializer ser, object obj) { const BindingFlags defaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy; var objType = obj.GetType(); var members = objType.GetMembers(defaultFlags); foreach (var member in members) { if (member.GetCustomAttributes(true).Any(a => a is DoNotSave)) { continue; } var name = member.Name; var nameAttribute = member.GetCustomAttributes(true).FirstOrDefault(a => a is SaveWithName); if (nameAttribute != null) { name = ((SaveWithName) nameAttribute).Name; } object currentValue = null; var fail = false; var fieldInfo = member as FieldInfo; Type valueType = null; if ((member.MemberType == MemberTypes.Field) && member.ReflectedType != null) { valueType = fieldInfo.FieldType; currentValue = fieldInfo.GetValue(obj); } if (currentValue != null) { ByteBuffer refByteBuffer; int refInt32; IntBuffer refIntBuffer; int refPointX; int refPointY; switch (valueType.Name) { case "Action`1": case "Action`2": break; case "Bit": var refBit = (Bit)currentValue; ser.Sync(name, ref refBit); currentValue = refBit; break; case "Boolean": var refBool = (bool)currentValue; ser.Sync(name, ref refBool); currentValue = refBool; break; case "Boolean[]": { var tmp = (bool[])currentValue; ser.Sync(name, ref tmp, false); currentValue = tmp; } break; case "Byte": var refByte = (byte)currentValue; ser.Sync(name, ref refByte); currentValue = refByte; break; case "Byte[]": refByteBuffer = new ByteBuffer((byte[])currentValue); ser.Sync(name, ref refByteBuffer); currentValue = refByteBuffer.Arr.Select(d => d).ToArray(); refByteBuffer.Dispose(); break; case "ByteBuffer": refByteBuffer = (ByteBuffer)currentValue; ser.Sync(name, ref refByteBuffer); currentValue = refByteBuffer; break; case "Func`1": case "Func`2": break; case "Int16": var refInt16 = (short)currentValue; ser.Sync(name, ref refInt16); currentValue = refInt16; break; case "Int32": refInt32 = (int)currentValue; ser.Sync(name, ref refInt32); currentValue = refInt32; break; case "Int32[]": refIntBuffer = new IntBuffer((int[])currentValue); ser.Sync(name, ref refIntBuffer); currentValue = refIntBuffer.Arr.Select(d => d).ToArray(); refIntBuffer.Dispose(); break; case "IntBuffer": refIntBuffer = (IntBuffer)currentValue; ser.Sync(name, ref refIntBuffer); currentValue = refIntBuffer; break; case "Point": refPointX = ((Point)currentValue).X; refPointY = ((Point)currentValue).Y; ser.Sync(name + "_X", ref refPointX); ser.Sync(name + "_Y", ref refPointY); currentValue = new Point(refPointX, refPointY); break; case "Rectangle": refPointX = ((Rectangle)currentValue).X; refPointY = ((Rectangle)currentValue).Y; var refRectWidth = ((Rectangle)currentValue).Width; var refRectHeight = ((Rectangle)currentValue).Height; ser.Sync(name + "_X", ref refPointX); ser.Sync(name + "_Y", ref refPointY); ser.Sync(name + "_Height", ref refRectHeight); ser.Sync(name + "_Width", ref refRectWidth); currentValue = new Rectangle(refPointX, refPointY, refRectWidth, refRectHeight); break; case "SByte": var refSByte = (sbyte)currentValue; ser.Sync(name, ref refSByte); currentValue = refSByte; break; case "String": var refString = (string)currentValue; var refVal = new ByteBuffer(Encoding.GetBytes(refString)); ser.Sync(name, ref refVal); currentValue = Encoding.GetString(refVal.Arr); refVal.Dispose(); break; case "UInt16": var refUInt16 = (ushort)currentValue; ser.Sync(name, ref refUInt16); currentValue = refUInt16; break; case "UInt32": var refUInt32 = (uint)currentValue; ser.Sync(name, ref refUInt32); currentValue = refUInt32; break; default: var t = currentValue.GetType(); if (t.IsEnum) { refInt32 = (int)currentValue; ser.Sync(name, ref refInt32); currentValue = refInt32; } else if (t.IsArray) { var currentValueArray = (Array) currentValue; for (var i = 0; i < currentValueArray.Length; i++) { ser.BeginSection(string.Format("{0}_{1}", name, i)); SyncObject(ser, currentValueArray.GetValue(i)); ser.EndSection(); } } else if (t.IsValueType) { fail = true; } else if (t.IsClass) { fail = true; foreach (var method in t.GetMethods().Where(method => method.Name == "SyncState")) { ser.BeginSection(fieldInfo.Name); method.Invoke(currentValue, new object[] { ser }); ser.EndSection(); fail = false; break; } } else { fail = true; } break; } } if (!fail) { if (member.MemberType == MemberTypes.Property) { var propInfo = member as PropertyInfo; if (propInfo.CanWrite) { var setMethod = propInfo.GetSetMethod(); if (setMethod != null) { setMethod.Invoke(obj, new[] { currentValue }); } } } else if (member.MemberType == MemberTypes.Field) { fieldInfo.SetValue(obj, currentValue); } } } }
static public void SyncObject(Serializer ser, object obj) { BindingFlags defaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy; MemberInfo[] members = obj.GetType().GetMembers(defaultFlags); Bit refBit; Boolean refBool; Byte refByte; ByteBuffer refByteBuffer; Int16 refInt16; Int32 refInt32; IntBuffer refIntBuffer; Int32 refPointX; Int32 refPointY; SByte refSByte; UInt16 refUInt16; UInt32 refUInt32; Int32 refRectHeight; Int32 refRectWidth; foreach (MemberInfo member in members) { object currentValue = null; bool fail = false; FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type valueType = null; if (member.MemberType == MemberTypes.Field) { fieldInfo = member.ReflectedType.GetField(member.Name, defaultFlags); valueType = fieldInfo.FieldType; currentValue = fieldInfo.GetValue(obj); } else { fail = true; } if (!fail) { if (valueType.IsArray) { } if (currentValue != null) { switch (valueType.Name) { case "Bit": refBit = (Bit)currentValue; ser.Sync(member.Name, ref refBit); currentValue = refBit; break; case "Boolean": refBool = (Boolean)currentValue; ser.Sync(member.Name, ref refBool); currentValue = refBool; break; case "Boolean[]": { bool[] tmp = (bool[])currentValue; ser.Sync(member.Name, ref tmp, false); currentValue = tmp; } break; case "Byte": refByte = (Byte)currentValue; ser.Sync(member.Name, ref refByte); currentValue = refByte; break; case "Byte[]": refByteBuffer = new ByteBuffer((byte[])currentValue); ser.Sync(member.Name, ref refByteBuffer); currentValue = refByteBuffer.Arr; break; case "ByteBuffer": refByteBuffer = (ByteBuffer)currentValue; ser.Sync(member.Name, ref refByteBuffer); currentValue = refByteBuffer; break; case "Func`1": break; case "Int16": refInt16 = (Int16)currentValue; ser.Sync(member.Name, ref refInt16); currentValue = refInt16; break; case "Int32": refInt32 = (Int32)currentValue; ser.Sync(member.Name, ref refInt32); currentValue = refInt32; break; case "Int32[]": refIntBuffer = new IntBuffer((int[])currentValue); ser.Sync(member.Name, ref refIntBuffer); currentValue = refIntBuffer.Arr; break; case "IntBuffer": refIntBuffer = (IntBuffer)currentValue; ser.Sync(member.Name, ref refIntBuffer); currentValue = refIntBuffer; break; case "Point": refPointX = ((Point)currentValue).X; refPointY = ((Point)currentValue).Y; ser.Sync(member.Name + "_X", ref refPointX); ser.Sync(member.Name + "_Y", ref refPointY); currentValue = new Point(refPointX, refPointY); break; case "Rectangle": refPointX = ((Rectangle)currentValue).X; refPointY = ((Rectangle)currentValue).Y; refRectWidth = ((Rectangle)currentValue).Width; refRectHeight = ((Rectangle)currentValue).Height; ser.Sync(member.Name + "_X", ref refPointX); ser.Sync(member.Name + "_Y", ref refPointY); ser.Sync(member.Name + "_Height", ref refRectHeight); ser.Sync(member.Name + "_Width", ref refRectWidth); currentValue = new Rectangle(refPointX, refPointY, refRectWidth, refRectHeight); break; case "SByte": refSByte = (SByte)currentValue; ser.Sync(member.Name, ref refSByte); currentValue = refSByte; break; case "String": { var refString = (String)currentValue; var refVal = new ByteBuffer(encoding.GetBytes(refString)); ser.Sync(member.Name, ref refVal); currentValue = encoding.GetString(refVal.Arr); } break; case "UInt16": refUInt16 = (UInt16)currentValue; ser.Sync(member.Name, ref refUInt16); currentValue = refUInt16; break; case "UInt32": refUInt32 = (UInt32)currentValue; ser.Sync(member.Name, ref refUInt32); currentValue = refUInt32; break; default: { Type t = currentValue.GetType(); if (t.IsEnum) { refInt32 = (Int32)currentValue; ser.Sync(member.Name, ref refInt32); currentValue = refInt32; } else if (t.IsValueType) { fail = true; } else if (t.IsClass) { fail = true; foreach (var method in t.GetMethods()) { if (method.Name == "SyncState") { ser.BeginSection(fieldInfo.Name); method.Invoke(currentValue, new object[] { (Serializer)ser }); ser.EndSection(); fail = false; break; } } } else { fail = true; } } break; } } if (member.MemberType == MemberTypes.Property) { if (propInfo.CanWrite && !fail) { MethodInfo setMethod = propInfo.GetSetMethod(); setMethod.Invoke(obj, new object[] { currentValue }); } } if (member.MemberType == MemberTypes.Field) { fieldInfo.SetValue(obj, currentValue); } } } }