Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.Cecil/0.9.5/Mono.Cecil-0.9.5/Symbols/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs @ 18242

Last change on this file since 18242 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 DataStream {
11    internal DataStream() {
12      this.contentSize = 0;
13      this.pages = null;
14    }
15
16    internal DataStream(int contentSize, BitAccess bits, int count) {
17      this.contentSize = contentSize;
18      if (count > 0) {
19        this.pages = new int[count];
20        bits.ReadInt32(this.pages);
21      }
22    }
23
24    internal void Read(PdbReader reader, BitAccess bits) {
25      bits.MinCapacity(contentSize);
26      Read(reader, 0, bits.Buffer, 0, contentSize);
27    }
28
29    internal void Read(PdbReader reader, int position,
30                     byte[] bytes, int offset, int data) {
31      if (position + data > contentSize) {
32        throw new PdbException("DataStream can't read off end of stream. " +
33                                       "(pos={0},siz={1})",
34                               position, data);
35      }
36      if (position == contentSize) {
37        return;
38      }
39
40      int left = data;
41      int page = position / reader.pageSize;
42      int rema = position % reader.pageSize;
43
44      // First get remained of first page.
45      if (rema != 0) {
46        int todo = reader.pageSize - rema;
47        if (todo > left) {
48          todo = left;
49        }
50
51        reader.Seek(pages[page], rema);
52        reader.Read(bytes, offset, todo);
53
54        offset += todo;
55        left -= todo;
56        page++;
57      }
58
59      // Now get the remaining pages.
60      while (left > 0) {
61        int todo = reader.pageSize;
62        if (todo > left) {
63          todo = left;
64        }
65
66        reader.Seek(pages[page], 0);
67        reader.Read(bytes, offset, todo);
68
69        offset += todo;
70        left -= todo;
71        page++;
72      }
73    }
74
75    internal void Write(PdbWriter writer, byte[] bytes) {
76      Write(writer, bytes, bytes.Length);
77    }
78
79    internal void Write(PdbWriter writer, byte[] bytes, int data) {
80      if (bytes == null || data == 0) {
81        return;
82      }
83
84      int left = data;
85      int used = 0;
86      int rema = contentSize % writer.pageSize;
87      if (rema != 0) {
88        int todo = writer.pageSize - rema;
89        if (todo > left) {
90          todo = left;
91        }
92
93        int lastPage = pages[pages.Length - 1];
94        writer.Seek(lastPage, rema);
95        writer.Write(bytes, used, todo);
96        used += todo;
97        left -= todo;
98      }
99
100      if (left > 0) {
101        int count = (left + writer.pageSize - 1) / writer.pageSize;
102        int page0 = writer.AllocatePages(count);
103
104        writer.Seek(page0, 0);
105        writer.Write(bytes, used, left);
106
107        AddPages(page0, count);
108      }
109
110      contentSize += data;
111    }
112
113    private void AddPages(int page0, int count) {
114      if (pages == null) {
115        pages = new int[count];
116        for (int i = 0; i < count; i++) {
117          pages[i] = page0 + i;
118        }
119      } else {
120        int[] old = pages;
121        int used = old.Length;
122
123        pages = new int[used + count];
124        Array.Copy(old, pages, used);
125        for (int i = 0; i < count; i++) {
126          pages[used + i] = page0 + i;
127        }
128      }
129    }
130
131    internal int Pages {
132      get { return pages == null ? 0 : pages.Length; }
133    }
134
135    internal int Length {
136      get { return contentSize; }
137    }
138
139    internal int GetPage(int index) {
140      return pages[index];
141    }
142
143    internal int contentSize;
144    internal int[] pages;
145  }
146}
Note: See TracBrowser for help on using the repository browser.