public XElement SerializeRoot(object obj, Type rootType, XName name, XSerializerNamespaceCollection namespaces, SerializationScope globalScope)
 {
     Debug.Assert(rootType.IsInstanceOfType(obj));
     Debug.Assert(namespaces != null);
     var root = SerializeXElement(obj, rootType, name, globalScope);
     //导入命名空间。
     foreach (var ns in namespaces)
         root.SetAttributeValue(XNamespace.Xmlns + ns.Prefix, ns.Uri);
     //处理导入的类型。
     var nsCounter = 0;
     foreach (var descendant in root.Descendants())
     {
         var actualTypeName = descendant.Annotation<XName>();
         if (actualTypeName != null)
         {
             if (actualTypeName.Namespace == descendant.GetDefaultNamespace())
             {
                 descendant.SetAttributeValue(SerializationHelper.Xsi + "type", actualTypeName.LocalName);
             }
             else
             {
                 var prefix = descendant.GetPrefixOfNamespace(actualTypeName.Namespace);
                 if (prefix == null)
                 {
                     nsCounter++;
                     prefix = "nss" + nsCounter;
                     descendant.SetAttributeValue(XNamespace.Xmlns + prefix, actualTypeName.NamespaceName);
                 }
                 descendant.SetAttributeValue(SerializationHelper.Xsi + "type", prefix + ":" + actualTypeName.LocalName);
             }
             descendant.RemoveAnnotations<XName>();
         }
     }
     return root;
 }
 public object DeserializeRoot(XElement e, object existingObject, Type rootType, SerializationScope globalScope)
 {
     var obj = DeserializeXElement(e, existingObject, rootType, globalScope);
     if (!rootType.IsInstanceOfType(obj))
         throw new InvalidOperationException("Invalid root element : " + e.Name);
     return obj;
 }
 public object DeserializeXCollectionItem(XElement e, SerializationScope typeScope)
 {
     //Debug.Print("DC : {0}\t{1}", e, typeScope);
     Debug.Assert(typeScope != null);
     var t = typeScope.GetType(e.Name);
     if (t == null) throw new NotSupportedException(string.Format(Prompts.UnregisteredType, e.Name, typeScope));
     return DeserializeXElement(e, null, t, typeScope);
 }
 // param : obj is the current value of property / field.
 public object DeserializeXProperty(XElement e, object obj, Type defaultType, SerializationScope childItemsTypeScope)
 {
     //Debug.Print("DP : {0}\t{1}", e, childItemsTypeScope);
     return DeserializeXElement(e, obj, defaultType, childItemsTypeScope);
 }
 // typeScope is applied for child items, rather than obj itself.
 private XElement SerializeXElement(object obj, Type defaultType, XName name, SerializationScope typeScope)
 {
     Debug.Assert(obj != null && defaultType != null && name != null);
     var objType = obj.GetType();
     var objTypeName = _Builder.GlobalScope.GetName(objType);
     if (objTypeName == null)
         throw new NotSupportedException(string.Format(Prompts.UnregisteredType, objType, _Builder.GlobalScope));
     var s = _Builder.GetSerializer(objType);
     var e = new XElement(name);
     //如果名义类型和实际类型不同,则注明实际类型。
     //如果是 TypeScope 中未定义的类型,则使用对应的元素名,而不使用 xsi:type
     if (name != objTypeName && objType != defaultType)
     {
         //先将 XName 加入批注,到根节点中处理。
         e.AddAnnotation(objTypeName);
     }
     //一般不会调用到此处,除非 obj 是根部节点,或是集合中的一项。
     if (s == null)
         throw new NotSupportedException(string.Format(Prompts.UnregisteredType, objType, typeScope));
     EnterObjectSerialization(obj);
     s.Serialize(e, obj, this, typeScope);
     ExitObjectSerialization(obj);
     return e;
 }
 private object DeserializeXElement(XElement e, object obj, Type defaultType, SerializationScope typeScope)
 {
     Debug.Assert(e != null && defaultType != null);
     // 对于集合,从元素名推理对象类型。
     var xsiTypeName = (string)e.Attribute(XsiType);
     Type objType;
     if (xsiTypeName == null)
     {
         //未指定 xsi:type,则使用 defaultType
         objType = defaultType;
     }
     else
     {
         //指定了 xsi:type
         //解析 prefix:localName
         var parts = xsiTypeName.Split(':');
         XName xName;
         if (parts.Length <= 1) xName = e.GetDefaultNamespace() + xsiTypeName;
         else xName = e.GetNamespaceOfPrefix(parts[0]) + parts[1];
         objType = _Builder.GlobalScope.GetType(xName);
         if (objType == null)
             throw new NotSupportedException(string.Format(Prompts.UnregisteredType, xsiTypeName, typeScope));
     }
     var s = _Builder.GetSerializer(objType);
     if (s == null)
         throw new NotSupportedException(string.Format(Prompts.UnregisteredType, objType, typeScope));
     return s.Deserialize(e, obj, this, typeScope);
 }
 // Serialize Collection or Complex objects
 public XElement SerializeXProperty(object obj, Type defaultType, XName name, SerializationScope childItemsTypeScope)
 {
     //Debug.Print("SP : {0}\t{1}\t{2}", name, obj, childItemsTypeScope);
     if (obj != null) return SerializeXElement(obj, defaultType, name, childItemsTypeScope);
     return null;
 }
 public XElement SerializeXCollectionItem(object obj, Type defaultType, SerializationScope typeScope)
 {
     //Debug.Print("SC : {0}\t{1}", obj, typeScope);
     Debug.Assert(typeScope != null);
     var nominalType = obj.GetType();
     var objTypeName = typeScope.GetName(nominalType);
     if (objTypeName == null)
     {
         objTypeName = typeScope.GetName(defaultType);
         nominalType = defaultType;
     }
     return SerializeXElement(obj, nominalType, objTypeName, null);
 }
Beispiel #9
0
        private static bool WriteIfPrimitiveOrNull(BinaryWriter writer, DObject.TypeCode type, object value, out SerializationScope scope)
        {
            if (type != DObject.TypeCode.DObject && !type.HasFlag(DObject.TypeCode.Array))
            {
                scope = null;
                switch (type)
                {
                case DObject.TypeCode.Boolean:
                    writer.Write((bool)value);
                    return(true);

                case DObject.TypeCode.Char:
                    writer.Write((char)value);
                    return(true);

                case DObject.TypeCode.SByte:
                    writer.Write((sbyte)value);
                    return(true);

                case DObject.TypeCode.Byte:
                    writer.Write((byte)value);
                    return(true);

                case DObject.TypeCode.Int16:
                    writer.Write((short)value);
                    return(true);

                case DObject.TypeCode.UInt16:
                    writer.Write((ushort)value);
                    return(true);

                case DObject.TypeCode.Int32:
                    writer.Write((int)value);
                    return(true);

                case DObject.TypeCode.UInt32:
                    writer.Write((uint)value);
                    return(true);

                case DObject.TypeCode.Int64:
                    writer.Write((long)value);
                    return(true);

                case DObject.TypeCode.UInt64:
                    writer.Write((ulong)value);
                    return(true);

                case DObject.TypeCode.Single:
                    writer.Write((float)value);
                    return(true);

                case DObject.TypeCode.Double:
                    writer.Write((double)value);
                    return(true);

                case DObject.TypeCode.Decimal:
                    writer.Write((decimal)value);
                    return(true);

                case DObject.TypeCode.DateTime:
                    writer.Write(((DateTime)value).ToBinary());
                    return(true);

                case DObject.TypeCode.TimeSpan:
                    writer.Write(((TimeSpan)value).Ticks);
                    return(true);

                case DObject.TypeCode.String:
                    if (value == null)
                    {
                        writer.Write((byte)0);
                    }
                    else
                    {
                        writer.Write((byte)1);
                        writer.Write((string)value);
                    }
                    return(true);

                case DObject.TypeCode.Guid:
                    writer.Write(((Guid)value).ToByteArray());
                    return(true);

                default:
                    throw new ArgumentOutOfRangeException("type", type, null);
                }
            }
            if (value == null)
            {
                writer.Write(-1);
                scope = null;
                return(true);
            }
            if (type == DObject.TypeCode.DObject)
            {
                DObject dObject = (DObject)value;
                if (dObject.Count < 1)
                {
                    writer.Write(0);
                    scope = null;
                    return(true);
                }
                writer.Write(dObject.Count);
                scope = new SerializationScope(dObject);
                return(false);
            }
            Array array = (Array)value;

            if (array.Length < 1)
            {
                writer.Write(0);
                scope = null;
                return(true);
            }
            writer.Write(array.Length);
            scope = new SerializationScope(array, type);
            return(false);
        }
        //--------------------------------------------------------------------------------------------------

        public SerializationContext(SerializationScope scope = SerializationScope.Storage)
        {
            Scope  = scope;
            Result = SerializationResult.None;
        }