void ReadString(ObjectReference objReference) { objReference.Value = ReadLine(); }
void ReadIntPtr(ObjectReference objReference) { objReference.Value = new IntPtr(Int64.Parse(ReadLine())); }
void ReadObject(ObjectReference objReference) { var type = ReadType(); objReference.Value = FormatterServices.GetUninitializedObject(type); if (type.Implements<ICrySerializable>()) { var crySerializable = objReference.Value as ICrySerializable; crySerializable.Serialize(this); return; } while (type != null) { var numFields = int.Parse(ReadLine()); for (int i = 0; i < numFields; i++) { var fieldReference = StartRead(); if (objReference.Value == null) continue; var fieldInfo = type.GetField(fieldReference.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fieldInfo != null) fieldInfo.SetValue(objReference.Value, fieldReference.Value); else if(IsDebugModeEnabled) throw new MissingFieldException(string.Format("Failed to find field {0} in type {1}", fieldReference.Name, type.Name)); } var numEvents = int.Parse(ReadLine()); for (int i = 0; i < numEvents; i++) { var eventName = ReadLine(); var eventInfo = type.GetEvent(eventName); var eventHandlerType = ReadType(); var numDelegates = Int32.Parse(ReadLine()); for (int iDelegate = 0; iDelegate < numDelegates; iDelegate++) { var foundDelegate = ReadDelegate(); eventInfo.AddEventHandler(objReference.Value, foundDelegate); } } type = type.BaseType; } }
void WriteType(ObjectReference objectReference) { WriteType(objectReference.Value as Type); }
void ReadEnumerable(ObjectReference objReference) { var numElements = int.Parse(ReadLine()); var type = ReadType(); objReference.Value = Array.CreateInstance(type, numElements); var array = objReference.Value as Array; for (int i = 0; i != numElements; ++i) array.SetValue(StartRead().Value, i); }
void WriteEnum(ObjectReference objectReference) { WriteType(objectReference.Value.GetType()); WriteLine(objectReference.Value); }
void WriteMemberInfo(ObjectReference objectReference) { var memberInfo = objectReference.Value as MemberInfo; WriteMemberInfo(memberInfo); }
void WriteString(ObjectReference objectReference) { WriteLine(objectReference.Value); }
void WriteEnum(ObjectReference objectReference) { WriteType(objectReference.Value.GetType()); WriteLine((int)objectReference.Value); }
void WriteReference(ObjectReference objReference, int line) { WriteLine(SerializationType.Reference); WriteLine(line); }
void WriteAny(ObjectReference objectReference) { WriteType(objectReference.Value.GetType()); WriteLine(objectReference.Value); }
void WriteIntPtr(ObjectReference objectReference) { WriteLine(((IntPtr)objectReference.Value).ToInt64()); }
void StartWrite(ObjectReference objectReference) { Type valueType = objectReference.Value != null?objectReference.Value.GetType() : null; WriteLine(objectReference.Name); if (TryWriteReference(objectReference)) { return; } if (objectReference.SerializationType == SerializationType.Any) { if (objectReference.Value is int && UnusedMarker.IsUnused((int)objectReference.Value)) { objectReference.SerializationType = SerializationType.UnusedMarker; } else if (objectReference.Value is uint && UnusedMarker.IsUnused((uint)objectReference.Value)) { objectReference.SerializationType = SerializationType.UnusedMarker; } else if (objectReference.Value is float && UnusedMarker.IsUnused((float)objectReference.Value)) { objectReference.SerializationType = SerializationType.UnusedMarker; } } else if (objectReference.SerializationType == SerializationType.Object && objectReference.Value is Vec3 && UnusedMarker.IsUnused((Vec3)objectReference.Value)) { objectReference.SerializationType = SerializationType.UnusedMarker; } WriteLine((int)objectReference.SerializationType); switch (objectReference.SerializationType) { case SerializationType.Null: break; case SerializationType.IntPtr: WriteIntPtr(objectReference); break; case SerializationType.Any: WriteAny(objectReference); break; case SerializationType.String: WriteString(objectReference); break; case SerializationType.Enumerable: WriteEnumerable(objectReference); break; case SerializationType.GenericEnumerable: WriteGenericEnumerable(objectReference); break; case SerializationType.Enum: WriteEnum(objectReference); break; case SerializationType.Type: WriteType(objectReference); break; case SerializationType.Delegate: WriteDelegate(objectReference); break; case SerializationType.MemberInfo: WriteMemberInfo(objectReference); break; case SerializationType.Object: WriteObject(objectReference); break; case SerializationType.UnusedMarker: WriteUnusedMarker(objectReference); break; } }
void ReadDelegate(ObjectReference objReference) { objReference.Value = ReadDelegate(); }
void ReadUnusedMarker(ObjectReference objReference) { var type = ReadType(); if (type == typeof(int)) objReference.Value = UnusedMarker.Integer; if (type == typeof(uint)) objReference.Value = UnusedMarker.UnsignedInteger; else if (type == typeof(float)) objReference.Value = UnusedMarker.Float; else if (type == typeof(Vec3)) objReference.Value = UnusedMarker.Vec3; }
void WriteArray(ObjectReference objectReference) { var array = objectReference.Value as Array; var numElements = array.Length; WriteLine(numElements); WriteType(array.GetType().GetElementType()); for (int i = 0; i < numElements; i++) StartWrite(new ObjectReference(i.ToString(), array.GetValue(i))); }
void WriteUnusedMarker(ObjectReference objectReference) { WriteType(objectReference.Value.GetType()); }
void WriteGenericEnumerable(ObjectReference objectReference) { var enumerable = (objectReference.Value as IEnumerable).Cast<object>(); WriteLine(enumerable.Count()); var type = objectReference.Value.GetType(); WriteType(type); if (type.Implements<IDictionary>()) { int i = 0; foreach (var element in enumerable) { StartWrite(new ObjectReference("key_" + i.ToString(), element.GetType().GetProperty("Key").GetValue(element, null))); StartWrite(new ObjectReference("value_" + i.ToString(), element.GetType().GetProperty("Value").GetValue(element, null))); i++; } } else { for (int i = 0; i < enumerable.Count(); i++) StartWrite(new ObjectReference(i.ToString(), enumerable.ElementAt(i))); } }
void WriteDelegate(ObjectReference objectReference) { WriteDelegate(objectReference.Value as Delegate); }
void ReadGenericEnumerable(ObjectReference objReference) { int elements = int.Parse(ReadLine()); var type = ReadType(); objReference.Value = Activator.CreateInstance(type); if (type.Implements<IDictionary>()) { var dict = objReference.Value as IDictionary; for (int i = 0; i < elements; i++) { var key = StartRead().Value; var value = StartRead().Value; dict.Add(key, value); } } else if (type.Implements<IList>()) { var list = objReference.Value as IList; for (int i = 0; i < elements; i++) list.Add(StartRead().Value); } else if (type.ImplementsGeneric(typeof(ISet<>)) || type.ImplementsGeneric(typeof(ICollection<>))) { var set = objReference.Value; MethodInfo addMethod = null; var baseType = type; while (baseType != null) { addMethod = type.GetMethod("Add", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (addMethod != null) break; baseType = baseType.BaseType; } for (int i = 0; i < elements; i++) { addMethod.Invoke(objReference.Value, new object[] { StartRead().Value }); } } else if (IsDebugModeEnabled) throw new SerializationException(string.Format("Failed to serialize generic enumerable of type {0}, not supported by implementation", type.Name)); }
void ReadMemberInfo(ObjectReference objReference) { objReference.Value = ReadMemberInfo(); }
void ReadType(ObjectReference objReference) { objReference.Value = ReadType(); }
void ReadReference(ObjectReference objReference) { int referenceLine = int.Parse(ReadLine()); ObjectReference originalReference; if (!ObjectReferences.TryGetValue(referenceLine, out originalReference)) throw new SerializationException(string.Format("Failed to obtain reference {0} at line {1}! Last line was {2})", objReference.Name, referenceLine, m_currentLine)); objReference.Value = originalReference.Value; objReference.AllowNull = originalReference.AllowNull; }
void StartWrite(ObjectReference objectReference) { Type valueType = objectReference.Value != null ? objectReference.Value.GetType() : null; WriteLine(objectReference.Name); if (TryWriteReference(objectReference)) return; if (objectReference.SerializationType == SerializationType.Any) { if (objectReference.Value is int && UnusedMarker.IsUnused((int)objectReference.Value)) objectReference.SerializationType = SerializationType.UnusedMarker; else if (objectReference.Value is uint && UnusedMarker.IsUnused((uint)objectReference.Value)) objectReference.SerializationType = SerializationType.UnusedMarker; else if (objectReference.Value is float && UnusedMarker.IsUnused((float)objectReference.Value)) objectReference.SerializationType = SerializationType.UnusedMarker; } else if (objectReference.SerializationType == SerializationType.Object && objectReference.Value is Vec3 && UnusedMarker.IsUnused((Vec3)objectReference.Value)) objectReference.SerializationType = SerializationType.UnusedMarker; WriteLine((int)objectReference.SerializationType); switch(objectReference.SerializationType) { case SerializationType.Null: break; case SerializationType.IntPtr: WriteIntPtr(objectReference); break; case SerializationType.Any: WriteAny(objectReference); break; case SerializationType.String: WriteString(objectReference); break; case SerializationType.Enumerable: WriteEnumerable(objectReference); break; case SerializationType.GenericEnumerable: WriteGenericEnumerable(objectReference); break; case SerializationType.Enum: WriteEnum(objectReference); break; case SerializationType.Type: WriteType(objectReference); break; case SerializationType.Delegate: WriteDelegate(objectReference); break; case SerializationType.MemberInfo: WriteMemberInfo(objectReference); break; case SerializationType.Object: WriteObject(objectReference); break; case SerializationType.UnusedMarker: WriteUnusedMarker(objectReference); break; } }
void WriteDelegate(ObjectReference objectReference) { var _delegate = objectReference.Value as Delegate; WriteType(_delegate.GetType()); WriteMemberInfo(_delegate.Method); if (_delegate.Target != null) { WriteLine("target"); StartWrite(new ObjectReference("delegateTarget", _delegate.Target)); } else WriteLine("null_target"); }
/// <summary> /// Checks if this object has already been serialized. /// </summary> /// <param name="objectReference"></param> /// <returns>true if object had already been serialized.</returns> bool TryWriteReference(ObjectReference objectReference) { if(objectReference.SerializationType > SerializationType.ReferenceTypes) { foreach (var pair in ObjectReferences) { if (pair.Value.Value.Equals(objectReference.Value)) { WriteReference(objectReference, pair.Key); return true; } } ObjectReferences.Add(m_currentLine, objectReference); } return false; }
void WriteObject(ObjectReference objectReference) { var type = objectReference.Value.GetType(); WriteType(type); while (type != null) { var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); WriteLine(fields.Length); foreach (var field in fields) StartWrite(new ObjectReference(field.Name, field.GetValue(objectReference.Value))); type = type.BaseType; } }
/// <summary> /// Starts reading an reference that was written with <see cref="StartWrite"/>. /// </summary> /// <returns></returns> public ObjectReference StartRead() { var name = ReadLine(); int line = m_currentLine; var serializationType = (SerializationType)Enum.Parse(typeof(SerializationType), ReadLine()); var objReference = new ObjectReference(name, serializationType); if (serializationType > SerializationType.ReferenceTypes) ObjectReferences.Add(line, objReference); switch (serializationType) { case SerializationType.Null: break; case SerializationType.Reference: ReadReference(objReference); break; case SerializationType.Object: ReadObject(objReference); break; case SerializationType.Array: ReadArray(objReference); break; case SerializationType.GenericEnumerable: ReadGenericEnumerable(objReference); break; case SerializationType.Enumerable: ReadEnumerable(objReference); break; case SerializationType.Enum: ReadEnum(objReference); break; case SerializationType.Any: ReadAny(objReference); break; case SerializationType.String: ReadString(objReference); break; case SerializationType.MemberInfo: ReadMemberInfo(objReference); break; case SerializationType.Type: ReadType(objReference); break; case SerializationType.Delegate: ReadDelegate(objReference); break; case SerializationType.IntPtr: ReadIntPtr(objReference); break; case SerializationType.UnusedMarker: ReadUnusedMarker(objReference); break; } #if !(RELEASE && RELEASE_DISABLE_CHECKS) if (!objReference.AllowNull && objReference.Value == null && serializationType != SerializationType.Null) throw new SerializationException(string.Format("Failed to deserialize object of type {0} {1} at line {2}!", objReference.SerializationType, objReference.Name, line)); #endif return objReference; }
void WriteEnumerable(ObjectReference objectReference) { var array = (objectReference.Value as IEnumerable).Cast<object>(); var numElements = array.Count(); WriteLine(numElements); WriteType(GetIEnumerableElementType(objectReference.Value.GetType())); for (int i = 0; i < numElements; i++) StartWrite(new ObjectReference(i.ToString(), array.ElementAt(i))); }
/// <summary> /// Starts writing the specified reference. /// </summary> /// <param name="objectReference"></param> public void StartWrite(ObjectReference objectReference) { WriteLine(objectReference.Name); if (TryWriteReference(objectReference)) return; WriteLine((int)objectReference.SerializationType); switch(objectReference.SerializationType) { case SerializationType.Null: break; case SerializationType.IntPtr: WriteIntPtr(objectReference); break; case SerializationType.Any: WriteAny(objectReference); break; case SerializationType.String: WriteString(objectReference); break; case SerializationType.Array: WriteArray(objectReference); break; case SerializationType.Enumerable: WriteEnumerable(objectReference); break; case SerializationType.GenericEnumerable: WriteGenericEnumerable(objectReference); break; case SerializationType.Enum: WriteEnum(objectReference); break; case SerializationType.Type: WriteType(objectReference); break; case SerializationType.Delegate: WriteDelegate(objectReference); break; case SerializationType.MemberInfo: WriteMemberInfo(objectReference); break; case SerializationType.Object: WriteObject(objectReference); break; case SerializationType.UnusedMarker: WriteUnusedMarker(objectReference); break; } }
void ReadAny(ObjectReference objReference) { var type = ReadType(); string valueString = ReadLine(); if (!string.IsNullOrEmpty(valueString)) objReference.Value = Converter.Convert(valueString, type); else objReference.Value = 0; }
void WriteObject(ObjectReference objectReference) { var type = objectReference.Value.GetType(); WriteType(type); if (type.Implements<ICrySerializable>()) { var crySerializable = objectReference.Value as ICrySerializable; crySerializable.Serialize(this); return; } while (type != null) { var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); WriteLine(fields.Length); foreach (var field in fields) StartWrite(new ObjectReference(field.Name, field.GetValue(objectReference.Value))); var events = type.GetEvents(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); WriteLine(events.Length); foreach (var eventInfo in events) { WriteLine(eventInfo.Name); WriteType(eventInfo.EventHandlerType); var eventFieldInfo = type.GetField(eventInfo.Name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField); var eventFieldValue = (Delegate)eventFieldInfo.GetValue(objectReference.Value); if (eventFieldValue != null) { var delegates = eventFieldValue.GetInvocationList(); WriteLine(delegates.Length); foreach (var eventDelegate in delegates) WriteDelegate(eventDelegate); } else WriteLine(0); } type = type.BaseType; } }
void ReadEnum(ObjectReference objReference) { var type = ReadType(); string valueString = ReadLine(); objReference.Value = Enum.Parse(type, valueString); }
/// <summary> /// Starts writing the specified reference. /// </summary> /// <param name="objectReference"></param> public void StartWrite(ObjectReference objectReference) { WriteLine(objectReference.Name); if (TryWriteReference(objectReference)) { return; } WriteLine((int)objectReference.SerializationType); switch (objectReference.SerializationType) { case SerializationType.Null: break; case SerializationType.IntPtr: WriteIntPtr(objectReference); break; case SerializationType.Any: WriteAny(objectReference); break; case SerializationType.String: WriteString(objectReference); break; case SerializationType.Array: WriteArray(objectReference); break; case SerializationType.Enumerable: WriteEnumerable(objectReference); break; case SerializationType.GenericEnumerable: WriteGenericEnumerable(objectReference); break; case SerializationType.Enum: WriteEnum(objectReference); break; case SerializationType.Type: WriteType(objectReference); break; case SerializationType.Delegate: WriteDelegate(objectReference); break; case SerializationType.MemberInfo: WriteMemberInfo(objectReference); break; case SerializationType.Object: WriteObject(objectReference); break; case SerializationType.UnusedMarker: WriteUnusedMarker(objectReference); break; } }