5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2011 Jb Evain
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections.Generic;
34 using Mono.Collections.Generic;
36 using Mono.Cecil.Metadata;
39 using RVA = System.UInt32;
40 using RID = System.UInt32;
41 using CodedRID = System.UInt32;
42 using StringIndex = System.UInt32;
43 using BlobIndex = System.UInt32;
45 namespace Mono.Cecil {
49 using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>;
50 using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>;
51 using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>;
52 using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>;
53 using ParamRow = Row<ParameterAttributes, ushort, StringIndex>;
54 using InterfaceImplRow = Row<uint, CodedRID>;
55 using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>;
56 using ConstantRow = Row<ElementType, CodedRID, BlobIndex>;
57 using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>;
58 using FieldMarshalRow = Row<CodedRID, BlobIndex>;
59 using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>;
60 using ClassLayoutRow = Row<ushort, uint, RID>;
61 using FieldLayoutRow = Row<uint, RID>;
62 using EventMapRow = Row<RID, RID>;
63 using EventRow = Row<EventAttributes, StringIndex, CodedRID>;
64 using PropertyMapRow = Row<RID, RID>;
65 using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>;
66 using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>;
67 using MethodImplRow = Row<RID, CodedRID, CodedRID>;
68 using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>;
69 using FieldRVARow = Row<RVA, RID>;
70 using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>;
71 using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>;
72 using FileRow = Row<FileAttributes, StringIndex, BlobIndex>;
73 using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>;
74 using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>;
75 using NestedClassRow = Row<RID, RID>;
76 using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>;
77 using MethodSpecRow = Row<CodedRID, BlobIndex>;
78 using GenericParamConstraintRow = Row<RID, CodedRID>;
80 static class ModuleWriter {
82 public static void WriteModuleTo (ModuleDefinition module, Stream stream, WriterParameters parameters)
84 if ((module.Attributes & ModuleAttributes.ILOnly) == 0)
85 throw new ArgumentException ();
87 if (module.HasImage && module.ReadingMode == ReadingMode.Deferred)
88 ImmediateModuleReader.ReadModule (module);
90 module.MetadataSystem.Clear ();
92 var name = module.assembly != null ? module.assembly.Name : null;
93 var fq_name = stream.GetFullyQualifiedName ();
94 var symbol_writer_provider = parameters.SymbolWriterProvider;
95 if (symbol_writer_provider == null && parameters.WriteSymbols)
96 symbol_writer_provider = SymbolProvider.GetPlatformWriterProvider ();
97 var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider);
99 #if !SILVERLIGHT && !CF
100 if (parameters.StrongNameKeyPair != null && name != null)
101 name.PublicKey = parameters.StrongNameKeyPair.PublicKey;
104 if (name != null && name.HasPublicKey)
105 module.Attributes |= ModuleAttributes.StrongNameSigned;
107 var metadata = new MetadataBuilder (module, fq_name,
108 symbol_writer_provider, symbol_writer);
110 BuildMetadata (module, metadata);
112 if (module.SymbolReader != null)
113 module.SymbolReader.Dispose ();
115 var writer = ImageWriter.CreateWriter (module, metadata, stream);
117 writer.WriteImage ();
119 #if !SILVERLIGHT && !CF
120 if (parameters.StrongNameKeyPair != null)
121 CryptoService.StrongName (stream, writer, parameters.StrongNameKeyPair);
123 if (symbol_writer != null)
124 symbol_writer.Dispose ();
127 static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata)
129 if (!module.HasImage) {
130 metadata.BuildMetadata ();
134 module.Read (metadata, (builder, _) => {
135 builder.BuildMetadata ();
140 static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider)
142 if (symbol_writer_provider == null)
145 return symbol_writer_provider.GetSymbolWriter (module, fq_name);
149 abstract class MetadataTable {
151 public abstract int Length { get; }
153 public bool IsLarge {
154 get { return Length > 65535; }
157 public abstract void Write (TableHeapBuffer buffer);
158 public abstract void Sort ();
161 abstract class OneRowTable<TRow> : MetadataTable where TRow : struct {
165 public sealed override int Length {
169 public sealed override void Sort ()
174 abstract class MetadataTable<TRow> : MetadataTable where TRow : struct {
176 internal TRow [] rows = new TRow [2];
179 public sealed override int Length {
180 get { return length; }
183 public int AddRow (TRow row)
185 if (rows.Length == length)
188 rows [length++] = row;
194 var rows = new TRow [this.rows.Length * 2];
195 Array.Copy (this.rows, rows, this.rows.Length);
199 public override void Sort ()
204 abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct {
206 public sealed override void Sort ()
208 Array.Sort (rows, 0, length, this);
211 protected int Compare (uint x, uint y)
213 return x == y ? 0 : x > y ? 1 : -1;
216 public abstract int Compare (TRow x, TRow y);
219 sealed class ModuleTable : OneRowTable<uint> {
221 public override void Write (TableHeapBuffer buffer)
223 buffer.WriteUInt16 (0); // Generation
224 buffer.WriteString (row); // Name
225 buffer.WriteUInt16 (1); // Mvid
226 buffer.WriteUInt16 (0); // EncId
227 buffer.WriteUInt16 (0); // EncBaseId
231 sealed class TypeRefTable : MetadataTable<TypeRefRow> {
233 public override void Write (TableHeapBuffer buffer)
235 for (int i = 0; i < length; i++) {
236 buffer.WriteCodedRID (
237 rows [i].Col1, CodedIndex.ResolutionScope); // Scope
238 buffer.WriteString (rows [i].Col2); // Name
239 buffer.WriteString (rows [i].Col3); // Namespace
244 sealed class TypeDefTable : MetadataTable<TypeDefRow> {
246 public override void Write (TableHeapBuffer buffer)
248 for (int i = 0; i < length; i++) {
249 buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes
250 buffer.WriteString (rows [i].Col2); // Name
251 buffer.WriteString (rows [i].Col3); // Namespace
252 buffer.WriteCodedRID (
253 rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends
254 buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList
255 buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList
260 sealed class FieldTable : MetadataTable<FieldRow> {
262 public override void Write (TableHeapBuffer buffer)
264 for (int i = 0; i < length; i++) {
265 buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
266 buffer.WriteString (rows [i].Col2); // Name
267 buffer.WriteBlob (rows [i].Col3); // Signature
272 sealed class MethodTable : MetadataTable<MethodRow> {
274 public override void Write (TableHeapBuffer buffer)
276 for (int i = 0; i < length; i++) {
277 buffer.WriteUInt32 (rows [i].Col1); // RVA
278 buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags
279 buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags
280 buffer.WriteString (rows [i].Col4); // Name
281 buffer.WriteBlob (rows [i].Col5); // Signature
282 buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList
287 sealed class ParamTable : MetadataTable<ParamRow> {
289 public override void Write (TableHeapBuffer buffer)
291 for (int i = 0; i < length; i++) {
292 buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes
293 buffer.WriteUInt16 (rows [i].Col2); // Sequence
294 buffer.WriteString (rows [i].Col3); // Name
299 sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> {
301 public override void Write (TableHeapBuffer buffer)
303 for (int i = 0; i < length; i++) {
304 buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
305 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface
309 /*public override int Compare (InterfaceImplRow x, InterfaceImplRow y)
311 return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1);
315 sealed class MemberRefTable : MetadataTable<MemberRefRow> {
317 public override void Write (TableHeapBuffer buffer)
319 for (int i = 0; i < length; i++) {
320 buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent);
321 buffer.WriteString (rows [i].Col2);
322 buffer.WriteBlob (rows [i].Col3);
327 sealed class ConstantTable : SortedTable<ConstantRow> {
329 public override void Write (TableHeapBuffer buffer)
331 for (int i = 0; i < length; i++) {
332 buffer.WriteUInt16 ((ushort) rows [i].Col1);
333 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant);
334 buffer.WriteBlob (rows [i].Col3);
338 public override int Compare (ConstantRow x, ConstantRow y)
340 return Compare (x.Col2, y.Col2);
344 sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> {
346 public override void Write (TableHeapBuffer buffer)
348 for (int i = 0; i < length; i++) {
349 buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent
350 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type
351 buffer.WriteBlob (rows [i].Col3);
355 public override int Compare (CustomAttributeRow x, CustomAttributeRow y)
357 return Compare (x.Col1, y.Col1);
361 sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> {
363 public override void Write (TableHeapBuffer buffer)
365 for (int i = 0; i < length; i++) {
366 buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal);
367 buffer.WriteBlob (rows [i].Col2);
371 public override int Compare (FieldMarshalRow x, FieldMarshalRow y)
373 return Compare (x.Col1, y.Col1);
377 sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> {
379 public override void Write (TableHeapBuffer buffer)
381 for (int i = 0; i < length; i++) {
382 buffer.WriteUInt16 ((ushort) rows [i].Col1);
383 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity);
384 buffer.WriteBlob (rows [i].Col3);
388 public override int Compare (DeclSecurityRow x, DeclSecurityRow y)
390 return Compare (x.Col2, y.Col2);
394 sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> {
396 public override void Write (TableHeapBuffer buffer)
398 for (int i = 0; i < length; i++) {
399 buffer.WriteUInt16 (rows [i].Col1); // PackingSize
400 buffer.WriteUInt32 (rows [i].Col2); // ClassSize
401 buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent
405 public override int Compare (ClassLayoutRow x, ClassLayoutRow y)
407 return Compare (x.Col3, y.Col3);
411 sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> {
413 public override void Write (TableHeapBuffer buffer)
415 for (int i = 0; i < length; i++) {
416 buffer.WriteUInt32 (rows [i].Col1); // Offset
417 buffer.WriteRID (rows [i].Col2, Table.Field); // Parent
421 public override int Compare (FieldLayoutRow x, FieldLayoutRow y)
423 return Compare (x.Col2, y.Col2);
427 sealed class StandAloneSigTable : MetadataTable<uint> {
429 public override void Write (TableHeapBuffer buffer)
431 for (int i = 0; i < length; i++)
432 buffer.WriteBlob (rows [i]);
436 sealed class EventMapTable : MetadataTable<EventMapRow> {
438 public override void Write (TableHeapBuffer buffer)
440 for (int i = 0; i < length; i++) {
441 buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
442 buffer.WriteRID (rows [i].Col2, Table.Event); // EventList
447 sealed class EventTable : MetadataTable<EventRow> {
449 public override void Write (TableHeapBuffer buffer)
451 for (int i = 0; i < length; i++) {
452 buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
453 buffer.WriteString (rows [i].Col2); // Name
454 buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType
459 sealed class PropertyMapTable : MetadataTable<PropertyMapRow> {
461 public override void Write (TableHeapBuffer buffer)
463 for (int i = 0; i < length; i++) {
464 buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent
465 buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList
470 sealed class PropertyTable : MetadataTable<PropertyRow> {
472 public override void Write (TableHeapBuffer buffer)
474 for (int i = 0; i < length; i++) {
475 buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
476 buffer.WriteString (rows [i].Col2); // Name
477 buffer.WriteBlob (rows [i].Col3); // Type
482 sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> {
484 public override void Write (TableHeapBuffer buffer)
486 for (int i = 0; i < length; i++) {
487 buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
488 buffer.WriteRID (rows [i].Col2, Table.Method); // Method
489 buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association
493 public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y)
495 return Compare (x.Col3, y.Col3);
499 sealed class MethodImplTable : MetadataTable<MethodImplRow> {
501 public override void Write (TableHeapBuffer buffer)
503 for (int i = 0; i < length; i++) {
504 buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class
505 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody
506 buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration
511 sealed class ModuleRefTable : MetadataTable<uint> {
513 public override void Write (TableHeapBuffer buffer)
515 for (int i = 0; i < length; i++)
516 buffer.WriteString (rows [i]); // Name
520 sealed class TypeSpecTable : MetadataTable<uint> {
522 public override void Write (TableHeapBuffer buffer)
524 for (int i = 0; i < length; i++)
525 buffer.WriteBlob (rows [i]); // Signature
529 sealed class ImplMapTable : SortedTable<ImplMapRow> {
531 public override void Write (TableHeapBuffer buffer)
533 for (int i = 0; i < length; i++) {
534 buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags
535 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded
536 buffer.WriteString (rows [i].Col3); // ImportName
537 buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope
541 public override int Compare (ImplMapRow x, ImplMapRow y)
543 return Compare (x.Col2, y.Col2);
547 sealed class FieldRVATable : SortedTable<FieldRVARow> {
549 internal int position;
551 public override void Write (TableHeapBuffer buffer)
553 position = buffer.position;
554 for (int i = 0; i < length; i++) {
555 buffer.WriteUInt32 (rows [i].Col1); // RVA
556 buffer.WriteRID (rows [i].Col2, Table.Field); // Field
560 public override int Compare (FieldRVARow x, FieldRVARow y)
562 return Compare (x.Col2, y.Col2);
566 sealed class AssemblyTable : OneRowTable<AssemblyRow> {
568 public override void Write (TableHeapBuffer buffer)
570 buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm
571 buffer.WriteUInt16 (row.Col2); // MajorVersion
572 buffer.WriteUInt16 (row.Col3); // MinorVersion
573 buffer.WriteUInt16 (row.Col4); // Build
574 buffer.WriteUInt16 (row.Col5); // Revision
575 buffer.WriteUInt32 ((uint) row.Col6); // Flags
576 buffer.WriteBlob (row.Col7); // PublicKey
577 buffer.WriteString (row.Col8); // Name
578 buffer.WriteString (row.Col9); // Culture
582 sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> {
584 public override void Write (TableHeapBuffer buffer)
586 for (int i = 0; i < length; i++) {
587 buffer.WriteUInt16 (rows [i].Col1); // MajorVersion
588 buffer.WriteUInt16 (rows [i].Col2); // MinorVersion
589 buffer.WriteUInt16 (rows [i].Col3); // Build
590 buffer.WriteUInt16 (rows [i].Col4); // Revision
591 buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags
592 buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken
593 buffer.WriteString (rows [i].Col7); // Name
594 buffer.WriteString (rows [i].Col8); // Culture
595 buffer.WriteBlob (rows [i].Col9); // Hash
600 sealed class FileTable : MetadataTable<FileRow> {
602 public override void Write (TableHeapBuffer buffer)
604 for (int i = 0; i < length; i++) {
605 buffer.WriteUInt32 ((uint) rows [i].Col1);
606 buffer.WriteString (rows [i].Col2);
607 buffer.WriteBlob (rows [i].Col3);
612 sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> {
614 public override void Write (TableHeapBuffer buffer)
616 for (int i = 0; i < length; i++) {
617 buffer.WriteUInt32 ((uint) rows [i].Col1);
618 buffer.WriteUInt32 (rows [i].Col2);
619 buffer.WriteString (rows [i].Col3);
620 buffer.WriteString (rows [i].Col4);
621 buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation);
626 sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> {
628 public override void Write (TableHeapBuffer buffer)
630 for (int i = 0; i < length; i++) {
631 buffer.WriteUInt32 (rows [i].Col1);
632 buffer.WriteUInt32 ((uint) rows [i].Col2);
633 buffer.WriteString (rows [i].Col3);
634 buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation);
639 sealed class NestedClassTable : SortedTable<NestedClassRow> {
641 public override void Write (TableHeapBuffer buffer)
643 for (int i = 0; i < length; i++) {
644 buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass
645 buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass
649 public override int Compare (NestedClassRow x, NestedClassRow y)
651 return Compare (x.Col1, y.Col1);
655 sealed class GenericParamTable : MetadataTable<GenericParamRow> {
657 public override void Write (TableHeapBuffer buffer)
659 for (int i = 0; i < length; i++) {
660 buffer.WriteUInt16 (rows [i].Col1); // Number
661 buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags
662 buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner
663 buffer.WriteString (rows [i].Col4); // Name
668 sealed class MethodSpecTable : MetadataTable<MethodSpecRow> {
670 public override void Write (TableHeapBuffer buffer)
672 for (int i = 0; i < length; i++) {
673 buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method
674 buffer.WriteBlob (rows [i].Col2); // Instantiation
679 sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> {
681 public override void Write (TableHeapBuffer buffer)
683 for (int i = 0; i < length; i++) {
684 buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner
685 buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint
690 sealed class MetadataBuilder {
692 readonly internal ModuleDefinition module;
693 readonly internal ISymbolWriterProvider symbol_writer_provider;
694 readonly internal ISymbolWriter symbol_writer;
695 readonly internal TextMap text_map;
696 readonly internal string fq_name;
698 readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map;
699 readonly Dictionary<uint, MetadataToken> type_spec_map;
700 readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map;
701 readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map;
702 readonly Collection<GenericParameter> generic_parameters;
703 readonly Dictionary<MetadataToken, MetadataToken> method_def_map;
705 readonly internal CodeWriter code;
706 readonly internal DataBuffer data;
707 readonly internal ResourceBuffer resources;
708 readonly internal StringHeapBuffer string_heap;
709 readonly internal UserStringHeapBuffer user_string_heap;
710 readonly internal BlobHeapBuffer blob_heap;
711 readonly internal TableHeapBuffer table_heap;
713 internal MetadataToken entry_point;
719 RID property_rid = 1;
722 readonly TypeRefTable type_ref_table;
723 readonly TypeDefTable type_def_table;
724 readonly FieldTable field_table;
725 readonly MethodTable method_table;
726 readonly ParamTable param_table;
727 readonly InterfaceImplTable iface_impl_table;
728 readonly MemberRefTable member_ref_table;
729 readonly ConstantTable constant_table;
730 readonly CustomAttributeTable custom_attribute_table;
731 readonly DeclSecurityTable declsec_table;
732 readonly StandAloneSigTable standalone_sig_table;
733 readonly EventMapTable event_map_table;
734 readonly EventTable event_table;
735 readonly PropertyMapTable property_map_table;
736 readonly PropertyTable property_table;
737 readonly TypeSpecTable typespec_table;
738 readonly MethodSpecTable method_spec_table;
740 readonly internal bool write_symbols;
742 public MetadataBuilder (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer)
744 this.module = module;
745 this.text_map = CreateTextMap ();
746 this.fq_name = fq_name;
747 this.symbol_writer_provider = symbol_writer_provider;
748 this.symbol_writer = symbol_writer;
749 this.write_symbols = symbol_writer != null;
750 this.code = new CodeWriter (this);
751 this.data = new DataBuffer ();
752 this.resources = new ResourceBuffer ();
753 this.string_heap = new StringHeapBuffer ();
754 this.user_string_heap = new UserStringHeapBuffer ();
755 this.blob_heap = new BlobHeapBuffer ();
756 this.table_heap = new TableHeapBuffer (module, this);
758 this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef);
759 this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef);
760 this.field_table = GetTable<FieldTable> (Table.Field);
761 this.method_table = GetTable<MethodTable> (Table.Method);
762 this.param_table = GetTable<ParamTable> (Table.Param);
763 this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl);
764 this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef);
765 this.constant_table = GetTable<ConstantTable> (Table.Constant);
766 this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute);
767 this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity);
768 this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig);
769 this.event_map_table = GetTable<EventMapTable> (Table.EventMap);
770 this.event_table = GetTable<EventTable> (Table.Event);
771 this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap);
772 this.property_table = GetTable<PropertyTable> (Table.Property);
773 this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec);
774 this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec);
776 var row_equality_comparer = new RowEqualityComparer ();
777 type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer);
778 type_spec_map = new Dictionary<uint, MetadataToken> ();
779 member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer);
780 method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer);
781 generic_parameters = new Collection<GenericParameter> ();
783 method_def_map = new Dictionary<MetadataToken, MetadataToken> ();
786 TextMap CreateTextMap ()
788 var map = new TextMap ();
789 map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 16);
790 map.AddMap (TextSegment.CLIHeader, 0x48, 8);
794 TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
796 return table_heap.GetTable<TTable> (table);
799 uint GetStringIndex (string @string)
801 if (string.IsNullOrEmpty (@string))
804 return string_heap.GetStringIndex (@string);
807 uint GetBlobIndex (ByteBuffer blob)
809 if (blob.length == 0)
812 return blob_heap.GetBlobIndex (blob);
815 uint GetBlobIndex (byte [] blob)
817 if (blob.IsNullOrEmpty ())
820 return GetBlobIndex (new ByteBuffer (blob));
823 public void BuildMetadata ()
827 table_heap.WriteTableHeap ();
832 var table = GetTable<ModuleTable> (Table.Module);
833 table.row = GetStringIndex (module.Name);
835 var assembly = module.Assembly;
837 if (assembly != null)
840 if (module.HasAssemblyReferences)
841 AddAssemblyReferences ();
843 if (module.HasModuleReferences)
844 AddModuleReferences ();
846 if (module.HasResources)
849 if (module.HasExportedTypes)
854 if (assembly != null) {
855 if (assembly.HasCustomAttributes)
856 AddCustomAttributes (assembly);
858 if (assembly.HasSecurityDeclarations)
859 AddSecurityDeclarations (assembly);
862 if (module.HasCustomAttributes)
863 AddCustomAttributes (module);
865 if (module.EntryPoint != null)
866 entry_point = LookupToken (module.EntryPoint);
869 void BuildAssembly ()
871 var assembly = module.Assembly;
872 var name = assembly.Name;
874 var table = GetTable<AssemblyTable> (Table.Assembly);
876 table.row = new AssemblyRow (
878 (ushort) name.Version.Major,
879 (ushort) name.Version.Minor,
880 (ushort) name.Version.Build,
881 (ushort) name.Version.Revision,
883 GetBlobIndex (name.PublicKey),
884 GetStringIndex (name.Name),
885 GetStringIndex (name.Culture));
887 if (assembly.Modules.Count > 1)
893 var modules = this.module.Assembly.Modules;
894 var table = GetTable<FileTable> (Table.File);
896 for (int i = 0; i < modules.Count; i++) {
897 var module = modules [i];
901 var parameters = new WriterParameters {
902 SymbolWriterProvider = symbol_writer_provider,
905 var file_name = GetModuleFileName (module.Name);
906 module.Write (file_name, parameters);
908 var hash = CryptoService.ComputeHash (file_name);
910 table.AddRow (new FileRow (
911 FileAttributes.ContainsMetaData,
912 GetStringIndex (module.Name),
913 GetBlobIndex (hash)));
917 string GetModuleFileName (string name)
919 if (string.IsNullOrEmpty (name))
920 throw new NotSupportedException ();
922 var path = Path.GetDirectoryName (fq_name);
923 return Path.Combine (path, name);
926 void AddAssemblyReferences ()
928 var references = module.AssemblyReferences;
929 var table = GetTable<AssemblyRefTable> (Table.AssemblyRef);
931 for (int i = 0; i < references.Count; i++) {
932 var reference = references [i];
934 var key_or_token = reference.PublicKey.IsNullOrEmpty ()
935 ? reference.PublicKeyToken
936 : reference.PublicKey;
938 var rid = table.AddRow (new AssemblyRefRow (
939 (ushort) reference.Version.Major,
940 (ushort) reference.Version.Minor,
941 (ushort) reference.Version.Build,
942 (ushort) reference.Version.Revision,
943 reference.Attributes,
944 GetBlobIndex (key_or_token),
945 GetStringIndex (reference.Name),
946 GetStringIndex (reference.Culture),
947 GetBlobIndex (reference.Hash)));
949 reference.token = new MetadataToken (TokenType.AssemblyRef, rid);
953 void AddModuleReferences ()
955 var references = module.ModuleReferences;
956 var table = GetTable<ModuleRefTable> (Table.ModuleRef);
958 for (int i = 0; i < references.Count; i++) {
959 var reference = references [i];
961 reference.token = new MetadataToken (
963 table.AddRow (GetStringIndex (reference.Name)));
969 var resources = module.Resources;
970 var table = GetTable<ManifestResourceTable> (Table.ManifestResource);
972 for (int i = 0; i < resources.Count; i++) {
973 var resource = resources [i];
975 var row = new ManifestResourceRow (
978 GetStringIndex (resource.Name),
981 switch (resource.ResourceType) {
982 case ResourceType.Embedded:
983 row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource);
985 case ResourceType.Linked:
986 row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
989 AddLinkedResource ((LinkedResource) resource)));
991 case ResourceType.AssemblyLinked:
992 row.Col4 = CodedIndex.Implementation.CompressMetadataToken (
993 ((AssemblyLinkedResource) resource).Assembly.MetadataToken);
996 throw new NotSupportedException ();
1003 uint AddLinkedResource (LinkedResource resource)
1005 var table = GetTable<FileTable> (Table.File);
1007 var hash = resource.Hash.IsNullOrEmpty ()
1008 ? CryptoService.ComputeHash (resource.File)
1011 return (uint) table.AddRow (new FileRow (
1012 FileAttributes.ContainsNoMetaData,
1013 GetStringIndex (resource.File),
1014 GetBlobIndex (hash)));
1017 uint AddEmbeddedResource (EmbeddedResource resource)
1019 return resources.AddResource (resource.GetResourceData ());
1022 void AddExportedTypes ()
1024 var exported_types = module.ExportedTypes;
1025 var table = GetTable<ExportedTypeTable> (Table.ExportedType);
1027 for (int i = 0; i < exported_types.Count; i++) {
1028 var exported_type = exported_types [i];
1030 var rid = table.AddRow (new ExportedTypeRow (
1031 exported_type.Attributes,
1032 (uint) exported_type.Identifier,
1033 GetStringIndex (exported_type.Name),
1034 GetStringIndex (exported_type.Namespace),
1035 MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation)));
1037 exported_type.token = new MetadataToken (TokenType.ExportedType, rid);
1041 MetadataToken GetExportedTypeScope (ExportedType exported_type)
1043 if (exported_type.DeclaringType != null)
1044 return exported_type.DeclaringType.MetadataToken;
1046 var scope = exported_type.Scope;
1047 switch (scope.MetadataToken.TokenType) {
1048 case TokenType.AssemblyRef:
1049 return scope.MetadataToken;
1050 case TokenType.ModuleRef:
1051 var file_table = GetTable<FileTable> (Table.File);
1052 for (int i = 0; i < file_table.length; i++)
1053 if (file_table.rows [i].Col2 == GetStringIndex (scope.Name))
1054 return new MetadataToken (TokenType.File, i + 1);
1059 throw new NotSupportedException ();
1064 if (!module.HasTypes)
1069 AddGenericParameters ();
1072 void AttachTokens ()
1074 var types = module.Types;
1076 for (int i = 0; i < types.Count; i++)
1077 AttachTypeDefToken (types [i]);
1080 void AttachTypeDefToken (TypeDefinition type)
1082 type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
1083 type.fields_range.Start = field_rid;
1084 type.methods_range.Start = method_rid;
1087 AttachFieldsDefToken (type);
1089 if (type.HasMethods)
1090 AttachMethodsDefToken (type);
1092 if (type.HasNestedTypes)
1093 AttachNestedTypesDefToken (type);
1096 void AttachNestedTypesDefToken (TypeDefinition type)
1098 var nested_types = type.NestedTypes;
1099 for (int i = 0; i < nested_types.Count; i++)
1100 AttachTypeDefToken (nested_types [i]);
1103 void AttachFieldsDefToken (TypeDefinition type)
1105 var fields = type.Fields;
1106 type.fields_range.Length = (uint) fields.Count;
1107 for (int i = 0; i < fields.Count; i++)
1108 fields [i].token = new MetadataToken (TokenType.Field, field_rid++);
1111 void AttachMethodsDefToken (TypeDefinition type)
1113 var methods = type.Methods;
1114 type.methods_range.Length = (uint) methods.Count;
1115 for (int i = 0; i < methods.Count; i++) {
1116 var method = methods [i];
1117 var new_token = new MetadataToken (TokenType.Method, method_rid++);
1119 if (write_symbols && method.token != MetadataToken.Zero)
1120 method_def_map.Add (new_token, method.token);
1122 method.token = new_token;
1126 public bool TryGetOriginalMethodToken (MetadataToken new_token, out MetadataToken original)
1128 return method_def_map.TryGetValue (new_token, out original);
1131 MetadataToken GetTypeToken (TypeReference type)
1134 return MetadataToken.Zero;
1136 if (type.IsDefinition)
1139 if (type.IsTypeSpecification ())
1140 return GetTypeSpecToken (type);
1142 return GetTypeRefToken (type);
1145 MetadataToken GetTypeSpecToken (TypeReference type)
1147 var row = GetBlobIndex (GetTypeSpecSignature (type));
1149 MetadataToken token;
1150 if (type_spec_map.TryGetValue (row, out token))
1153 return AddTypeSpecification (type, row);
1156 MetadataToken AddTypeSpecification (TypeReference type, uint row)
1158 type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row));
1160 var token = type.token;
1161 type_spec_map.Add (row, token);
1165 MetadataToken GetTypeRefToken (TypeReference type)
1167 var row = CreateTypeRefRow (type);
1169 MetadataToken token;
1170 if (type_ref_map.TryGetValue (row, out token))
1173 return AddTypeReference (type, row);
1176 TypeRefRow CreateTypeRefRow (TypeReference type)
1178 var scope_token = type.IsNested
1179 ? GetTypeRefToken (type.DeclaringType)
1180 : type.Scope.MetadataToken;
1182 return new TypeRefRow (
1183 MakeCodedRID (scope_token, CodedIndex.ResolutionScope),
1184 GetStringIndex (type.Name),
1185 GetStringIndex (type.Namespace));
1188 static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index)
1190 return MakeCodedRID (provider.MetadataToken, index);
1193 static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index)
1195 return index.CompressMetadataToken (token);
1198 MetadataToken AddTypeReference (TypeReference type, TypeRefRow row)
1200 type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row));
1202 var token = type.token;
1203 type_ref_map.Add (row, token);
1209 var types = module.Types;
1211 for (int i = 0; i < types.Count; i++)
1212 AddType (types [i]);
1215 void AddType (TypeDefinition type)
1217 type_def_table.AddRow (new TypeDefRow (
1219 GetStringIndex (type.Name),
1220 GetStringIndex (type.Namespace),
1221 MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef),
1222 type.fields_range.Start,
1223 type.methods_range.Start));
1225 if (type.HasGenericParameters)
1226 AddGenericParameters (type);
1228 if (type.HasInterfaces)
1229 AddInterfaces (type);
1231 if (type.HasLayoutInfo)
1232 AddLayoutInfo (type);
1237 if (type.HasMethods)
1240 if (type.HasProperties)
1241 AddProperties (type);
1246 if (type.HasCustomAttributes)
1247 AddCustomAttributes (type);
1249 if (type.HasSecurityDeclarations)
1250 AddSecurityDeclarations (type);
1252 if (type.HasNestedTypes)
1253 AddNestedTypes (type);
1256 void AddGenericParameters (IGenericParameterProvider owner)
1258 var parameters = owner.GenericParameters;
1260 for (int i = 0; i < parameters.Count; i++)
1261 generic_parameters.Add (parameters [i]);
1264 sealed class GenericParameterComparer : IComparer<GenericParameter> {
1266 public int Compare (GenericParameter a, GenericParameter b)
1268 var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef);
1269 var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef);
1270 if (a_owner == b_owner) {
1271 var a_pos = a.Position;
1272 var b_pos = b.Position;
1273 return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1;
1276 return a_owner > b_owner ? 1 : -1;
1280 void AddGenericParameters ()
1282 var items = this.generic_parameters.items;
1283 var size = this.generic_parameters.size;
1284 Array.Sort (items, 0, size, new GenericParameterComparer ());
1286 var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam);
1287 var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint);
1289 for (int i = 0; i < size; i++) {
1290 var generic_parameter = items [i];
1292 var rid = generic_param_table.AddRow (new GenericParamRow (
1293 (ushort) generic_parameter.Position,
1294 generic_parameter.Attributes,
1295 MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef),
1296 GetStringIndex (generic_parameter.Name)));
1298 generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid);
1300 if (generic_parameter.HasConstraints)
1301 AddConstraints (generic_parameter, generic_param_constraint_table);
1303 if (generic_parameter.HasCustomAttributes)
1304 AddCustomAttributes (generic_parameter);
1308 void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table)
1310 var constraints = generic_parameter.Constraints;
1312 var rid = generic_parameter.token.RID;
1314 for (int i = 0; i < constraints.Count; i++)
1315 table.AddRow (new GenericParamConstraintRow (
1317 MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef)));
1320 void AddInterfaces (TypeDefinition type)
1322 var interfaces = type.Interfaces;
1323 var type_rid = type.token.RID;
1325 for (int i = 0; i < interfaces.Count; i++)
1326 iface_impl_table.AddRow (new InterfaceImplRow (
1328 MakeCodedRID (GetTypeToken (interfaces [i]), CodedIndex.TypeDefOrRef)));
1331 void AddLayoutInfo (TypeDefinition type)
1333 var table = GetTable<ClassLayoutTable> (Table.ClassLayout);
1335 table.AddRow (new ClassLayoutRow (
1336 (ushort) type.PackingSize,
1337 (uint) type.ClassSize,
1341 void AddNestedTypes (TypeDefinition type)
1343 var nested_types = type.NestedTypes;
1344 var nested_table = GetTable<NestedClassTable> (Table.NestedClass);
1346 for (int i = 0; i < nested_types.Count; i++) {
1347 var nested = nested_types [i];
1349 nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID));
1353 void AddFields (TypeDefinition type)
1355 var fields = type.Fields;
1357 for (int i = 0; i < fields.Count; i++)
1358 AddField (fields [i]);
1361 void AddField (FieldDefinition field)
1363 field_table.AddRow (new FieldRow (
1365 GetStringIndex (field.Name),
1366 GetBlobIndex (GetFieldSignature (field))));
1368 if (!field.InitialValue.IsNullOrEmpty ())
1369 AddFieldRVA (field);
1371 if (field.HasLayoutInfo)
1372 AddFieldLayout (field);
1374 if (field.HasCustomAttributes)
1375 AddCustomAttributes (field);
1377 if (field.HasConstant)
1378 AddConstant (field, field.FieldType);
1380 if (field.HasMarshalInfo)
1381 AddMarshalInfo (field);
1384 void AddFieldRVA (FieldDefinition field)
1386 var table = GetTable<FieldRVATable> (Table.FieldRVA);
1387 table.AddRow (new FieldRVARow (
1388 data.AddData (field.InitialValue),
1392 void AddFieldLayout (FieldDefinition field)
1394 var table = GetTable<FieldLayoutTable> (Table.FieldLayout);
1395 table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID));
1398 void AddMethods (TypeDefinition type)
1400 var methods = type.Methods;
1402 for (int i = 0; i < methods.Count; i++)
1403 AddMethod (methods [i]);
1406 void AddMethod (MethodDefinition method)
1408 method_table.AddRow (new MethodRow (
1409 method.HasBody ? code.WriteMethodBody (method) : 0,
1410 method.ImplAttributes,
1412 GetStringIndex (method.Name),
1413 GetBlobIndex (GetMethodSignature (method)),
1416 AddParameters (method);
1418 if (method.HasGenericParameters)
1419 AddGenericParameters (method);
1421 if (method.IsPInvokeImpl)
1422 AddPInvokeInfo (method);
1424 if (method.HasCustomAttributes)
1425 AddCustomAttributes (method);
1427 if (method.HasSecurityDeclarations)
1428 AddSecurityDeclarations (method);
1430 if (method.HasOverrides)
1431 AddOverrides (method);
1434 void AddParameters (MethodDefinition method)
1436 var return_parameter = method.MethodReturnType.parameter;
1438 if (return_parameter != null && RequiresParameterRow (return_parameter))
1439 AddParameter (0, return_parameter, param_table);
1441 if (!method.HasParameters)
1444 var parameters = method.Parameters;
1446 for (int i = 0; i < parameters.Count; i++) {
1447 var parameter = parameters [i];
1448 if (!RequiresParameterRow (parameter))
1451 AddParameter ((ushort) (i + 1), parameter, param_table);
1455 void AddPInvokeInfo (MethodDefinition method)
1457 var pinvoke = method.PInvokeInfo;
1458 if (pinvoke == null)
1459 throw new ArgumentException ();
1461 var table = GetTable<ImplMapTable> (Table.ImplMap);
1462 table.AddRow (new ImplMapRow (
1464 MakeCodedRID (method, CodedIndex.MemberForwarded),
1465 GetStringIndex (pinvoke.EntryPoint),
1466 pinvoke.Module.MetadataToken.RID));
1469 void AddOverrides (MethodDefinition method)
1471 var overrides = method.Overrides;
1472 var table = GetTable<MethodImplTable> (Table.MethodImpl);
1474 for (int i = 0; i < overrides.Count; i++) {
1475 table.AddRow (new MethodImplRow (
1476 method.DeclaringType.token.RID,
1477 MakeCodedRID (method, CodedIndex.MethodDefOrRef),
1478 MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef)));
1482 static bool RequiresParameterRow (ParameterDefinition parameter)
1484 return !string.IsNullOrEmpty (parameter.Name)
1485 || parameter.Attributes != ParameterAttributes.None
1486 || parameter.HasMarshalInfo
1487 || parameter.HasConstant
1488 || parameter.HasCustomAttributes;
1491 void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table)
1493 table.AddRow (new ParamRow (
1494 parameter.Attributes,
1496 GetStringIndex (parameter.Name)));
1498 parameter.token = new MetadataToken (TokenType.Param, param_rid++);
1500 if (parameter.HasCustomAttributes)
1501 AddCustomAttributes (parameter);
1503 if (parameter.HasConstant)
1504 AddConstant (parameter, parameter.ParameterType);
1506 if (parameter.HasMarshalInfo)
1507 AddMarshalInfo (parameter);
1510 void AddMarshalInfo (IMarshalInfoProvider owner)
1512 var table = GetTable<FieldMarshalTable> (Table.FieldMarshal);
1514 table.AddRow (new FieldMarshalRow (
1515 MakeCodedRID (owner, CodedIndex.HasFieldMarshal),
1516 GetBlobIndex (GetMarshalInfoSignature (owner))));
1519 void AddProperties (TypeDefinition type)
1521 var properties = type.Properties;
1523 property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid));
1525 for (int i = 0; i < properties.Count; i++)
1526 AddProperty (properties [i]);
1529 void AddProperty (PropertyDefinition property)
1531 property_table.AddRow (new PropertyRow (
1532 property.Attributes,
1533 GetStringIndex (property.Name),
1534 GetBlobIndex (GetPropertySignature (property))));
1535 property.token = new MetadataToken (TokenType.Property, property_rid++);
1537 var method = property.GetMethod;
1539 AddSemantic (MethodSemanticsAttributes.Getter, property, method);
1541 method = property.SetMethod;
1543 AddSemantic (MethodSemanticsAttributes.Setter, property, method);
1545 if (property.HasOtherMethods)
1546 AddOtherSemantic (property, property.OtherMethods);
1548 if (property.HasCustomAttributes)
1549 AddCustomAttributes (property);
1551 if (property.HasConstant)
1552 AddConstant (property, property.PropertyType);
1555 void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others)
1557 for (int i = 0; i < others.Count; i++)
1558 AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]);
1561 void AddEvents (TypeDefinition type)
1563 var events = type.Events;
1565 event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid));
1567 for (int i = 0; i < events.Count; i++)
1568 AddEvent (events [i]);
1571 void AddEvent (EventDefinition @event)
1573 event_table.AddRow (new EventRow (
1575 GetStringIndex (@event.Name),
1576 MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef)));
1577 @event.token = new MetadataToken (TokenType.Event, event_rid++);
1579 var method = @event.AddMethod;
1581 AddSemantic (MethodSemanticsAttributes.AddOn, @event, method);
1583 method = @event.InvokeMethod;
1585 AddSemantic (MethodSemanticsAttributes.Fire, @event, method);
1587 method = @event.RemoveMethod;
1589 AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method);
1591 if (@event.HasOtherMethods)
1592 AddOtherSemantic (@event, @event.OtherMethods);
1594 if (@event.HasCustomAttributes)
1595 AddCustomAttributes (@event);
1598 void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method)
1600 method.SemanticsAttributes = semantics;
1601 var table = GetTable<MethodSemanticsTable> (Table.MethodSemantics);
1603 table.AddRow (new MethodSemanticsRow (
1606 MakeCodedRID (provider, CodedIndex.HasSemantics)));
1609 void AddConstant (IConstantProvider owner, TypeReference type)
1611 var constant = owner.Constant;
1612 var etype = GetConstantType (type, constant);
1614 constant_table.AddRow (new ConstantRow (
1616 MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant),
1617 GetBlobIndex (GetConstantSignature (etype, constant))));
1620 static ElementType GetConstantType (TypeReference constant_type, object constant)
1622 if (constant == null)
1623 return ElementType.Class;
1625 var etype = constant_type.etype;
1627 case ElementType.None:
1628 var type = constant_type.CheckedResolve ();
1630 return GetConstantType (type.GetEnumUnderlyingType (), constant);
1632 return ElementType.Class;
1633 case ElementType.String:
1634 return ElementType.String;
1635 case ElementType.Object:
1636 return GetConstantType (constant.GetType ());
1637 case ElementType.Array:
1638 case ElementType.SzArray:
1639 case ElementType.MVar:
1640 case ElementType.Var:
1641 return ElementType.Class;
1642 case ElementType.GenericInst:
1643 case ElementType.CModOpt:
1644 case ElementType.CModReqD:
1645 case ElementType.ByRef:
1646 case ElementType.Sentinel:
1647 return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
1648 case ElementType.Boolean:
1649 case ElementType.Char:
1651 case ElementType.I1:
1652 case ElementType.I2:
1653 case ElementType.I4:
1654 case ElementType.I8:
1656 case ElementType.U1:
1657 case ElementType.U2:
1658 case ElementType.U4:
1659 case ElementType.U8:
1660 case ElementType.R4:
1661 case ElementType.R8:
1662 return GetConstantType (constant.GetType ());
1668 static ElementType GetConstantType (Type type)
1670 switch (Type.GetTypeCode (type)) {
1671 case TypeCode.Boolean:
1672 return ElementType.Boolean;
1674 return ElementType.U1;
1675 case TypeCode.SByte:
1676 return ElementType.I1;
1678 return ElementType.Char;
1679 case TypeCode.Int16:
1680 return ElementType.I2;
1681 case TypeCode.UInt16:
1682 return ElementType.U2;
1683 case TypeCode.Int32:
1684 return ElementType.I4;
1685 case TypeCode.UInt32:
1686 return ElementType.U4;
1687 case TypeCode.Int64:
1688 return ElementType.I8;
1689 case TypeCode.UInt64:
1690 return ElementType.U8;
1691 case TypeCode.Single:
1692 return ElementType.R4;
1693 case TypeCode.Double:
1694 return ElementType.R8;
1695 case TypeCode.String:
1696 return ElementType.String;
1698 throw new NotSupportedException (type.FullName);
1702 void AddCustomAttributes (ICustomAttributeProvider owner)
1704 var custom_attributes = owner.CustomAttributes;
1706 for (int i = 0; i < custom_attributes.Count; i++) {
1707 var attribute = custom_attributes [i];
1709 custom_attribute_table.AddRow (new CustomAttributeRow (
1710 MakeCodedRID (owner, CodedIndex.HasCustomAttribute),
1711 MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType),
1712 GetBlobIndex (GetCustomAttributeSignature (attribute))));
1716 void AddSecurityDeclarations (ISecurityDeclarationProvider owner)
1718 var declarations = owner.SecurityDeclarations;
1720 for (int i = 0; i < declarations.Count; i++) {
1721 var declaration = declarations [i];
1723 declsec_table.AddRow (new DeclSecurityRow (
1725 MakeCodedRID (owner, CodedIndex.HasDeclSecurity),
1726 GetBlobIndex (GetSecurityDeclarationSignature (declaration))));
1730 MetadataToken GetMemberRefToken (MemberReference member)
1732 var row = CreateMemberRefRow (member);
1734 MetadataToken token;
1735 if (member_ref_map.TryGetValue (row, out token))
1738 AddMemberReference (member, row);
1740 return member.token;
1743 MemberRefRow CreateMemberRefRow (MemberReference member)
1745 return new MemberRefRow (
1746 MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent),
1747 GetStringIndex (member.Name),
1748 GetBlobIndex (GetMemberRefSignature (member)));
1751 void AddMemberReference (MemberReference member, MemberRefRow row)
1753 member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row));
1754 member_ref_map.Add (row, member.token);
1757 MetadataToken GetMethodSpecToken (MethodSpecification method_spec)
1759 var row = CreateMethodSpecRow (method_spec);
1761 MetadataToken token;
1762 if (method_spec_map.TryGetValue (row, out token))
1765 AddMethodSpecification (method_spec, row);
1767 return method_spec.token;
1770 void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row)
1772 method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row));
1773 method_spec_map.Add (row, method_spec.token);
1776 MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec)
1778 return new MethodSpecRow (
1779 MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef),
1780 GetBlobIndex (GetMethodSpecSignature (method_spec)));
1783 SignatureWriter CreateSignatureWriter ()
1785 return new SignatureWriter (this);
1788 SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec)
1790 if (!method_spec.IsGenericInstance)
1791 throw new NotSupportedException ();
1793 var generic_instance = (GenericInstanceMethod) method_spec;
1795 var signature = CreateSignatureWriter ();
1796 signature.WriteByte (0x0a);
1798 signature.WriteGenericInstanceSignature (generic_instance);
1803 public uint AddStandAloneSignature (uint signature)
1805 return (uint) standalone_sig_table.AddRow (signature);
1808 public uint GetLocalVariableBlobIndex (Collection<VariableDefinition> variables)
1810 return GetBlobIndex (GetVariablesSignature (variables));
1813 public uint GetCallSiteBlobIndex (CallSite call_site)
1815 return GetBlobIndex (GetMethodSignature (call_site));
1818 SignatureWriter GetVariablesSignature (Collection<VariableDefinition> variables)
1820 var signature = CreateSignatureWriter ();
1821 signature.WriteByte (0x7);
1822 signature.WriteCompressedUInt32 ((uint) variables.Count);
1823 for (int i = 0; i < variables.Count; i++)
1824 signature.WriteTypeSignature (variables [i].VariableType);
1828 SignatureWriter GetFieldSignature (FieldReference field)
1830 var signature = CreateSignatureWriter ();
1831 signature.WriteByte (0x6);
1832 signature.WriteTypeSignature (field.FieldType);
1836 SignatureWriter GetMethodSignature (IMethodSignature method)
1838 var signature = CreateSignatureWriter ();
1839 signature.WriteMethodSignature (method);
1843 SignatureWriter GetMemberRefSignature (MemberReference member)
1845 var field = member as FieldReference;
1847 return GetFieldSignature (field);
1849 var method = member as MethodReference;
1851 return GetMethodSignature (method);
1853 throw new NotSupportedException ();
1856 SignatureWriter GetPropertySignature (PropertyDefinition property)
1858 var signature = CreateSignatureWriter ();
1859 byte calling_convention = 0x8;
1860 if (property.HasThis)
1861 calling_convention |= 0x20;
1863 uint param_count = 0;
1864 Collection<ParameterDefinition> parameters = null;
1866 if (property.HasParameters) {
1867 parameters = property.Parameters;
1868 param_count = (uint) parameters.Count;
1871 signature.WriteByte (calling_convention);
1872 signature.WriteCompressedUInt32 (param_count);
1873 signature.WriteTypeSignature (property.PropertyType);
1875 if (param_count == 0)
1878 for (int i = 0; i < param_count; i++)
1879 signature.WriteTypeSignature (parameters [i].ParameterType);
1884 SignatureWriter GetTypeSpecSignature (TypeReference type)
1886 var signature = CreateSignatureWriter ();
1887 signature.WriteTypeSignature (type);
1891 SignatureWriter GetConstantSignature (ElementType type, object value)
1893 var signature = CreateSignatureWriter ();
1896 case ElementType.Array:
1897 case ElementType.SzArray:
1898 case ElementType.Class:
1899 case ElementType.Object:
1900 case ElementType.Var:
1901 case ElementType.MVar:
1902 signature.WriteInt32 (0);
1904 case ElementType.String:
1905 signature.WriteConstantString ((string) value);
1908 signature.WriteConstantPrimitive (value);
1915 SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute)
1917 var signature = CreateSignatureWriter ();
1918 if (!attribute.resolved) {
1919 signature.WriteBytes (attribute.GetBlob ());
1923 signature.WriteUInt16 (0x0001);
1925 signature.WriteCustomAttributeConstructorArguments (attribute);
1927 signature.WriteCustomAttributeNamedArguments (attribute);
1932 SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration)
1934 var signature = CreateSignatureWriter ();
1936 if (!declaration.resolved)
1937 signature.WriteBytes (declaration.GetBlob ());
1938 else if (module.Runtime < TargetRuntime.Net_2_0)
1939 signature.WriteXmlSecurityDeclaration (declaration);
1941 signature.WriteSecurityDeclaration (declaration);
1946 SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner)
1948 var signature = CreateSignatureWriter ();
1950 signature.WriteMarshalInfo (owner.MarshalInfo);
1955 static Exception CreateForeignMemberException (MemberReference member)
1957 return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member));
1960 public MetadataToken LookupToken (IMetadataTokenProvider provider)
1962 if (provider == null)
1963 throw new ArgumentNullException ();
1965 var member = provider as MemberReference;
1966 if (member == null || member.Module != module)
1967 throw CreateForeignMemberException (member);
1969 var token = provider.MetadataToken;
1971 switch (token.TokenType) {
1972 case TokenType.TypeDef:
1973 case TokenType.Method:
1974 case TokenType.Field:
1975 case TokenType.Event:
1976 case TokenType.Property:
1978 case TokenType.TypeRef:
1979 case TokenType.TypeSpec:
1980 case TokenType.GenericParam:
1981 return GetTypeToken ((TypeReference) provider);
1982 case TokenType.MethodSpec:
1983 return GetMethodSpecToken ((MethodSpecification) provider);
1984 case TokenType.MemberRef:
1985 return GetMemberRefToken (member);
1987 throw new NotSupportedException ();
1992 sealed class SignatureWriter : ByteBuffer {
1994 readonly MetadataBuilder metadata;
1996 public SignatureWriter (MetadataBuilder metadata)
1999 this.metadata = metadata;
2002 public void WriteElementType (ElementType element_type)
2004 WriteByte ((byte) element_type);
2007 public void WriteUTF8String (string @string)
2009 if (@string == null) {
2014 var bytes = Encoding.UTF8.GetBytes (@string);
2015 WriteCompressedUInt32 ((uint) bytes.Length);
2019 public void WriteMethodSignature (IMethodSignature method)
2021 byte calling_convention = (byte) method.CallingConvention;
2023 calling_convention |= 0x20;
2024 if (method.ExplicitThis)
2025 calling_convention |= 0x40;
2027 var generic_provider = method as IGenericParameterProvider;
2028 var generic_arity = generic_provider != null && generic_provider.HasGenericParameters
2029 ? generic_provider.GenericParameters.Count
2032 if (generic_arity > 0)
2033 calling_convention |= 0x10;
2035 var param_count = method.HasParameters ? method.Parameters.Count : 0;
2037 WriteByte (calling_convention);
2039 if (generic_arity > 0)
2040 WriteCompressedUInt32 ((uint) generic_arity);
2042 WriteCompressedUInt32 ((uint) param_count);
2043 WriteTypeSignature (method.ReturnType);
2045 if (param_count == 0)
2048 var parameters = method.Parameters;
2050 for (int i = 0; i < param_count; i++)
2051 WriteTypeSignature (parameters [i].ParameterType);
2054 uint MakeTypeDefOrRefCodedRID (TypeReference type)
2056 return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type));
2059 public void WriteTypeSignature (TypeReference type)
2062 throw new ArgumentNullException ();
2064 var etype = type.etype;
2067 case ElementType.MVar:
2068 case ElementType.Var: {
2069 var generic_parameter = (GenericParameter) type;
2071 WriteElementType (etype);
2072 var position = generic_parameter.Position;
2074 throw new NotSupportedException ();
2076 WriteCompressedUInt32 ((uint) position);
2080 case ElementType.GenericInst: {
2081 var generic_instance = (GenericInstanceType) type;
2082 WriteElementType (ElementType.GenericInst);
2083 WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class);
2084 WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType));
2086 WriteGenericInstanceSignature (generic_instance);
2090 case ElementType.Ptr:
2091 case ElementType.ByRef:
2092 case ElementType.Pinned:
2093 case ElementType.Sentinel: {
2094 var type_spec = (TypeSpecification) type;
2095 WriteElementType (etype);
2096 WriteTypeSignature (type_spec.ElementType);
2100 case ElementType.FnPtr: {
2101 var fptr = (FunctionPointerType) type;
2102 WriteElementType (ElementType.FnPtr);
2103 WriteMethodSignature (fptr);
2107 case ElementType.CModOpt:
2108 case ElementType.CModReqD: {
2109 var modifier = (IModifierType) type;
2110 WriteModifierSignature (etype, modifier);
2114 case ElementType.Array: {
2115 var array = (ArrayType) type;
2116 if (!array.IsVector) {
2117 WriteArrayTypeSignature (array);
2121 WriteElementType (ElementType.SzArray);
2122 WriteTypeSignature (array.ElementType);
2126 case ElementType.None: {
2127 WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class);
2128 WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type));
2133 if (!TryWriteElementType (type))
2134 throw new NotSupportedException ();
2141 void WriteArrayTypeSignature (ArrayType array)
2143 WriteElementType (ElementType.Array);
2144 WriteTypeSignature (array.ElementType);
2146 var dimensions = array.Dimensions;
2147 var rank = dimensions.Count;
2149 WriteCompressedUInt32 ((uint) rank);
2154 for (int i = 0; i < rank; i++) {
2155 var dimension = dimensions [i];
2157 if (dimension.UpperBound.HasValue) {
2160 } else if (dimension.LowerBound.HasValue)
2164 var sizes = new int [sized];
2165 var low_bounds = new int [lbounds];
2167 for (int i = 0; i < lbounds; i++) {
2168 var dimension = dimensions [i];
2169 low_bounds [i] = dimension.LowerBound.GetValueOrDefault ();
2170 if (dimension.UpperBound.HasValue)
2171 sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1;
2174 WriteCompressedUInt32 ((uint) sized);
2175 for (int i = 0; i < sized; i++)
2176 WriteCompressedUInt32 ((uint) sizes [i]);
2178 WriteCompressedUInt32 ((uint) lbounds);
2179 for (int i = 0; i < lbounds; i++)
2180 WriteCompressedInt32 (low_bounds [i]);
2183 public void WriteGenericInstanceSignature (IGenericInstance instance)
2185 var generic_arguments = instance.GenericArguments;
2186 var arity = generic_arguments.Count;
2188 WriteCompressedUInt32 ((uint) arity);
2189 for (int i = 0; i < arity; i++)
2190 WriteTypeSignature (generic_arguments [i]);
2193 void WriteModifierSignature (ElementType element_type, IModifierType type)
2195 WriteElementType (element_type);
2196 WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType));
2197 WriteTypeSignature (type.ElementType);
2200 bool TryWriteElementType (TypeReference type)
2202 var element = type.etype;
2204 if (element == ElementType.None)
2207 WriteElementType (element);
2211 public void WriteConstantString (string value)
2213 WriteBytes (Encoding.Unicode.GetBytes (value));
2216 public void WriteConstantPrimitive (object value)
2218 WritePrimitiveValue (value);
2221 public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute)
2223 if (!attribute.HasConstructorArguments)
2226 var arguments = attribute.ConstructorArguments;
2227 var parameters = attribute.Constructor.Parameters;
2229 if (parameters.Count != arguments.Count)
2230 throw new InvalidOperationException ();
2232 for (int i = 0; i < arguments.Count; i++)
2233 WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]);
2236 void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument)
2239 WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
2243 WriteCustomAttributeElement (type, argument);
2246 void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument)
2248 var values = argument.Value as CustomAttributeArgument [];
2250 if (values == null) {
2251 WriteUInt32 (0xffffffff);
2255 WriteInt32 (values.Length);
2257 if (values.Length == 0)
2260 var element_type = type.ElementType;
2262 for (int i = 0; i < values.Length; i++)
2263 WriteCustomAttributeElement (element_type, values [i]);
2266 void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument)
2269 WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument);
2273 if (type.etype == ElementType.Object) {
2274 argument = (CustomAttributeArgument) argument.Value;
2275 type = argument.Type;
2277 WriteCustomAttributeFieldOrPropType (type);
2278 WriteCustomAttributeElement (type, argument);
2282 WriteCustomAttributeValue (type, argument.Value);
2285 void WriteCustomAttributeValue (TypeReference type, object value)
2287 var etype = type.etype;
2290 case ElementType.String:
2291 var @string = (string) value;
2292 if (@string == null)
2295 WriteUTF8String (@string);
2297 case ElementType.None:
2298 if (type.IsTypeOf ("System", "Type"))
2299 WriteTypeReference ((TypeReference) value);
2301 WriteCustomAttributeEnumValue (type, value);
2304 WritePrimitiveValue (value);
2309 void WritePrimitiveValue (object value)
2312 throw new ArgumentNullException ();
2314 switch (Type.GetTypeCode (value.GetType ())) {
2315 case TypeCode.Boolean:
2316 WriteByte ((byte) (((bool) value) ? 1 : 0));
2319 WriteByte ((byte) value);
2321 case TypeCode.SByte:
2322 WriteSByte ((sbyte) value);
2324 case TypeCode.Int16:
2325 WriteInt16 ((short) value);
2327 case TypeCode.UInt16:
2328 WriteUInt16 ((ushort) value);
2331 WriteInt16 ((short) (char) value);
2333 case TypeCode.Int32:
2334 WriteInt32 ((int) value);
2336 case TypeCode.UInt32:
2337 WriteUInt32 ((uint) value);
2339 case TypeCode.Single:
2340 WriteSingle ((float) value);
2342 case TypeCode.Int64:
2343 WriteInt64 ((long) value);
2345 case TypeCode.UInt64:
2346 WriteUInt64 ((ulong) value);
2348 case TypeCode.Double:
2349 WriteDouble ((double) value);
2352 throw new NotSupportedException (value.GetType ().FullName);
2356 void WriteCustomAttributeEnumValue (TypeReference enum_type, object value)
2358 var type = enum_type.CheckedResolve ();
2360 throw new ArgumentException ();
2362 WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value);
2365 void WriteCustomAttributeFieldOrPropType (TypeReference type)
2368 var array = (ArrayType) type;
2369 WriteElementType (ElementType.SzArray);
2370 WriteCustomAttributeFieldOrPropType (array.ElementType);
2374 var etype = type.etype;
2377 case ElementType.Object:
2378 WriteElementType (ElementType.Boxed);
2380 case ElementType.None:
2381 if (type.IsTypeOf ("System", "Type"))
2382 WriteElementType (ElementType.Type);
2384 WriteElementType (ElementType.Enum);
2385 WriteTypeReference (type);
2389 WriteElementType (etype);
2394 public void WriteCustomAttributeNamedArguments (CustomAttribute attribute)
2396 var count = GetNamedArgumentCount (attribute);
2398 WriteUInt16 ((ushort) count);
2403 WriteICustomAttributeNamedArguments (attribute);
2406 static int GetNamedArgumentCount (ICustomAttribute attribute)
2410 if (attribute.HasFields)
2411 count += attribute.Fields.Count;
2413 if (attribute.HasProperties)
2414 count += attribute.Properties.Count;
2419 void WriteICustomAttributeNamedArguments (ICustomAttribute attribute)
2421 if (attribute.HasFields)
2422 WriteCustomAttributeNamedArguments (0x53, attribute.Fields);
2424 if (attribute.HasProperties)
2425 WriteCustomAttributeNamedArguments (0x54, attribute.Properties);
2428 void WriteCustomAttributeNamedArguments (byte kind, Collection<CustomAttributeNamedArgument> named_arguments)
2430 for (int i = 0; i < named_arguments.Count; i++)
2431 WriteCustomAttributeNamedArgument (kind, named_arguments [i]);
2434 void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument)
2436 var argument = named_argument.Argument;
2439 WriteCustomAttributeFieldOrPropType (argument.Type);
2440 WriteUTF8String (named_argument.Name);
2441 WriteCustomAttributeFixedArgument (argument.Type, argument);
2444 void WriteSecurityAttribute (SecurityAttribute attribute)
2446 WriteTypeReference (attribute.AttributeType);
2448 var count = GetNamedArgumentCount (attribute);
2451 WriteCompressedUInt32 (0); // length
2452 WriteCompressedUInt32 (0); // count
2456 var buffer = new SignatureWriter (metadata);
2457 buffer.WriteCompressedUInt32 ((uint) count);
2458 buffer.WriteICustomAttributeNamedArguments (attribute);
2460 WriteCompressedUInt32 ((uint) buffer.length);
2461 WriteBytes (buffer);
2464 public void WriteSecurityDeclaration (SecurityDeclaration declaration)
2466 WriteByte ((byte) '.');
2468 var attributes = declaration.security_attributes;
2469 if (attributes == null)
2470 throw new NotSupportedException ();
2472 WriteCompressedUInt32 ((uint) attributes.Count);
2474 for (int i = 0; i < attributes.Count; i++)
2475 WriteSecurityAttribute (attributes [i]);
2478 public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration)
2480 var xml = GetXmlSecurityDeclaration (declaration);
2482 throw new NotSupportedException ();
2484 WriteBytes (Encoding.Unicode.GetBytes (xml));
2487 static string GetXmlSecurityDeclaration (SecurityDeclaration declaration)
2489 if (declaration.security_attributes == null || declaration.security_attributes.Count != 1)
2492 var attribute = declaration.security_attributes [0];
2494 if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute"))
2497 if (attribute.properties == null || attribute.properties.Count != 1)
2500 var property = attribute.properties [0];
2501 if (property.Name != "XML")
2504 return (string) property.Argument.Value;
2507 void WriteTypeReference (TypeReference type)
2509 WriteUTF8String (TypeParser.ToParseable (type));
2512 public void WriteMarshalInfo (MarshalInfo marshal_info)
2514 WriteNativeType (marshal_info.native);
2516 switch (marshal_info.native) {
2517 case NativeType.Array: {
2518 var array = (ArrayMarshalInfo) marshal_info;
2519 if (array.element_type != NativeType.None)
2520 WriteNativeType (array.element_type);
2521 if (array.size_parameter_index > -1)
2522 WriteCompressedUInt32 ((uint) array.size_parameter_index);
2523 if (array.size > -1)
2524 WriteCompressedUInt32 ((uint) array.size);
2525 if (array.size_parameter_multiplier > -1)
2526 WriteCompressedUInt32 ((uint) array.size_parameter_multiplier);
2529 case NativeType.SafeArray: {
2530 var array = (SafeArrayMarshalInfo) marshal_info;
2531 if (array.element_type != VariantType.None)
2532 WriteVariantType (array.element_type);
2535 case NativeType.FixedArray: {
2536 var array = (FixedArrayMarshalInfo) marshal_info;
2537 if (array.size > -1)
2538 WriteCompressedUInt32 ((uint) array.size);
2539 if (array.element_type != NativeType.None)
2540 WriteNativeType (array.element_type);
2543 case NativeType.FixedSysString:
2544 var sys_string = (FixedSysStringMarshalInfo) marshal_info;
2545 if (sys_string.size > -1)
2546 WriteCompressedUInt32 ((uint) sys_string.size);
2548 case NativeType.CustomMarshaler:
2549 var marshaler = (CustomMarshalInfo) marshal_info;
2550 WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty);
2551 WriteUTF8String (marshaler.unmanaged_type);
2552 WriteTypeReference (marshaler.managed_type);
2553 WriteUTF8String (marshaler.cookie);
2558 void WriteNativeType (NativeType native)
2560 WriteByte ((byte) native);
2563 void WriteVariantType (VariantType variant)
2565 WriteByte ((byte) variant);