private void ReadUnusedMarker(ObjectReference objReference) { var type = this.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(Vector3)) objReference.Value = UnusedMarker.Vector3; }
private void WriteArray(ObjectReference objectReference) { var array = objectReference.Value as Array; var numElements = array.Length; this.WriteLine(numElements); this.WriteType(array.GetType().GetElementType()); for (int i = 0; i < numElements; i++) this.StartWrite(new ObjectReference(i.ToString(), array.GetValue(i))); }
private void ReadObject(ObjectReference objReference) { var type = this.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(this.ReadLine()); for (int i = 0; i < numFields; i++) { var fieldReference = this.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 (this.IsDebugModeEnabled) throw new MissingFieldException(string.Format("Failed to find field {0} in type {1}", fieldReference.Name, type.Name)); } var numEvents = int.Parse(this.ReadLine()); for (int i = 0; i < numEvents; i++) { var eventName = this.ReadLine(); var eventInfo = type.GetEvent(eventName); // ReSharper disable UnusedVariable var eventHandlerType = this.ReadType(); // ReSharper restore UnusedVariable var numDelegates = Int32.Parse(this.ReadLine()); for (int iDelegate = 0; iDelegate < numDelegates; iDelegate++) { var foundDelegate = this.ReadDelegate(); eventInfo.AddEventHandler(objReference.Value, foundDelegate); } } type = type.BaseType; } }
private void ReadString(ObjectReference objReference) { objReference.Value = this.ReadLine(); }
private void WriteType(ObjectReference objectReference) { this.WriteType(objectReference.Value as Type); }
private void ReadIntPtr(ObjectReference objReference) { objReference.Value = new IntPtr(Int64.Parse(this.ReadLine())); }
private void WriteUnusedMarker(ObjectReference objectReference) { this.WriteType(objectReference.Value.GetType()); }
private void WriteMemberInfo(ObjectReference objectReference) { var memberInfo = objectReference.Value as MemberInfo; this.WriteMemberInfo(memberInfo); }
private void WriteDelegate(ObjectReference objectReference) { this.WriteDelegate(objectReference.Value as Delegate); }
private void WriteEnum(ObjectReference objectReference) { this.WriteType(objectReference.Value.GetType()); this.WriteLine(objectReference.Value); }
private void WriteString(ObjectReference objectReference) { this.WriteLine(objectReference.Value); }
// ReSharper disable UnusedParameter.Local private void WriteReference(ObjectReference objReference, int line) // ReSharper restore UnusedParameter.Local { this.WriteLine(SerializationType.Reference); this.WriteLine(line); }
private void WriteGenericEnumerable(ObjectReference objectReference) { var enumerable = ((IEnumerable)objectReference.Value).Cast<object>().ToArray(); this.WriteLine(enumerable.Count()); var type = objectReference.Value.GetType(); this.WriteType(type); if (type.Implements<IDictionary>()) { int i = 0; foreach (var element in enumerable) { this.StartWrite(new ObjectReference("key_" + i, element.GetType().GetProperty("Key").GetValue(element, null))); this.StartWrite(new ObjectReference("value_" + i, element.GetType().GetProperty("Value").GetValue(element, null))); i++; } } else { for (int i = 0; i < enumerable.Count(); i++) this.StartWrite(new ObjectReference(i.ToString(), enumerable.ElementAt(i))); } }
// ReSharper restore UnusedParameter.Local // ReSharper disable UnusedParameter.Local private void WriteReference(ObjectReference objReference, int line) { this.WriteLine(SerializationType.Reference); this.WriteLine(line); }
private void ReadObject(ObjectReference objReference) { var type = this.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(this.ReadLine()); for (int i = 0; i < numFields; i++) { var fieldReference = this.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 (this.IsDebugModeEnabled) { throw new MissingFieldException(string.Format("Failed to find field {0} in type {1}", fieldReference.Name, type.Name)); } } var numEvents = int.Parse(this.ReadLine()); for (int i = 0; i < numEvents; i++) { var eventName = this.ReadLine(); var eventInfo = type.GetEvent(eventName); // ReSharper disable UnusedVariable var eventHandlerType = this.ReadType(); // ReSharper restore UnusedVariable var numDelegates = Int32.Parse(this.ReadLine()); for (int iDelegate = 0; iDelegate < numDelegates; iDelegate++) { var foundDelegate = this.ReadDelegate(); eventInfo.AddEventHandler(objReference.Value, foundDelegate); } } type = type.BaseType; } }
private void WriteIntPtr(ObjectReference objectReference) { this.WriteLine(((IntPtr)objectReference.Value).ToInt64()); }
private void ReadGenericEnumerable(ObjectReference objReference) { int elements = int.Parse(this.ReadLine()); var type = this.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 = this.StartRead().Value; var value = this.StartRead().Value; dict.Add(key, value); } } else if (type.Implements <IList>()) { var list = objReference.Value as IList; for (int i = 0; i < elements; i++) { if (list != null) { list.Add(this.StartRead().Value); } } } else if (type.ImplementsGeneric(typeof(ISet <>)) || type.ImplementsGeneric(typeof(ICollection <>))) { // ReSharper disable UnusedVariable var set = objReference.Value; // ReSharper restore UnusedVariable 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 [] { this.StartRead().Value }); } } else if (this.IsDebugModeEnabled) { throw new SerializationException(string.Format("Failed to serialize generic enumerable of type {0}, not supported by implementation", type.Name)); } }
private void ReadMemberInfo(ObjectReference objReference) { objReference.Value = this.ReadMemberInfo(); }
private void ReadReference(ObjectReference objReference) { int referenceLine = int.Parse(this.ReadLine()); ObjectReference originalReference; if (!this.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, this.m_currentLine)); objReference.Value = originalReference.Value; objReference.AllowNull = originalReference.AllowNull; }
private void ReadType(ObjectReference objReference) { objReference.Value = this.ReadType(); }
/// <summary> /// Checks if this object has already been serialized. /// </summary> /// <param name="objectReference"></param> /// <returns>true if object had already been serialized.</returns> private bool TryWriteReference(ObjectReference objectReference) { if (objectReference.SerializationType > SerializationType.ReferenceTypes) { foreach (var pair in this.ObjectReferences) { if (pair.Value.Value.Equals(objectReference.Value)) { this.WriteReference(objectReference, pair.Key); return true; } } this.ObjectReferences.Add(this.m_currentLine, objectReference); } return false; }
/// <summary> /// Starts reading an reference that was written with <see cref="StartWrite" />. /// </summary> /// <returns></returns> public ObjectReference StartRead() { var name = this.ReadLine(); int line = this.m_currentLine; var serializationType = (SerializationType)Enum.Parse(typeof(SerializationType), this.ReadLine()); var objReference = new ObjectReference(name, serializationType); if (serializationType > SerializationType.ReferenceTypes) this.ObjectReferences.Add(line, objReference); switch (serializationType) { case SerializationType.Null: break; case SerializationType.Reference: this.ReadReference(objReference); break; case SerializationType.Object: this.ReadObject(objReference); break; case SerializationType.Array: this.ReadArray(objReference); break; case SerializationType.GenericEnumerable: this.ReadGenericEnumerable(objReference); break; case SerializationType.Enumerable: this.ReadEnumerable(objReference); break; case SerializationType.Enum: this.ReadEnum(objReference); break; case SerializationType.Any: this.ReadAny(objReference); break; case SerializationType.String: this.ReadString(objReference); break; case SerializationType.MemberInfo: this.ReadMemberInfo(objReference); break; case SerializationType.Type: this.ReadType(objReference); break; case SerializationType.Delegate: this.ReadDelegate(objReference); break; case SerializationType.IntPtr: this.ReadIntPtr(objReference); break; case SerializationType.UnusedMarker: this.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; }
/// <summary> /// Starts writing the specified reference. /// </summary> /// <param name="objectReference"></param> public void StartWrite(ObjectReference objectReference) { this.WriteLine(objectReference.Name); if (this.TryWriteReference(objectReference)) return; this.WriteLine((int)objectReference.SerializationType); switch (objectReference.SerializationType) { case SerializationType.Null: break; case SerializationType.IntPtr: this.WriteIntPtr(objectReference); break; case SerializationType.Any: this.WriteAny(objectReference); break; case SerializationType.String: this.WriteString(objectReference); break; case SerializationType.Array: this.WriteArray(objectReference); break; case SerializationType.Enumerable: this.WriteEnumerable(objectReference); break; case SerializationType.GenericEnumerable: this.WriteGenericEnumerable(objectReference); break; case SerializationType.Enum: this.WriteEnum(objectReference); break; case SerializationType.Type: this.WriteType(objectReference); break; case SerializationType.Delegate: this.WriteDelegate(objectReference); break; case SerializationType.MemberInfo: this.WriteMemberInfo(objectReference); break; case SerializationType.Object: this.WriteObject(objectReference); break; case SerializationType.UnusedMarker: this.WriteUnusedMarker(objectReference); break; } }
private void WriteEnumerable(ObjectReference objectReference) { var array = ((IEnumerable)objectReference.Value).Cast<object>().ToArray(); var numElements = array.Length; this.WriteLine(numElements); this.WriteType(GetIEnumerableElementType(objectReference.Value.GetType())); for (int i = 0; i < numElements; i++) this.StartWrite(new ObjectReference(i.ToString(CultureInfo.InvariantCulture), array[i])); }
private void ReadAny(ObjectReference objReference) { var type = this.ReadType(); string valueString = this.ReadLine(); objReference.Value = !string.IsNullOrEmpty(valueString) ? this.Converter.Convert(valueString, type) : 0; }
private void ReadEnum(ObjectReference objReference) { var type = this.ReadType(); string valueString = this.ReadLine(); objReference.Value = Enum.Parse(type, valueString); }
private void WriteObject(ObjectReference objectReference) { var type = objectReference.Value.GetType(); this.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); this.WriteLine(fields.Length); foreach (var field in fields) this.StartWrite(new ObjectReference(field.Name, field.GetValue(objectReference.Value))); var events = type.GetEvents(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); this.WriteLine(events.Length); foreach (var eventInfo in events) { this.WriteLine(eventInfo.Name); this.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(); this.WriteLine(delegates.Length); foreach (var eventDelegate in delegates) this.WriteDelegate(eventDelegate); } else this.WriteLine(0); } type = type.BaseType; } }
private void ReadEnumerable(ObjectReference objReference) { var numElements = int.Parse(this.ReadLine()); var type = this.ReadType(); objReference.Value = Array.CreateInstance(type, numElements); var array = objReference.Value as Array; for (int i = 0; i != numElements; ++i) array.SetValue(this.StartRead().Value, i); }
private void ReadGenericEnumerable(ObjectReference objReference) { int elements = int.Parse(this.ReadLine()); var type = this.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 = this.StartRead().Value; var value = this.StartRead().Value; dict.Add(key, value); } } else if (type.Implements<IList>()) { var list = objReference.Value as IList; for (int i = 0; i < elements; i++) if (list != null) list.Add(this.StartRead().Value); } else if (type.ImplementsGeneric(typeof(ISet<>)) || type.ImplementsGeneric(typeof(ICollection<>))) { // ReSharper disable UnusedVariable var set = objReference.Value; // ReSharper restore UnusedVariable 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 [] { this.StartRead().Value }); } } else if (this.IsDebugModeEnabled) throw new SerializationException(string.Format("Failed to serialize generic enumerable of type {0}, not supported by implementation", type.Name)); }
/// <summary> /// Starts writing the specified reference. /// </summary> /// <param name="objectReference"></param> public void StartWrite(ObjectReference objectReference) { this.WriteLine(objectReference.Name); if (this.TryWriteReference(objectReference)) { return; } this.WriteLine((int)objectReference.SerializationType); switch (objectReference.SerializationType) { case SerializationType.Null: break; case SerializationType.IntPtr: this.WriteIntPtr(objectReference); break; case SerializationType.Any: this.WriteAny(objectReference); break; case SerializationType.String: this.WriteString(objectReference); break; case SerializationType.Array: this.WriteArray(objectReference); break; case SerializationType.Enumerable: this.WriteEnumerable(objectReference); break; case SerializationType.GenericEnumerable: this.WriteGenericEnumerable(objectReference); break; case SerializationType.Enum: this.WriteEnum(objectReference); break; case SerializationType.Type: this.WriteType(objectReference); break; case SerializationType.Delegate: this.WriteDelegate(objectReference); break; case SerializationType.MemberInfo: this.WriteMemberInfo(objectReference); break; case SerializationType.Object: this.WriteObject(objectReference); break; case SerializationType.UnusedMarker: this.WriteUnusedMarker(objectReference); break; } }