예제 #1
0
        public object DeserializeRootOrInner(SlimReader reader, TypeRegistry registry, RefPool refs, StreamingContext streamingContext, bool root, Type valueType = null)
        {
            Type type = valueType;

            if (type == null)
            {
                var thandle = reader.ReadVarIntStr();
                if (thandle.StringValue != null)               //need to search for possible array descriptor
                {
                    var ip = thandle.StringValue.IndexOf('|'); //array descriptor start
                    if (ip > 0)
                    {
                        var tname = thandle.StringValue.Substring(0, ip);
                        if (TypeRegistry.IsNullHandle(tname))
                        {
                            return(null);
                        }
                        type = registry[tname];
                    }
                    else
                    {
                        if (TypeRegistry.IsNullHandle(thandle))
                        {
                            return(null);
                        }
                        type = registry[thandle];
                    }
                }
                else
                {
                    if (TypeRegistry.IsNullHandle(thandle))
                    {
                        return(null);
                    }
                    type = registry[thandle];
                }
            }

            //we get here if we have a boxed value of directly-handled type
            var ra = Format.GetReadActionForType(type) ?? Format.GetReadActionForRefType(type);//20150503 DKh fixed root byte[] slow

            if (ra != null)
            {
                return(ra(reader));
            }


            TypeDescriptor td = getTypeDescriptorCachedOrMake(type);

            object instance = null;

            if (td.IsArray)
            {
                instance = Arrays.DescriptorToArray(reader.ReadString(), type);
            }
            else
            {
                instance = SerializationUtils.MakeNewObjectInstance(type);
            }

            if (root)
            {
                if (!type.IsValueType)//if this is a reference type
                {
                    refs.Add(instance);
                }
            }

            td.DeserializeInstance(reader, registry, refs, ref instance, streamingContext);


            return(instance);
        }
예제 #2
0
 public object Deserialize(SlimReader reader, TypeRegistry registry, RefPool refs, StreamingContext streamingContext, Type valueType = null)
 {
     return(DeserializeRootOrInner(reader, registry, refs, streamingContext, false, valueType));
 }
예제 #3
0
        /// <summary>
        /// Returns object reference for supplied metahandle
        /// </summary>
        public object HandleToReference(MetaHandle handle, TypeRegistry treg, SlimFormat format, SlimReader reader)
        {
            Debug.Assert(m_Mode == SerializationOperation.Deserializing, "HandleToReference() called while serializing", DebugAction.Throw);

            if (handle.IsInlinedString)
            {
                return(handle.Metadata.Value.StringValue);
            }
            if (handle.IsInlinedTypeValue)
            {
                var tref = treg[handle.Metadata.Value];//adding this type to registry if it is not there yet
                return(tref);
            }

            if (handle.IsInlinedRefType)
            {
                var tref = treg[handle.Metadata.Value];//adding this type to registry if it is not there yet
                var ra   = format.GetReadActionForRefType(tref);
                if (ra != null)
                {
                    var inst = ra(reader);
                    m_List.Add(inst);
                    return(inst);
                }
                else
                {
                    throw new SlimDeserializationException("Internal error HandleToReference: no read action for ref type, but ref mhandle is inlined");
                }
            }


            int idx = (int)handle.Handle;

            if (idx < m_List.Count)
            {
                return(m_List[idx]);
            }

            if (!handle.Metadata.HasValue)
            {
                throw new SlimDeserializationException(StringConsts.SLIM_HNDLTOREF_MISSING_TYPE_NAME_ERROR + handle.ToString());
            }

            Type type;
            var  metadata = handle.Metadata.Value;

            if (metadata.StringValue != null)               //need to search for possible array descriptor
            {
                var ip = metadata.StringValue.IndexOf('|'); //array descriptor start
                if (ip > 0)
                {
                    var tname = metadata.StringValue.Substring(0, ip);
                    if (TypeRegistry.IsNullHandle(tname))
                    {
                        return(null);
                    }
                    type = treg[tname];
                }
                else
                {
                    if (TypeRegistry.IsNullHandle(metadata))
                    {
                        return(null);
                    }
                    type = treg[metadata];
                }
            }
            else
            {
                if (TypeRegistry.IsNullHandle(metadata))
                {
                    return(null);
                }
                type = treg[metadata];
            }

            object instance = null;

            if (type.IsArray)
            {
                //DKh 20130712 Removed repetitive code that was refactored into Arrays class
                instance = Arrays.DescriptorToArray(metadata.StringValue, type);
            }
            else
            {
                //20130715 DKh
                instance = SerializationUtils.MakeNewObjectInstance(type);
            }

            m_List.Add(instance);
            return(instance);
        }
예제 #4
0
        private object deserialize(SlimReader reader, RefPool pool)
        {
            object root = null;

            var scontext = new StreamingContext();
            var registry = (m_TypeMode == TypeRegistryMode.PerCall) ? new TypeRegistry(m_GlobalTypes) : m_BatchTypeRegistry;

            {
                var rcount = registry.Count;
                m_BatchTypeRegistryPriorCount = rcount;

                readHeader(reader);
                if (!m_SkipTypeRegistryCrosschecks)
                {
                    if (reader.ReadUInt() != rcount)
                    {
                        throw new SlimDeserializationException(StringConsts.SLIM_TREG_COUNT_ERROR);
                    }
                    if (reader.ReadULong() != registry.CSum)
                    {
                        throw new SlimDeserializationException(StringConsts.SLIM_TREG_CSUM_ERROR);
                    }
                }

                //Read root
                //Deser will add root to pool[1] if its ref-typed
                //------------------------------------------------
                root = m_Format.TypeSchema.DeserializeRootOrInner(reader, registry, pool, scontext, root: true);
                if (root == null)
                {
                    return(null);
                }
                if (root is rootTypeBox)
                {
                    return(((rootTypeBox)root).TypeValue);
                }


                var type      = root.GetType();
                var isValType = type.IsValueType;

                var i = 1;

                if (!isValType)
                {
                    i++;
                }

                //Read all the rest of objects. The upper bound of this loop may increase as objects are read and their references added to pool
                //0 = NULL
                //1 = root IF root is ref type
                //-----------------------------------------------
                var ts = m_Format.TypeSchema;
                for (; i < pool.Count; i++)
                {
                    var instance = pool[i];
                    var tinst    = instance.GetType();
                    if (!m_Format.IsRefTypeSupported(tinst))
                    {
                        ts.DeserializeRefTypeInstance(instance, reader, registry, pool, scontext);
                    }
                }
            }

            //perform fixups for ISerializable
            //---------------------------------------------
            var fxps = pool.Fixups;

            for (var i = 0; i < fxps.Count; i++)
            {
                var fixup = fxps[i];
                var t     = fixup.Instance.GetType();
                var ctor  = SerializationUtils.GetISerializableCtorInfo(t);
                if (ctor == null)
                {
                    throw new SlimDeserializationException(StringConsts.SLIM_ISERIALIZABLE_MISSING_CTOR_ERROR + t.FullName);
                }
                ctor.Invoke(fixup.Instance, new object[] { fixup.Info, scontext });
            }


            //20150214 DD - fixing deserialization problem of Dictionary(InvariantStringComparer)
            //before 20150214 this was AFTER OnDeserialization
            //invoke OnDeserialized-decorated methods
            //--------------------------------------------
            var odc = pool.OnDeserializedCallbacks;

            for (int i = 0; i < odc.Count; i++)
            {
                var cb = odc[i];
                cb.Descriptor.InvokeOnDeserializedCallbak(cb.Instance, scontext);
            }

            //before 20150214 this was BEFORE OnDeserializedCallbacks
            //invoke IDeserializationCallback
            //---------------------------------------------
            for (int i = 1; i < pool.Count; i++)//[0]=null
            {
                var dc = pool[i] as IDeserializationCallback;
                if (dc != null)
                {
                    try
                    {
                        dc.OnDeserialization(this);
                    }
                    catch (Exception error)
                    {
                        throw new SlimDeserializationException(StringConsts.SLIM_DESERIALIZE_CALLBACK_ERROR + error.ToMessageWithType(), error);
                    }
                }
            }



            return(root);
        }
예제 #5
0
파일: SlimSerializer.cs 프로젝트: ame89/nfx
        /// <summary>
        /// Returns object reference for supplied metahandle
        /// </summary>
        public object HandleToReference(MetaHandle handle, TypeRegistry treg, SlimFormat format, SlimReader reader)
        {
            if (handle.IsInlinedString)
            {
                return(handle.Metadata);
            }
            if (handle.IsInlinedTypeValue)
            {
                var tref = treg.GetByHandle(handle.Metadata);//adding this type to registry if it is not there yet
                return(tref);
            }

            if (handle.IsInlinedRefType)
            {
                var tref = treg.GetByHandle(handle.Metadata);//adding this type to registry if it is not there yet
                var ra   = format.GetReadActionForRefType(tref);
                if (ra != null)
                {
                    var inst = ra(reader);
                    m_List.Add(inst);
                    m_Dict.Add(inst, m_List.Count - 1);
                    return(inst);
                }
                else
                {
                    throw new SlimDeserializationException("Internal error HandleToReference: no read action for ref type, but ref mhandle is inlined");
                }
            }


            int idx = (int)handle.Handle;

            if (idx < m_List.Count)
            {
                return(m_List[idx]);
            }

            if (string.IsNullOrEmpty(handle.Metadata))
            {
                throw new SlimDeserializationException(StringConsts.SLIM_HNDLTOREF_MISSING_TYPE_NAME_ERROR + handle.ToString());
            }

            var metadata = handle.Metadata;
            var ip       = metadata.IndexOf('|');
            //var segments = metadata.Split('|');
            var th = ip > 0 ? metadata.Substring(0, ip) : metadata;

            //20140701 DKh
            var type = treg[th];//segments[0]];

            object instance = null;

            if (type.IsArray)
            {
                //DKh 20130712 Removed repetitive code that was refactored into Arrays class
                instance = Arrays.DescriptorToArray(metadata, treg, type);
            }
            else
            {
                //20130715 DKh
                instance = SerializationUtils.MakeNewObjectInstance(type);
            }

            m_List.Add(instance);
            m_Dict.Add(instance, m_List.Count - 1);
            return(instance);
        }