needed for applet search
[jalview.git] / src / com / stevesoft / pat / RegexReader.java
diff --git a/src/com/stevesoft/pat/RegexReader.java b/src/com/stevesoft/pat/RegexReader.java
new file mode 100755 (executable)
index 0000000..0ff33e3
--- /dev/null
@@ -0,0 +1,248 @@
+//\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