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}