/// <summary> /// Returns the offset of metadata heap data that corresponds /// to the specified <paramref name="handle"/>. /// </summary> /// <returns> /// Zero based offset, or -1 if <paramref name="handle"/> can only be interpreted in a context of a specific <see cref="MetadataReader"/> or <see cref="MetadataBuilder"/>. /// See <see cref="GetHeapOffset(MetadataReader, Handle)"/>. /// </returns> public static int GetHeapOffset(BlobHandle handle) => handle.IsVirtual ? -1 : handle.GetHeapOffset();
internal int SerializeHandle(BlobHandle handle) => handle.GetHeapOffset();
/// <summary> /// Returns the offset of metadata heap data that corresponds /// to the specified <paramref name="handle"/>. /// </summary> /// <returns> /// Zero based offset, or -1 if <paramref name="handle"/> can only be interpreted in a context of a specific <see cref="MetadataReader"/> or <see cref="MetadataBuilder"/>. /// See <see cref="GetHeapOffset(MetadataReader, Handle)"/>. /// </returns> internal static int GetHeapOffset(BlobHandle handle) => handle.IsVirtual ? -1 : handle.GetHeapOffset();
internal byte[] GetBytes(BlobHandle handle) { if (handle.IsVirtual) { // consider: if we returned an ImmutableArray we wouldn't need to copy return GetVirtualBlobBytes(handle, unique: true); } int offset = handle.GetHeapOffset(); int bytesRead; int numberOfBytes = Block.PeekCompressedInteger(offset, out bytesRead); if (numberOfBytes == BlobReader.InvalidCompressedInteger) { return EmptyArray<byte>.Instance; } return Block.PeekBytes(offset + bytesRead, numberOfBytes); }
internal BlobHandle GetNextHandle(BlobHandle handle) { if (handle.IsVirtual) { return default(BlobHandle); } int offset, size; if (!Block.PeekHeapValueOffsetAndSize(handle.GetHeapOffset(), out offset, out size)) { return default(BlobHandle); } int nextIndex = offset + size; if (nextIndex >= Block.Length) { return default(BlobHandle); } return BlobHandle.FromOffset(nextIndex); }
internal MemoryBlock GetMemoryBlock(BlobHandle handle) { if (handle.IsVirtual) { return GetVirtualHandleMemoryBlock(handle); } int offset, size; Block.PeekHeapValueOffsetAndSize(handle.GetHeapOffset(), out offset, out size); return Block.GetMemoryBlockAt(offset, size); }
internal MemoryBlock GetMemoryBlock(BlobHandle handle) { if (handle.IsVirtual) { if (_lazyVirtualHeapBlobs == null) { Interlocked.CompareExchange(ref _lazyVirtualHeapBlobs, new VirtualHeapBlobTable(), null); } int index = (int)handle.GetVirtualIndex(); int length = s_virtualHeapBlobs[index].Length; VirtualHeapBlob virtualBlob; lock (_lazyVirtualHeapBlobs) { if (!_lazyVirtualHeapBlobs.Table.TryGetValue(handle, out virtualBlob)) { virtualBlob = new VirtualHeapBlob(GetVirtualBlobArray(handle, unique: false)); _lazyVirtualHeapBlobs.Table.Add(handle, virtualBlob); } } return new MemoryBlock((byte*)virtualBlob.Pinned.AddrOfPinnedObject(), length); } int offset, size; Block.PeekHeapValueOffsetAndSize(handle.GetHeapOffset(), out offset, out size); return this.Block.GetMemoryBlockAt(offset, size); }