Merge commit '929409950e82914aa3cee323cfa7c5007585d2ea'
[nikiroo-utils.git] / src / be / nikiroo / utils / streams / NextableInputStreamStep.java
1 package be.nikiroo.utils.streams;
2
3 import java.io.InputStream;
4
5 /**
6 * Divide an {@link InputStream} into sub-streams.
7 *
8 * @author niki
9 */
10 public class NextableInputStreamStep {
11 private int stopAt;
12 private int last = -1;
13 private int resumeLen;
14 private int resumeSkip;
15 private boolean resumeEof;
16
17 /**
18 * Create a new divider that will separate the sub-streams each time it sees
19 * this byte.
20 * <p>
21 * Note that the byte will be bypassed by the {@link InputStream} as far as
22 * the consumers will be aware.
23 *
24 * @param byt
25 * the byte at which to separate two sub-streams
26 */
27 public NextableInputStreamStep(int byt) {
28 stopAt = byt;
29 }
30
31 /**
32 * Check if we need to stop the {@link InputStream} reading at some point in
33 * the current buffer.
34 * <p>
35 * If we do, return the index at which to stop; if not, return -1.
36 * <p>
37 * This method will <b>not</b> return the same index a second time (unless
38 * we cleared the buffer).
39 *
40 * @param buffer
41 * the buffer to check
42 * @param pos
43 * the current position of what was read in the buffer
44 * @param len
45 * the maximum index to use in the buffer (anything above that is
46 * not to be used)
47 * @param eof
48 * the current state of the under-laying stream
49 *
50 * @return the index at which to stop, or -1
51 */
52 public int stop(byte[] buffer, int pos, int len, boolean eof) {
53 for (int i = pos; i < len; i++) {
54 if (buffer[i] == stopAt) {
55 if (i > this.last) {
56 // we skip the sep
57 this.resumeSkip = 1;
58
59 this.resumeLen = len;
60 this.resumeEof = eof;
61 this.last = i;
62 return i;
63 }
64 }
65 }
66
67 return -1;
68 }
69
70 /**
71 * Get the maximum index to use in the buffer used in
72 * {@link NextableInputStreamStep#stop(byte[], int, int, boolean)} at resume
73 * time.
74 *
75 * @return the index
76 */
77 public int getResumeLen() {
78 return resumeLen;
79 }
80
81 /**
82 * Get the number of bytes to skip at resume time.
83 *
84 * @return the number of bytes to skip
85 */
86 public int getResumeSkip() {
87 return resumeSkip;
88 }
89
90 /**
91 * Get the under-laying stream state at resume time.
92 *
93 * @return the EOF state
94 */
95 public boolean getResumeEof() {
96 return resumeEof;
97 }
98
99 /**
100 * Clear the information we may have kept about the current buffer
101 * <p>
102 * You should call this method each time you change the content of the
103 * buffer used in
104 * {@link NextableInputStreamStep#stop(byte[], int, int, boolean)}.
105 */
106 public void clearBuffer() {
107 this.last = -1;
108 this.resumeSkip = 0;
109 this.resumeLen = 0;
110 this.resumeEof = false;
111 }
112 }