01: package org.jvnet.mimepull;
02:
03: import java.io.InputStream;
04: import java.io.IOException;
05:
06: /**
07: * Constructs a InputStream from a linked list of {@link Chunk}s.
08: *
09: * @author Kohsuke Kawaguchi
10: * @author Jitendra Kotamraju
11: */
12: final class ChunkInputStream extends InputStream {
13: Chunk current;
14: int offset;
15: int len;
16: final MIMEMessage msg;
17: final MIMEPart part;
18: byte[] buf;
19:
20: public ChunkInputStream(MIMEMessage msg, MIMEPart part,
21: Chunk startPos) {
22: this .current = startPos;
23: len = current.data.size();
24: buf = current.data.read();
25: this .msg = msg;
26: this .part = part;
27: }
28:
29: @Override
30: public int read(byte b[], int off, int sz) throws IOException {
31: if (!fetch())
32: return -1;
33:
34: sz = Math.min(sz, len - offset);
35: System.arraycopy(buf, offset, b, off, sz);
36: return sz;
37: }
38:
39: public int read() throws IOException {
40: if (!fetch())
41: return -1;
42: return (buf[offset++] & 0xff);
43: }
44:
45: /**
46: * Gets to the next chunk if we are done with the current one.
47: * @return
48: */
49: private boolean fetch() {
50: if (current == null) {
51: throw new IllegalStateException("Stream already closed");
52: }
53: while (offset == len) {
54: while (!part.parsed && current.next == null) {
55: msg.makeProgress();
56: }
57: current = current.next;
58:
59: if (current == null) {
60: return false;
61: }
62: this .offset = 0;
63: this .buf = current.data.read();
64: this .len = current.data.size();
65: }
66: return true;
67: }
68:
69: public void close() throws IOException {
70: super.close();
71: current = null;
72: }
73: }
|