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