public void Serialize(Stream serializationStream, object graph) { using (StreamWriter sw = new StreamWriter(serializationStream)) { ObjectsBufferSave objectsBuffer = new ObjectsBufferSave(); objectsBuffer.AddObject(graph); using (JsonTextWriter writer = new JsonTextWriter(sw)) { writer.Formatting = Formatting.Indented; writer.WriteStartObject(); writer.WritePropertyName(fieldRoot); writer.WriteValue(graph.GetHashCode()); writer.WritePropertyName(fieldArrayElements); writer.WriteStartArray(); object obj; while ((obj = objectsBuffer.PopObject()) != null) { Type objType = obj.GetType(); WriteObject(obj, false, objType, writer, objectsBuffer); } writer.WriteEndArray(); writer.WriteEndObject(); } } }
private void WriteArray(JsonTextWriter writer, ObjectsBufferSave objectsBuffer, Array arr, int dimension, int[] indexes) { writer.WriteStartArray(); for (int i = 0; i < arr.GetLength(dimension); i++) { indexes[dimension] = i; if (dimension == 0) { WriteArrayEl(writer, objectsBuffer, indexes, arr.GetValue(indexes)); } else { WriteArray(writer, objectsBuffer, arr, dimension - 1, indexes); } } writer.WriteEndArray(); }
private void WriteArrayEl(JsonTextWriter writer, ObjectsBufferSave objectsBuffer, int[] indexes, object value) { if (value != null) { writer.WriteStartObject(); writer.WritePropertyName(fieldArrayElIndex); if (indexes.Length > 1) { writer.WriteStartArray(); foreach (int index in indexes) { writer.WriteValue(index); } writer.WriteEndArray(); } else { writer.WriteValue(indexes[0]); } writer.WritePropertyName(fieldArrayElValue); Type type = value.GetType(); if (IsValueType(type)) { if (IsPrimitive(type)) { writer.WriteValue(value); } else { WriteObject(value, false, type, writer, objectsBuffer); } } else { int refIndex = value.GetHashCode(); writer.WriteValue(refOperatorStr + refIndex.ToString()); objectsBuffer.AddObject(value); } writer.WriteEndObject(); } }
private void WriteObject(object obj, bool isBase, Type type, JsonTextWriter writer, ObjectsBufferSave objectsBuffer) { writer.WriteStartObject(); writer.WritePropertyName(fieldType); writer.WriteValue(type.AssemblyQualifiedName); if (!type.IsValueType && !isBase) { writer.WritePropertyName(fieldRef); writer.WriteValue(obj.GetHashCode()); } if (type.IsArray) { Array arr = (Array)obj; writer.WritePropertyName(fieldArraySize); if (arr.Rank > 1) { writer.WriteStartArray(); for (int i = 0; i < arr.Rank; i++) { writer.WriteValue(arr.GetLength(i)); } writer.WriteEndArray(); } else { writer.WriteValue(arr.Length); } writer.WritePropertyName(fieldArrayElements); int[] indexes = new int[arr.Rank]; WriteArray(writer, objectsBuffer, (Array)obj, arr.Rank - 1, indexes); } FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo field in fields) { if (field.GetCustomAttribute(typeof(NonSerializedAttribute)) == null) { object value = field.GetValue(obj); string name = field.Name; Type fieldType = field.FieldType; writer.WritePropertyName(name); if (IsValueType(fieldType)) { if (IsPrimitive(fieldType)) { writer.WriteValue(value); } else { WriteObject(value, false, fieldType, writer, objectsBuffer); } } else { if (value != null) { int refIndex = value.GetHashCode(); writer.WriteValue(refOperatorStr + refIndex.ToString()); objectsBuffer.AddObject(value); } else { writer.WriteValue(refOperatorStr + "null"); } } } } Type baseType = type.BaseType; if (baseType != null) { if (Attribute.GetCustomAttribute(baseType, typeof(SerializableAttribute)) != null) { writer.WritePropertyName(fieldBase); WriteObject(obj, true, baseType, writer, objectsBuffer); } } writer.WriteEndObject(); }