Commit | Line | Data |
---|---|---|
8e76f6ab | 1 | package be.nikiroo.utils.streams; |
4098af70 | 2 | |
63b46ca9 NR |
3 | import java.io.InputStream; |
4 | ||
5 | /** | |
6 | * Divide an {@link InputStream} into sub-streams. | |
7 | * | |
8 | * @author niki | |
9 | */ | |
4098af70 N |
10 | public class NextableInputStreamStep { |
11 | private int stopAt; | |
4098af70 | 12 | private int last = -1; |
028ff7c2 NR |
13 | private int resumeLen; |
14 | private int resumeSkip; | |
15 | private boolean resumeEof; | |
4098af70 | 16 | |
63b46ca9 NR |
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 | */ | |
4098af70 N |
27 | public NextableInputStreamStep(int byt) { |
28 | stopAt = byt; | |
29 | } | |
30 | ||
63b46ca9 NR |
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) | |
028ff7c2 NR |
47 | * @param eof |
48 | * the current state of the under-laying stream | |
63b46ca9 NR |
49 | * |
50 | * @return the index at which to stop, or -1 | |
51 | */ | |
028ff7c2 | 52 | public int stop(byte[] buffer, int pos, int len, boolean eof) { |
4098af70 N |
53 | for (int i = pos; i < len; i++) { |
54 | if (buffer[i] == stopAt) { | |
55 | if (i > this.last) { | |
56 | // we skip the sep | |
028ff7c2 | 57 | this.resumeSkip = 1; |
63b46ca9 | 58 | |
4098af70 | 59 | this.resumeLen = len; |
028ff7c2 | 60 | this.resumeEof = eof; |
4098af70 N |
61 | this.last = i; |
62 | return i; | |
63 | } | |
64 | } | |
65 | } | |
66 | ||
67 | return -1; | |
68 | } | |
69 | ||
63b46ca9 NR |
70 | /** |
71 | * Get the maximum index to use in the buffer used in | |
028ff7c2 NR |
72 | * {@link NextableInputStreamStep#stop(byte[], int, int, boolean)} at resume |
73 | * time. | |
63b46ca9 NR |
74 | * |
75 | * @return the index | |
76 | */ | |
4098af70 N |
77 | public int getResumeLen() { |
78 | return resumeLen; | |
79 | } | |
63b46ca9 NR |
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() { | |
028ff7c2 NR |
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; | |
4098af70 N |
97 | } |
98 | ||
63b46ca9 NR |
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 | |
028ff7c2 NR |
103 | * buffer used in |
104 | * {@link NextableInputStreamStep#stop(byte[], int, int, boolean)}. | |
63b46ca9 | 105 | */ |
4098af70 N |
106 | public void clearBuffer() { |
107 | this.last = -1; | |
028ff7c2 | 108 | this.resumeSkip = 0; |
4098af70 | 109 | this.resumeLen = 0; |
028ff7c2 | 110 | this.resumeEof = false; |
4098af70 | 111 | } |
4098af70 | 112 | } |