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 stream.WriteByte((byte)value);
79 stream.WriteByte((byte)(value >> 8));
82 internal void Write(uint value)
87 internal void Write(int value)
89 buffer[0] = (byte)value;
90 buffer[1] = (byte)(value >> 8);
91 buffer[2] = (byte)(value >> 16);
92 buffer[3] = (byte)(value >> 24);
93 stream.Write(buffer, 0, 4);
96 internal void Write(ulong value)
101 internal void Write(long value)
103 buffer[0] = (byte)value;
104 buffer[1] = (byte)(value >> 8);
105 buffer[2] = (byte)(value >> 16);
106 buffer[3] = (byte)(value >> 24);
107 buffer[4] = (byte)(value >> 32);
108 buffer[5] = (byte)(value >> 40);
109 buffer[6] = (byte)(value >> 48);
110 buffer[7] = (byte)(value >> 56);
111 stream.Write(buffer, 0, 8);
114 internal void WriteCompressedInt(int value)
120 else if (value <= 0x3FFF)
122 Write((byte)(0x80 | (value >> 8)));
127 Write((byte)(0xC0 | (value >> 24)));
128 Write((byte)(value >> 16));
129 Write((byte)(value >> 8));
134 internal static int GetCompressedIntLength(int value)
140 else if (value <= 0x3FFF)
150 internal void WriteStringIndex(int index)
162 internal void WriteGuidIndex(int index)
174 internal void WriteBlobIndex(int index)
186 internal void WriteTypeDefOrRef(int token)
192 case TypeDefTable.Index:
193 token = (token & 0xFFFFFF) << 2 | 0;
195 case TypeRefTable.Index:
196 token = (token & 0xFFFFFF) << 2 | 1;
198 case TypeSpecTable.Index:
199 token = (token & 0xFFFFFF) << 2 | 2;
202 throw new InvalidOperationException();
214 internal void WriteEncodedTypeDefOrRef(int encodedToken)
222 Write((short)encodedToken);
226 internal void WriteHasCustomAttribute(int token)
228 int encodedToken = CustomAttributeTable.EncodeHasCustomAttribute(token);
229 if (bigHasCustomAttribute)
235 Write((short)encodedToken);
239 internal void WriteCustomAttributeType(int token)
243 case MethodDefTable.Index:
244 token = (token & 0xFFFFFF) << 3 | 2;
246 case MemberRefTable.Index:
247 token = (token & 0xFFFFFF) << 3 | 3;
250 throw new InvalidOperationException();
252 if (bigCustomAttributeType)
262 internal void WriteField(int index)
266 Write(index & 0xFFFFFF);
274 internal void WriteMethodDef(int index)
278 Write(index & 0xFFFFFF);
286 internal void WriteParam(int index)
290 Write(index & 0xFFFFFF);
298 internal void WriteTypeDef(int index)
302 Write(index & 0xFFFFFF);
310 internal void WriteEvent(int index)
314 Write(index & 0xFFFFFF);
322 internal void WriteProperty(int index)
326 Write(index & 0xFFFFFF);
334 internal void WriteGenericParam(int index)
338 Write(index & 0xFFFFFF);
346 internal void WriteModuleRef(int index)
350 Write(index & 0xFFFFFF);
358 internal void WriteResolutionScope(int token)
362 case ModuleTable.Index:
363 token = (token & 0xFFFFFF) << 2 | 0;
365 case ModuleRefTable.Index:
366 token = (token & 0xFFFFFF) << 2 | 1;
368 case AssemblyRefTable.Index:
369 token = (token & 0xFFFFFF) << 2 | 2;
371 case TypeRefTable.Index:
372 token = (token & 0xFFFFFF) << 2 | 3;
375 throw new InvalidOperationException();
377 if (bigResolutionScope)
387 internal void WriteMemberRefParent(int token)
391 case TypeDefTable.Index:
392 token = (token & 0xFFFFFF) << 3 | 0;
394 case TypeRefTable.Index:
395 token = (token & 0xFFFFFF) << 3 | 1;
397 case ModuleRefTable.Index:
398 token = (token & 0xFFFFFF) << 3 | 2;
400 case MethodDefTable.Index:
401 token = (token & 0xFFFFFF) << 3 | 3;
403 case TypeSpecTable.Index:
404 token = (token & 0xFFFFFF) << 3 | 4;
407 throw new InvalidOperationException();
409 if (bigMemberRefParent)
419 internal void WriteMethodDefOrRef(int token)
423 case MethodDefTable.Index:
424 token = (token & 0xFFFFFF) << 1 | 0;
426 case MemberRefTable.Index:
427 token = (token & 0xFFFFFF) << 1 | 1;
430 throw new InvalidOperationException();
432 if (bigMethodDefOrRef)
442 internal void WriteHasConstant(int token)
444 int encodedToken = ConstantTable.EncodeHasConstant(token);
451 Write((short)encodedToken);
455 internal void WriteHasSemantics(int encodedToken)
457 // NOTE because we've already had to do the encoding (to be able to sort the table)
458 // here we simple write the value
465 Write((short)encodedToken);
469 internal void WriteImplementation(int token)
475 case FileTable.Index:
476 token = (token & 0xFFFFFF) << 2 | 0;
478 case AssemblyRefTable.Index:
479 token = (token & 0xFFFFFF) << 2 | 1;
481 case ExportedTypeTable.Index:
482 token = (token & 0xFFFFFF) << 2 | 2;
485 throw new InvalidOperationException();
487 if (bigImplementation)
497 internal void WriteTypeOrMethodDef(int encodedToken)
499 // NOTE because we've already had to do the encoding (to be able to sort the table)
500 // here we simple write the value
501 if (bigTypeOrMethodDef)
507 Write((short)encodedToken);
511 internal void WriteHasDeclSecurity(int encodedToken)
513 // NOTE because we've already had to do the encoding (to be able to sort the table)
514 // here we simple write the value
515 if (bigHasDeclSecurity)
521 Write((short)encodedToken);
525 internal void WriteMemberForwarded(int token)
529 case FieldTable.Index:
530 token = (token & 0xFFFFFF) << 1 | 0;
532 case MethodDefTable.Index:
533 token = (token & 0xFFFFFF) << 1 | 1;
536 throw new InvalidOperationException();
538 if (bigMemberForwarded)
548 internal void WriteHasFieldMarshal(int token)
550 int encodedToken = FieldMarshalTable.EncodeHasFieldMarshal(token);
551 if (bigHasFieldMarshal)
557 Write((short)encodedToken);