/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * JFlex 1.4.3 * * Copyright (C) 1998-2009 Gerwin Klein * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License. See the file * * COPYRIGHT for more information. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package JFlex; /** * Enumerates the states of a StateSet. * * @author Gerwin Klein * @version JFlex 1.4.3, $Revision: 433 $, $Date: 2009-01-31 19:52:34 +1100 (Sat, 31 Jan 2009) $ */ final public class StateSetEnumerator { private final static boolean DEBUG = false; private int index; private int offset; private long mask; private long [] bits; /** * creates a new StateSetEnumerator that is not yet associated * with a StateSet. hasMoreElements() and nextElement() will * throw NullPointerException when used before reset() */ public StateSetEnumerator() { } public StateSetEnumerator(StateSet states) { reset(states); } public void reset(StateSet states) { bits = states.bits; index = 0; offset = 0; mask = 1; while (index < bits.length && bits[index] == 0) index++; if (index >= bits.length) return; while (offset <= StateSet.MASK && ((bits[index] & mask) == 0)) { mask<<= 1; offset++; } } private void advance() { if (DEBUG) Out.dump("Advancing, at start, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ // cache fields in local variable for faster access int _index = this.index; int _offset = this.offset; long _mask = this.mask; long [] _bits = this.bits; long bi = _bits[_index]; do { _offset++; _mask<<= 1; } while (_offset <= StateSet.MASK && ((bi & _mask) == 0)); if (_offset > StateSet.MASK) { int length = _bits.length; do _index++; while (_index < length && _bits[_index] == 0); if (_index >= length) { this.index = length; // indicates "no more elements" return; } _offset = 0; _mask = 1; bi = _bits[_index]; // terminates, because bi != 0 while ((bi & _mask) == 0) { _mask<<= 1; _offset++; } } // write back cached values this.index = _index; this.mask = _mask; this.offset = _offset; } public boolean hasMoreElements() { if (DEBUG) Out.dump("hasMoreElements, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ return index < bits.length; } public int nextElement() { if (DEBUG) Out.dump("nextElement, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ int x = (index << StateSet.BITS) + offset; advance(); return x; } }