diff options
Diffstat (limited to 'mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java')
-rw-r--r-- | mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java b/mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java new file mode 100644 index 00000000..97cfd9c0 --- /dev/null +++ b/mail/src/main/java/org/spongycastle/mail/smime/util/SharedFileInputStream.java @@ -0,0 +1,241 @@ +package org.bouncycastle.mail.smime.util; + +import javax.mail.internet.SharedInputStream; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +public class SharedFileInputStream + extends FilterInputStream + implements SharedInputStream +{ + private final SharedFileInputStream _parent; + private final File _file; + private final long _start; + private final long _length; + + private long _position; + private long _markedPosition; + + private List _subStreams = new LinkedList(); + + public SharedFileInputStream( + String fileName) + throws IOException + { + this(new File(fileName)); + } + + public SharedFileInputStream( + File file) + throws IOException + { + this(file, 0, file.length()); + } + + private SharedFileInputStream( + File file, + long start, + long length) + throws IOException + { + super(new BufferedInputStream(new FileInputStream(file))); + + _parent = null; + _file = file; + _start = start; + _length = length; + + in.skip(start); + } + + private SharedFileInputStream( + SharedFileInputStream parent, + long start, + long length) + throws IOException + { + super(new BufferedInputStream(new FileInputStream(parent._file))); + + _parent = parent; + _file = parent._file; + _start = start; + _length = length; + + in.skip(start); + } + + public long getPosition() + { + return _position; + } + + public InputStream newStream(long start, long finish) + { + try + { + SharedFileInputStream stream; + + if (finish < 0) + { + if (_length > 0) + { + stream = new SharedFileInputStream(this, _start + start, _length - start); + } + else if (_length == 0) + { + stream = new SharedFileInputStream(this, _start + start, 0); + } + else + { + stream = new SharedFileInputStream(this, _start + start, -1); + } + } + else + { + stream = new SharedFileInputStream(this, _start + start, finish - start); + } + + _subStreams.add(stream); + + return stream; + } + catch (IOException e) + { + throw new IllegalStateException("unable to create shared stream: " + e); + } + } + + public int read( + byte[] buf) + throws IOException + { + return this.read(buf, 0, buf.length); + } + + public int read( + byte[] buf, + int off, + int len) + throws IOException + { + int count = 0; + + if (len == 0) + { + return 0; + } + + while (count < len) + { + int ch = this.read(); + + if (ch < 0) + { + break; + } + + buf[off + count] = (byte)ch; + count++; + } + + if (count == 0) + { + return -1; // EOF + } + + return count; + } + + public int read() + throws IOException + { + if (_position == _length) + { + return -1; + } + + _position++; + return in.read(); + } + + public boolean markSupported() + { + return true; + } + + public long skip(long n) + throws IOException + { + long count; + + for (count = 0; count != n; count++) + { + if (this.read() < 0) + { + break; + } + } + + return count; + } + + public void mark( + int readLimit) + { + _markedPosition = _position; + in.mark(readLimit); + } + + public void reset() + throws IOException + { + _position = _markedPosition; + in.reset(); + } + + /** + * Return the shared stream that represents the top most stream that + * this stream inherits from. + * @return the base of the shared stream tree. + */ + public SharedFileInputStream getRoot() + { + if (_parent != null) + { + return _parent.getRoot(); + } + + return this; + } + + /** + * Close of this stream and any substreams that have been created from it. + * @throws IOException on problem closing the main stream. + */ + public void dispose() + throws IOException + { + Iterator it = _subStreams.iterator(); + + while (it.hasNext()) + { + try + { + ((SharedFileInputStream)it.next()).dispose(); + } + catch (IOException e) + { + // ignore + } + } + + in.close(); + } +} |