/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.fs.ntfs.index; import java.util.Iterator; import java.util.NoSuchElementException; import org.jnode.fs.ntfs.FileRecord; import org.jnode.fs.ntfs.NTFSStructure; /** * Iterator used to iterate over all IndexEntry's in an index block * or index_root attribute. * * @author Ewout Prangsma (epr@users.sourceforge.net) */ public final class IndexEntryIterator implements Iterator<IndexEntry> { private int offset; private IndexEntry nextEntry; private final NTFSStructure parent; private final FileRecord parentFileRecord; /** * Initialize this instance. */ public IndexEntryIterator(FileRecord parentFileRecord, NTFSStructure parent, int firstOffset) { this.offset = firstOffset; this.parentFileRecord = parentFileRecord; this.parent = parent; readNext(); } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { if (nextEntry == null) { return false; } return !nextEntry.isLastIndexEntryInSubnode() || nextEntry.hasSubNodes(); } /** * @see java.util.Iterator#next() */ public IndexEntry next() { if (nextEntry == null) { throw new NoSuchElementException(); } else { final IndexEntry result = nextEntry; final int size = nextEntry.getSize(); // Prevents an infinite loop. Seen on images where the size of the index entry has been zeroed out. if (size <= 0) { throw new IllegalStateException(String.format( "Index entry size is 0, filesystem is corrupt. Parent directory: '%s', reference number '%d'", nextEntry.getParentFileRecord().getFileName(), nextEntry.getParentFileRecord().getReferenceNumber())); } offset += size; // Now read the next next entry readNext(); return result; } } /** * @see java.util.Iterator#remove() */ public void remove() { throw new UnsupportedOperationException(); } private void readNext() { nextEntry = new IndexEntry(parentFileRecord, parent, offset); try { if (nextEntry.isLastIndexEntryInSubnode() && !nextEntry.hasSubNodes()) { nextEntry = null; } } catch (ArrayIndexOutOfBoundsException e) { // If the last entry in the sub-node doesn't have the right flags set, an out-of-bounds exception can be // raised trying to read the next entry that isn't there. E.g. offset 4088 in a 4096 block. Just ignore this // for now nextEntry = null; } } }