internal byte[] GetVirtualBlobBytes(BlobHandle handle, bool unique) { BlobHandle.VirtualIndex index = handle.GetVirtualIndex(); byte[] result = s_virtualValues[(int)index]; switch (index) { case BlobHandle.VirtualIndex.AttributeUsage_AllowMultiple: case BlobHandle.VirtualIndex.AttributeUsage_AllowSingle: result = (byte[])result.Clone(); handle.SubstituteTemplateParameters(result); break; default: if (unique) { result = (byte[])result.Clone(); } break; } return result; }
internal BlobReader GetBlobReader(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 BlobReader(new MemoryBlock((byte*)virtualBlob.Pinned.AddrOfPinnedObject(), length)); } int offset, size; Block.PeekHeapValueOffsetAndSize(handle.Index, out offset, out size); return new BlobReader(this.Block.GetMemoryBlockAt(offset, size)); }