[msvc] Update csproj files
[mono.git] / mcs / tools / pdb2mdb / DataStream.cs
1 //-----------------------------------------------------------------------------
2 //
3 // Copyright (C) Microsoft Corporation.  All Rights Reserved.
4 //
5 //-----------------------------------------------------------------------------
6 using System;
7 using System.IO;
8
9 namespace 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 }