Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 17:01:39 GMT
  2. Package com.stevesoft.pat

File FastBracket.java

 

Coverage histogram

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

Code metrics

56
101
10
1
258
201
43
0.43
10.1
10
4.3

Classes

Class Line # Actions
FastBracket 18 101 43
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.util.BitSet;
11    import java.util.Vector;
12   
13    /**
14    * Uses table lookup to match [] type constructs, but only if it can use a
15    * lookup table 256 bits in size. It is impractical to make a table if it is too
16    * large.
17    */
 
18    public class FastBracket extends Bracket
19    {
20    int min, max;
21   
22    BitSet bs;
23   
 
24  0 toggle FastBracket(boolean n)
25    {
26  0 super(n);
27    }
28   
29    // This routine can optimize a bracket, possibly
30    // it will replace it with a FastBracket.
 
31  0 toggle static Bracket process(Bracket b, boolean ignc)
32    {
33  0 Vector v = b.v;
34  0 b.pv = null;
35  0 try
36    {
37   
38    // Expand out the vector to make separate
39    // entries for other cases if ignoreCase is
40    // turned on.
41  0 Vector nv = v;
42  0 if (ignc)
43    {
44  0 nv = new Vector();
45  0 for (int i = 0; i < v.size(); i++)
46    {
47  0 Pattern p = (Pattern) v.elementAt(i);
48  0 nv.addElement(p);
49  0 if (p instanceof oneChar)
50    {
51  0 oneChar oc = (oneChar) p;
52  0 nv.addElement(new oneChar(oc.altc));
53    }
54  0 else if (p instanceof Range)
55    {
56  0 Range ra = (Range) p;
57  0 nv.addElement(new Range(ra.altlo, ra.althi));
58    }
59    }
60    }
61  0 v = nv;
62   
63    // Bubble sort, make sure elements
64    // are in order. This will allow us
65    // to merge them.
66  0 for (int i = 0; i < v.size() - 1; i++)
67    {
68  0 for (int j = 0; j < v.size() - 1; j++)
69    {
70  0 char c1 = getl(v.elementAt(j));
71  0 char c2 = getl(v.elementAt(j + 1));
72  0 if (c2 < c1)
73    {
74  0 Object o = v.elementAt(j);
75  0 v.setElementAt(v.elementAt(j + 1), j);
76  0 v.setElementAt(o, j + 1);
77    }
78    }
79    }
80   
81  0 nv = new Vector();
82    // merge -- remove overlaps
83  0 Pattern p = (Pattern) v.elementAt(0);
84  0 nv.addElement(p);
85  0 for (int i = 1; i < v.size(); i++)
86    {
87  0 if (geth(p) + 1 >= getl(v.elementAt(i)))
88    {
89  0 Pattern p2 = (Pattern) v.elementAt(i);
90  0 char lo = min(getl(p), getl(p2));
91  0 char hi = max(geth(p), geth(p2));
92  0 nv.setElementAt(p = mkelem(lo, hi), nv.size() - 1);
93    }
94    else
95    {
96  0 p = (Pattern) v.elementAt(i);
97  0 nv.addElement(p);
98    }
99    }
100   
101  0 b.v = v = nv;
102    } catch (RegSyntax e)
103    {
104  0 e.printStackTrace();
105    }
106   
107    // We don't want these things to be empty.
108  0 Vector negv = neg(v);
109  0 if (v.size() == 1)
110    {
111  0 return b;
112    }
113  0 if (negv.size() == 1)
114    {
115  0 b.v = negv;
116  0 b.neg = !b.neg;
117  0 return b;
118    }
119   
120    // Now consider if we can make a FastBracket.
121    // Uses a BitSet to do a lookup.
122  0 FastBracket fb = newbrack(v, b.neg);
123  0 if (fb == null)
124    {
125  0 fb = newbrack(negv, !b.neg);
126    }
127  0 if (fb != null)
128    {
129  0 fb.parent = b.parent;
130  0 fb.next = b.next;
131  0 return fb;
132    }
133   
134    // return the normal Bracket.
135  0 return b;
136    }
137   
138    // Build a FastBracket and set bits. If this can't
139    // be done, return null.
 
140  0 toggle final static FastBracket newbrack(Vector v, boolean neg)
141    {
142  0 FastBracket fb = new FastBracket(neg);
143  0 fb.v = v;
144  0 if (v.size() == 0)
145    {
146  0 return null;
147    }
148  0 fb.min = getl(v.elementAt(0));
149  0 fb.max = geth(v.elementAt(v.size() - 1));
150  0 if (fb.max - fb.min <= 256)
151    {
152  0 fb.bs = new BitSet(fb.max - fb.min + 1);
153  0 for (int i = 0; i < v.size(); i++)
154    {
155  0 Object o = v.elementAt(i);
156  0 int min0 = getl(o) - fb.min;
157  0 int max0 = geth(o) - fb.min;
158  0 for (int j = min0; j <= max0; j++)
159    {
160  0 fb.bs.set(j);
161    }
162    }
163  0 return fb;
164    }
165  0 return null;
166    }
167   
168    // Negate a sorted Vector. Applying this
169    // operation twice should yield the same Vector
170    // back.
 
171  0 toggle final static Vector neg(Vector v)
172    {
173  0 try
174    {
175  0 Vector nv = new Vector();
176  0 if (v.size() == 0)
177    {
178  0 nv.addElement(new Range((char) 0, (char) 65535));
179  0 return nv;
180    }
181  0 int p0 = getl(v.elementAt(0));
182  0 if (p0 != 0)
183    {
184  0 nv.addElement(mkelem((char) 0, (char) (p0 - 1)));
185    }
186  0 for (int i = 0; i < v.size() - 1; i++)
187    {
188  0 int hi = getl(v.elementAt(i + 1)) - 1;
189  0 int lo = geth(v.elementAt(i)) + 1;
190  0 nv.addElement(mkelem((char) lo, (char) hi));
191    }
192  0 int pN = geth(v.lastElement());
193  0 if (pN != 65535)
194    {
195  0 nv.addElement(mkelem((char) (pN + 1), (char) 65535));
196    }
197  0 return nv;
198    } catch (RegSyntax rs)
199    {
200  0 return null;
201    }
202    }
203   
204    // Make either a Range or oneChar Object, depending on which
205    // is appropriate.
 
206  0 toggle final static Pattern mkelem(char lo, char hi) throws RegSyntax
207    {
208  0 return lo == hi ? (Pattern) (new oneChar(lo))
209    : (Pattern) (new Range(lo, hi));
210    }
211   
 
212  0 toggle static final char min(char a, char b)
213    {
214  0 return a < b ? a : b;
215    }
216   
 
217  0 toggle static final char max(char a, char b)
218    {
219  0 return a > b ? a : b;
220    }
221   
222    // getl -- get lower value of Range object,
223    // or get value of oneChar object.
 
224  0 toggle final static char getl(Object o)
225    {
226  0 Pattern p = (Pattern) o;
227  0 if (p instanceof Range)
228    {
229  0 return ((Range) p).lo;
230    }
231  0 return ((oneChar) p).c;
232    }
233   
234    // geth -- get higher value of Range object,
235    // or get value of oneChar object.
 
236  0 toggle final static char geth(Object o)
237    {
238  0 Pattern p = (Pattern) o;
239  0 if (p instanceof Range)
240    {
241  0 return ((Range) p).hi;
242    }
243  0 return ((oneChar) p).c;
244    }
245   
246    // This is the easy part!
 
247  0 toggle public int matchInternal(int pos, Pthings pt)
248    {
249  0 if (pos >= pt.src.length() || Masked(pos, pt))
250    {
251  0 return -1;
252    }
253  0 char c = pt.src.charAt(pos);
254  0 return (neg ^ (c >= min && c <= max && bs.get(c - min)))
255    ? nextMatch(pos + 1, pt)
256    : -1;
257    }
258    }