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 WriteCompressedUInt(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 GetCompressedUIntLength(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);