ComplexData?GetStructure(BlobDataInfo info, HexPosition position) { var pos = info.Span.Start; var lengthStart = pos; var len = ReadCompressedUInt32(ref pos) ?? -1; if (len < 0) { return(null); } if (pos + len > Span.Span.End) { return(null); } var lengthSpan = HexSpan.FromBounds(lengthStart, pos); var dataSpan = new HexSpan(lengthSpan.End, (ulong)len); var fullSpan = HexSpan.FromBounds(lengthSpan.Start, dataSpan.End); if (!fullSpan.Contains(position)) { return(null); } switch (info.Kind) { case BlobDataKind.None: case BlobDataKind.TypeSignature: case BlobDataKind.Signature: case BlobDataKind.Constant: case BlobDataKind.CustomAttribute: case BlobDataKind.NativeType: case BlobDataKind.PermissionSet: case BlobDataKind.PublicKey: case BlobDataKind.PublicKeyOrToken: case BlobDataKind.HashValue: case BlobDataKind.Utf8Name: case BlobDataKind.Name: case BlobDataKind.SequencePoints: case BlobDataKind.LocalConstantSig: case BlobDataKind.Imports: case BlobDataKind.CustomDebugInformationValue: var varray = ArrayData.CreateVirtualByteArray(new HexBufferSpan(Span.Buffer, dataSpan)); return(new BlobHeapRecordData(Span.Buffer, fullSpan, lengthSpan, varray, info.Tokens, this)); default: throw new InvalidOperationException(); } }
BlobDataInfo[] CreateBlobDataInfos(TablesHeap?tables) { if (tables is null || Span.IsEmpty) { return(Array.Empty <BlobDataInfo>()); } var dict = new Dictionary <uint, BlobDataInfoPosition>(); foreach (var info in tableInitInfos) { if (info.Column2 >= 0) { Add(dict, tables.MDTables[(int)info.Table], info.Column1, info.Kind1, info.Column2, info.Kind2); } else { Add(dict, tables.MDTables[(int)info.Table], info.Column1, info.Kind1); } } AddNameIndexes(dict, tables, Table.Document, 0); AddImportScopeIndexes(dict, tables, Table.ImportScope, 1); dict[0] = new BlobDataInfoPosition(Span.Span.Start, BlobDataKind.None); var infos = dict.Values.ToArray(); var res = new BlobDataInfo[infos.Length]; Array.Sort(infos, (a, b) => a.Position.CompareTo(b.Position)); for (int i = 0; i < infos.Length; i++) { var info = infos[i]; var end = i + 1 < infos.Length ? infos[i + 1].Position : Span.Span.End; res[i] = new BlobDataInfo(HexSpan.FromBounds(info.Position, end), info.Tokens.ToArray(), info.Kind); } return(res); }