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
11 import com.stevesoft.pat.wrap.*;
\r
13 /** This class allows you to replace the text in strings
\r
14 as you read them in. Be careful what you do with
\r
15 this freedom... using Regex.perlCode("s{.*}{x}s")
\r
16 as your pattern will result in loading the entire
\r
17 contents of the Reader into memory.
\r
19 public class RegexReader extends Reader {
\r
20 RBuffer rb = new RBuffer(new StringBuffer());
\r
21 PartialBuffer wrap = new PartialBuffer(rb.sb);
\r
22 boolean moreToRead = true;
\r
29 public RegexReader(Regex rex,Reader r) {
\r
31 rp = rex.getReplacer();
\r
33 public RegexReader(Transformer tex,Reader r) {
\r
35 rp = tex.getReplacer();
\r
37 public void reset() throws IOException {
\r
39 rb = new RBuffer(new StringBuffer());
\r
40 wrap = new PartialBuffer(rb.sb);
\r
43 void readData() throws IOException {
\r
46 while( (c = r.read()) != -1) {
\r
47 rb.sb.append((char)c);
\r
51 if(c == -1 && n == 0) {
\r
53 wrap.allowOverRun = false;
\r
56 void getMoreData() throws IOException {
\r
57 while(rb.pos >= rb.epos) {
\r
58 wrap.overRun = false;
\r
59 if(rb.next != null) {
\r
61 } else if(rb.done) {
\r
63 } else if(rb.epos >= rb.sb.length()
\r
64 && rb.epos > nmax) {
\r
69 } else if(rb.epos >= rb.sb.length()
\r
72 } else if(rp.getRegex().matchAt(wrap,rb.epos)) {
\r
76 StringBufferWrap sbw = new StringBufferWrap();
\r
77 StringBufferLike sbl = new StringBufferLike(sbw);
\r
79 ReplaceRule rr = rex.getReplaceRule();
\r
85 Regex rex = rp.getRegex();
\r
86 int npos = rex.matchedTo();
\r
90 rp.apply(rex,rex.getReplaceRule());
\r
92 RBuffer rb2 = new RBuffer((StringBuffer)sbw.unwrap());
\r
93 rb2.epos = rb2.sb.length();
\r
94 RBuffer rb3 = new RBuffer(rb.sb);
\r
101 if(rb3.epos > rb3.sb.length()) {
\r
102 if(rb.pos >= rb.epos)
\r
104 rb3.pos = rb3.epos = 0;
\r
110 rb3.pos = rb3.epos = npos;
\r
117 } else if(rb.epos<rb.sb.length()) {
\r
125 public int read() throws IOException {
\r
126 if(rb.pos >= rb.epos) {
\r
128 if(rb.pos >= rb.epos)
\r
131 //System.out.println(rb);
\r
132 return rb.sb.charAt(rb.pos++);
\r
134 public int read(char[] buf,int off,int len)
\r
139 for(int i=off;i<end;i++) {
\r
150 public void close()
\r
156 public boolean markSupported() { return false; }
\r
158 /** Get the size of the working buffer.
\r
159 The current buffer may be larger if
\r
160 the pattern demands it. */
\r
161 public int getBufferSize() {
\r
164 /** Set the size of the working buffer.
\r
165 The current buffer may be larger if
\r
166 the pattern demands it. */
\r
167 public void setBufferSize(int n) {
\r
172 /** This function no longer serves any purpose.
\r
175 public int getMaxLines() { return max_lines; }
\r
176 /** This function no longer serves any purpose.
\r
179 public void setMaxLines(int ml) { max_lines = ml; }
\r
181 char EOLchar = '\n';
\r
182 /** This function no longer serves any purpose.
\r
185 public char getEOLchar() {
\r
188 /** This function no longer serves any purpose.
\r
191 public void setEOLchar(char c) {
\r
195 public long skip(long d) throws IOException {
\r
196 // This is probably inefficient, I just did it
\r
197 // this way to avoid possible bugs.
\r
199 while(n<d && read() != -1)
\r
205 static void test(String re,String inp,int n) throws Exception {
\r
206 Reader r = new StringReader(inp);
\r
207 r = new BufferedReader(r);
\r
208 Regex rex = Regex.perlCode(re);
\r
209 String res1 = rex.replaceAll(inp);
\r
211 StringBuffer sb = new StringBuffer();
\r
212 RegexReader rr = new RegexReader(rex,r);
\r
213 rr.setBufferSize(n);
\r
214 while( (c = rr.read()) != -1)
\r
215 sb.append((char)c);
\r
216 String res2 = sb.toString();
\r
217 if(!res1.equals(res2)) {
\r
218 System.out.println("nmax="+n);
\r
219 System.out.println("re="+re);
\r
220 System.out.println("inp="+inp);
\r
221 System.out.println("res1="+res1);
\r
222 System.out.println("res2="+res2);
\r
226 public static void main(String[] args) throws Exception {
\r
227 for(int n=6;n<15;n++) {
\r
228 test("s/x/y/","-----x123456789",n);
\r
229 test("s/x/y/","x123456789",n);
\r
230 test("s/x/y/","-----x",n);
\r
231 test("s/x.*?x/y/",".xx..x..x...x...x....x....x",n);
\r
232 test("s/x.*x/[$&]/","--x........x--xx",n);
\r
233 test("s/x.*x/[$&]/","--x........x------",n);
\r
234 test("s/.$/a/m","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb",n);
\r
235 test("s/.$/a/","123",n);
\r
236 test("s/.$/a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n);
\r
237 test("s/^./a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n);
\r
238 test("s/$/a/","bbb",n);
\r
239 test("s/^/a/","bbb",n);
\r
240 test("s/^/a/","",n);
\r
241 test("s{.*}{N}","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",n);
\r
242 test("s/.{0,7}/y/","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",n);
\r
243 test("s/x/$&/","xxx",n);
\r
245 System.out.println("Success!!!");
\r