/* * This file is part of VLCJ. * * VLCJ is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VLCJ 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 VLCJ. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2009-2016 Caprica Software Limited. */ package uk.co.caprica.vlcj.player; import java.util.Iterator; import uk.co.caprica.vlcj.binding.LibVlc; import uk.co.caprica.vlcj.binding.internal.libvlc_media_list_t; import uk.co.caprica.vlcj.binding.internal.libvlc_media_t; /** * A one-time media list iterator. * <p> * For simplicities sake, and since this is a <em>private implementation * class</em>, the iterator may not be re-used and the implementation takes some liberties to ensure * that native resources are properly released. * <p> * Specifically, the native media instance for each sub-item must be explicitly released. The only * reliable place to carry this out is in the {@link #hasNext()} method implementation. * <p> * Consequently a user of this class <strong>must</strong> invoke {@link #hasNext()} after * processing each sub item. Since in any event this is the typical usage pattern for an iterator, * this is no big deal. * <p> * The reason that this class is used, despite the issues described above, is that it makes the code * in the media player implementation that deals with sub-items a lot simpler and reduces a lot of * code duplication when iterating the sub-items. */ class LibVlcMediaListIterator implements Iterable<libvlc_media_t>, Iterator<libvlc_media_t> { /** * Native library interface. */ private final LibVlc libvlc; /** * Native media list instance. */ private final libvlc_media_list_t mediaList; /** * Number of items in the media list. */ private final int count; /** * Current iteration index. */ private int index = -1; /** * Native instance for the current sub-item. */ private libvlc_media_t current; /** * Create a new media list iterable iterator. * * @param libvlc native library instance * @param mediaList native media list instance, may be <code>null</code> */ LibVlcMediaListIterator(LibVlc libvlc, libvlc_media_list_t mediaList) { this.libvlc = libvlc; this.mediaList = mediaList; this.count = mediaList != null ? libvlc.libvlc_media_list_count(mediaList) : 0; } @Override public Iterator<libvlc_media_t> iterator() { return this; } @Override public boolean hasNext() { // First release the current item if there is one... if(current != null) { libvlc.libvlc_media_release(current); current = null; } return mediaList != null && index + 1 < count; } @Override public libvlc_media_t next() { // Get the next item, this native handle must be released later current = libvlc.libvlc_media_list_item_at_index(mediaList, ++ index); return current; } @Override public void remove() { throw new UnsupportedOperationException(); } }