Clover icon

Coverage Report

  1. Project Clover database Fri Nov 1 2024 11:46:37 GMT
  2. Package com.stevesoft.pat

File RegexWriter.java

 

Coverage histogram

../../../img/srcFileCovDistChart0.png
59% of files have more coverage

Code metrics

30
90
18
1
282
196
37
0.41
5
18
2.06

Classes

Class Line # Actions
RegexWriter 39 90 37
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    //
2    // This software is now distributed according to
3    // the Lesser Gnu Public License. Please see
4    // http://www.gnu.org/copyleft/lesser.txt for
5    // the details.
6    // -- Happy Computing!
7    //
8    package com.stevesoft.pat;
9   
10    import java.io.IOException;
11    import java.io.StringWriter;
12    import java.io.Writer;
13   
14    import com.stevesoft.pat.wrap.WriterWrap;
15   
16    /**
17    * A basic extension of FilterWriter that uses Transformer to make replacements
18    * in data as it is written out. It attempts to transform a string whenever the
19    * End-of-Line (EOL) character is written (which is, by default, the carriage
20    * return '\n'). Only the transformed portion of the line is written out,
21    * allowing the RegexWriter to wait until a complete pattern is present before
22    * attempting to write out info. Until a pattern completes, data is stored in a
23    * StringBuffer -- which can be accessed through the length() and charAt()
24    * methods of this class.
25    * <p>
26    * Note a subtlety here -- while a Transformer normally matches at higher
27    * priority against the pattern added to it first, this will not necessarily be
28    * true when a multi-line match is in progress because one of the complete
29    * multi-line patterns may not be completely loaded in RegexWriter's buffer. For
30    * this reason, the Transformer class is equipped with a way to add a pattern
31    * and replacement rule in three pieces -- a beginning (once this matches,
32    * nothing else in the Transformer can match until the whole pattern matches),
33    * an ending (the whole pattern is a String formed by adding the beginning and
34    * ending), and a ReplaceRule.
35    * <p>
36    * An illustration of this is given in the this
37    * <a href="../test/trans.java">example.</a>
38    */
 
39    public class RegexWriter extends Writer
40    {
41    Replacer repr;
42   
43    Writer w;
44   
45    WriterWrap ww;
46   
47    StringBuffer sb = new StringBuffer();
48   
49    PartialBuffer wrap = new PartialBuffer(sb);
50   
51    int pos, epos;
52   
53    int interval = 128;
54   
55    int bufferSize = 2 * 1024;
56   
 
57  0 toggle public RegexWriter(Transformer t, Writer w)
58    {
59  0 this.w = w;
60  0 ww = new WriterWrap(w);
61  0 repr = t.getReplacer();
62  0 repr.setBuffer(new StringBufferLike(ww));
63  0 repr.setSource(wrap);
64    }
65   
 
66  0 toggle public RegexWriter(Regex r, Writer w)
67    {
68  0 this.w = w;
69  0 ww = new WriterWrap(w);
70  0 repr = r.getReplacer();
71  0 repr.setBuffer(new StringBufferLike(ww));
72  0 repr.setSource(wrap);
73    }
74   
75    char EOLchar = '\n';
76   
77    /**
78    * This method no longer serves any purpose.
79    *
80    * @deprecated
81    */
 
82  0 toggle @Deprecated
83    public char getEOLchar()
84    {
85  0 return EOLchar;
86    }
87   
88    /**
89    * This method no longer serves any purpose.
90    *
91    * @deprecated
92    */
 
93  0 toggle @Deprecated
94    public void setEOLchar(char c)
95    {
96  0 EOLchar = c;
97    }
98   
99    int max_lines = 2;
100   
101    /**
102    * This method no longer serves any purpose.
103    *
104    * @deprecated
105    */
 
106  0 toggle @Deprecated
107    public int getMaxLines()
108    {
109  0 return max_lines;
110    }
111   
112    /**
113    * This method no longer serves any purpose.
114    *
115    * @deprecated
116    */
 
117  0 toggle @Deprecated
118    public void setMaxLines(int ml)
119    {
120  0 max_lines = ml;
121    }
122   
 
123  0 toggle void write() throws IOException
124    {
125  0 Regex rex = repr.getRegex();
126  0 int eposOld = epos;
127  0 if (rex.matchAt(wrap, epos) && !wrap.overRun)
128    {
129  0 while (pos < epos)
130    {
131  0 w.write(sb.charAt(pos++));
132    }
133  0 int to = rex.matchedTo();
134  0 repr.setPos(to);
135  0 repr.apply(rex, rex.getReplaceRule());
136  0 epos = pos = to;
137  0 if (epos == eposOld && epos < sb.length())
138    {
139  0 epos++;
140    }
141    }
142  0 else if (!wrap.overRun && epos < sb.length())
143    {
144  0 epos++;
145    }
146  0 while (pos < epos)
147    {
148  0 w.write(sb.charAt(pos++));
149    }
150  0 if (epos == sb.length())
151    {
152  0 sb.setLength(1);
153  0 pos = epos = 1;
154    }
155  0 else if (pos > bufferSize)
156    {
157  0 for (int i = bufferSize; i < sb.length(); i++)
158    {
159  0 sb.setCharAt(i - bufferSize, sb.charAt(i));
160    }
161  0 pos -= bufferSize;
162  0 epos -= bufferSize;
163  0 sb.setLength(sb.length() - bufferSize);
164    }
165    }
166   
 
167  0 toggle public void write(char[] ca, int b, int n) throws IOException
168    {
169  0 int m = b + n;
170  0 for (int i = b; i < m; i++)
171    {
172  0 sb.append(ca[i]);
173  0 if (sb.length() % interval == interval - 1)
174    {
175  0 wrap.overRun = false;
176  0 while (epos + interval < sb.length() && !wrap.overRun)
177    {
178  0 write();
179    }
180    }
181    }
182    }
183   
 
184  0 toggle public void flush() throws IOException
185    {
186    }
187   
 
188  0 toggle public void close() throws IOException
189    {
190  0 wrap.allowOverRun = false;
191  0 wrap.overRun = false;
192  0 while (epos < sb.length())
193    {
194  0 write();
195    }
196  0 write();
197  0 w.close();
198    }
199   
200    /** The current size of the StringBuffer in use by RegexWriter. */
 
201  0 toggle public int length()
202    {
203  0 return sb.length();
204    }
205   
206    /** The character at location i in the StringBuffer. */
 
207  0 toggle public char charAt(int i)
208    {
209  0 return sb.charAt(i);
210    }
211   
212    /** Set the interval at which regex patterns are checked. */
 
213  0 toggle public void setInterval(int i)
214    {
215  0 interval = i;
216    }
217   
218    /** Get the interval at which regex matches are checked. */
 
219  0 toggle public int getInterval()
220    {
221  0 return interval;
222    }
223   
224    /** Get the buffer size. */
 
225  0 toggle public int getBufferSize()
226    {
227  0 return bufferSize;
228    }
229   
230    /** Set the buffer size. */
 
231  0 toggle public void setBufferSize(int i)
232    {
233  0 bufferSize = i;
234    }
235   
 
236  0 toggle static void test(String re, String inp, int n) throws Exception
237    {
238  0 StringWriter sw = new StringWriter();
239  0 Regex rex = Regex.perlCode(re);
240  0 String res1 = rex.replaceAll(inp);
241  0 RegexWriter rw = new RegexWriter(rex, sw);
242  0 for (int i = 0; i < inp.length(); i++)
243    {
244  0 rw.write(inp.charAt(i));
245    }
246  0 rw.close();
247  0 String res2 = sw.toString();
248  0 if (!res1.equals(res2))
249    {
250  0 System.out.println("nmax=" + n);
251  0 System.out.println("re=" + re);
252  0 System.out.println("inp=" + inp);
253  0 System.out.println("res1=" + res1);
254  0 System.out.println("res2=" + res2);
255  0 System.exit(255);
256    }
257    }
258   
 
259  0 toggle public static void main(String[] args) throws Exception
260    {
261  0 for (int n = 1; n <= 1; n++)
262    {
263  0 test("s/x/y/", "-----x123456789", n);
264  0 test("s/x/y/", "x123456789", n);
265  0 test("s/x/y/", "-----x", n);
266  0 test("s/x.*?x/y/", ".xx..x..x...x...x....x....x", n);
267  0 test("s/x.*x/[$&]/", "--x........x--xx", n);
268  0 test("s/x.*x/[$&]/", "--x........x------", n);
269  0 test("s/.$/a/m", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbbbbbbbbbbbb", n);
270  0 test("s/.$/a/", "123", n);
271  0 test("s/.$/a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb", n);
272  0 test("s/^./a/", "bb\nbbb\nbbbb\nbbbbb\nbbbbbb\nbb", n);
273  0 test("s/$/a/", "bbb", n);
274  0 test("s/^/a/", "bbb", n);
275  0 test("s/^/a/", "", n);
276  0 test("s{.*}{N}", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", n);
277  0 test("s/.{0,7}/y/", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", n);
278  0 test("s/x/$&/", "xxx", n);
279    }
280  0 System.out.println("Success!!!");
281    }
282    }