001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     matic
018 */
019package org.nuxeo.ecm.automation.jaxrs.io;
020
021import java.io.BufferedInputStream;
022import java.io.File;
023import java.io.FileInputStream;
024import java.io.IOException;
025import java.io.InputStream;
026
027import javax.mail.internet.SharedInputStream;
028
029public class SharedFileInputStream extends InputStream implements SharedInputStream {
030
031    protected final InputStream in;
032
033    protected final SharedFileInputStream parent;
034
035    protected final File file;
036
037    protected final long length;
038
039    protected final long start;
040
041    protected long current;
042
043    protected long marked;
044
045    public SharedFileInputStream(File file) throws IOException {
046        this.in = new BufferedInputStream(new FileInputStream(file));
047        this.parent = null;
048        this.file = file;
049        this.start = 0;
050        this.length = file.length();
051        this.in.skip(start);
052    }
053
054    protected SharedFileInputStream(SharedFileInputStream parent, long start, long len) throws IOException {
055        this.in = new BufferedInputStream(new FileInputStream(parent.file));
056        this.parent = parent;
057        this.file = parent.file;
058        this.start = start;
059        this.length = len;
060        this.in.skip(start);
061    }
062
063    public long getPosition() {
064        return this.current;
065    }
066
067    public SharedFileInputStream newStream(long start, long end) {
068        try {
069            long length;
070            if (end == -1L) {
071                length = this.length - start;
072            } else {
073                length = end - start;
074            }
075            return new SharedFileInputStream(this, this.start + start, length);
076        } catch (IOException localIOException) {
077            throw new IllegalStateException("unable to create shared stream: " + localIOException);
078        }
079    }
080
081    public int read(byte[] buffer) throws IOException {
082        return read(buffer, 0, buffer.length);
083    }
084
085    public int read(byte[] buffer, int offset, int len) throws IOException {
086        int i = 0;
087        if (len == 0)
088            return 0;
089        while (i < len) {
090            int j = read();
091            if (j < 0)
092                break;
093            buffer[(offset + i)] = (byte) j;
094            ++i;
095        }
096        if (i == 0)
097            return -1;
098        return i;
099    }
100
101    public int read() throws IOException {
102        if (this.current == this.length)
103            return -1;
104        this.current += 1L;
105        return this.in.read();
106    }
107
108    public boolean markSupported() {
109        return true;
110    }
111
112    public long skip(long len) throws IOException {
113        for (int count = 0; count < len; ++count) {
114            if (read() < 0)
115                return count;
116        }
117        return len;
118    }
119
120    public void mark(int limit) {
121        this.marked = this.current;
122        this.in.mark(limit);
123    }
124
125    public void reset() throws IOException {
126        current = marked;
127        in.reset();
128    }
129
130    public SharedFileInputStream getRoot() {
131        if (parent != null)
132            return parent.getRoot();
133        return this;
134    }
135}