示例#1
0
 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;
 }
示例#2
0
        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();
        }
示例#3
0
        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);
        }
示例#4
0
 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;
     }
 }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
 private void WriteEnum(XElement element, Enum obj, ObjectHeader header)
 {
     element.SetAttributeValue("name", obj.ToString());
     element.SetAttributeValue("value", XmlConvert.ToString(Convert.ToInt64(obj)));
 }
示例#8
0
        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));
                }
            }
        }
示例#9
0
        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));
                }
            }
        }