예제 #1
0
        /// <summary>Writes a class instance to the stream.</summary>
        /// <param name="v">The class instance to write. This instance cannot be null.</param>
        /// <param name="formalTypeId">The type ID of the formal type of the parameter or data member being written.
        /// Use null when the type of the parameter/data member is AnyClass.</param>
        public void WriteClass(AnyClass v, string?formalTypeId)
        {
            Debug.Assert(InEncapsulation);

            if (_current.InstanceType != InstanceType.None && _format == FormatType.Sliced)
            {
                // If writing an instance within a slice and using the sliced format, write an index of that slice's
                // indirection table.
                if (_current.IndirectionMap != null && _current.IndirectionMap.TryGetValue(v, out int index))
                {
                    // Found, index is position in indirection table + 1
                    Debug.Assert(index > 0);
                }
                else
                {
                    _current.IndirectionTable ??= new List <AnyClass>();
                    _current.IndirectionMap ??= new Dictionary <AnyClass, int>();
                    _current.IndirectionTable.Add(v);
                    index = _current.IndirectionTable.Count; // Position + 1 (0 is reserved for null)
                    _current.IndirectionMap.Add(v, index);
                }
                WriteSize(index);
            }
            else
            {
                WriteInstance(v, formalTypeId); // Writes the instance or a reference if already marshaled.
            }
        }
예제 #2
0
        internal void FirstSliceInit(AnyClass v, bool setSlicedData)
        {
            Debug.Assert(_current != null);

            // Add the instance to the map/list of instances. This must be done before reading the instances (for
            // circular references).
            _instanceMap ??= new List <AnyClass>();
            _instanceMap.Add(v);

            // Read all the deferred indirection tables now that the instance is inserted in _instanceMap.
            if (_current.DeferredIndirectionTableList?.Count > 0)
            {
                int savedPos = _pos;

                Debug.Assert(_current.Slices?.Count == _current.DeferredIndirectionTableList.Count);
                for (int i = 0; i < _current.DeferredIndirectionTableList.Count; ++i)
                {
                    int pos = _current.DeferredIndirectionTableList[i];
                    if (pos > 0)
                    {
                        _pos = pos;
                        _current.Slices[i].Instances = Array.AsReadOnly(ReadIndirectionTable());
                    }
                    // else remains empty
                }
                _pos = savedPos;
            }

            if (setSlicedData)
            {
                v.SlicedData = GetSlicedData();
            }
        }
예제 #3
0
        public void IceStartFirstSlice(string typeId, AnyClass v, bool setSlicedData = false)
        {
            Debug.Assert(InEncapsulation);
            Debug.Assert(_current != null && (_current.SliceTypeId == null || _current.SliceTypeId == typeId));
            Debug.Assert(_current.InstanceType == InstanceType.Class);

            FirstSliceInit(v, setSlicedData);
            ReadIndirectionTableIntoCurrent();
        }
예제 #4
0
        /// <summary>Reads an indirection table from the stream, without updating _current.</summary>
        /// <returns>The indirection table.</returns>
        private AnyClass[] ReadIndirectionTable()
        {
            int size = ReadAndCheckSeqSize(1);

            if (size == 0)
            {
                throw new InvalidDataException("invalid empty indirection table");
            }
            var indirectionTable = new AnyClass[size];

            for (int i = 0; i < indirectionTable.Length; ++i)
            {
                int index = ReadSize();
                if (index < 1)
                {
                    throw new InvalidDataException($"read invalid index {index} in indirection table");
                }
                indirectionTable[i] = ReadInstance(index, formalTypeId: null);
            }
            return(indirectionTable);
        }