/****************************************************************************** * Copyright (C) 2012, 2013, 2014, 2015, 2016 * Younghyung Cho. <yhcting77@gmail.com> * All rights reserved. * * This file is part of NetMBuddy * * This program is licensed under the FreeBSD license * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation * are those of the authors and should not be interpreted as representing * official policies, either expressed or implied, of the FreeBSD Project. *****************************************************************************/ package free.yhc.netmbuddy.scmp; import free.yhc.baselib.Logger; /** * Package Private */ class DNLoop { private static final boolean DBG = Logger.DBG_DEFAULT; private static final Logger P = Logger.create(DNLoop.class, Logger.LOGLV_DEFAULT); private final Object[][] mLoopVals; private final IteratorListener mIterL; private int[] mLoopI; private Object mUser; interface IteratorListener { /** * * @param dnl DNLoop object * @param oVals iteration values * @return true : keep going. * false: stop iteration. */ boolean iter(DNLoop dnl, Object[] oVals); /** * * @param dnl DNLoop object * @param depth 0 : inner-most loop */ void end(DNLoop dnl, int depth); } /** * index '0' is 'inner-most loop'. * That is, 'loopVals[0][]' is loop-value-array of inner-most loop. * [ Example ] * loop <5> * loop <4> * loop <2> <= loopVals[0][2] */ DNLoop(Object[][] loopVals, IteratorListener iterL) { mLoopVals = loopVals; mIterL = iterL; mLoopI = new int[mLoopVals.length]; } Object getUser() { return mUser; } void setUser(Object user) { mUser = user; } void start(Object user) { mUser = user; // initialize loop index. for (int i = 0; i < mLoopI.length; i++) mLoopI[i] = 0; Object[] oVals = new Object[mLoopI.length]; boolean bDone = false; while (!bDone) { bDone = true; for (int i = 0; i < mLoopI.length; i++) { int lc = mLoopVals[i].length; // lc : Loop Count // is end of this loop? if (mLoopI[i] >= lc) { // end of this loop. if (null != mIterL) mIterL.end(this, i); if (i < (mLoopI.length -1)) { mLoopI[i] = 0; ++mLoopI[i + 1]; } } else { for (int j = 0; j < mLoopI.length; j++) oVals[j] = mLoopVals[j][mLoopI[j]]; ++mLoopI[0]; bDone = null != mIterL && !mIterL.iter(this, oVals); break; // exit from for-loop. } } } } @SuppressWarnings("unused") static void test() { String[][] oVals = new String[][] { new String[] {"a", "b"}, new String[] {"A", "B", "C"}, new String[] {"1", "2", "3", "4"}, }; IteratorListener iter = new IteratorListener() { @Override public boolean iter(DNLoop dnl, Object[] oVals) { String s = ""; for (Object o : oVals) s += o + " "; if (DBG) P.v("- " + s); return true; } @Override public void end(DNLoop dnl, int depth) { if (DBG) P.v("End : " + depth); } }; DNLoop dnl = new DNLoop(oVals, iter); dnl.start(null); } }