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