2 // This software is now distributed according to
\r
3 // the Lesser Gnu Public License. Please see
\r
4 // http://www.gnu.org/copyleft/lesser.txt for
\r
6 // -- Happy Computing!
\r
8 package com.stevesoft.pat;
\r
12 import com.stevesoft.pat.wrap.*;
\r
14 /** This class allows you to replace the text in strings
\r
15 as you read them in. Be careful what you do with
\r
16 this freedom... using Regex.perlCode("s{.*}{x}s")
\r
17 as your pattern will result in loading the entire
\r
18 contents of the Reader into memory.
\r
20 public class RegexReader
\r
23 RBuffer rb = new RBuffer(new StringBuffer());
\r
24 PartialBuffer wrap = new PartialBuffer(rb.sb);
\r
25 boolean moreToRead = true;
\r
30 int nmax = 2 * 1024;
\r
32 public RegexReader(Regex rex, Reader r)
\r
35 rp = rex.getReplacer();
\r
38 public RegexReader(Transformer tex, Reader r)
\r
41 rp = tex.getReplacer();
\r
48 rb = new RBuffer(new StringBuffer());
\r
49 wrap = new PartialBuffer(rb.sb);
\r
58 while ( (c = r.read()) != -1)
\r
60 rb.sb.append( (char) c);
\r
66 if (c == -1 && n == 0)
\r
69 wrap.allowOverRun = false;
\r
76 while (rb.pos >= rb.epos)
\r
78 wrap.overRun = false;
\r
79 if (rb.next != null)
\r
87 else if (rb.epos >= rb.sb.length()
\r
95 else if (rb.epos >= rb.sb.length()
\r
100 else if (rp.getRegex().matchAt(wrap, rb.epos))
\r
108 StringBufferWrap sbw = new StringBufferWrap();
\r
109 StringBufferLike sbl = new StringBufferLike(sbw);
\r
111 ReplaceRule rr = rex.getReplaceRule();
\r
112 while(rr != null) {
\r
117 Regex rex = rp.getRegex();
\r
118 int npos = rex.matchedTo();
\r
120 rp.setSource(wrap);
\r
122 rp.apply(rex, rex.getReplaceRule());
\r
123 int opos = rb.epos;
\r
124 RBuffer rb2 = new RBuffer( (StringBuffer) sbw.unwrap());
\r
125 rb2.epos = rb2.sb.length();
\r
126 RBuffer rb3 = new RBuffer(rb.sb);
\r
133 rb3.epos = npos + 1;
\r
134 if (rb3.epos > rb3.sb.length())
\r
136 if (rb.pos >= rb.epos)
\r
140 rb3.pos = rb3.epos = 0;
\r
148 rb3.pos = rb3.epos = npos;
\r
159 else if (rb.epos < rb.sb.length())
\r
174 if (rb.pos >= rb.epos)
\r
177 if (rb.pos >= rb.epos)
\r
182 //System.out.println(rb);
\r
183 return rb.sb.charAt(rb.pos++);
\r
186 public int read(char[] buf, int off, int len)
\r
190 int end = off + len;
\r
191 for (int i = off; i < end; i++)
\r
207 public void close()
\r
213 public boolean markSupported()
\r
218 /** Get the size of the working buffer.
\r
219 The current buffer may be larger if
\r
220 the pattern demands it. */
\r
221 public int getBufferSize()
\r
226 /** Set the size of the working buffer.
\r
227 The current buffer may be larger if
\r
228 the pattern demands it. */
\r
229 public void setBufferSize(int n)
\r
235 /** This function no longer serves any purpose.
\r
238 public int getMaxLines()
\r
243 /** This function no longer serves any purpose.
\r
246 public void setMaxLines(int ml)
\r
251 char EOLchar = '\n';
\r
252 /** This function no longer serves any purpose.
\r
255 public char getEOLchar()
\r
260 /** This function no longer serves any purpose.
\r
263 public void setEOLchar(char c)
\r
268 public long skip(long d)
\r
271 // This is probably inefficient, I just did it
\r
272 // this way to avoid possible bugs.
\r
274 while (n < d && read() != -1)
\r
282 static void test(String re,String inp,int n) throws Exception {
\r
283 Reader r = new StringReader(inp);
\r
284 r = new BufferedReader(r);
\r
285 Regex rex = Regex.perlCode(re);
\r
286 String res1 = rex.replaceAll(inp);
\r
288 StringBuffer sb = new StringBuffer();
\r
289 RegexReader rr = new RegexReader(rex,r);
\r
290 rr.setBufferSize(n);
\r
291 while( (c = rr.read()) != -1)
\r
292 sb.append((char)c);
\r
293 String res2 = sb.toString();
\r
294 if(!res1.equals(res2)) {
\r
295 System.out.println("nmax="+n);
\r
296 System.out.println("re="+re);
\r
297 System.out.println("inp="+inp);
\r
298 System.out.println("res1="+res1);
\r
299 System.out.println("res2="+res2);
\r
303 public static void main(String[] args) throws Exception {
\r
304 for(int n=6;n<15;n++) {
\r
305 test("s/x/y/","-----x123456789",n);
\r
306 test("s/x/y/","x123456789",n);
\r
307 test("s/x/y/","-----x",n);
\r
308 test("s/x.*?x/y/",".xx..x..x...x...x....x....x",n);
\r
309 test("s/x.*x/[$&]/","--x........x--xx",n);
\r
310 test("s/x.*x/[$&]/","--x........x------",n);
\r
311 test("s/.$/a/m","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb",n);
\r
312 test("s/.$/a/","123",n);
\r
313 test("s/.$/a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n);
\r
314 test("s/^./a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n);
\r
315 test("s/$/a/","bbb",n);
\r
316 test("s/^/a/","bbb",n);
\r
317 test("s/^/a/","",n);
\r
318 test("s{.*}{N}","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",n);
\r
319 test("s/.{0,7}/y/","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",n);
\r
320 test("s/x/$&/","xxx",n);
\r
322 System.out.println("Success!!!");
\r