示例#1
0
        private AnyClass ReadInstance(int index)
        {
            Debug.Assert(index > 0);

            if (index > 1)
            {
                if (_instanceMap != null && _instanceMap.Count > index - 2)
                {
                    return(_instanceMap[index - 2]);
                }
                throw new InvalidDataException($"could not find index {index} in {nameof(_instanceMap)}");
            }

            if (++_classGraphDepth > Communicator.ClassGraphDepthMax)
            {
                throw new InvalidDataException("maximum class graph depth reached");
            }

            InstanceData?previousCurrent = Push(InstanceType.Class);

            Debug.Assert(_current != null);

            AnyClass?instance = null;

            do
            {
                // Read the slice header.
                string?typeIdOpt = ReadSliceHeaderIntoCurrent();

                // We cannot read the indirection table at this point as it may reference the new instance that is
                // not created yet.

                IClassFactory?factory = null;
                if (typeIdOpt is string typeId)
                {
                    Debug.Assert(_current.SliceCompactId == null);
                    factory = Communicator.FindClassFactory(typeId);
                }
                else if (_current.SliceCompactId is int compactId)
                {
                    factory = Communicator.FindClassFactory(compactId);
                }

                if (factory != null)
                {
                    instance = factory.Read(this);
                }
                else if (SkipSlice()) // Slice off what we don't understand.
                {
                    instance = new UnknownSlicedClass(this);
                }
            }while (instance == null);

            Pop(previousCurrent);
            --_classGraphDepth;
            return(instance);
        }