KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > persistence > btreeimpl > btreestorage > CachedPageInputStream


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.persistence.btreeimpl.btreestorage;
20
21 import java.util.*;
22 import java.io.*;
23
24 import org.netbeans.mdr.persistence.*;
25
26 /**
27 * A stream composed of segments stored in CachedPages. The pages
28 * are pinned while members of a CachedPageInputStream. When done with
29 * the stream, close it to unpin the pages.
30 */

31 public class CachedPageInputStream extends java.io.InputStream JavaDoc {
32
33     /* first page in stream */
34     private PageDescriptor first;
35
36     /* last page in stream */
37     private PageDescriptor last;
38
39     /* page currently being read from */
40     private PageDescriptor currentPage;
41
42     /* current offset in curent page */
43     private int currentOffset;
44
45     /* to support mark and reset */
46     private PageDescriptor markedPage;
47     private int markedOffset;
48
49     /** Add a page to the stream
50     * @param pg the page to add
51     * @param offst the offset in the page where the stream data begins
52     * @page len length of stream data
53     */

54     public void addPage(CachedPage pg, int offst, int len) {
55         PageDescriptor newPage = new PageDescriptor(pg, offst, len);
56         if (first == null) {
57             first = last = newPage;
58             currentPage = first;
59             currentOffset = offst;
60         }
61         else {
62             last.next = newPage;
63             last = newPage;
64         }
65     }
66
67     /** close the stream. This unpins all of the pages from the cache.
68     * @exception IOException if there is an error unpinning the pages.
69     */

70     public void close() throws IOException {
71         try {
72             unpinAll();
73         }
74         catch (StorageException ex) {
75             // By the contract of close, we are only allowed to
76
// throw IOExceptions
77
StreamCorruptedException newEx =
78                 new StreamCorruptedException(ex.getMessage());
79             throw newEx;
80         }
81         finally {
82             first = last = currentPage = null;
83             currentOffset = 0;
84             super.close();
85         }
86     }
87
88
89     /** read a byte from the stream
90     * @return The next byte in the stream, or -1 if at EOF.
91     */

92     public int read() {
93         while (true) {
94             if (currentPage == null) {
95                 return -1;
96             }
97             else if (currentOffset < currentPage.end) {
98                 int val = (int)currentPage.page.contents[currentOffset++];
99                 return (val & 0xFF);
100             }
101             else {
102                 currentPage = currentPage.next;
103                 if (currentPage != null)
104                     currentOffset = currentPage.start;
105             }
106         }
107     }
108
109     /** read bytes into an array
110     * @param b up to b.length bytes are read into this array
111     * @return The number of bytes read. If at EOF, -1 is returned
112     */

113     public int read(byte b[]) {
114         return read(b, 0, b.length);
115     }
116
117     /** read bytes into an array
118     * @param b up to length bytes are read into this array
119     * @param offset the offset into the array at whch to start storing bytes
120     * @param maximum number of bytes to read
121     * @return The number of bytes read. If at EOF, -1 is returned
122     */

123     public int read(byte b[], int offset, int length) {
124         int left;
125
126         int toCopy = length;
127         int byteOffset = offset;
128
129         while (true) {
130             if (currentPage == null) {
131                 return (toCopy == length) ? -1 : (length - toCopy);
132             }
133             else if ((left = currentPage.end - currentOffset) > 0) {
134                 int size = Math.min(left, toCopy);
135                 System.arraycopy(currentPage.page.contents, currentOffset,
136                                  b, byteOffset, size);
137                 currentOffset += size;
138                 byteOffset += size;
139                 toCopy -= size;
140                 if (toCopy == 0) {
141                     return length;
142                 }
143             }
144             else {
145                 currentPage = currentPage.next;
146                 if (currentPage != null)
147                     currentOffset = currentPage.start;
148             }
149         }
150     }
151
152     /** this class supports mark (since it's easy)
153     * @return true, since we support mark
154     */

155     public boolean markSupported() {
156         return true;
157     }
158
159     /** mark a spot in the stream, which reset will return to
160     * @param readlimit ignored
161     */

162     public void mark(int readlimit) {
163         markedPage = currentPage;
164         markedOffset = currentOffset;
165     }
166
167     /** report how many bytes are still unread
168     * @return number of bytes left in stream
169     */

170     public int available() {
171         if (currentPage == null)
172             return 0;
173
174         int total = currentPage.end - currentOffset;
175
176         for (PageDescriptor p = currentPage.next; p != null; p = p.next) {
177             total += p.end - p.start;
178         }
179
180         return total;
181     }
182
183     /** return to where mark was last called, or to the beginning if
184     * mark was never called.
185     */

186     public void reset() {
187         if (markedPage != null) {
188             currentPage = markedPage;
189             currentOffset = markedOffset;
190         }
191         else {
192             currentPage = first;
193             if (first != null)
194                 currentOffset = first.start;
195             else
196                 currentOffset = 0;
197         }
198     }
199
200     /** if the stream was never closed, unpin the pages now
201     */

202     protected void finalize() throws StorageException {
203         unpinAll();
204     }
205
206     /* unpin all of the pages in the array */
207     private void unpinAll() throws StorageException{
208         for (PageDescriptor p = first; p != null; p = p.next) {
209             p.page.unpin();
210         }
211     }
212
213     
214     /** This class describes each page in the stream.
215     */

216     static class PageDescriptor {
217
218         /** The page contianing the data */
219         CachedPage page;
220
221         /** The first byte of data in the page */
222         int start;
223
224         /** One past the last byte of data in the page */
225         int end;
226
227         /** the next page in the stream */
228         PageDescriptor next;
229
230         /** Create a new page descriptor
231         * @param pg the page
232         * @param offset where the stream data starts
233         * @param length how mnay bytes of data the page contains
234         */

235         public PageDescriptor(CachedPage pg, int offset, int length) {
236             page = pg;
237             start = offset;
238             end = offset + length;
239         }
240     }
241 }
242     
243
Popular Tags