/// <summary> /// Writes a <c>Module</c> table /// </summary> /// <param name="writer">Writer</param> /// <param name="metadata">Metadata</param> /// <param name="table">Table</param> public static void Write(this DataWriter writer, Metadata metadata, MDTable <RawModuleRow> table) { var columns = table.TableInfo.Columns; var columns1 = columns[1]; var columns2 = columns[2]; var columns3 = columns[3]; var columns4 = columns[4]; var stringsHeap = metadata.StringsHeap; for (int i = 0; i < table.Rows; i++) { var row = table[(uint)i + 1]; writer.WriteUInt16(row.Generation); columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); columns2.Write24(writer, row.Mvid); columns3.Write24(writer, row.EncId); columns4.Write24(writer, row.EncBaseId); } }
void Write(CustomAttribute ca) { if (ca is null) { helper.Error("The custom attribute is null"); return; } // Check whether it's raw first. If it is, we don't care whether the ctor is // invalid. Just use the raw data. if (ca.IsRawBlob) { if ((ca.ConstructorArguments is not null && ca.ConstructorArguments.Count > 0) || (ca.NamedArguments is not null && ca.NamedArguments.Count > 0)) { helper.Error("Raw custom attribute contains arguments and/or named arguments"); } writer.WriteBytes(ca.RawData); return; } if (ca.Constructor is null) { helper.Error("Custom attribute ctor is null"); return; } var methodSig = GetMethodSig(ca.Constructor); if (methodSig is null) { helper.Error("Custom attribute ctor's method signature is invalid"); return; } if (ca.ConstructorArguments.Count != methodSig.Params.Count) { helper.Error("Custom attribute arguments count != method sig arguments count"); } if (methodSig.ParamsAfterSentinel is not null && methodSig.ParamsAfterSentinel.Count > 0) { helper.Error("Custom attribute ctor has parameters after the sentinel"); } if (ca.NamedArguments.Count > ushort.MaxValue) { helper.Error("Custom attribute has too many named arguments"); } if (ca.Constructor is MemberRef mrCtor && mrCtor.Class is TypeSpec owner && owner.TypeSig is GenericInstSig gis) { genericArguments = new GenericArguments(); genericArguments.PushTypeArgs(gis.GenericArguments); } writer.WriteUInt16((ushort)1); int numArgs = Math.Min(methodSig.Params.Count, ca.ConstructorArguments.Count); for (int i = 0; i < numArgs; i++) { WriteValue(FixTypeSig(methodSig.Params[i]), ca.ConstructorArguments[i]); } int numNamedArgs = Math.Min((int)ushort.MaxValue, ca.NamedArguments.Count); writer.WriteUInt16((ushort)numNamedArgs); for (int i = 0; i < numNamedArgs; i++) { Write(ca.NamedArguments[i]); } }