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)
126 throws IOException {
127
128 if (_read >= _length) {
129 return -1;
130 }
131
132 int read = 0;
133
134 if ((_read + length) > _length) {
135 read = _inputStream.read(bytes, 0, (int)(_length - _read));
136 }
137 else {
138 read = _inputStream.read(bytes, offset, length);
139 }
140
141 _read += read;
142
143 return read;
144 }
145
146 @Override
147 public void reset() {
148 }
149
150 @Override
151 public long skip(long skip) throws IOException {
152 long allowed = _length - _read;
153
154 if (allowed < skip) {
155 skip = allowed;
156 }
157
158 skip = _inputStream.skip(skip);
159
160 _read += skip;
161
162 return skip;
163 }
164
165 private static final int _SKIP_RETRY_COUNT = 3;
166
167 private InputStream _inputStream;
168 private long _length;
169 private long _read;
170
171 }