~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Writer/MetadataWriter.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (C) 2008 Jeroen Frijters
 
3
 
 
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.
 
7
 
 
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:
 
11
 
 
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.
 
19
 
 
20
  Jeroen Frijters
 
21
  jeroen@frijters.net
 
22
  
 
23
*/
 
24
using System;
 
25
using System.IO;
 
26
using System.Collections.Generic;
 
27
using System.Text;
 
28
using IKVM.Reflection.Emit;
 
29
using IKVM.Reflection.Metadata;
 
30
 
 
31
namespace IKVM.Reflection.Writer
 
32
{
 
33
        sealed class MetadataWriter : MetadataRW
 
34
        {
 
35
                private readonly ModuleBuilder moduleBuilder;
 
36
                private readonly Stream stream;
 
37
                private readonly byte[] buffer = new byte[8];
 
38
 
 
39
                internal MetadataWriter(ModuleBuilder module, Stream stream)
 
40
                        : base(module, module.Strings.IsBig, module.Guids.IsBig, module.Blobs.IsBig)
 
41
                {
 
42
                        this.moduleBuilder = module;
 
43
                        this.stream = stream;
 
44
                }
 
45
 
 
46
                internal ModuleBuilder ModuleBuilder
 
47
                {
 
48
                        get { return moduleBuilder; }
 
49
                }
 
50
 
 
51
                internal int Position
 
52
                {
 
53
                        get { return (int)stream.Position; }
 
54
                }
 
55
 
 
56
                internal void Write(ByteBuffer bb)
 
57
                {
 
58
                        bb.WriteTo(stream);
 
59
                }
 
60
 
 
61
                internal void Write(byte[] value)
 
62
                {
 
63
                        stream.Write(value, 0, value.Length);
 
64
                }
 
65
 
 
66
                internal void Write(byte value)
 
67
                {
 
68
                        stream.WriteByte(value);
 
69
                }
 
70
 
 
71
                internal void Write(ushort value)
 
72
                {
 
73
                        Write((short)value);
 
74
                }
 
75
 
 
76
                internal void Write(short value)
 
77
                {
 
78
                        stream.WriteByte((byte)value);
 
79
                        stream.WriteByte((byte)(value >> 8));
 
80
                }
 
81
 
 
82
                internal void Write(uint value)
 
83
                {
 
84
                        Write((int)value);
 
85
                }
 
86
 
 
87
                internal void Write(int value)
 
88
                {
 
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);
 
94
                }
 
95
 
 
96
                internal void Write(ulong value)
 
97
                {
 
98
                        Write((long)value);
 
99
                }
 
100
 
 
101
                internal void Write(long value)
 
102
                {
 
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);
 
112
                }
 
113
 
 
114
                internal void WriteCompressedUInt(int value)
 
115
                {
 
116
                        if (value <= 0x7F)
 
117
                        {
 
118
                                Write((byte)value);
 
119
                        }
 
120
                        else if (value <= 0x3FFF)
 
121
                        {
 
122
                                Write((byte)(0x80 | (value >> 8)));
 
123
                                Write((byte)value);
 
124
                        }
 
125
                        else
 
126
                        {
 
127
                                Write((byte)(0xC0 | (value >> 24)));
 
128
                                Write((byte)(value >> 16));
 
129
                                Write((byte)(value >> 8));
 
130
                                Write((byte)value);
 
131
                        }
 
132
                }
 
133
 
 
134
                internal static int GetCompressedUIntLength(int value)
 
135
                {
 
136
                        if (value <= 0x7F)
 
137
                        {
 
138
                                return 1;
 
139
                        }
 
140
                        else if (value <= 0x3FFF)
 
141
                        {
 
142
                                return 2;
 
143
                        }
 
144
                        else
 
145
                        {
 
146
                                return 4;
 
147
                        }
 
148
                }
 
149
 
 
150
                internal void WriteStringIndex(int index)
 
151
                {
 
152
                        if (bigStrings)
 
153
                        {
 
154
                                Write(index);
 
155
                        }
 
156
                        else
 
157
                        {
 
158
                                Write((short)index);
 
159
                        }
 
160
                }
 
161
 
 
162
                internal void WriteGuidIndex(int index)
 
163
                {
 
164
                        if (bigGuids)
 
165
                        {
 
166
                                Write(index);
 
167
                        }
 
168
                        else
 
169
                        {
 
170
                                Write((short)index);
 
171
                        }
 
172
                }
 
173
 
 
174
                internal void WriteBlobIndex(int index)
 
175
                {
 
176
                        if (bigBlobs)
 
177
                        {
 
178
                                Write(index);
 
179
                        }
 
180
                        else
 
181
                        {
 
182
                                Write((short)index);
 
183
                        }
 
184
                }
 
185
 
 
186
                internal void WriteTypeDefOrRef(int token)
 
187
                {
 
188
                        switch (token >> 24)
 
189
                        {
 
190
                                case 0:
 
191
                                        break;
 
192
                                case TypeDefTable.Index:
 
193
                                        token = (token & 0xFFFFFF) << 2 | 0;
 
194
                                        break;
 
195
                                case TypeRefTable.Index:
 
196
                                        token = (token & 0xFFFFFF) << 2 | 1;
 
197
                                        break;
 
198
                                case TypeSpecTable.Index:
 
199
                                        token = (token & 0xFFFFFF) << 2 | 2;
 
200
                                        break;
 
201
                                default:
 
202
                                        throw new InvalidOperationException();
 
203
                        }
 
204
                        if (bigTypeDefOrRef)
 
205
                        {
 
206
                                Write(token);
 
207
                        }
 
208
                        else
 
209
                        {
 
210
                                Write((short)token);
 
211
                        }
 
212
                }
 
213
 
 
214
                internal void WriteEncodedTypeDefOrRef(int encodedToken)
 
215
                {
 
216
                        if (bigTypeDefOrRef)
 
217
                        {
 
218
                                Write(encodedToken);
 
219
                        }
 
220
                        else
 
221
                        {
 
222
                                Write((short)encodedToken);
 
223
                        }
 
224
                }
 
225
 
 
226
                internal void WriteHasCustomAttribute(int token)
 
227
                {
 
228
                        int encodedToken = CustomAttributeTable.EncodeHasCustomAttribute(token);
 
229
                        if (bigHasCustomAttribute)
 
230
                        {
 
231
                                Write(encodedToken);
 
232
                        }
 
233
                        else
 
234
                        {
 
235
                                Write((short)encodedToken);
 
236
                        }
 
237
                }
 
238
 
 
239
                internal void WriteCustomAttributeType(int token)
 
240
                {
 
241
                        switch (token >> 24)
 
242
                        {
 
243
                                case MethodDefTable.Index:
 
244
                                        token = (token & 0xFFFFFF) << 3 | 2;
 
245
                                        break;
 
246
                                case MemberRefTable.Index:
 
247
                                        token = (token & 0xFFFFFF) << 3 | 3;
 
248
                                        break;
 
249
                                default:
 
250
                                        throw new InvalidOperationException();
 
251
                        }
 
252
                        if (bigCustomAttributeType)
 
253
                        {
 
254
                                Write(token);
 
255
                        }
 
256
                        else
 
257
                        {
 
258
                                Write((short)token);
 
259
                        }
 
260
                }
 
261
 
 
262
                internal void WriteField(int index)
 
263
                {
 
264
                        if (bigField)
 
265
                        {
 
266
                                Write(index & 0xFFFFFF);
 
267
                        }
 
268
                        else
 
269
                        {
 
270
                                Write((short)index);
 
271
                        }
 
272
                }
 
273
 
 
274
                internal void WriteMethodDef(int index)
 
275
                {
 
276
                        if (bigMethodDef)
 
277
                        {
 
278
                                Write(index & 0xFFFFFF);
 
279
                        }
 
280
                        else
 
281
                        {
 
282
                                Write((short)index);
 
283
                        }
 
284
                }
 
285
 
 
286
                internal void WriteParam(int index)
 
287
                {
 
288
                        if (bigParam)
 
289
                        {
 
290
                                Write(index & 0xFFFFFF);
 
291
                        }
 
292
                        else
 
293
                        {
 
294
                                Write((short)index);
 
295
                        }
 
296
                }
 
297
 
 
298
                internal void WriteTypeDef(int index)
 
299
                {
 
300
                        if (bigTypeDef)
 
301
                        {
 
302
                                Write(index & 0xFFFFFF);
 
303
                        }
 
304
                        else
 
305
                        {
 
306
                                Write((short)index);
 
307
                        }
 
308
                }
 
309
 
 
310
                internal void WriteEvent(int index)
 
311
                {
 
312
                        if (bigEvent)
 
313
                        {
 
314
                                Write(index & 0xFFFFFF);
 
315
                        }
 
316
                        else
 
317
                        {
 
318
                                Write((short)index);
 
319
                        }
 
320
                }
 
321
 
 
322
                internal void WriteProperty(int index)
 
323
                {
 
324
                        if (bigProperty)
 
325
                        {
 
326
                                Write(index & 0xFFFFFF);
 
327
                        }
 
328
                        else
 
329
                        {
 
330
                                Write((short)index);
 
331
                        }
 
332
                }
 
333
 
 
334
                internal void WriteGenericParam(int index)
 
335
                {
 
336
                        if (bigGenericParam)
 
337
                        {
 
338
                                Write(index & 0xFFFFFF);
 
339
                        }
 
340
                        else
 
341
                        {
 
342
                                Write((short)index);
 
343
                        }
 
344
                }
 
345
 
 
346
                internal void WriteModuleRef(int index)
 
347
                {
 
348
                        if (bigModuleRef)
 
349
                        {
 
350
                                Write(index & 0xFFFFFF);
 
351
                        }
 
352
                        else
 
353
                        {
 
354
                                Write((short)index);
 
355
                        }
 
356
                }
 
357
 
 
358
                internal void WriteResolutionScope(int token)
 
359
                {
 
360
                        switch (token >> 24)
 
361
                        {
 
362
                                case ModuleTable.Index:
 
363
                                        token = (token & 0xFFFFFF) << 2 | 0;
 
364
                                        break;
 
365
                                case ModuleRefTable.Index:
 
366
                                        token = (token & 0xFFFFFF) << 2 | 1;
 
367
                                        break;
 
368
                                case AssemblyRefTable.Index:
 
369
                                        token = (token & 0xFFFFFF) << 2 | 2;
 
370
                                        break;
 
371
                                case TypeRefTable.Index:
 
372
                                        token = (token & 0xFFFFFF) << 2 | 3;
 
373
                                        break;
 
374
                                default:
 
375
                                        throw new InvalidOperationException();
 
376
                        }
 
377
                        if (bigResolutionScope)
 
378
                        {
 
379
                                Write(token);
 
380
                        }
 
381
                        else
 
382
                        {
 
383
                                Write((short)token);
 
384
                        }
 
385
                }
 
386
 
 
387
                internal void WriteMemberRefParent(int token)
 
388
                {
 
389
                        switch (token >> 24)
 
390
                        {
 
391
                                case TypeDefTable.Index:
 
392
                                        token = (token & 0xFFFFFF) << 3 | 0;
 
393
                                        break;
 
394
                                case TypeRefTable.Index:
 
395
                                        token = (token & 0xFFFFFF) << 3 | 1;
 
396
                                        break;
 
397
                                case ModuleRefTable.Index:
 
398
                                        token = (token & 0xFFFFFF) << 3 | 2;
 
399
                                        break;
 
400
                                case MethodDefTable.Index:
 
401
                                        token = (token & 0xFFFFFF) << 3 | 3;
 
402
                                        break;
 
403
                                case TypeSpecTable.Index:
 
404
                                        token = (token & 0xFFFFFF) << 3 | 4;
 
405
                                        break;
 
406
                                default:
 
407
                                        throw new InvalidOperationException();
 
408
                        }
 
409
                        if (bigMemberRefParent)
 
410
                        {
 
411
                                Write(token);
 
412
                        }
 
413
                        else
 
414
                        {
 
415
                                Write((short)token);
 
416
                        }
 
417
                }
 
418
 
 
419
                internal void WriteMethodDefOrRef(int token)
 
420
                {
 
421
                        switch (token >> 24)
 
422
                        {
 
423
                                case MethodDefTable.Index:
 
424
                                        token = (token & 0xFFFFFF) << 1 | 0;
 
425
                                        break;
 
426
                                case MemberRefTable.Index:
 
427
                                        token = (token & 0xFFFFFF) << 1 | 1;
 
428
                                        break;
 
429
                                default:
 
430
                                        throw new InvalidOperationException();
 
431
                        }
 
432
                        if (bigMethodDefOrRef)
 
433
                        {
 
434
                                Write(token);
 
435
                        }
 
436
                        else
 
437
                        {
 
438
                                Write((short)token);
 
439
                        }
 
440
                }
 
441
 
 
442
                internal void WriteHasConstant(int token)
 
443
                {
 
444
                        int encodedToken = ConstantTable.EncodeHasConstant(token);
 
445
                        if (bigHasConstant)
 
446
                        {
 
447
                                Write(encodedToken);
 
448
                        }
 
449
                        else
 
450
                        {
 
451
                                Write((short)encodedToken);
 
452
                        }
 
453
                }
 
454
 
 
455
                internal void WriteHasSemantics(int encodedToken)
 
456
                {
 
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
 
459
                        if (bigHasSemantics)
 
460
                        {
 
461
                                Write(encodedToken);
 
462
                        }
 
463
                        else
 
464
                        {
 
465
                                Write((short)encodedToken);
 
466
                        }
 
467
                }
 
468
 
 
469
                internal void WriteImplementation(int token)
 
470
                {
 
471
                        switch (token >> 24)
 
472
                        {
 
473
                                case 0:
 
474
                                        break;
 
475
                                case FileTable.Index:
 
476
                                        token = (token & 0xFFFFFF) << 2 | 0;
 
477
                                        break;
 
478
                                case AssemblyRefTable.Index:
 
479
                                        token = (token & 0xFFFFFF) << 2 | 1;
 
480
                                        break;
 
481
                                case ExportedTypeTable.Index:
 
482
                                        token = (token & 0xFFFFFF) << 2 | 2;
 
483
                                        break;
 
484
                                default:
 
485
                                        throw new InvalidOperationException();
 
486
                        }
 
487
                        if (bigImplementation)
 
488
                        {
 
489
                                Write(token);
 
490
                        }
 
491
                        else
 
492
                        {
 
493
                                Write((short)token);
 
494
                        }
 
495
                }
 
496
 
 
497
                internal void WriteTypeOrMethodDef(int encodedToken)
 
498
                {
 
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)
 
502
                        {
 
503
                                Write(encodedToken);
 
504
                        }
 
505
                        else
 
506
                        {
 
507
                                Write((short)encodedToken);
 
508
                        }
 
509
                }
 
510
 
 
511
                internal void WriteHasDeclSecurity(int encodedToken)
 
512
                {
 
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)
 
516
                        {
 
517
                                Write(encodedToken);
 
518
                        }
 
519
                        else
 
520
                        {
 
521
                                Write((short)encodedToken);
 
522
                        }
 
523
                }
 
524
 
 
525
                internal void WriteMemberForwarded(int token)
 
526
                {
 
527
                        switch (token >> 24)
 
528
                        {
 
529
                                case FieldTable.Index:
 
530
                                        token = (token & 0xFFFFFF) << 1 | 0;
 
531
                                    break;
 
532
                                case MethodDefTable.Index:
 
533
                                        token = (token & 0xFFFFFF) << 1 | 1;
 
534
                                        break;
 
535
                                default:
 
536
                                        throw new InvalidOperationException();
 
537
                        }
 
538
                        if (bigMemberForwarded)
 
539
                        {
 
540
                                Write(token);
 
541
                        }
 
542
                        else
 
543
                        {
 
544
                                Write((short)token);
 
545
                        }
 
546
                }
 
547
 
 
548
                internal void WriteHasFieldMarshal(int token)
 
549
                {
 
550
                        int encodedToken = FieldMarshalTable.EncodeHasFieldMarshal(token);
 
551
                        if (bigHasFieldMarshal)
 
552
                        {
 
553
                                Write(encodedToken);
 
554
                        }
 
555
                        else
 
556
                        {
 
557
                                Write((short)encodedToken);
 
558
                        }
 
559
                }
 
560
        }
 
561
}