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

« back to all changes in this revision

Viewing changes to external/mono-addins/Mono.Addins.CecilReflector/Mono.Cecil/Mono.Cecil.Metadata/Buffers.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
// TableHeapBuffer.cs
 
3
//
 
4
// Author:
 
5
//   Jb Evain (jbevain@gmail.com)
 
6
//
 
7
// Copyright (c) 2008 - 2010 Jb Evain
 
8
//
 
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:
 
16
//
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
//
 
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.
 
27
//
 
28
 
 
29
using System;
 
30
using System.Collections.Generic;
 
31
using System.Text;
 
32
 
 
33
using Mono.Cecil.PE;
 
34
 
 
35
using RVA = System.UInt32;
 
36
 
 
37
#if !READ_ONLY
 
38
 
 
39
namespace Mono.Cecil.Metadata {
 
40
 
 
41
        sealed class TableHeapBuffer : HeapBuffer {
 
42
 
 
43
                readonly ModuleDefinition module;
 
44
                readonly MetadataBuilder metadata;
 
45
 
 
46
                internal MetadataTable [] tables = new MetadataTable [45];
 
47
 
 
48
                bool large_string;
 
49
                bool large_blob;
 
50
                readonly int [] coded_index_sizes = new int [13];
 
51
                readonly Func<Table, int> counter;
 
52
 
 
53
                public override bool IsEmpty {
 
54
                        get { return false; }
 
55
                }
 
56
 
 
57
                public TableHeapBuffer (ModuleDefinition module, MetadataBuilder metadata)
 
58
                        : base (24)
 
59
                {
 
60
                        this.module = module;
 
61
                        this.metadata = metadata;
 
62
                        this.counter = GetTableLength;
 
63
                }
 
64
 
 
65
                int GetTableLength (Table table)
 
66
                {
 
67
                        var md_table = tables [(int) table];
 
68
                        return md_table != null ? md_table.Length : 0;
 
69
                }
 
70
 
 
71
                public TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new ()
 
72
                {
 
73
                        var md_table = (TTable) tables [(int) table];
 
74
                        if (md_table != null)
 
75
                                return md_table;
 
76
 
 
77
                        md_table = new TTable ();
 
78
                        tables [(int) table] = md_table;
 
79
                        return md_table;
 
80
                }
 
81
 
 
82
                public void WriteBySize (uint value, int size)
 
83
                {
 
84
                        if (size == 4)
 
85
                                WriteUInt32 (value);
 
86
                        else
 
87
                                WriteUInt16 ((ushort) value);
 
88
                }
 
89
 
 
90
                public void WriteBySize (uint value, bool large)
 
91
                {
 
92
                        if (large)
 
93
                                WriteUInt32 (value);
 
94
                        else
 
95
                                WriteUInt16 ((ushort) value);
 
96
                }
 
97
 
 
98
                public void WriteString (uint @string)
 
99
                {
 
100
                        WriteBySize (@string, large_string);
 
101
                }
 
102
 
 
103
                public void WriteBlob (uint blob)
 
104
                {
 
105
                        WriteBySize (blob, large_blob);
 
106
                }
 
107
 
 
108
                public void WriteRID (uint rid, Table table)
 
109
                {
 
110
                        var md_table = tables [(int) table];
 
111
                        WriteBySize (rid, md_table == null ? false : md_table.IsLarge);
 
112
                }
 
113
 
 
114
                int GetCodedIndexSize (CodedIndex coded_index)
 
115
                {
 
116
                        var index = (int) coded_index;
 
117
                        var size = coded_index_sizes [index];
 
118
                        if (size != 0)
 
119
                                return size;
 
120
 
 
121
                        return coded_index_sizes [index] = coded_index.GetSize (counter);
 
122
                }
 
123
 
 
124
                public void WriteCodedRID (uint rid, CodedIndex coded_index)
 
125
                {
 
126
                        WriteBySize (rid, GetCodedIndexSize (coded_index));
 
127
                }
 
128
 
 
129
                public void WriteTableHeap ()
 
130
                {
 
131
                        WriteUInt32 (0);                                        // Reserved
 
132
                        WriteByte (GetTableHeapVersion ());     // MajorVersion
 
133
                        WriteByte (0);                                          // MinorVersion
 
134
                        WriteByte (GetHeapSizes ());            // HeapSizes
 
135
                        WriteByte (10);                                         // Reserved2
 
136
                        WriteUInt64 (GetValid ());                      // Valid
 
137
                        WriteUInt64 (0x0016003301fa00);         // Sorted
 
138
 
 
139
                        WriteRowCount ();
 
140
                        WriteTables ();
 
141
                }
 
142
 
 
143
                void WriteRowCount ()
 
144
                {
 
145
                        for (int i = 0; i < tables.Length; i++) {
 
146
                                var table = tables [i];
 
147
                                if (table == null || table.Length == 0)
 
148
                                        continue;
 
149
 
 
150
                                WriteUInt32 ((uint) table.Length);
 
151
                        }
 
152
                }
 
153
 
 
154
                void WriteTables ()
 
155
                {
 
156
                        for (int i = 0; i < tables.Length; i++) {
 
157
                                var table = tables [i];
 
158
                                if (table == null || table.Length == 0)
 
159
                                        continue;
 
160
 
 
161
                                table.Write (this);
 
162
                        }
 
163
                }
 
164
 
 
165
                ulong GetValid ()
 
166
                {
 
167
                        ulong valid = 0;
 
168
 
 
169
                        for (int i = 0; i < tables.Length; i++) {
 
170
                                var table = tables [i];
 
171
                                if (table == null || table.Length == 0)
 
172
                                        continue;
 
173
 
 
174
                                table.Sort ();
 
175
                                valid |= (1UL << i);
 
176
                        }
 
177
 
 
178
                        return valid;
 
179
                }
 
180
 
 
181
                byte GetHeapSizes ()
 
182
                {
 
183
                        byte heap_sizes = 0;
 
184
 
 
185
                        if (metadata.string_heap.IsLarge) {
 
186
                                large_string = true;
 
187
                                heap_sizes |= 0x01;
 
188
                        }
 
189
 
 
190
                        if (metadata.blob_heap.IsLarge) {
 
191
                                large_blob = true;
 
192
                                heap_sizes |= 0x04;
 
193
                        }
 
194
 
 
195
                        return heap_sizes;
 
196
                }
 
197
 
 
198
                byte GetTableHeapVersion ()
 
199
                {
 
200
                        switch (module.Runtime) {
 
201
                        case TargetRuntime.Net_1_0:
 
202
                        case TargetRuntime.Net_1_1:
 
203
                                return 1;
 
204
                        default:
 
205
                                return 2;
 
206
                        }
 
207
                }
 
208
 
 
209
                public void FixupData (RVA data_rva)
 
210
                {
 
211
                        var table = GetTable<FieldRVATable> (Table.FieldRVA);
 
212
                        if (table.length == 0)
 
213
                                return;
 
214
 
 
215
                        var field_idx_size = GetTable<FieldTable> (Table.Field).IsLarge ? 4 : 2;
 
216
                        var previous = this.position;
 
217
 
 
218
                        base.position = table.position;
 
219
                        for (int i = 0; i < table.length; i++) {
 
220
                                var rva = ReadUInt32 ();
 
221
                                base.position -= 4;
 
222
                                WriteUInt32 (rva + data_rva);
 
223
                                base.position += field_idx_size;
 
224
                        }
 
225
 
 
226
                        base.position = previous;
 
227
                }
 
228
        }
 
229
 
 
230
        sealed class ResourceBuffer : ByteBuffer {
 
231
 
 
232
                public ResourceBuffer ()
 
233
                        : base (0)
 
234
                {
 
235
                }
 
236
 
 
237
                public uint AddResource (byte [] resource)
 
238
                {
 
239
                        var offset = (uint) this.position;
 
240
                        WriteInt32 (resource.Length);
 
241
                        WriteBytes (resource);
 
242
                        return offset;
 
243
                }
 
244
        }
 
245
 
 
246
        sealed class DataBuffer : ByteBuffer {
 
247
 
 
248
                public DataBuffer ()
 
249
                        : base (0)
 
250
                {
 
251
                }
 
252
 
 
253
                public RVA AddData (byte [] data)
 
254
                {
 
255
                        var rva = (RVA) position;
 
256
                        WriteBytes (data);
 
257
                        return rva;
 
258
                }
 
259
        }
 
260
 
 
261
        abstract class HeapBuffer : ByteBuffer {
 
262
 
 
263
                public bool IsLarge {
 
264
                        get { return base.length > 65536; }
 
265
                }
 
266
 
 
267
                public abstract bool IsEmpty { get; }
 
268
 
 
269
                protected HeapBuffer (int length)
 
270
                        : base (length)
 
271
                {
 
272
                }
 
273
        }
 
274
 
 
275
        class StringHeapBuffer : HeapBuffer {
 
276
 
 
277
                readonly Dictionary<string, uint> strings = new Dictionary<string, uint> ();
 
278
 
 
279
                public sealed override bool IsEmpty {
 
280
                        get { return length <= 1; }
 
281
                }
 
282
 
 
283
                public StringHeapBuffer ()
 
284
                        : base (1)
 
285
                {
 
286
                        WriteByte (0);
 
287
                }
 
288
 
 
289
                public uint GetStringIndex (string @string)
 
290
                {
 
291
                        uint index;
 
292
                        if (strings.TryGetValue (@string, out index))
 
293
                                return index;
 
294
 
 
295
                        index = (uint) base.position;
 
296
                        WriteString (@string);
 
297
                        strings.Add (@string, index);
 
298
                        return index;
 
299
                }
 
300
 
 
301
                protected virtual void WriteString (string @string)
 
302
                {
 
303
                        WriteBytes (Encoding.UTF8.GetBytes (@string));
 
304
                        WriteByte (0);
 
305
                }
 
306
        }
 
307
 
 
308
        sealed class BlobHeapBuffer : HeapBuffer {
 
309
 
 
310
                readonly Dictionary<ByteBuffer, uint> blobs = new Dictionary<ByteBuffer, uint> (new ByteBufferEqualityComparer ());
 
311
 
 
312
                public override bool IsEmpty {
 
313
                        get { return length <= 1; }
 
314
                }
 
315
 
 
316
                public BlobHeapBuffer ()
 
317
                        : base (1)
 
318
                {
 
319
                        WriteByte (0);
 
320
                }
 
321
 
 
322
                public uint GetBlobIndex (ByteBuffer blob)
 
323
                {
 
324
                        uint index;
 
325
                        if (blobs.TryGetValue (blob, out index))
 
326
                                return index;
 
327
 
 
328
                        index = (uint) base.position;
 
329
                        WriteBlob (blob);
 
330
                        blobs.Add (blob, index);
 
331
                        return index;
 
332
                }
 
333
 
 
334
                void WriteBlob (ByteBuffer blob)
 
335
                {
 
336
                        WriteCompressedUInt32 ((uint) blob.length);
 
337
                        WriteBytes (blob);
 
338
                }
 
339
        }
 
340
 
 
341
        sealed class UserStringHeapBuffer : StringHeapBuffer {
 
342
 
 
343
                protected override void WriteString (string @string)
 
344
                {
 
345
                        WriteCompressedUInt32 ((uint) @string.Length * 2 + 1);
 
346
 
 
347
                        byte special = 0;
 
348
 
 
349
                        for (int i = 0; i < @string.Length; i++) {
 
350
                                var @char = @string [i];
 
351
                                WriteUInt16 (@char);
 
352
 
 
353
                                if (special == 1)
 
354
                                        continue;
 
355
 
 
356
                                if (@char < 0x20 || @char > 0x7e) {
 
357
                                        if (@char > 0x7e
 
358
                                                || (@char >= 0x01 && @char <= 0x08)
 
359
                                                || (@char >= 0x0e && @char <= 0x1f)
 
360
                                                || @char == 0x27
 
361
                                                || @char == 0x2d) {
 
362
 
 
363
                                                special = 1;
 
364
                                        }
 
365
                                }
 
366
                        }
 
367
 
 
368
                        WriteByte (special);
 
369
                }
 
370
        }
 
371
}
 
372
 
 
373
#endif