// // This software is now distributed according to // the Lesser Gnu Public License. Please see // http://www.gnu.org/copyleft/lesser.txt for // the details. // -- Happy Computing! // package com.stevesoft.pat; import java.util.*; /** Uses table lookup to match [] type constructs, but only if it can use a lookup table 256 bits in size. It is impractical to make a table if it is too large. */ public class FastBracket extends Bracket { int min, max; BitSet bs; FastBracket(boolean n) { super(n); } // This routine can optimize a bracket, possibly // it will replace it with a FastBracket. static Bracket process(Bracket b,boolean ignc) { Vector v = b.v; b.pv = null; try { // Expand out the vector to make separate // entries for other cases if ignoreCase is // turned on. Vector nv = v; if(ignc) { nv = new Vector(); for(int i=0;i= getl(v.elementAt(i))) { Pattern p2 = (Pattern)v.elementAt(i); char lo = min(getl(p),getl(p2)); char hi = max(geth(p),geth(p2)); nv.setElementAt(p=mkelem(lo,hi),nv.size()-1); } else { p = (Pattern)v.elementAt(i); nv.addElement(p); } } b.v = v = nv; } catch(RegSyntax e) { e.printStackTrace(); } // We don't want these things to be empty. Vector negv = neg(v); if(v.size()==1) return b; if(negv.size()==1) { b.v = negv; b.neg = !b.neg; return b; } // Now consider if we can make a FastBracket. // Uses a BitSet to do a lookup. FastBracket fb = newbrack(v,b.neg); if(fb == null) fb = newbrack(negv,!b.neg); if(fb != null) { fb.parent = b.parent; fb.next = b.next; return fb; } // return the normal Bracket. return b; } // Build a FastBracket and set bits. If this can't // be done, return null. final static FastBracket newbrack(Vector v,boolean neg) { FastBracket fb = new FastBracket(neg); fb.v = v; if(v.size()==0) return null; fb.min = getl(v.elementAt(0)); fb.max = geth(v.elementAt(v.size()-1)); if(fb.max-fb.min <= 256) { fb.bs = new BitSet(fb.max-fb.min+1); for(int i=0;ib ? a : b; } // getl -- get lower value of Range object, // or get value of oneChar object. final static char getl(Object o) { Pattern p = (Pattern)o; if(p instanceof Range) return ((Range)p).lo; return ((oneChar)p).c; } // geth -- get higher value of Range object, // or get value of oneChar object. final static char geth(Object o) { Pattern p = (Pattern)o; if(p instanceof Range) return ((Range)p).hi; return ((oneChar)p).c; } // This is the easy part! public int matchInternal(int pos,Pthings pt) { if(pos >= pt.src.length() || Masked(pos,pt)) return -1; char c = pt.src.charAt(pos); return (neg ^ (c >= min && c <= max && bs.get(c-min)) ) ? nextMatch(pos+1,pt) : -1; } }