2 Copyright (C) 2008 Jeroen Frijters
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
26 using System.Collections.Generic;
28 using IKVM.Reflection.Emit;
29 using IKVM.Reflection.Metadata;
31 namespace IKVM.Reflection.Writer
33 sealed class MetadataWriter : MetadataRW
35 private readonly ModuleBuilder moduleBuilder;
36 private readonly Stream stream;
37 private readonly byte[] buffer = new byte[8];
39 internal MetadataWriter(ModuleBuilder module, Stream stream)
40 : base(module, module.Strings.IsBig, module.Guids.IsBig, module.Blobs.IsBig)
42 this.moduleBuilder = module;
46 internal ModuleBuilder ModuleBuilder
48 get { return moduleBuilder; }
53 get { return (int)stream.Position; }
56 internal void Write(ByteBuffer bb)
61 internal void Write(byte[] value)
63 stream.Write(value, 0, value.Length);
66 internal void Write(byte value)
68 stream.WriteByte(value);
71 internal void Write(ushort value)
76 internal void Write(short value)
78 buffer[0] = (byte)value;
79 buffer[1] = (byte)(value >> 8);
80 stream.Write(buffer, 0, 2);
83 internal void Write(uint value)
88 internal void Write(int value)
90 buffer[0] = (byte)value;
91 buffer[1] = (byte)(value >> 8);
92 buffer[2] = (byte)(value >> 16);
93 buffer[3] = (byte)(value >> 24);
94 stream.Write(buffer, 0, 4);
97 internal void Write(ulong value)
102 internal void Write(long value)
104 buffer[0] = (byte)value;
105 buffer[1] = (byte)(value >> 8);
106 buffer[2] = (byte)(value >> 16);
107 buffer[3] = (byte)(value >> 24);
108 buffer[4] = (byte)(value >> 32);
109 buffer[5] = (byte)(value >> 40);
110 buffer[6] = (byte)(value >> 48);
111 buffer[7] = (byte)(value >> 56);
112 stream.Write(buffer, 0, 8);
115 internal void WriteCompressedInt(int value)
121 else if (value <= 0x3FFF)
123 Write((byte)(0x80 | (value >> 8)));
128 Write((byte)(0xC0 | (value >> 24)));
129 Write((byte)(value >> 16));
130 Write((byte)(value >> 8));
135 internal static int GetCompressedIntLength(int value)
141 else if (value <= 0x3FFF)
151 internal void WriteStringIndex(int index)
163 internal void WriteGuidIndex(int index)
175 internal void WriteBlobIndex(int index)
187 internal void WriteTypeDefOrRef(int token)
193 case TypeDefTable.Index:
194 token = (token & 0xFFFFFF) << 2 | 0;
196 case TypeRefTable.Index:
197 token = (token & 0xFFFFFF) << 2 | 1;
199 case TypeSpecTable.Index:
200 token = (token & 0xFFFFFF) << 2 | 2;
203 throw new InvalidOperationException();
215 internal void WriteEncodedTypeDefOrRef(int encodedToken)
223 Write((short)encodedToken);
227 internal void WriteHasCustomAttribute(int encodedToken)
229 // NOTE because we've already had to do the encoding (to be able to sort the table)
230 // here we simple write the value
231 if (bigHasCustomAttribute)
237 Write((short)encodedToken);
241 internal void WriteCustomAttributeType(int token)
245 case MethodDefTable.Index:
246 token = (token & 0xFFFFFF) << 3 | 2;
248 case MemberRefTable.Index:
249 token = (token & 0xFFFFFF) << 3 | 3;
252 throw new InvalidOperationException();
254 if (bigCustomAttributeType)
264 internal void WriteField(int index)
268 Write(index & 0xFFFFFF);
276 internal void WriteMethodDef(int index)
280 Write(index & 0xFFFFFF);
288 internal void WriteParam(int index)
292 Write(index & 0xFFFFFF);
300 internal void WriteTypeDef(int index)
304 Write(index & 0xFFFFFF);
312 internal void WriteEvent(int index)
316 Write(index & 0xFFFFFF);
324 internal void WriteProperty(int index)
328 Write(index & 0xFFFFFF);
336 internal void WriteGenericParam(int index)
340 Write(index & 0xFFFFFF);
348 internal void WriteModuleRef(int index)
352 Write(index & 0xFFFFFF);
360 internal void WriteResolutionScope(int token)
364 case ModuleTable.Index:
365 token = (token & 0xFFFFFF) << 2 | 0;
367 case ModuleRefTable.Index:
368 token = (token & 0xFFFFFF) << 2 | 1;
370 case AssemblyRefTable.Index:
371 token = (token & 0xFFFFFF) << 2 | 2;
373 case TypeRefTable.Index:
374 token = (token & 0xFFFFFF) << 2 | 3;
377 throw new InvalidOperationException();
379 if (bigResolutionScope)
389 internal void WriteMemberRefParent(int token)
393 case TypeDefTable.Index:
394 token = (token & 0xFFFFFF) << 3 | 0;
396 case TypeRefTable.Index:
397 token = (token & 0xFFFFFF) << 3 | 1;
399 case ModuleRefTable.Index:
400 token = (token & 0xFFFFFF) << 3 | 2;
402 case MethodDefTable.Index:
403 token = (token & 0xFFFFFF) << 3 | 3;
405 case TypeSpecTable.Index:
406 token = (token & 0xFFFFFF) << 3 | 4;
409 throw new InvalidOperationException();
411 if (bigMemberRefParent)
421 internal void WriteMethodDefOrRef(int token)
425 case MethodDefTable.Index:
426 token = (token & 0xFFFFFF) << 1 | 0;
428 case MemberRefTable.Index:
429 token = (token & 0xFFFFFF) << 1 | 1;
432 throw new InvalidOperationException();
434 if (bigMethodDefOrRef)
444 internal void WriteHasConstant(int encodedToken)
446 // NOTE because we've already had to do the encoding (to be able to sort the table)
447 // here we simple write the value
454 Write((short)encodedToken);
458 internal void WriteHasSemantics(int encodedToken)
460 // NOTE because we've already had to do the encoding (to be able to sort the table)
461 // here we simple write the value
468 Write((short)encodedToken);
472 internal void WriteImplementation(int token)
478 case FileTable.Index:
479 token = (token & 0xFFFFFF) << 2 | 0;
481 case AssemblyRefTable.Index:
482 token = (token & 0xFFFFFF) << 2 | 1;
484 case ExportedTypeTable.Index:
485 token = (token & 0xFFFFFF) << 2 | 2;
488 throw new InvalidOperationException();
490 if (bigImplementation)
500 internal void WriteTypeOrMethodDef(int encodedToken)
502 // NOTE because we've already had to do the encoding (to be able to sort the table)
503 // here we simple write the value
504 if (bigTypeOrMethodDef)
510 Write((short)encodedToken);
514 internal void WriteHasDeclSecurity(int encodedToken)
516 // NOTE because we've already had to do the encoding (to be able to sort the table)
517 // here we simple write the value
518 if (bigHasDeclSecurity)
524 Write((short)encodedToken);
528 internal void WriteMemberForwarded(int token)
532 case FieldTable.Index:
533 token = (token & 0xFFFFFF) << 1 | 0;
535 case MethodDefTable.Index:
536 token = (token & 0xFFFFFF) << 1 | 1;
539 throw new InvalidOperationException();
541 if (bigMemberForwarded)
551 internal void WriteHasFieldMarshal(int encodedToken)
553 // NOTE because we've already had to do the encoding (to be able to sort the table)
554 // here we simple write the value
555 if (bigHasFieldMarshal)
557 Write(encodedToken & 0xFFFFFF);
561 Write((short)encodedToken);