--- /dev/null
+//\r
+// This software is now distributed according to\r
+// the Lesser Gnu Public License. Please see\r
+// http://www.gnu.org/copyleft/lesser.txt for\r
+// the details.\r
+// -- Happy Computing!\r
+//\r
+package com.stevesoft.pat;\r
+\r
+import java.io.*;\r
+import com.stevesoft.pat.wrap.*;\r
+\r
+/** This class allows you to replace the text in strings\r
+ as you read them in. Be careful what you do with\r
+ this freedom... using Regex.perlCode("s{.*}{x}s")\r
+ as your pattern will result in loading the entire\r
+ contents of the Reader into memory.\r
+ */\r
+public class RegexReader extends Reader {\r
+ RBuffer rb = new RBuffer(new StringBuffer());\r
+ PartialBuffer wrap = new PartialBuffer(rb.sb);\r
+ boolean moreToRead = true;\r
+ Reader r;\r
+ Replacer rp;\r
+\r
+ // the buffer size\r
+ int nmax = 2*1024;\r
+\r
+ public RegexReader(Regex rex,Reader r) {\r
+ this.r = r;\r
+ rp = rex.getReplacer();\r
+ }\r
+ public RegexReader(Transformer tex,Reader r) {\r
+ this.r = r;\r
+ rp = tex.getReplacer();\r
+ }\r
+ public void reset() throws IOException {\r
+ r.reset();\r
+ rb = new RBuffer(new StringBuffer());\r
+ wrap = new PartialBuffer(rb.sb);\r
+ moreToRead = true;\r
+ }\r
+ void readData() throws IOException {\r
+ int c;\r
+ int n = 0;\r
+ while( (c = r.read()) != -1) {\r
+ rb.sb.append((char)c);\r
+ if(n++ > nmax)\r
+ break;\r
+ }\r
+ if(c == -1 && n == 0) {\r
+ moreToRead = false;\r
+ wrap.allowOverRun = false;\r
+ }\r
+ }\r
+ void getMoreData() throws IOException {\r
+ while(rb.pos >= rb.epos) {\r
+ wrap.overRun = false;\r
+ if(rb.next != null) {\r
+ rb = rb.next;\r
+ } else if(rb.done) {\r
+ break;\r
+ } else if(rb.epos >= rb.sb.length()\r
+ && rb.epos > nmax) {\r
+ rb.pos = 1;\r
+ rb.epos = 1;\r
+ rb.sb.setLength(1);\r
+ readData();\r
+ } else if(rb.epos >= rb.sb.length()\r
+ && moreToRead) {\r
+ readData();\r
+ } else if(rp.getRegex().matchAt(wrap,rb.epos)) {\r
+ if(wrap.overRun) {\r
+ readData();\r
+ } else {\r
+ StringBufferWrap sbw = new StringBufferWrap();\r
+ StringBufferLike sbl = new StringBufferLike(sbw);\r
+ /*\r
+ ReplaceRule rr = rex.getReplaceRule();\r
+ while(rr != null) {\r
+ rr.apply(sbl,rex);\r
+ rr = rr.next;\r
+ }\r
+ */\r
+ Regex rex = rp.getRegex();\r
+ int npos = rex.matchedTo();\r
+ rp.setBuffer(sbl);\r
+ rp.setSource(wrap);\r
+ rp.setPos(npos);\r
+ rp.apply(rex,rex.getReplaceRule());\r
+ int opos = rb.epos;\r
+ RBuffer rb2 = new RBuffer((StringBuffer)sbw.unwrap());\r
+ rb2.epos = rb2.sb.length();\r
+ RBuffer rb3 = new RBuffer(rb.sb);\r
+\r
+ rb.next = rb2;\r
+ rb2.next = rb3;\r
+\r
+ if(npos == opos) {\r
+ rb3.epos = npos+1;\r
+ if(rb3.epos > rb3.sb.length()) {\r
+ if(rb.pos >= rb.epos)\r
+ rb = rb.next;\r
+ rb3.pos = rb3.epos = 0;\r
+ rb3.done = true;\r
+ //break;\r
+ }\r
+ rb3.pos = npos;\r
+ } else {\r
+ rb3.pos = rb3.epos = npos;\r
+ }\r
+\r
+ }\r
+ } else {\r
+ if(wrap.overRun) {\r
+ readData();\r
+ } else if(rb.epos<rb.sb.length()) {\r
+ rb.epos++;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public int read() throws IOException {\r
+ if(rb.pos >= rb.epos) {\r
+ getMoreData();\r
+ if(rb.pos >= rb.epos)\r
+ return -1;\r
+ }\r
+ //System.out.println(rb);\r
+ return rb.sb.charAt(rb.pos++);\r
+ }\r
+ public int read(char[] buf,int off,int len)\r
+ throws IOException\r
+ {\r
+ int c = -1;\r
+ int end = off+len;\r
+ for(int i=off;i<end;i++) {\r
+ c = read();\r
+ if(c < 0) {\r
+ if(i == off)\r
+ return -1;\r
+ return i-off;\r
+ }\r
+ buf[i] = (char)c;\r
+ }\r
+ return len;\r
+ }\r
+ public void close()\r
+ throws IOException\r
+ {\r
+ r.close();\r
+ }\r
+\r
+ public boolean markSupported() { return false; }\r
+\r
+ /** Get the size of the working buffer.\r
+ The current buffer may be larger if\r
+ the pattern demands it. */\r
+ public int getBufferSize() {\r
+ return nmax;\r
+ }\r
+ /** Set the size of the working buffer.\r
+ The current buffer may be larger if\r
+ the pattern demands it. */\r
+ public void setBufferSize(int n) {\r
+ nmax = n;\r
+ }\r
+\r
+ int max_lines = 2;\r
+ /** This function no longer serves any purpose.\r
+ @deprecated\r
+ */\r
+ public int getMaxLines() { return max_lines; }\r
+ /** This function no longer serves any purpose.\r
+ @deprecated\r
+ */\r
+ public void setMaxLines(int ml) { max_lines = ml; }\r
+\r
+ char EOLchar = '\n';\r
+ /** This function no longer serves any purpose.\r
+ @deprecated\r
+ */\r
+ public char getEOLchar() {\r
+ return EOLchar;\r
+ }\r
+ /** This function no longer serves any purpose.\r
+ @deprecated\r
+ */\r
+ public void setEOLchar(char c) {\r
+ EOLchar = c;\r
+ }\r
+\r
+ public long skip(long d) throws IOException {\r
+ // This is probably inefficient, I just did it\r
+ // this way to avoid possible bugs.\r
+ long n = 0;\r
+ while(n<d && read() != -1)\r
+ n++;\r
+ return n;\r
+ }\r
+\r
+ /*\r
+ static void test(String re,String inp,int n) throws Exception {\r
+ Reader r = new StringReader(inp);\r
+ r = new BufferedReader(r);\r
+ Regex rex = Regex.perlCode(re);\r
+ String res1 = rex.replaceAll(inp);\r
+ int c = -1;\r
+ StringBuffer sb = new StringBuffer();\r
+ RegexReader rr = new RegexReader(rex,r);\r
+ rr.setBufferSize(n);\r
+ while( (c = rr.read()) != -1)\r
+ sb.append((char)c);\r
+ String res2 = sb.toString();\r
+ if(!res1.equals(res2)) {\r
+ System.out.println("nmax="+n);\r
+ System.out.println("re="+re);\r
+ System.out.println("inp="+inp);\r
+ System.out.println("res1="+res1);\r
+ System.out.println("res2="+res2);\r
+ System.exit(255);\r
+ }\r
+ }\r
+ public static void main(String[] args) throws Exception {\r
+ for(int n=6;n<15;n++) {\r
+ test("s/x/y/","-----x123456789",n);\r
+ test("s/x/y/","x123456789",n);\r
+ test("s/x/y/","-----x",n);\r
+ test("s/x.*?x/y/",".xx..x..x...x...x....x....x",n);\r
+ test("s/x.*x/[$&]/","--x........x--xx",n);\r
+ test("s/x.*x/[$&]/","--x........x------",n);\r
+ test("s/.$/a/m","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb",n);\r
+ test("s/.$/a/","123",n);\r
+ test("s/.$/a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n);\r
+ test("s/^./a/","bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb",n);\r
+ test("s/$/a/","bbb",n);\r
+ test("s/^/a/","bbb",n);\r
+ test("s/^/a/","",n);\r
+ test("s{.*}{N}","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",n);\r
+ test("s/.{0,7}/y/","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",n);\r
+ test("s/x/$&/","xxx",n);\r
+ }\r
+ System.out.println("Success!!!");\r
+ }\r
+ */\r
+}\r