Esempio n. 1
0
        private static void LoadCodedTokenDataSizes(TableCompressionInfo info, MetadataScope metadata, int[] rowCounts)
        {
            for (int i = 0; i < MetadataConstants.CodedTokenCount; i++)
            {
                int maxRowCount    = 0;
                int codedTokenType = i + CodedTokenType.TypeDefOrRef;
                var token          = CodedTokenInfo.Get(codedTokenType);

                for (int j = 0; j < token.TokenTypes.Length; j++)
                {
                    int tableType = MetadataToken.GetTableTypeByTokenType(token.TokenTypes[j]);

                    int rowCount = rowCounts[tableType];
                    if (maxRowCount < rowCount)
                    {
                        maxRowCount = rowCount;
                    }
                }

                info.CodedTokenDataSize4[i] = (maxRowCount >= (1 << (16 - token.Tag)));
            }
        }
		private void ReadTables()
		{
			_tables = new TableInfo[MetadataConstants.TableCount];
			_tableRowIndexSize4 = new bool[MetadataConstants.TableCount];

			// Reserved, 4 bytes
			_accessor.ReadInt32();

			_tableSchemaMajorVersion = _accessor.ReadByte();
			_tableSchemaMinorVersion = _accessor.ReadByte();

			byte heapFlags = _accessor.ReadByte();

			// Reserved, 1 bytes
			_accessor.ReadByte();

			ulong maskValid = _accessor.ReadUInt64();
			_sortTableMask = _accessor.ReadUInt64();

			// Row counts
			int[] rowCounts = new int[MetadataConstants.TableCount];
			for (int tableIndex = 0; tableIndex < MetadataConstants.TableCount; tableIndex++)
			{
				if ((maskValid & (1UL << tableIndex)) != 0)
				{
					int rowCount = _accessor.ReadInt32();
					rowCounts[tableIndex] = rowCount;
					_tableRowIndexSize4[tableIndex] = (rowCount >= (1 << 16));
				}
			}

			// Heap offset sizes.
			_stringHeapOffsetSize4 = ((heapFlags & HeapOffsetFlags.StringHeap4) == HeapOffsetFlags.StringHeap4);
			_guidHeapOffsetSize4 = ((heapFlags & HeapOffsetFlags.GuidHeap4) == HeapOffsetFlags.GuidHeap4);
			_blobHeapOffsetSize4 = ((heapFlags & HeapOffsetFlags.BlobHeap4) == HeapOffsetFlags.BlobHeap4);

			// Coded token size.
			_codedTokenDataSize4 = new bool[MetadataConstants.CodedTokenCount];
			for (int i = 0; i < MetadataConstants.CodedTokenCount; i++)
			{
				int maxRowCount = 0;
				int codedTokenType = i + CodedTokenType.TypeDefOrRef;
				var token = CodedTokenInfo.Get(codedTokenType);

				for (int j = 0; j < token.TokenTypes.Length; j++)
				{
					int tableType = MetadataToken.GetTableTypeByTokenType(token.TokenTypes[j]);

					int rowCount = rowCounts[tableType];
					if (maxRowCount < rowCount)
						maxRowCount = rowCount;
				}

				_codedTokenDataSize4[i] = (maxRowCount >= (1 << (16 - token.Tag)));
			}

			int stringHeapOffsetSize = (_stringHeapOffsetSize4 ? 4 : 2);
			int guidHeapOffsetSize = (_guidHeapOffsetSize4 ? 4 : 2);
			int blobHeapOffsetSize = (_blobHeapOffsetSize4 ? 4 : 2);

			// Create tables
			var tableSchemas = MetadataSchema.Tables;
			int offset = (int)(_accessor.Position - _offset);
			for (int tableIndex = 0; tableIndex < MetadataConstants.TableCount; tableIndex++)
			{
				var tableSchema = tableSchemas[tableIndex];
				var columnSchemas = tableSchema.Columns;

				int rowCount = rowCounts[tableIndex];

				var columns = new ColumnInfo[columnSchemas.Length];
				int columnOffset = 0;
				for (int columnIndex = 0; columnIndex < columnSchemas.Length; columnIndex++)
				{
					int columnSize;
					int columnPadding = 0;
					var columnSchema = columnSchemas[columnIndex];
					if (columnSchema.IsTableIndex)
					{
						columnSize = (_tableRowIndexSize4[columnSchema.Type] ? 4 : 2);
					}
					else if (columnSchema.IsCodedToken)
					{
						columnSize = (_codedTokenDataSize4[columnSchema.Type - 64] ? 4 : 2);
					}
					else
					{
						switch (columnSchema.Type)
						{
							case MetadataColumnType.Int16:
							case MetadataColumnType.UInt16:
								columnSize = 2;
								break;

							case MetadataColumnType.Int32:
							case MetadataColumnType.UInt32:
								columnSize = 4;
								break;

							case MetadataColumnType.Byte2:
								columnSize = 1;
								columnPadding = 1;
								break;

							case MetadataColumnType.String:
								columnSize = stringHeapOffsetSize;
								break;

							case MetadataColumnType.Guid:
								columnSize = guidHeapOffsetSize;
								break;

							case MetadataColumnType.Blob:
								columnSize = blobHeapOffsetSize;
								break;

							default:
								throw new InvalidOperationException();
						}
					}

					columns[columnIndex] = new ColumnInfo()
					{
						Offset = (short)columnOffset,
						Size = (short)columnSize,
					};

					columnOffset += (columnSize + columnPadding);
				}

				int rowSize = columnOffset;

				_tables[tableIndex] = new TableInfo()
				{
					Offset = offset,
					RowCount = rowCount,
					RowSize = (short)rowSize,
					Columns = columns,
				};

				offset += (rowSize * rowCount);
			}
		}