001
014
015 package com.liferay.portal.kernel.io;
016
017 import java.io.IOException;
018 import java.io.InputStream;
019
020
026 public class LimitedInputStream extends InputStream {
027
028 public LimitedInputStream(InputStream inputStream, long offset, long length)
029 throws IOException {
030
031 if (offset < 0) {
032 throw new IllegalArgumentException("Offset is less than 0");
033 }
034
035 if (length < 0) {
036 throw new IllegalArgumentException("Length is less than 0");
037 }
038
039 _inputStream = inputStream;
040 _length = length;
041
042 int count = 0;
043
044 while (offset > 0) {
045 long skip = _inputStream.skip(offset);
046
047 if (skip == 0) {
048 if (++count >= _SKIP_RETRY_COUNT) {
049 throw new IOException(
050 "Most likely reached the end of the input stream");
051 }
052 }
053 else {
054 count = 0;
055 }
056
057 offset = offset - skip;
058 }
059 }
060
061 @Override
062 public int available() throws IOException {
063 int available = _inputStream.available();
064
065 int allowed = (int)(_length - _read);
066
067 if (available > allowed) {
068 return allowed;
069 }
070 else {
071 return available;
072 }
073 }
074
075 @Override
076 public void close() throws IOException {
077 _inputStream.close();
078 }
079
080 @Override
081 public void mark(int readLimit) {
082 }
083
084 @Override
085 public boolean markSupported() {
086 return false;
087 }
088
089 @Override
090 public int read() throws IOException {
091 if (_read >= _length) {
092 return -1;
093 }
094
095 int read = _inputStream.read();
096
097 if (read >= 0) {
098 _read++;
099 }
100
101 return read;
102 }
103
104 @Override
105 public int read(byte[] bytes) throws IOException {
106 if (_read >= _length) {
107 return -1;
108 }
109
110 int read = 0;
111
112 if ((_read + bytes.length) > _length) {
113 read = _inputStream.read(bytes, 0, (int)(_length - _read));
114 }
115 else {
116 read = _inputStream.read(bytes);
117 }
118
119 _read += read;
120
121 return read;
122 }
123
124 @Override
125 public int read(byte[] bytes, int offset, int length) throws IOException {
126 if (_read >= _length) {
127 return -1;
128 }
129
130 int read = 0;
131
132 if ((_read + length) > _length) {
133 read = _inputStream.read(bytes, 0, (int)(_length - _read));
134 }
135 else {
136 read = _inputStream.read(bytes, offset, length);
137 }
138
139 _read += read;
140
141 return read;
142 }
143
144 @Override
145 public void reset() {
146 }
147
148 @Override
149 public long skip(long skip) throws IOException {
150 long allowed = _length - _read;
151
152 if (allowed < skip) {
153 skip = allowed;
154 }
155
156 skip = _inputStream.skip(skip);
157
158 _read += skip;
159
160 return skip;
161 }
162
163 private static final int _SKIP_RETRY_COUNT = 3;
164
165 private InputStream _inputStream;
166 private long _length;
167 private long _read;
168
169 }