Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
RegexReader | 21 | 88 | 41 |
1 | // | |
2 | // This software is now distributed according to | |
3 | // the Lesser Gnu Public License. Please see | |
4 | // http://www.gnu.org/copyleft/lesser.txt for | |
5 | // the details. | |
6 | // -- Happy Computing! | |
7 | // | |
8 | package com.stevesoft.pat; | |
9 | ||
10 | import java.io.IOException; | |
11 | import java.io.Reader; | |
12 | ||
13 | import com.stevesoft.pat.wrap.StringBufferWrap; | |
14 | ||
15 | /** | |
16 | * This class allows you to replace the text in strings as you read them in. Be | |
17 | * careful what you do with this freedom... using Regex.perlCode("s{.*}{x}s") as | |
18 | * your pattern will result in loading the entire contents of the Reader into | |
19 | * memory. | |
20 | */ | |
21 | public class RegexReader extends Reader | |
22 | { | |
23 | RBuffer rb = new RBuffer(new StringBuffer()); | |
24 | ||
25 | PartialBuffer wrap = new PartialBuffer(rb.sb); | |
26 | ||
27 | boolean moreToRead = true; | |
28 | ||
29 | Reader r; | |
30 | ||
31 | Replacer rp; | |
32 | ||
33 | // the buffer size | |
34 | int nmax = 2 * 1024; | |
35 | ||
36 | 0 | public RegexReader(Regex rex, Reader r) |
37 | { | |
38 | 0 | this.r = r; |
39 | 0 | rp = rex.getReplacer(); |
40 | } | |
41 | ||
42 | 0 | public RegexReader(Transformer tex, Reader r) |
43 | { | |
44 | 0 | this.r = r; |
45 | 0 | rp = tex.getReplacer(); |
46 | } | |
47 | ||
48 | 0 | public void reset() throws IOException |
49 | { | |
50 | 0 | r.reset(); |
51 | 0 | rb = new RBuffer(new StringBuffer()); |
52 | 0 | wrap = new PartialBuffer(rb.sb); |
53 | 0 | moreToRead = true; |
54 | } | |
55 | ||
56 | 0 | void readData() throws IOException |
57 | { | |
58 | 0 | int c; |
59 | 0 | int n = 0; |
60 | 0 | while ((c = r.read()) != -1) |
61 | { | |
62 | 0 | rb.sb.append((char) c); |
63 | 0 | if (n++ > nmax) |
64 | { | |
65 | 0 | break; |
66 | } | |
67 | } | |
68 | 0 | if (c == -1 && n == 0) |
69 | { | |
70 | 0 | moreToRead = false; |
71 | 0 | wrap.allowOverRun = false; |
72 | } | |
73 | } | |
74 | ||
75 | 0 | void getMoreData() throws IOException |
76 | { | |
77 | 0 | while (rb.pos >= rb.epos) |
78 | { | |
79 | 0 | wrap.overRun = false; |
80 | 0 | if (rb.next != null) |
81 | { | |
82 | 0 | rb = rb.next; |
83 | } | |
84 | 0 | else if (rb.done) |
85 | { | |
86 | 0 | break; |
87 | } | |
88 | 0 | else if (rb.epos >= rb.sb.length() && rb.epos > nmax) |
89 | { | |
90 | 0 | rb.pos = 1; |
91 | 0 | rb.epos = 1; |
92 | 0 | rb.sb.setLength(1); |
93 | 0 | readData(); |
94 | } | |
95 | 0 | else if (rb.epos >= rb.sb.length() && moreToRead) |
96 | { | |
97 | 0 | readData(); |
98 | } | |
99 | 0 | else if (rp.getRegex().matchAt(wrap, rb.epos)) |
100 | { | |
101 | 0 | if (wrap.overRun) |
102 | { | |
103 | 0 | readData(); |
104 | } | |
105 | else | |
106 | { | |
107 | 0 | StringBufferWrap sbw = new StringBufferWrap(); |
108 | 0 | StringBufferLike sbl = new StringBufferLike(sbw); |
109 | /* | |
110 | * ReplaceRule rr = rex.getReplaceRule(); while(rr != null) { | |
111 | * rr.apply(sbl,rex); rr = rr.next; } | |
112 | */ | |
113 | 0 | Regex rex = rp.getRegex(); |
114 | 0 | int npos = rex.matchedTo(); |
115 | 0 | rp.setBuffer(sbl); |
116 | 0 | rp.setSource(wrap); |
117 | 0 | rp.setPos(npos); |
118 | 0 | rp.apply(rex, rex.getReplaceRule()); |
119 | 0 | int opos = rb.epos; |
120 | 0 | RBuffer rb2 = new RBuffer((StringBuffer) sbw.unwrap()); |
121 | 0 | rb2.epos = rb2.sb.length(); |
122 | 0 | RBuffer rb3 = new RBuffer(rb.sb); |
123 | ||
124 | 0 | rb.next = rb2; |
125 | 0 | rb2.next = rb3; |
126 | ||
127 | 0 | if (npos == opos) |
128 | { | |
129 | 0 | rb3.epos = npos + 1; |
130 | 0 | if (rb3.epos > rb3.sb.length()) |
131 | { | |
132 | 0 | if (rb.pos >= rb.epos) |
133 | { | |
134 | 0 | rb = rb.next; |
135 | } | |
136 | 0 | rb3.pos = rb3.epos = 0; |
137 | 0 | rb3.done = true; |
138 | // break; | |
139 | } | |
140 | 0 | rb3.pos = npos; |
141 | } | |
142 | else | |
143 | { | |
144 | 0 | rb3.pos = rb3.epos = npos; |
145 | } | |
146 | ||
147 | } | |
148 | } | |
149 | else | |
150 | { | |
151 | 0 | if (wrap.overRun) |
152 | { | |
153 | 0 | readData(); |
154 | } | |
155 | 0 | else if (rb.epos < rb.sb.length()) |
156 | { | |
157 | 0 | rb.epos++; |
158 | } | |
159 | else | |
160 | { | |
161 | 0 | break; |
162 | } | |
163 | } | |
164 | } | |
165 | } | |
166 | ||
167 | 0 | public int read() throws IOException |
168 | { | |
169 | 0 | if (rb.pos >= rb.epos) |
170 | { | |
171 | 0 | getMoreData(); |
172 | 0 | if (rb.pos >= rb.epos) |
173 | { | |
174 | 0 | return -1; |
175 | } | |
176 | } | |
177 | // System.out.println(rb); | |
178 | 0 | return rb.sb.charAt(rb.pos++); |
179 | } | |
180 | ||
181 | 0 | public int read(char[] buf, int off, int len) throws IOException |
182 | { | |
183 | 0 | int c = -1; |
184 | 0 | int end = off + len; |
185 | 0 | for (int i = off; i < end; i++) |
186 | { | |
187 | 0 | c = read(); |
188 | 0 | if (c < 0) |
189 | { | |
190 | 0 | if (i == off) |
191 | { | |
192 | 0 | return -1; |
193 | } | |
194 | 0 | return i - off; |
195 | } | |
196 | 0 | buf[i] = (char) c; |
197 | } | |
198 | 0 | return len; |
199 | } | |
200 | ||
201 | 0 | public void close() throws IOException |
202 | { | |
203 | 0 | r.close(); |
204 | } | |
205 | ||
206 | 0 | public boolean markSupported() |
207 | { | |
208 | 0 | return false; |
209 | } | |
210 | ||
211 | /** | |
212 | * Get the size of the working buffer. The current buffer may be larger if the | |
213 | * pattern demands it. | |
214 | */ | |
215 | 0 | public int getBufferSize() |
216 | { | |
217 | 0 | return nmax; |
218 | } | |
219 | ||
220 | /** | |
221 | * Set the size of the working buffer. The current buffer may be larger if the | |
222 | * pattern demands it. | |
223 | */ | |
224 | 0 | public void setBufferSize(int n) |
225 | { | |
226 | 0 | nmax = n; |
227 | } | |
228 | ||
229 | int max_lines = 2; | |
230 | ||
231 | /** | |
232 | * This function no longer serves any purpose. | |
233 | * | |
234 | * @deprecated | |
235 | */ | |
236 | 0 | @Deprecated |
237 | public int getMaxLines() | |
238 | { | |
239 | 0 | return max_lines; |
240 | } | |
241 | ||
242 | /** | |
243 | * This function no longer serves any purpose. | |
244 | * | |
245 | * @deprecated | |
246 | */ | |
247 | 0 | @Deprecated |
248 | public void setMaxLines(int ml) | |
249 | { | |
250 | 0 | max_lines = ml; |
251 | } | |
252 | ||
253 | char EOLchar = '\n'; | |
254 | ||
255 | /** | |
256 | * This function no longer serves any purpose. | |
257 | * | |
258 | * @deprecated | |
259 | */ | |
260 | 0 | @Deprecated |
261 | public char getEOLchar() | |
262 | { | |
263 | 0 | return EOLchar; |
264 | } | |
265 | ||
266 | /** | |
267 | * This function no longer serves any purpose. | |
268 | * | |
269 | * @deprecated | |
270 | */ | |
271 | 0 | @Deprecated |
272 | public void setEOLchar(char c) | |
273 | { | |
274 | 0 | EOLchar = c; |
275 | } | |
276 | ||
277 | 0 | public long skip(long d) throws IOException |
278 | { | |
279 | // This is probably inefficient, I just did it | |
280 | // this way to avoid possible bugs. | |
281 | 0 | long n = 0; |
282 | 0 | while (n < d && read() != -1) |
283 | { | |
284 | 0 | n++; |
285 | } | |
286 | 0 | return n; |
287 | } | |
288 | ||
289 | /* | |
290 | * static void test(String re,String inp,int n) throws Exception { Reader r = | |
291 | * new StringReader(inp); r = new BufferedReader(r); Regex rex = | |
292 | * Regex.perlCode(re); String res1 = rex.replaceAll(inp); int c = -1; | |
293 | * StringBuffer sb = new StringBuffer(); RegexReader rr = new | |
294 | * RegexReader(rex,r); rr.setBufferSize(n); while( (c = rr.read()) != -1) | |
295 | * sb.append((char)c); String res2 = sb.toString(); if(!res1.equals(res2)) { | |
296 | * System.out.println("nmax="+n); System.out.println("re="+re); | |
297 | * System.out.println("inp="+inp); System.out.println("res1="+res1); | |
298 | * System.out.println("res2="+res2); System.exit(255); } } public static void | |
299 | * main(String[] args) throws Exception { for(int n=6;n<15;n++) { | |
300 | * test("s/x/y/","-----x123456789",n); test("s/x/y/","x123456789",n); | |
301 | * test("s/x/y/","-----x",n); | |
302 | * test("s/x.*?x/y/",".xx..x..x...x...x....x....x",n); | |
303 | * test("s/x.*x/[$&]/","--x........x--xx",n); | |
304 | * test("s/x.*x/[$&]/","--x........x------",n); | |
305 | * test("s/.$/a/m","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb",n); | |
306 | * test("s/.$/a/","123",n); | |
307 | * test("s/.$/a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n); | |
308 | * test("s/^./a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n); | |
309 | * test("s/$/a/","bbb",n); test("s/^/a/","bbb",n); test("s/^/a/","",n); | |
310 | * test("s{.*}{N}","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",n); | |
311 | * test("s/.{0,7}/y/","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",n); | |
312 | * test("s/x/$&/","xxx",n); } System.out.println("Success!!!"); } | |
313 | */ | |
314 | } |