/// <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; }
private void readHeader(SlimReader reader) { if (reader.ReadByte() != 0 || reader.ReadByte() != 0 || reader.ReadByte() != (byte)((HEADER >> 8) & 0xff) || reader.ReadByte() != (byte)(HEADER & 0xff) ) throw new SlimDeserializationException(StringConsts.SLIM_BAD_HEADER_ERROR); }
public object Deserialize(Stream stream) { try { var singleThreaded = m_TypeMode == TypeRegistryMode.Batch; SlimReader reader; if (!singleThreaded || m_DeserializeNestLevel>0) reader = m_Format.MakeReadingStreamer(); else { reader = m_CachedReader; if (reader==null) { reader = m_Format.MakeReadingStreamer(); m_CachedReader = reader; } } var pool = reservePool( SerializationOperation.Deserializing ); try { m_DeserializeNestLevel++; reader.BindStream( stream ); return deserialize(reader, pool); } finally { reader.UndindStream(); m_DeserializeNestLevel--; releasePool(pool); } } catch(Exception error) { throw new SlimDeserializationException(StringConsts.SLIM_DESERIALIZATION_EXCEPTION_ERROR + error.ToMessageWithType(), error); } }
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 = t.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext)}, null); 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; }
/// <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; }