import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
/**
* This {@link InputStream} can be separated into sub-streams (you can process
* It can only be called when the "current" stream is spent (i.e., you must
* first process the stream until it is spent).
* <p>
- * We consider that when the under-laying {@link InputStream} is also spent,
- * we cannot have a next sub-stream (it will thus return FALSE).
- * <p>
* {@link IOException}s can happen when we have no data available in the
* buffer; in that case, we fetch more data to know if we can have a next
* sub-stream or not.
+ * <p>
+ * This is can be a blocking call when data need to be fetched.
*
- * @return TRUE if we unblocked the next sub-stream, FALSE if not
+ * @return TRUE if we unblocked the next sub-stream, FALSE if not (i.e.,
+ * FALSE when there are no more sub-streams to fetch)
*
* @throws IOException
* in case of I/O error or if the stream is closed
* <p>
* That is, the next stream, if any, will be the last one and will not be
* subject to the {@link NextableInputStreamStep}.
+ * <p>
+ * This is can be a blocking call when data need to be fetched.
*
* @return TRUE if we unblocked the next sub-stream, FALSE if not
*
* process).
* <p>
* Note: when the stream is divided into sub-streams, each sub-stream will
- * report it is eof when emptied.
+ * report its own eof when spent.
*
* @return TRUE if it is
*
return false;
}
- /**
- * We have more data available in the buffer or we can fetch more.
- *
- * @return TRUE if it is the case, FALSE if not
- */
@Override
protected boolean hasMoreData() {
return started && super.hasMoreData();
/**
* The implementation of {@link NextableInputStream#next()} and
* {@link NextableInputStream#nextAll()}.
+ * <p>
+ * This is can be a blocking call when data need to be fetched.
*
* @param all
* TRUE for {@link NextableInputStream#nextAll()}, FALSE for
* {@link NextableInputStream#next()}
*
- * @return TRUE if we unblocked the next sub-stream, FALSE if not
+ * @return TRUE if we unblocked the next sub-stream, FALSE if not (i.e.,
+ * FALSE when there are no more sub-streams to fetch)
*
* @throws IOException
* in case of I/O error or if the stream is closed
return true;
}
- if (step != null && !hasMoreData() && stopped) {
+ // If started, must be stopped and no more data to continue
+ // i.e., sub-stream must be spent
+ if (!stopped || hasMoreData()) {
+ return false;
+ }
+
+ if (step != null) {
stop = step.getResumeLen();
start += step.getResumeSkip();
eof = step.getResumeEof();
checkBuffer(false);
- // consider that if EOF, there is no next
- return hasMoreData();
+ return true;
}
return false;
+
+ // // consider that if EOF, there is no next
+ // if (start >= stop) {
+ // // Make sure, block if necessary
+ // preRead();
+ //
+ // return hasMoreData();
+ // }
+ //
+ // return true;
+ }
+
+ /**
+ * Display a DEBUG {@link String} representation of this object.
+ * <p>
+ * Do <b>not</b> use for release code.
+ */
+ @Override
+ public String toString() {
+ String data = "";
+ if (stop > 0) {
+ try {
+ data = new String(Arrays.copyOfRange(buffer, 0, stop), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ }
+ if (data.length() > 200) {
+ data = data.substring(0, 197) + "...";
+ }
+ }
+ String rep = String.format(
+ "Nextable %s: %d -> %d [eof: %s] [more data: %s]: %s",
+ (stopped ? "stopped" : "running"), start, stop, "" + eof, ""
+ + hasMoreData(), data);
+
+ return rep;
}
}