public static ObjectHeader Defrag(DefragmentContextImpl context) { var source = context.SourceBuffer(); var target = context.TargetBuffer(); var header = new ObjectHeader (context.Services().SystemTrans().Container(), null, source); var newID = context.Mapping().StrictMappedID(header.ClassMetadata().GetID()); var slotFormat = header.SlotFormat(); slotFormat.WriteObjectClassID(target, newID); slotFormat.SkipMarshallerInfo(target); slotFormat.ReadHeaderAttributes(target); return header; }
private static void ReadTree(Stream s, GitObject go, ObjectHeader header) { var sb = new StringBuilder(); // The counter is increased inside the loop // with every read operation. for (int i = 0; i < header.Size; ) { var leading = ReadLeadingBytes(s); sb.Append(leading); sb.Append(' '); i += 7; var filename = ReadFileName(s); sb.Append(filename); sb.Append(' '); i += filename.Length + 1; var hash = ReadHash(s); sb.AppendLine(hash); i += 20; go.AddReference(hash, filename); } go.Body = sb.ToString(); }
private object ReadStruct(XElement element, ObjectHeader header) { // Read struct type string customString = element.GetAttributeValue("custom"); string surrogateString = element.GetAttributeValue("surrogate"); bool custom = customString != null && XmlConvert.ToBoolean(customString); bool surrogate = surrogateString != null && XmlConvert.ToBoolean(surrogateString); // Retrieve surrogate if requested ISerializeSurrogate objSurrogate = null; if (surrogate && header.ObjectType != null) { objSurrogate = GetSurrogateFor(header.ObjectType); } // Construct object object obj = null; if (header.ObjectType != null) { if (objSurrogate != null) { custom = true; // Set fake object reference for surrogate constructor: No self-references allowed here. this.idManager.Inject(null, header.ObjectId); CustomSerialIO customIO = new CustomSerialIO(); XElement customHeaderElement = element.Element(CustomSerialIO.HeaderElement) ?? element.Elements().FirstOrDefault(); if (customHeaderElement != null) { customIO.Deserialize(this, customHeaderElement); } try { obj = objSurrogate.ConstructObject(customIO, header.ObjectType); } catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); } } if (obj == null) { obj = header.ObjectType.CreateInstanceOf(); } } // Prepare object reference this.idManager.Inject(obj, header.ObjectId); // Read custom object data if (custom) { CustomSerialIO customIO = new CustomSerialIO(); XElement customBodyElement = element.Element(CustomSerialIO.BodyElement) ?? element.Elements().ElementAtOrDefault(1); if (customBodyElement != null) { customIO.Deserialize(this, customBodyElement); } ISerializeExplicit objAsCustom; if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; } else { objAsCustom = obj as ISerializeExplicit; } if (objAsCustom != null) { try { objAsCustom.ReadData(customIO); } catch (Exception e) { this.LogCustomDeserializationError(header.ObjectId, header.ObjectType, e); } } else if (obj != null && header.ObjectType != null) { this.LocalLog.WriteWarning( "Object data (Id {0}) is flagged for custom deserialization, yet the objects Type ('{1}') does not support it. Guessing associated fields...", header.ObjectId, Log.Type(header.ObjectType)); this.LocalLog.PushIndent(); foreach (var pair in customIO.Data) { this.AssignValueToField(header.SerializeType, obj, pair.Key, pair.Value); } this.LocalLog.PopIndent(); } } // Red non-custom object data else if (!element.IsEmpty) { // Read fields object fieldValue; foreach (XElement fieldElement in element.Elements()) { fieldValue = this.ReadObjectData(fieldElement); this.AssignValueToField(header.SerializeType, obj, GetCodeElementName(fieldElement.Name.LocalName), fieldValue); } } return(obj); }
private static void ReadBody(Stream s, GitObject go, ObjectHeader header) { switch (header.Type) { case ObjectType.Tree: ReadTree(s, go, header); break; case ObjectType.Commit: ReadCommit(s, go); break; default: go.Body = ReadFile(s); break; } }
private Array ReadArray(XElement element, ObjectHeader header) { Array arrObj; TypeInfo arrayTypeInfo = header.ObjectType; Type elementType = arrayTypeInfo.GetElementType(); // Determine the array length based on child elements or explicit value string explicitLengthString = element.GetAttributeValue("length"); int explicitLength = explicitLengthString == null ? -1 : XmlConvert.ToInt32(explicitLengthString); // Expect the "complex" array format, if there are child elements or an explicit length (children may be omitted) bool isComplex = element.Elements().Any() || explicitLength != -1; bool isEmpty = explicitLength == 0 || (!isComplex && string.IsNullOrEmpty(element.Value)); // Early-out: Create an empty array if (isEmpty) { arrObj = header.ObjectType != null?Array.CreateInstance(elementType, 0) : null; this.idManager.Inject(arrObj, header.ObjectId); } // Read a primitive value array else if (!isComplex) { if (elementType == typeof(bool)) { bool[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(byte)) { byte[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(sbyte)) { sbyte[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(short)) { short[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(ushort)) { ushort[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(int)) { int[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(uint)) { uint[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(long)) { long[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(ulong)) { ulong[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(float)) { float[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(double)) { double[] array; this.ReadArrayData(element, out array); arrObj = array; } else if (elementType == typeof(decimal)) { decimal[] array; this.ReadArrayData(element, out array); arrObj = array; } else { this.LocalLog.WriteWarning("Can't read primitive value array. Unknown element type '{0}'. Discarding data.", Log.Type(elementType)); arrObj = header.ObjectType != null?Array.CreateInstance(elementType, 0) : null; } // Set object reference this.idManager.Inject(arrObj, header.ObjectId); } // Read a complex value array, where each item is an XML element else { int arrLength = explicitLength != -1 ? explicitLength : element.Elements().Count(); // Prepare object reference arrObj = header.ObjectType != null?Array.CreateInstance(elementType, arrLength) : null; this.idManager.Inject(arrObj, header.ObjectId); int itemIndex = 0; foreach (XElement itemElement in element.Elements()) { object item = this.ReadObjectData(itemElement); if (arrObj != null) { arrObj.SetValue(item, itemIndex); } itemIndex++; if (itemIndex >= arrLength) { break; } } } return(arrObj); }
private object ReadObjectData(XElement element) { // Empty element without type data? Return null if (element.IsEmpty && !element.HasAttributes) { return(null); } // Read data type header string objIdString = element.GetAttributeValue("id"); string dataTypeStr = element.GetAttributeValue("dataType"); string typeStr = element.GetAttributeValue("type"); uint objId = objIdString == null ? 0 : XmlConvert.ToUInt32(objIdString); DataType dataType = DataType.Unknown; if (!Enum.TryParse <DataType>(dataTypeStr, out dataType)) { if (dataTypeStr == "Class") // Legacy support (Written 2014-03-10) { dataType = DataType.Struct; } if (dataTypeStr == "MethodInfo" || // Legacy support (Written 2015-06-07) dataTypeStr == "ConstructorInfo" || dataTypeStr == "PropertyInfo" || dataTypeStr == "FieldInfo" || dataTypeStr == "EventInfo") { dataType = DataType.MemberInfo; } else { dataType = DataType.Unknown; } } Type type = null; if (typeStr != null) { type = this.ResolveType(typeStr, objId); } ObjectHeader header = new ObjectHeader(objId, dataType, GetSerializeType(type)); if (header.DataType == DataType.Unknown) { this.LocalLog.WriteError("Unable to process DataType: {0}.", dataTypeStr); return(null); } // Read object object result = null; try { // Read the objects body result = this.ReadObjectBody(element, header); } catch (Exception e) { this.LocalLog.WriteError("Error reading object: {0}", Log.Exception(e)); } return(result); }
private void WriteEnum(XElement element, Enum obj, ObjectHeader header) { element.SetAttributeValue("name", obj.ToString()); element.SetAttributeValue("value", XmlConvert.ToString(Convert.ToInt64(obj))); }
private void WriteStruct(XElement element, object obj, ObjectHeader header) { ISerializeExplicit objAsCustom = obj as ISerializeExplicit; ISerializeSurrogate objSurrogate = GetSurrogateFor(header.ObjectType); // If we're serializing a value type, skip the entire object body if // it equals the zero-init struct. This will keep struct-heavy data a lot // more concise. if (header.ObjectType.IsValueType && object.Equals(obj, header.SerializeType.DefaultValue)) { return; } // Write information about custom or surrogate serialization if (objAsCustom != null) { element.SetAttributeValue("custom", XmlConvert.ToString(true)); } if (objSurrogate != null) { element.SetAttributeValue("surrogate", XmlConvert.ToString(true)); } if (objSurrogate != null) { objSurrogate.RealObject = obj; objAsCustom = objSurrogate.SurrogateObject; CustomSerialIO customIO = new CustomSerialIO(); try { objSurrogate.WriteConstructorData(customIO); } catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); } XElement customHeaderElement = new XElement(CustomSerialIO.HeaderElement); element.Add(customHeaderElement); customIO.Serialize(this, customHeaderElement); } if (objAsCustom != null) { CustomSerialIO customIO = new CustomSerialIO(); try { objAsCustom.WriteData(customIO); } catch (Exception e) { this.LogCustomSerializationError(header.ObjectId, header.ObjectType, e); } XElement customBodyElement = new XElement(CustomSerialIO.BodyElement); element.Add(customBodyElement); customIO.Serialize(this, customBodyElement); } else { // Write the structs fields foreach (FieldInfo field in header.SerializeType.Fields) { if (this.IsFieldBlocked(field, obj)) { continue; } XElement fieldElement = new XElement(GetXmlElementName(field.Name)); element.Add(fieldElement); this.WriteObjectData(fieldElement, field.GetValue(obj)); } } }
private void WriteArray(XElement element, object obj, ObjectHeader header) { Array objAsArray = obj as Array; TypeInfo arrayTypeInfo = header.ObjectType; Type elementType = arrayTypeInfo.GetElementType(); TypeInfo elementTypeInfo = elementType.GetTypeInfo(); if (objAsArray.Rank != 1) { throw new NotSupportedException("Non single-Rank arrays are not supported"); } if (objAsArray.GetLowerBound(0) != 0) { throw new NotSupportedException("Non zero-based arrays are not supported"); } // If it's a primitive array, save the values as a comma-separated list if (elementType == typeof(bool)) { this.WriteArrayData(element, objAsArray as bool[]); } else if (elementType == typeof(byte)) { this.WriteArrayData(element, objAsArray as byte[]); } else if (elementType == typeof(sbyte)) { this.WriteArrayData(element, objAsArray as sbyte[]); } else if (elementType == typeof(short)) { this.WriteArrayData(element, objAsArray as short[]); } else if (elementType == typeof(ushort)) { this.WriteArrayData(element, objAsArray as ushort[]); } else if (elementType == typeof(int)) { this.WriteArrayData(element, objAsArray as int[]); } else if (elementType == typeof(uint)) { this.WriteArrayData(element, objAsArray as uint[]); } else if (elementType == typeof(long)) { this.WriteArrayData(element, objAsArray as long[]); } else if (elementType == typeof(ulong)) { this.WriteArrayData(element, objAsArray as ulong[]); } else if (elementType == typeof(float)) { this.WriteArrayData(element, objAsArray as float[]); } else if (elementType == typeof(double)) { this.WriteArrayData(element, objAsArray as double[]); } else if (elementType == typeof(decimal)) { this.WriteArrayData(element, objAsArray as decimal[]); } // Any non-trivial object data will be serialized recursively else { int nonDefaultElementCount = this.GetArrayNonDefaultElementCount(objAsArray, elementTypeInfo); // Write Array elements for (int i = 0; i < nonDefaultElementCount; i++) { XElement itemElement = new XElement("item"); element.Add(itemElement); this.WriteObjectData(itemElement, objAsArray.GetValue(i)); } // Write original length, in case trailing elements were omitted or we have an (XML-ambiguous) zero-element array. if (nonDefaultElementCount != objAsArray.Length || nonDefaultElementCount == 0) { element.SetAttributeValue("length", XmlConvert.ToString(objAsArray.Length)); } } }