KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > content > LazyReader


1 /*******************************************************************************
2  * Copyright (c) 2004, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.content;
12
13 import java.io.IOException JavaDoc;
14 import java.io.Reader JavaDoc;
15
16 public class LazyReader extends Reader JavaDoc implements ILazySource {
17     private int blockCapacity;
18     char[][] blocks = {};
19     private int bufferSize;
20     private Reader JavaDoc in;
21     private int mark;
22     private int offset;
23
24     public LazyReader(Reader JavaDoc in, int blockCapacity) {
25         this.in = in;
26         this.blockCapacity = blockCapacity;
27     }
28
29     public void close() {
30         // we don't close the underlying stream
31
}
32
33     private int computeBlockSize(int blockIndex) {
34         if (blockIndex < blocks.length - 1)
35             return blockCapacity;
36         int blockSize = bufferSize % blockCapacity;
37         return blockSize == 0 ? blockCapacity : blockSize;
38     }
39
40     private int copyFromBuffer(char[] userBuffer, int userOffset, int needed) {
41         int copied = 0;
42         int current = offset / blockCapacity;
43         while ((needed - copied) > 0 && current < blocks.length) {
44             int blockSize = computeBlockSize(current);
45             int offsetInBlock = offset % blockCapacity;
46             int availableInBlock = blockSize - offsetInBlock;
47             int toCopy = Math.min(availableInBlock, needed - copied);
48             System.arraycopy(blocks[current], offsetInBlock, userBuffer, userOffset + copied, toCopy);
49             copied += toCopy;
50             current++;
51             offset += toCopy;
52         }
53         return copied;
54     }
55
56     private void ensureAvailable(long charsToRead) throws IOException JavaDoc {
57         int loadedBlockSize = blockCapacity;
58         while (bufferSize < offset + charsToRead && loadedBlockSize == blockCapacity) {
59             try {
60                 loadedBlockSize = loadBlock();
61             } catch (IOException JavaDoc ioe) {
62                 throw new LowLevelIOException(ioe);
63             }
64             bufferSize += loadedBlockSize;
65         }
66     }
67
68     // for testing purposes
69
protected int getBlockCount() {
70         return blocks.length;
71     }
72
73     // for testing purposes
74
protected int getBufferSize() {
75         return bufferSize;
76     }
77
78     // for testing purposes
79
protected int getMark() {
80         return mark;
81     }
82
83     // for testing purposes
84
protected int getOffset() {
85         return offset;
86     }
87
88     public boolean isText() {
89         return true;
90     }
91
92     private int loadBlock() throws IOException JavaDoc {
93         // read a block from the underlying stream
94
char[] newBlock = new char[blockCapacity];
95         int readCount = in.read(newBlock);
96         if (readCount == -1)
97             return 0;
98         // expand blocks array
99
char[][] tmpBlocks = new char[blocks.length + 1][];
100         System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
101         blocks = tmpBlocks;
102         blocks[blocks.length - 1] = newBlock;
103         return readCount;
104     }
105
106     public void mark(int readlimit) {
107         mark = offset;
108     }
109
110     public boolean markSupported() {
111         return true;
112     }
113
114     public int read() throws IOException JavaDoc {
115         ensureAvailable(1);
116         if (bufferSize <= offset)
117             return -1;
118         char nextChar = blocks[offset / blockCapacity][offset % blockCapacity];
119         offset++;
120         return nextChar;
121     }
122
123     public int read(char[] c) throws IOException JavaDoc {
124         return read(c, 0, c.length);
125     }
126
127     public int read(char[] c, int off, int len) throws IOException JavaDoc {
128         ensureAvailable(len);
129         int copied = copyFromBuffer(c, off, len);
130         return copied == 0 ? -1 : copied;
131     }
132
133     public boolean ready() throws IOException JavaDoc {
134         try {
135             return (bufferSize - offset) > 0 || in.ready();
136         } catch (IOException JavaDoc ioe) {
137             throw new LowLevelIOException(ioe);
138         }
139     }
140
141     public void reset() {
142         offset = mark;
143     }
144
145     public void rewind() {
146         mark = 0;
147         offset = 0;
148     }
149
150     public long skip(long toSkip) throws IOException JavaDoc {
151         if (toSkip <= 0)
152             return 0;
153         ensureAvailable(toSkip);
154         long skipped = Math.min(toSkip, bufferSize - offset);
155         offset += skipped;
156         return skipped;
157     }
158 }
159
Popular Tags