Exemple #1
0
        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);
                    }
                }
            }
        }
Exemple #2
0
		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);
					}
				}
			}
		}