KickJava   Java API By Example, From Geeks To Geeks.

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


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