1 package org.paneris.messageboard.receivemail;
2
3 import java.io.FilterInputStream;
4 import java.io.IOException;
5 import java.io.PushbackInputStream;
6
7
8
9
10
11
12
13
14
15
16 class DotTerminatedInputStream extends FilterInputStream {
17 private static final int
18 TEXT = 0, FIRSTCR = 1, FIRSTNL = 2, DOT = 3, SECONDCR = 4, TERMINATED = 5,
19 POP = 6;
20
21 private int state = FIRSTNL;
22 private int state1 = -1;
23 private int byte1 = -1;
24 private byte[] pushedBack = new byte[4];
25 private int pushedBackIn = 0;
26 private int pushedBackOut = 0;
27
28
29
30
31
32
33
34
35
36 public DotTerminatedInputStream(PushbackInputStream in) {
37 super(in);
38 }
39
40 private int superRead() throws IOException {
41 if (byte1 == -1) return super.read();
42 else {
43 int it = byte1;
44 byte1 = -1;
45 return it;
46 }
47 }
48
49 private void pushBack(byte b) {
50 if (pushedBackIn == pushedBack.length) {
51
52 byte[] pushedBack_ = new byte[pushedBack.length * 2];
53 System.arraycopy(pushedBack, 0, pushedBack_, 0, pushedBack.length);
54 pushedBack = pushedBack_;
55 }
56
57 pushedBack[pushedBackIn++] = b;
58 }
59
60 public synchronized int read() throws IOException {
61 int b;
62 for (;;) {
63 switch (state) {
64 case TERMINATED:
65 pushedBack = null;
66 return -1;
67
68 case POP:
69 if (pushedBackOut < pushedBackIn) {
70 return pushedBack[pushedBackOut++];
71 }
72 else {
73 pushedBackOut = 0;
74 pushedBackIn = 0;
75 state = state1;
76 }
77 break;
78
79 case TEXT:
80 switch (b = superRead()) {
81 case '\r': state = FIRSTCR; pushBack((byte)13); break;
82 case '\n': state = FIRSTNL; pushBack((byte)10); break;
83 case -1: state = POP; state1 = TERMINATED; break;
84 default: return b;
85 }
86 break;
87
88 case FIRSTCR:
89 switch (b = superRead()) {
90 case '\n': state = FIRSTNL; pushBack((byte)10); break;
91 case '\r': state = POP; state1 = TEXT; byte1 = '\r'; break;
92 case -1: state = POP; state1 = TERMINATED; break;
93 default: state = POP; state1 = TEXT; byte1 = b; break;
94 }
95 break;
96
97 case FIRSTNL:
98 switch (b = superRead()) {
99 case '.': state = DOT; pushBack((byte)46); break;
100 case '\n': state = POP; state1 = TEXT; byte1 = '\n'; break;
101 case '\r': state = POP; state1 = TEXT; byte1 = '\r'; break;
102 case -1: state = POP; state1 = TERMINATED; break;
103 default: state = POP; state1 = TEXT; byte1 = b; break;
104 }
105 break;
106
107 case DOT:
108 switch (b = superRead()) {
109 case '\n': state = TERMINATED; break;
110 case '\r': state = SECONDCR; break;
111 case -1: state = POP; state1 = TERMINATED; break;
112 default: state = POP; state1 = TEXT; byte1 = b; break;
113 }
114 break;
115
116 case SECONDCR:
117 if ((b = superRead()) != '\n')
118 ((PushbackInputStream)in).unread(b);
119 state = TERMINATED;
120 break;
121 }
122 }
123 }
124
125 public synchronized int read(byte[] b, int off, int len) throws IOException {
126 if (len <= 0) {
127 return 0;
128 }
129
130 int c = read();
131 if (c == -1) {
132 return -1;
133 }
134 b[off] = (byte)c;
135
136 int i = 1;
137 try {
138 for (; i < len ; i++) {
139 c = read();
140 if (c == -1) {
141 break;
142 }
143 if (b != null) {
144 b[off + i] = (byte)c;
145 }
146 }
147 } catch (IOException ee) {
148 ;
149 }
150 return i;
151 }
152
153 public synchronized long skip(long n) throws IOException {
154 while (n > 0L && read() != -1) --n;
155 return n;
156 }
157 }