Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2893_BNLR/HeuristicLab.ExtLibs/HeuristicLab.Cecil/0.9.5/Mono.Cecil-0.9.5/Symbols/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbWriter.cs

Last change on this file was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 3.5 KB
Line 
1//-----------------------------------------------------------------------------
2//
3// Copyright (C) Microsoft Corporation.  All Rights Reserved.
4//
5//-----------------------------------------------------------------------------
6using System;
7using System.IO;
8
9namespace Microsoft.Cci.Pdb {
10  internal class PdbWriter {
11    internal PdbWriter(Stream writer, int pageSize) {
12      this.pageSize = pageSize;
13      this.usedBytes = pageSize * 3;
14      this.writer = writer;
15
16      writer.SetLength(usedBytes);
17    }
18
19    internal void WriteMeta(DataStream[] streams, BitAccess bits) {
20      PdbFileHeader head = new PdbFileHeader(pageSize);
21
22      WriteDirectory(streams,
23                     out head.directoryRoot,
24                     out head.directorySize,
25                     bits);
26      WriteFreeMap();
27
28      head.freePageMap = 2;
29      head.pagesUsed = usedBytes / pageSize;
30
31      writer.Seek(0, SeekOrigin.Begin);
32      head.Write(writer, bits);
33    }
34
35    private void WriteDirectory(DataStream[] streams,
36                                out int directoryRoot,
37                                out int directorySize,
38                                BitAccess bits) {
39      DataStream directory = new DataStream();
40
41      int pages = 0;
42      for (int s = 0; s < streams.Length; s++) {
43        if (streams[s].Length > 0) {
44          pages += streams[s].Pages;
45        }
46      }
47
48      int use = 4 * (1 + streams.Length + pages);
49      bits.MinCapacity(use);
50      bits.WriteInt32(streams.Length);
51      for (int s = 0; s < streams.Length; s++) {
52        bits.WriteInt32(streams[s].Length);
53      }
54      for (int s = 0; s < streams.Length; s++) {
55        if (streams[s].Length > 0) {
56          bits.WriteInt32(streams[s].pages);
57        }
58      }
59      directory.Write(this, bits.Buffer, use);
60      directorySize = directory.Length;
61
62      use = 4 * directory.Pages;
63      bits.MinCapacity(use);
64      bits.WriteInt32(directory.pages);
65
66      DataStream ddir = new DataStream();
67      ddir.Write(this, bits.Buffer, use);
68
69      directoryRoot = ddir.pages[0];
70    }
71
72    private void WriteFreeMap() {
73      byte[] buffer = new byte[pageSize];
74
75      // We configure the old free map with only the first 3 pages allocated.
76      buffer[0] = 0xf8;
77      for (int i = 1; i < pageSize; i++) {
78        buffer[i] = 0xff;
79      }
80      Seek(1, 0);
81      Write(buffer, 0, pageSize);
82
83      // We configure the new free map with all of the used pages gone.
84      int count = usedBytes / pageSize;
85      int full = count / 8;
86      for (int i = 0; i < full; i++) {
87        buffer[i] = 0;
88      }
89      int rema = count % 8;
90      buffer[full] = (byte)(0xff << rema);
91
92      Seek(2, 0);
93      Write(buffer, 0, pageSize);
94    }
95
96    internal int AllocatePages(int count) {
97      int begin = usedBytes;
98
99      usedBytes += count * pageSize;
100      writer.SetLength(usedBytes);
101
102      if (usedBytes > pageSize * pageSize * 8) {
103        throw new Exception("PdbWriter does not support multiple free maps.");
104      }
105      return begin / pageSize;
106    }
107
108    internal void Seek(int page, int offset) {
109      writer.Seek(page * pageSize + offset, SeekOrigin.Begin);
110    }
111
112    internal void Write(byte[] bytes, int offset, int count) {
113      writer.Write(bytes, offset, count);
114    }
115
116    //////////////////////////////////////////////////////////////////////
117    //
118    internal int PageSize {
119      get { return pageSize; }
120    }
121
122    //////////////////////////////////////////////////////////////////////
123    //
124    internal readonly int pageSize;
125    private Stream writer;
126    private int usedBytes;
127  }
128
129}
Note: See TracBrowser for help on using the repository browser.