001: package org.bouncycastle.mail.smime.util;
002:
003: import javax.mail.internet.SharedInputStream;
004: import java.io.BufferedInputStream;
005: import java.io.File;
006: import java.io.FileInputStream;
007: import java.io.FilterInputStream;
008: import java.io.IOException;
009: import java.io.InputStream;
010: import java.util.Iterator;
011: import java.util.LinkedList;
012: import java.util.List;
013:
014: public class SharedFileInputStream extends FilterInputStream implements
015: SharedInputStream {
016: private final SharedFileInputStream _parent;
017: private final File _file;
018: private final long _start;
019: private final long _length;
020:
021: private long _position;
022: private long _markedPosition;
023:
024: private List _subStreams = new LinkedList();
025:
026: public SharedFileInputStream(String fileName) throws IOException {
027: this (new File(fileName));
028: }
029:
030: public SharedFileInputStream(File file) throws IOException {
031: this (file, 0, file.length());
032: }
033:
034: private SharedFileInputStream(File file, long start, long length)
035: throws IOException {
036: super (new BufferedInputStream(new FileInputStream(file)));
037:
038: _parent = null;
039: _file = file;
040: _start = start;
041: _length = length;
042:
043: in.skip(start);
044: }
045:
046: private SharedFileInputStream(SharedFileInputStream parent,
047: long start, long length) throws IOException {
048: super (
049: new BufferedInputStream(new FileInputStream(
050: parent._file)));
051:
052: _parent = parent;
053: _file = parent._file;
054: _start = start;
055: _length = length;
056:
057: in.skip(start);
058: }
059:
060: public long getPosition() {
061: return _position;
062: }
063:
064: public InputStream newStream(long start, long finish) {
065: try {
066: SharedFileInputStream stream;
067:
068: if (finish < 0) {
069: if (_length > 0) {
070: stream = new SharedFileInputStream(this , _start
071: + start, _length - start);
072: } else if (_length == 0) {
073: stream = new SharedFileInputStream(this , _start
074: + start, 0);
075: } else {
076: stream = new SharedFileInputStream(this , _start
077: + start, -1);
078: }
079: } else {
080: stream = new SharedFileInputStream(this ,
081: _start + start, finish - start);
082: }
083:
084: _subStreams.add(stream);
085:
086: return stream;
087: } catch (IOException e) {
088: throw new IllegalStateException(
089: "unable to create shared stream: " + e);
090: }
091: }
092:
093: public int read(byte[] buf) throws IOException {
094: return this .read(buf, 0, buf.length);
095: }
096:
097: public int read(byte[] buf, int off, int len) throws IOException {
098: int count = 0;
099:
100: if (len == 0) {
101: return 0;
102: }
103:
104: while (count < len) {
105: int ch = this .read();
106:
107: if (ch < 0) {
108: break;
109: }
110:
111: buf[off + count] = (byte) ch;
112: count++;
113: }
114:
115: if (count == 0) {
116: return -1; // EOF
117: }
118:
119: return count;
120: }
121:
122: public int read() throws IOException {
123: if (_position == _length) {
124: return -1;
125: }
126:
127: _position++;
128: return in.read();
129: }
130:
131: public boolean markSupported() {
132: return true;
133: }
134:
135: public long skip(long n) throws IOException {
136: long count;
137:
138: for (count = 0; count != n; count++) {
139: if (this .read() < 0) {
140: break;
141: }
142: }
143:
144: return count;
145: }
146:
147: public void mark(int readLimit) {
148: _markedPosition = _position;
149: in.mark(readLimit);
150: }
151:
152: public void reset() throws IOException {
153: _position = _markedPosition;
154: in.reset();
155: }
156:
157: /**
158: * Return the shared stream that represents the top most stream that
159: * this stream inherits from.
160: * @return the base of the shared stream tree.
161: */
162: public SharedFileInputStream getRoot() {
163: if (_parent != null) {
164: return _parent.getRoot();
165: }
166:
167: return this ;
168: }
169:
170: /**
171: * Close of this stream and any substreams that have been created from it.
172: * @throws IOException on problem closing the main stream.
173: */
174: public void dispose() throws IOException {
175: Iterator it = _subStreams.iterator();
176:
177: while (it.hasNext()) {
178: try {
179: ((SharedFileInputStream) it.next()).dispose();
180: } catch (IOException e) {
181: // ignore
182: }
183: }
184:
185: in.close();
186: }
187: }
|