예제 #1
0
        public T Read <T>(SerializationCtx ctx, UnsafeReader reader, [CanBeNull] CtxReadDelegate <T> unknownInstanceReader = null)
        {
            bool TryGetReader(RdId rdId, out CtxReadDelegate <object> readDelegate)
            {
                lock (myLock)
                    return(myReaders.TryGetValue(rdId, out readDelegate));
            }

#if !NET35
            myBackgroundRegistrar.WaitForEmpty();
#endif

            var typeId = RdId.Read(reader);
            if (typeId.IsNil)
            {
                return(default(T));
            }
            var size = reader.ReadInt();

            if (!TryGetReader(typeId, out var ctxReadDelegate))
            {
                if (unknownInstanceReader == null)
                {
                    myRegistrar?.TryRegister(typeId, this);
                    myRegistrar?.TryRegister(typeof(T), this);
                    if (!TryGetReader(typeId, out ctxReadDelegate))
                    {
                        var realType = myTypeMapping.SingleOrDefault(c => Equals(c.Value, typeId)); //ok because it's rarely needed
                        throw new KeyNotFoundException(string.Format("There is no readers found. Requested type '{0}'. Real type {1}", typeof(T).FullName, realType));
                    }
                }
                else
                {
                    var objectStart = reader.Position;
                    var result      = unknownInstanceReader(ctx, reader);
                    var bytesRead   = reader.Position - objectStart;
                    reader.Skip(size - bytesRead);
                    return(result);
                }
            }

            var uncasted = ctxReadDelegate(ctx, reader);
            Assertion.Assert(uncasted is T, "Bad cast for id {0}. Expected: {1}, actual: {2}", typeId, typeof(T).Name, uncasted.GetType().Name);
            return((T)uncasted);
        }