diff --git a/pom.xml b/pom.xml index cb45d66..544e4a4 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ me.coley cafedude https://github.com/Col-E/CAFED00D/ - 1.0.1 + 1.1.0 CAFED00D diff --git a/src/main/java/me/coley/cafedude/ConstPool.java b/src/main/java/me/coley/cafedude/ConstPool.java index 553c8dc..5c2b325 100644 --- a/src/main/java/me/coley/cafedude/ConstPool.java +++ b/src/main/java/me/coley/cafedude/ConstPool.java @@ -2,7 +2,9 @@ import me.coley.cafedude.constant.ConstPoolEntry; -import java.util.ListIterator; +import java.util.Iterator; +import java.util.function.Function; +import java.util.function.Predicate; /** * Constant pool wrapper. @@ -82,10 +84,69 @@ public int size() { return last.getCpIndex(); } + /** + * @param entry + * Entry to fetch index of. Must not be {@code null}. + * + * @return Index in pool. {@code -1} if not in pool. + */ + public int indexOf(ConstPoolEntry entry) { + CpIter it = (CpIter) iterator(); + ConstPoolEntry itEntry = null; + while ((itEntry = it.next()) != null) { + if (entry.equals(itEntry)) + return it.currentIndex(); + } + return -1; + } + + + /** + * Removes all entries in the pool that matches the given filter. + * + * @param filter + * Filter for constant matching. + */ + public void removeIf(Predicate filter) { + CpIter it = (CpIter) iterator(); + ConstPoolEntry entry = null; + while ((entry = it.next()) != null) { + if (filter.test(entry)) + it.remove(); + } + } + + /** + * Replace all entries in the pool that matches the given filter. + * + * @param filter + * Filter for constant matching. + * @param replacer + * Function of old constant to replacement constant. + */ + public void replaceIf(Predicate filter, Function replacer) { + CpIter it = (CpIter) iterator(); + ConstPoolEntry entry = null; + while ((entry = it.next()) != null) { + if (filter.test(entry)) + it.replace(replacer.apply(entry)); + } + } + @Override - public ListIterator iterator() { + public Iterator iterator() { + assertNotEmpty(); + return new CpIter(first, true); + } + + /** + * Iterates over the constant pool from the last to the first. + * + * @return Backwards iterator. + */ + public Iterator backwardsIterator() { assertNotEmpty(); - return new CpIter(first); + return new CpIter(last, false); } /** @@ -124,8 +185,10 @@ private void assertNotEmpty() { /** * Linked list entry wrapper. + * + * @author Matt Coley */ - protected static class CpListNode { + public static class CpListNode { private ConstPoolEntry entry; private CpListNode next; private CpListNode prev; @@ -218,60 +281,60 @@ public void delete() { /** * Linked list iterator. + * + * @author Matt Coley */ - private static class CpIter implements ListIterator { + public static class CpIter implements Iterator { + private final boolean forward; private CpListNode current; - private CpIter(CpListNode initial) { + private CpIter(CpListNode initial, boolean forward) { current = initial; + this.forward = forward; } - @Override - public boolean hasNext() { - return current != null; - } - - @Override - public boolean hasPrevious() { - return current.prev != null; + /** + * @return Current index. + */ + public int currentIndex() { + return current.getCpIndex(); } - @Override - public int nextIndex() { - return current.getCpIndex() + current.getCpEntrySize(); + /** + * Replace the current constant pool entry. + * + * @param entry + * New constant pool entry. + */ + public void replace(ConstPoolEntry entry) { + if (forward) { + current.prev.set(entry); + } else { + current.next.set(entry); + } } @Override - public int previousIndex() { - return current.getCpIndex() - current.prev.getCpEntrySize(); + public boolean hasNext() { + return current != null; } @Override public ConstPoolEntry next() { ConstPoolEntry value = current.entry; - current = current.next; + current = forward ? current.next : current.prev; return value; - } - @Override - public ConstPoolEntry previous() { - current = current.prev; - return current.entry; } @Override public void remove() { - current.delete(); - } - - @Override - public void set(ConstPoolEntry entry) { - current.set(entry); - } - - @Override - public void add(ConstPoolEntry entry) { - current.insertAfter(entry); + // This is valid because to get the "current" value the user will have to call "next" + if (forward) { + current.prev.delete(); + } else { + current.next.delete(); + } } } }