diff options
author | Roman Shevchenko <roman.shevchenko@jetbrains.com> | 2014-08-28 20:52:43 +0400 |
---|---|---|
committer | Roman Shevchenko <roman.shevchenko@jetbrains.com> | 2014-08-28 20:52:43 +0400 |
commit | 663631f0456fcc245dd835889f86541d75161c53 (patch) | |
tree | e183fa9777242e2900ff3648a726f05b190bc51b /src/org/jetbrains/java/decompiler/util | |
parent | f864084061806fda5510e50bfd2e69bf1dea406b (diff) | |
download | fernflower-663631f0456fcc245dd835889f86541d75161c53.tar fernflower-663631f0456fcc245dd835889f86541d75161c53.tar.gz fernflower-663631f0456fcc245dd835889f86541d75161c53.tar.lz fernflower-663631f0456fcc245dd835889f86541d75161c53.tar.xz fernflower-663631f0456fcc245dd835889f86541d75161c53.zip |
java-decompiler: post-import cleanup (classes moved)
Diffstat (limited to 'src/org/jetbrains/java/decompiler/util')
10 files changed, 2823 insertions, 0 deletions
diff --git a/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java b/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java new file mode 100644 index 0000000..94b68b5 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java @@ -0,0 +1,50 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class DataInputFullStream extends DataInputStream { + + public DataInputFullStream(InputStream in) { + super(in); + } + + public final int readFull(byte b[]) throws IOException { + + int length = b.length; + byte[] btemp = new byte[length]; + int pos = 0; + + int bytes_read = -1; + for(;;) { + bytes_read = read(btemp, 0, length-pos); + if(bytes_read==-1) { + return -1; + } + + System.arraycopy(btemp, 0, b, pos, bytes_read); + pos+=bytes_read; + if(pos == length) { + break; + } + } + + return length; + } + +} diff --git a/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java b/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java new file mode 100644 index 0000000..524f50d --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java @@ -0,0 +1,363 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class FastFixedSetFactory<E> { + + private VBStyleCollection<int[], E> colValuesInternal = new VBStyleCollection<int[], E>(); + + private int dataLength; + + public FastFixedSetFactory(Collection<E> set) { + + dataLength = set.size() / 32 + 1; + + int index = 0; + int mask = 1; + + for(E element : set) { + + int block = index / 32; + + if(index % 32 == 0) { + mask = 1; + } + + colValuesInternal.putWithKey(new int[] {block, mask}, element); + + index++; + mask <<= 1; + } + } + + public FastFixedSet<E> spawnEmptySet() { + return new FastFixedSet<E>(this); + } + + private int getDataLength() { + return dataLength; + } + + private VBStyleCollection<int[], E> getInternalValuesCollection() { + return colValuesInternal; + } + + public static class FastFixedSet<E> implements Iterable<E> { + + private FastFixedSetFactory<E> factory; + + private VBStyleCollection<int[], E> colValuesInternal; + + private int[] data; + + + private FastFixedSet(FastFixedSetFactory<E> factory) { + this.factory = factory; + this.colValuesInternal = factory.getInternalValuesCollection(); + this.data = new int[factory.getDataLength()]; + } + + public FastFixedSet<E> getCopy() { + + FastFixedSet<E> copy = new FastFixedSet<E>(factory); + + int arrlength = data.length; + int[] cpdata = new int[arrlength]; + System.arraycopy(data, 0, cpdata, 0, arrlength); + copy.setData(cpdata); + + return copy; + } + + public void setAllElements() { + + int[] lastindex = colValuesInternal.get(colValuesInternal.size()-1); + + for(int i=lastindex[0]-1;i>=0;i--) { + data[i] = 0xFFFFFFFF; + } + + data[lastindex[0]] = lastindex[1] | (lastindex[1]-1); + } + + public void add(E element) { + int[] index = colValuesInternal.getWithKey(element); + data[index[0]] |= index[1]; + } + + public void addAll(Collection<E> set) { + for(E element : set) { + add(element); + } + } + + public void remove(E element) { + int[] index = colValuesInternal.getWithKey(element); + data[index[0]] &= ~index[1]; + } + + public void removeAll(Collection<E> set) { + for(E element : set) { + remove(element); + } + } + + public boolean contains(E element) { + int[] index = colValuesInternal.getWithKey(element); + return (data[index[0]] & index[1]) != 0; + } + + public boolean contains(FastFixedSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + if((extdata[i] & ~intdata[i]) != 0) { + return false; + } + } + + return true; + } + + public void union(FastFixedSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + intdata[i] |= extdata[i]; + } + } + + public void intersection(FastFixedSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + intdata[i] &= extdata[i]; + } + } + + public void symdiff(FastFixedSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + intdata[i] ^= extdata[i]; + } + } + + public void complement(FastFixedSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + intdata[i] &= ~extdata[i]; + } + } + + + public boolean equals(Object o) { + if(o == this) return true; + if(o == null || !(o instanceof FastFixedSet)) return false; + + int[] extdata = ((FastFixedSet)o).getData(); + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + if(intdata[i] != extdata[i]) { + return false; + } + } + + return true; + } + + public boolean isEmpty() { + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + if(intdata[i] != 0) { + return false; + } + } + + return true; + } + + public Iterator<E> iterator() { + return new FastFixedSetIterator<E>(this); + } + + public Set<E> toPlainSet() { + return toPlainCollection(new HashSet<E>()); + } + + public List<E> toPlainList() { + return toPlainCollection(new ArrayList<E>()); + } + + + private <T extends Collection<E>> T toPlainCollection(T cl) { + + int[] intdata = data; + for(int bindex=0; bindex < intdata.length; bindex++) { + int block = intdata[bindex]; + if(block != 0) { + int index = bindex << 5; // * 32 + for(int i = 31; i>=0; i--){ + if((block & 1) != 0) { + cl.add(colValuesInternal.getKey(index)); + } + index++; + block >>>= 1; + } + } + } + + return cl; + } + + public String toBinary() { + + StringBuilder buffer = new StringBuilder(); + int[] intdata = data; + + for(int i=0;i<intdata.length;i++) { + buffer.append(" ").append(Integer.toBinaryString(intdata[i])); + } + + return buffer.toString(); + } + + public String toString() { + + StringBuilder buffer = new StringBuilder("{"); + + int[] intdata = data; + boolean first = true; + + for(int i=colValuesInternal.size()-1;i>=0;i--) { + int[] index = colValuesInternal.get(i); + + if((intdata[index[0]] & index[1]) != 0) { + if(first) { + first = false; + } else { + buffer.append(","); + } + buffer.append(colValuesInternal.getKey(i)); + } + } + + buffer.append("}"); + + return buffer.toString(); + } + + private int[] getData() { + return data; + } + + private void setData(int[] data) { + this.data = data; + } + + public FastFixedSetFactory<E> getFactory() { + return factory; + } + } + + public static class FastFixedSetIterator<E> implements Iterator<E> { + + private VBStyleCollection<int[], E> colValuesInternal; + private int[] data; + private int size; + + private int pointer = -1; + private int next_pointer = -1; + + private FastFixedSetIterator(FastFixedSet<E> set) { + colValuesInternal = set.getFactory().getInternalValuesCollection(); + data = set.getData(); + size = colValuesInternal.size(); + } + + private int getNextIndex(int index) { + + index++; + int ret = index; + int bindex = index / 32; + int dindex = index % 32; + + while(bindex < data.length) { + int block = data[bindex]; + + if(block != 0) { + block >>>= dindex; + while(dindex < 32) { + if((block & 1) != 0) { + return ret; + } + block >>>= 1; + dindex++; + ret++; + } + } else { + ret += (32 - dindex); + } + + dindex = 0; + bindex++; + } + + return -1; + } + + public boolean hasNext() { + next_pointer = getNextIndex(pointer); + return (next_pointer >= 0); + } + + public E next() { + if(next_pointer >= 0) { + pointer = next_pointer; + } else { + pointer = getNextIndex(pointer); + if(pointer == -1) { + pointer = size; + } + } + + next_pointer = -1; + return pointer<size?colValuesInternal.getKey(pointer):null; + } + + public void remove() { + int[] index = colValuesInternal.get(pointer); + data[index[0]] &= ~index[1]; + } + + } + +} + diff --git a/src/org/jetbrains/java/decompiler/util/FastSetFactory.java b/src/org/jetbrains/java/decompiler/util/FastSetFactory.java new file mode 100644 index 0000000..4e5a631 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/FastSetFactory.java @@ -0,0 +1,486 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class FastSetFactory<E> { + + private VBStyleCollection<int[], E> colValuesInternal = new VBStyleCollection<int[], E>(); + + private int lastBlock; + + private int lastMask; + + public FastSetFactory(Collection<E> set) { + + int block = -1; + int mask = -1; + int index = 0; + + for(E element : set) { + + block = index / 32; + + if(index % 32 == 0) { + mask = 1; + } else { + mask <<= 1; + } + + colValuesInternal.putWithKey(new int[] {block, mask}, element); + + index++; + } + + lastBlock = block; + lastMask = mask; + } + + private int[] addElement(E element) { + + if(lastMask == -1 || lastMask == 0x80000000) { + lastMask = 1; + lastBlock++; + } else { + lastMask <<= 1; + } + + int[] pointer = new int[] {lastBlock, lastMask}; + colValuesInternal.putWithKey(pointer, element); + + return pointer; + } + + public FastSet<E> spawnEmptySet() { + return new FastSet<E>(this); + } + + public int getLastBlock() { + return lastBlock; + } + + public int getLastMask() { + return lastMask; + } + + private VBStyleCollection<int[], E> getInternalValuesCollection() { + return colValuesInternal; + } + + + public static class FastSet<E> implements Iterable<E> { + + private FastSetFactory<E> factory; + + private VBStyleCollection<int[], E> colValuesInternal; + + private int[] data; + + private FastSet(FastSetFactory<E> factory) { + this.factory = factory; + this.colValuesInternal = factory.getInternalValuesCollection(); + this.data = new int[factory.getLastBlock()+1]; + } + + public FastSet<E> getCopy() { + + FastSet<E> copy = new FastSet<E>(factory); + + int arrlength = data.length; + int[] cpdata = new int[arrlength]; + + System.arraycopy(data, 0, cpdata, 0, arrlength); + copy.setData(cpdata); + + return copy; + } + + private int[] ensureCapacity(int index) { + + int newlength = data.length; + if(newlength == 0) { + newlength = 1; + } + + while(newlength <= index) { + newlength *=2; + } + + int[] newdata = new int[newlength]; + System.arraycopy(data, 0, newdata, 0, data.length); + + return data = newdata; + } + + public void add(E element) { + int[] index = colValuesInternal.getWithKey(element); + + if(index == null) { + index = factory.addElement(element); + } + + if(index[0] >= data.length) { + ensureCapacity(index[0]); + } + + data[index[0]] |= index[1]; + } + + public void setAllElements() { + + int lastblock = factory.getLastBlock(); + int lastmask = factory.getLastMask(); + + if(lastblock >= data.length) { + ensureCapacity(lastblock); + } + + for(int i=lastblock-1;i>=0;i--) { + data[i] = 0xFFFFFFFF; + } + + data[lastblock] = lastmask | (lastmask-1); + } + + public void addAll(Set<E> set) { + for(E element : set) { + add(element); + } + } + + public void remove(E element) { + int[] index = colValuesInternal.getWithKey(element); + + if(index == null) { + index = factory.addElement(element); + } + + if(index[0] < data.length) { + data[index[0]] &= ~index[1]; + } + } + + public void removeAll(Set<E> set) { + for(E element : set) { + remove(element); + } + } + + public boolean contains(E element) { + int[] index = colValuesInternal.getWithKey(element); + + if(index == null) { + index = factory.addElement(element); + } + + return index[0] >= data.length?false:((data[index[0]] & index[1]) != 0); + } + + public boolean contains(FastSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + if((extdata[i] & ~intdata[i]) != 0) { + return false; + } + } + + for(int i=extdata.length-1;i>=minlength;i--) { + if(extdata[i] != 0) { + return false; + } + } + + return true; + } + + public void union(FastSet<E> set) { + + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + intdata[i] |= extdata[i]; + } + + boolean expanded = false; + for(int i=extdata.length-1;i>=minlength;i--) { + if(extdata[i] != 0) { + if(!expanded) { + intdata = ensureCapacity(extdata.length - 1); + } + intdata[i] = extdata[i]; + } + } + } + + public void intersection(FastSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + intdata[i] &= extdata[i]; + } + + for(int i=intdata.length-1;i>=minlength;i--) { + intdata[i] = 0; + } + + } + + public void symdiff(FastSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + intdata[i] ^= extdata[i]; + } + + boolean expanded = false; + for(int i=extdata.length-1;i>=minlength;i--) { + if(extdata[i] != 0) { + if(!expanded) { + intdata = ensureCapacity(extdata.length - 1); + } + intdata[i] = extdata[i]; + } + } + } + + public void complement(FastSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + intdata[i] &= ~extdata[i]; + } + } + + + public boolean equals(Object o) { + if(o == this) return true; + if(o == null || !(o instanceof FastSet)) return false; + + int[] longdata = ((FastSet)o).getData(); + int[] shortdata = data; + + if(data.length > longdata.length) { + shortdata = longdata; + longdata = data; + } + + for(int i=shortdata.length-1;i>=0;i--) { + if(shortdata[i] != longdata[i]) { + return false; + } + } + + for(int i=longdata.length-1;i>=shortdata.length;i--) { + if(longdata[i] != 0) { + return false; + } + } + + return true; + } + + public int getCardinality() { + + boolean found = false; + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + int block = intdata[i]; + if(block != 0) { + if(found) { + return 2; + } else { + if ((block & (block-1)) == 0) { + found = true; + } else { + return 2; + } + } + } + } + + return found?1:0; + } + + public int size() { + + int size = 0; + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + size+=Integer.bitCount(intdata[i]); + } + + return size; + } + + public boolean isEmpty() { + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + if(intdata[i] != 0) { + return false; + } + } + + return true; + } + + public Iterator<E> iterator() { + return new FastSetIterator<E>(this); + } + + public Set<E> toPlainSet() { + HashSet<E> set = new HashSet<E>(); + + int[] intdata = data; + + int size = data.length*32; + if(size > colValuesInternal.size()) { + size = colValuesInternal.size(); + } + + for(int i=size-1;i>=0;i--) { + int[] index = colValuesInternal.get(i); + + if((intdata[index[0]] & index[1]) != 0) { + set.add(colValuesInternal.getKey(i)); + } + } + + return set; + } + + public String toBinary() { + + StringBuilder buffer = new StringBuilder(); + int[] intdata = data; + + for(int i=0;i<intdata.length;i++) { + buffer.append(" ").append(Integer.toBinaryString(intdata[i])); + } + + return buffer.toString(); + } + + private int[] getData() { + return data; + } + + private void setData(int[] data) { + this.data = data; + } + + public int[] getLoad() { + int[] intdata = data; + int notempty = 0; + + for(int i=0;i<intdata.length;i++) { + if(intdata[i] != 0) { + notempty++; + } + } + + return new int[]{intdata.length, notempty}; + } + + public FastSetFactory<E> getFactory() { + return factory; + } + } + + public static class FastSetIterator<E> implements Iterator<E> { + + private VBStyleCollection<int[], E> colValuesInternal; + private int[] data; + private int size; + + private int pointer = -1; + private int next_pointer = -1; + + private FastSetIterator(FastSet<E> set) { + colValuesInternal = set.getFactory().getInternalValuesCollection(); + data = set.getData(); + + size = colValuesInternal.size(); + int datasize = data.length*32; + + if(datasize < size) { + size = datasize; + } + } + + public boolean hasNext() { + + next_pointer = pointer; + + while(++next_pointer < size) { + int[] index = colValuesInternal.get(next_pointer); + if((data[index[0]] & index[1]) != 0) { + return true; + } + } + + next_pointer = -1; + return false; + } + + public E next() { + if(next_pointer >= 0) { + pointer = next_pointer; + } else { + while(++pointer < size) { + int[] index = colValuesInternal.get(pointer); + if((data[index[0]] & index[1]) != 0) { + break; + } + } + } + + next_pointer = -1; + return pointer<size?colValuesInternal.getKey(pointer):null; + } + + public void remove() { + int[] index = colValuesInternal.get(pointer); + data[index[0]] &= ~index[1]; + + pointer--; + } + + } + +} + diff --git a/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java b/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java new file mode 100644 index 0000000..352dc2a --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java @@ -0,0 +1,549 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class FastSparseSetFactory<E> { + + private VBStyleCollection<int[], E> colValuesInternal = new VBStyleCollection<int[], E>(); + + private int lastBlock; + + private int lastMask; + + public FastSparseSetFactory(Collection<E> set) { + + int block = -1; + int mask = -1; + int index = 0; + + for(E element : set) { + + block = index / 32; + + if(index % 32 == 0) { + mask = 1; + } else { + mask <<= 1; + } + + colValuesInternal.putWithKey(new int[] {block, mask}, element); + + index++; + } + + lastBlock = block; + lastMask = mask; + } + + private int[] addElement(E element) { + + if(lastMask == -1 || lastMask == 0x80000000) { + lastMask = 1; + lastBlock++; + } else { + lastMask <<= 1; + } + + int[] pointer = new int[] {lastBlock, lastMask}; + colValuesInternal.putWithKey(pointer, element); + + return pointer; + } + + public FastSparseSet<E> spawnEmptySet() { + return new FastSparseSet<E>(this); + } + + public int getLastBlock() { + return lastBlock; + } + + public int getLastMask() { + return lastMask; + } + + private VBStyleCollection<int[], E> getInternalValuesCollection() { + return colValuesInternal; + } + + + public static class FastSparseSet<E> implements Iterable<E> { + + private FastSparseSetFactory<E> factory; + + private VBStyleCollection<int[], E> colValuesInternal; + + private int[] data; + private int[] next; + + private FastSparseSet(FastSparseSetFactory<E> factory) { + this.factory = factory; + this.colValuesInternal = factory.getInternalValuesCollection(); + + int length = factory.getLastBlock()+1; + this.data = new int[length]; + this.next = new int[length]; + } + + private FastSparseSet(FastSparseSetFactory<E> factory, int[] data, int[] next) { + this.factory = factory; + this.colValuesInternal = factory.getInternalValuesCollection(); + + this.data = data; + this.next = next; + } + + public FastSparseSet<E> getCopy() { + + int arrlength = data.length; + int[] cpdata = new int[arrlength]; + int[] cpnext = new int[arrlength]; + + System.arraycopy(data, 0, cpdata, 0, arrlength); + System.arraycopy(next, 0, cpnext, 0, arrlength); + + FastSparseSet<E> copy = new FastSparseSet<E>(factory, cpdata, cpnext); + + return copy; + } + + private int[] ensureCapacity(int index) { + + int newlength = data.length; + if(newlength == 0) { + newlength = 1; + } + + while(newlength <= index) { + newlength *=2; + } + + int[] newdata = new int[newlength]; + System.arraycopy(data, 0, newdata, 0, data.length); + data = newdata; + + int[] newnext = new int[newlength]; + System.arraycopy(next, 0, newnext, 0, next.length); + next = newnext; + + return newdata; + } + + public void add(E element) { + int[] index = colValuesInternal.getWithKey(element); + + if(index == null) { + index = factory.addElement(element); + } + + int block = index[0]; + if(block >= data.length) { + ensureCapacity(block); + } + + data[block] |= index[1]; + + changeNext(next, block, next[block], block); + } + + public void setAllElements() { + + int lastblock = factory.getLastBlock(); + int lastmask = factory.getLastMask(); + + if(lastblock >= data.length) { + ensureCapacity(lastblock); + } + + for(int i=lastblock-1;i>=0;i--) { + data[i] = 0xFFFFFFFF; + next[i] = i+1; + } + + data[lastblock] = lastmask | (lastmask-1); + next[lastblock] = 0; + } + + public void addAll(Set<E> set) { + for(E element : set) { + add(element); + } + } + + public void remove(E element) { + int[] index = colValuesInternal.getWithKey(element); + + if(index == null) { + index = factory.addElement(element); + } + + int block = index[0]; + if(block < data.length) { + data[block] &= ~index[1]; + + if(data[block] == 0) { + changeNext(next, block, block, next[block]); + } + } + } + + public void removeAll(Set<E> set) { + for(E element : set) { + remove(element); + } + } + + public boolean contains(E element) { + int[] index = colValuesInternal.getWithKey(element); + + if(index == null) { + index = factory.addElement(element); + } + + return index[0] >= data.length?false:((data[index[0]] & index[1]) != 0); + } + + public boolean contains(FastSparseSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + if((extdata[i] & ~intdata[i]) != 0) { + return false; + } + } + + for(int i=extdata.length-1;i>=minlength;i--) { + if(extdata[i] != 0) { + return false; + } + } + + return true; + } + + private void setNext() { + + int link = 0; + for(int i=data.length-1;i>=0;i--) { + next[i] = link; + if(data[i] != 0) { + link = i; + } + } + } + + private void changeNext(int[] arrnext, int key, int oldnext, int newnext) { + for(int i=key-1;i>=0;i--) { + if(arrnext[i] == oldnext) { + arrnext[i] = newnext; + } else { + break; + } + } + } + + public void union(FastSparseSet<E> set) { + + int[] extdata = set.getData(); + int[] extnext = set.getNext(); + int[] intdata = data; + int intlength = intdata.length; + + int pointer = 0; + do { + if(pointer >= intlength) { + intdata = ensureCapacity(extdata.length - 1); + } + + boolean nextrec = (intdata[pointer] == 0); + intdata[pointer] |= extdata[pointer]; + + if(nextrec) { + changeNext(next, pointer, next[pointer], pointer); + } + + pointer = extnext[pointer]; + + } while(pointer!=0); + } + + public void intersection(FastSparseSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + intdata[i] &= extdata[i]; + } + + for(int i=intdata.length-1;i>=minlength;i--) { + intdata[i] = 0; + } + + setNext(); + } + + public void symdiff(FastSparseSet<E> set) { + int[] extdata = set.getData(); + int[] intdata = data; + + int minlength = Math.min(extdata.length, intdata.length); + + for(int i=minlength-1;i>=0;i--) { + intdata[i] ^= extdata[i]; + } + + boolean expanded = false; + for(int i=extdata.length-1;i>=minlength;i--) { + if(extdata[i] != 0) { + if(!expanded) { + intdata = ensureCapacity(extdata.length - 1); + } + intdata[i] = extdata[i]; + } + } + + setNext(); + } + + public void complement(FastSparseSet<E> set) { + + int[] extdata = set.getData(); + int[] intdata = data; + int extlength = extdata.length; + + int pointer = 0; + do { + if(pointer >= extlength) { + break; + } + + intdata[pointer] &= ~extdata[pointer]; + if(intdata[pointer] == 0) { + changeNext(next, pointer, pointer, next[pointer]); + } + + pointer = next[pointer]; + + } while(pointer!=0); + } + + + public boolean equals(Object o) { + if(o == this) return true; + if(o == null || !(o instanceof FastSparseSet)) return false; + + int[] longdata = ((FastSparseSet)o).getData(); + int[] shortdata = data; + + if(data.length > longdata.length) { + shortdata = longdata; + longdata = data; + } + + for(int i=shortdata.length-1;i>=0;i--) { + if(shortdata[i] != longdata[i]) { + return false; + } + } + + for(int i=longdata.length-1;i>=shortdata.length;i--) { + if(longdata[i] != 0) { + return false; + } + } + + return true; + } + + public int getCardinality() { + + boolean found = false; + int[] intdata = data; + + for(int i=intdata.length-1;i>=0;i--) { + int block = intdata[i]; + if(block != 0) { + if(found) { + return 2; + } else { + if ((block & (block-1)) == 0) { + found = true; + } else { + return 2; + } + } + } + } + + return found?1:0; + } + + public boolean isEmpty() { + return data.length == 0 || (next[0] == 0 && data[0] == 0); + } + + public Iterator<E> iterator() { + return new FastSparseSetIterator<E>(this); + } + + public Set<E> toPlainSet() { + HashSet<E> set = new HashSet<E>(); + + int[] intdata = data; + + int size = data.length*32; + if(size > colValuesInternal.size()) { + size = colValuesInternal.size(); + } + + for(int i=size-1;i>=0;i--) { + int[] index = colValuesInternal.get(i); + + if((intdata[index[0]] & index[1]) != 0) { + set.add(colValuesInternal.getKey(i)); + } + } + + return set; + } + + public String toString() { + return toPlainSet().toString(); + } + + public String toBinary() { + + StringBuilder buffer = new StringBuilder(); + int[] intdata = data; + + for(int i=0;i<intdata.length;i++) { + buffer.append(" ").append(Integer.toBinaryString(intdata[i])); + } + + return buffer.toString(); + } + + private int[] getData() { + return data; + } + + private int[] getNext() { + return next; + } + + public int[] getLoad() { + int[] intdata = data; + int notempty = 0; + + for(int i=0;i<intdata.length;i++) { + if(intdata[i] != 0) { + notempty++; + } + } + + return new int[]{intdata.length, notempty}; + } + + public FastSparseSetFactory<E> getFactory() { + return factory; + } + } + + public static class FastSparseSetIterator<E> implements Iterator<E> { + + private VBStyleCollection<int[], E> colValuesInternal; + private int[] data; + private int[] next; + private int size; + + private int pointer = -1; + private int next_pointer = -1; + + private FastSparseSetIterator(FastSparseSet<E> set) { + colValuesInternal = set.getFactory().getInternalValuesCollection(); + data = set.getData(); + next = set.getNext(); + size = colValuesInternal.size(); + } + + private int getNextIndex(int index) { + + index++; + int bindex = index >>> 5; + int dindex = index & 0x1F; + + while(bindex < data.length) { + int block = data[bindex]; + + if(block != 0) { + block >>>= dindex; + while(dindex < 32) { + if((block & 1) != 0) { + return (bindex << 5) + dindex; + } + block >>>= 1; + dindex++; + } + } + + dindex = 0; + bindex = next[bindex]; + + if(bindex == 0) { + break; + } + } + + return -1; + } + + public boolean hasNext() { + next_pointer = getNextIndex(pointer); + return (next_pointer >= 0); + } + + public E next() { + if(next_pointer >= 0) { + pointer = next_pointer; + } else { + pointer = getNextIndex(pointer); + if(pointer == -1) { + pointer = size; + } + } + + next_pointer = -1; + return pointer<size?colValuesInternal.getKey(pointer):null; + } + + public void remove() { + int[] index = colValuesInternal.get(pointer); + data[index[0]] &= ~index[1]; + } + + } + +} + diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java new file mode 100644 index 0000000..4914d36 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -0,0 +1,157 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.channels.FileChannel; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; + +public class InterpreterUtil { + + public static void copyFile(File in, File out) throws IOException { + FileChannel inChannel = new FileInputStream(in).getChannel(); + FileChannel outChannel = new FileOutputStream(out).getChannel(); + try { + // magic number for Windows, 64Mb - 32Kb) + int maxCount = (64 * 1024 * 1024) - (32 * 1024); + long size = inChannel.size(); + long position = 0; + while (position < size) { + position += inChannel.transferTo(position, maxCount, outChannel); + } + } catch (IOException e) { + throw e; + } + finally { + if (inChannel != null) { + inChannel.close(); + } + if (outChannel != null) { + outChannel.close(); + } + } + } + + public static void copyInputStream(InputStream in, OutputStream out)throws IOException { + + byte[] buffer = new byte[1024]; + int len; + + while((len = in.read(buffer)) >= 0) { + out.write(buffer, 0, len); + } + + } + + public static String getIndentString(int length) { + String indent = (String) DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING); + StringBuilder buf = new StringBuilder(); + while(length-->0) { + buf.append(indent); + } + return buf.toString(); + } + + + public static boolean equalSets(Collection<?> c1, Collection<?> c2) { + + if(c1 == null) { + return c2 == null?true:false; + } else { + if(c2 == null) { + return false; + } + } + + if(c1.size() != c2.size()) { + return false; + } + + HashSet<?> set = new HashSet(c1); + set.removeAll(c2); + + return (set.size() == 0); + } + + public static boolean equalObjects(Object first, Object second) { + return first==null?second==null:first.equals(second); + } + + public static boolean equalObjectArrays(Object[] first, Object[] second) { + + if(first == null || second == null) { + return equalObjects(first, second); + } else { + if(first.length != second.length) { + return false; + } + + for(int i=0;i<first.length;i++) { + if(!equalObjects(first[i], second[i])) { + return false; + } + } + } + + return true; + } + + public static boolean equalLists(List<?> first, List<?> second) { + + if(first == null) { + return second == null; + } else if(second == null) { + return first == null; + } + + if(first.size() == second.size()) { + for(int i=0;i<first.size();i++) { + if(!equalObjects(first.get(i), second.get(i))) { + return false; + } + } + return true; + } + + return false; + } + + public static boolean isPrintableUnicode(char c) { + int t = Character.getType(c); + return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR && + t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE; + } + + public static String charToUnicodeLiteral(int value) { + String sTemp = Integer.toHexString(value); + sTemp = ("0000"+sTemp).substring(sTemp.length()); + return "\\u"+sTemp; + } + + public static String makeUniqueKey(String name, String descriptor) { + return name+" "+descriptor; + } + +} diff --git a/src/org/jetbrains/java/decompiler/util/ListStack.java b/src/org/jetbrains/java/decompiler/util/ListStack.java new file mode 100644 index 0000000..fa36a0b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/ListStack.java @@ -0,0 +1,101 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.util.ArrayList; + +public class ListStack<T> extends ArrayList<T> { + + protected int pointer = 0; + + public ListStack(){ + super(); + } + + public ListStack(ArrayList<T> list){ + super(list); + } + + public ListStack<T> clone() { + ListStack<T> newstack = new ListStack<T>(this); + newstack.pointer = this.pointer; + return newstack; + } + + public T push(T item) { + this.add(item); + pointer++; + return item; + } + + public T pop() { + pointer--; + T o = this.get(pointer); + this.remove(pointer); + return o; + } + + public T pop(int count) { + T o = null; + for(int i=count;i>0;i--) { + o = this.pop(); + } + return o; + } + + public void remove() { + pointer--; + this.remove(pointer); + } + + public void removeMultiple(int count) { + while(count>0) { + pointer--; + this.remove(pointer); + count--; + } + } + + public boolean empty() { + return (pointer==0); + } + + public int getPointer() { + return pointer; + } + + public T get(int index) { + return super.get(index); + } + + public T set(int index, T element) { + return super.set(index, element); + } + + public T getByOffset(int offset) { + return this.get(pointer+offset); + } + + public void insertByOffset(int offset, T item) { + this.add(pointer+offset, item); + pointer++; + } + + public void clear() { + super.clear(); + pointer = 0; + } + +} diff --git a/src/org/jetbrains/java/decompiler/util/SFormsFastMap.java b/src/org/jetbrains/java/decompiler/util/SFormsFastMap.java new file mode 100644 index 0000000..546e32e --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/SFormsFastMap.java @@ -0,0 +1,232 @@ +package org.jetbrains.java.decompiler.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; + +public class SFormsFastMap<E> { + + private int size; + + private List<E[]> lstElements = new ArrayList<E[]>(3); + + { + lstElements.add((E[])new Object[5]); + lstElements.add((E[])new Object[5]); + lstElements.add((E[])new Object[5]); + } + + public SFormsFastMap() {} + + public SFormsFastMap(SFormsFastMap<E> map) { + for(int i=2;i>=0;i--) { + E[] arr = map.lstElements.get(i); + E[] arrnew = (E[])new Object[arr.length]; + + System.arraycopy(arr, 0, arrnew, 0, arr.length); + + lstElements.set(i, arrnew); + + for(E element : arrnew) { + if(element != null) { + size++; + } + } + } + + } + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public void put(int key, E value) { + putInternal(key, value, false); + } + + public void remove(int key) { + putInternal(key, null, true); + } + + public void removeAllFields() { + E[] arr = lstElements.get(2); + for(int i=arr.length-1;i>=0;i--) { + E val = arr[i]; + if(val != null) { + arr[i] = null; + size--; + } + } + } + + public void putInternal(final int key, final E value, boolean remove) { + + int index = 0; + int ikey = key; + if(ikey < 0) { + index = 2; + ikey = -ikey; + } else if(ikey >= VarExprent.STACK_BASE) { + index = 1; + ikey -= VarExprent.STACK_BASE; + } + + E[] arr = lstElements.get(index); + if(ikey >= arr.length) { + if(remove) { + return; + } else { + arr = ensureCapacity(arr, ikey+1, false); + lstElements.set(index, arr); + } + } + + E oldval = arr[ikey]; + arr[ikey] = value; + + if(oldval == null && value != null) { + size++; + } else if(oldval != null && value == null) { + size--; + } + } + + public boolean containsKey(int key) { + return get(key) != null; + } + + public E get(int key) { + + int index = 0; + if(key < 0) { + index = 2; + key = -key; + } else if(key >= VarExprent.STACK_BASE) { + index = 1; + key -= VarExprent.STACK_BASE; + } + + E[] arr = lstElements.get(index); + + if(key < arr.length) { + return arr[key]; + } + return null; + } + + public void union(SFormsFastMap<E> map, IElementsUnion<E> union) { + + for(int i=2;i>=0;i--) { + E[] lstOwn = lstElements.get(i); + E[] lstExtern = map.lstElements.get(i); + + int externsize = lstExtern.length; + + if(lstOwn.length<externsize) { + lstOwn = ensureCapacity(lstOwn, externsize, true); + lstElements.set(i, lstOwn); + } + + int ownsize = lstOwn.length; + int minsize = ownsize>externsize?externsize:ownsize; + + for(int j=minsize-1;j>=0;j--) { + E second = lstExtern[j]; + + if(second != null) { + E first = lstOwn[j]; + + if(first == null) { + lstOwn[j] = union.copy(second); + size++; + } else { + union.union(first, second); + } + } + } + +// ITimer timer = TimerFactory.newTimer(); +// timer.start(); +// +// if(externsize > minsize) { +// for(int j=minsize;j<externsize;j++) { +// E second = lstExtern.get(j); +// if(second != null) { +// lstOwn.add(union.copy(second)); +// size++; +// } else { +// lstOwn.add(null); +// } +// } +// } +// +// timer.stop(); +// Timer.addTime("sformunion", timer.getDuration()); + + } + + } + + public List<Entry<Integer, E>> entryList() { + List<Entry<Integer, E>> list = new ArrayList<Entry<Integer, E>>(); + + for(int i=2;i>=0;i--) { + int ikey = 0; + for(final E ent : lstElements.get(i)) { + if(ent != null) { + final int key = i==0?ikey:(i==1?ikey+VarExprent.STACK_BASE:-ikey); + + list.add(new Entry<Integer, E>() { + + private Integer var = key; + private E val = ent; + + public Integer getKey() { + return var; + } + + public E getValue() { + return val; + } + + public E setValue(E newvalue) { + return null; + } + }); + } + + ikey++; + } + } + + return list; + } + + private E[] ensureCapacity(E[] arr, int size, boolean exact) { + + int minsize = size; + if(!exact) { + minsize = 2*arr.length/3 +1; + if(size > minsize) { + minsize = size; + } + } + + E[] arrnew = (E[])new Object[minsize]; + System.arraycopy(arr, 0, arrnew, 0, arr.length); + + return arrnew; + } + + public static interface IElementsUnion<E> { + public E union(E first, E second); + public E copy(E element); + } + +} diff --git a/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java b/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java new file mode 100644 index 0000000..615162f --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java @@ -0,0 +1,411 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.Map.Entry; + +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; +import org.jetbrains.java.decompiler.util.FastSparseSetFactory.FastSparseSet; + +public class SFormsFastMapDirect { + + private int size; + + private FastSparseSet<Integer>[][] elements = new FastSparseSet[3][]; + + private int[][] next = new int[3][]; + + public SFormsFastMapDirect() { + this(true); + } + + private SFormsFastMapDirect(boolean initialize) { + if(initialize) { + for(int i=2; i>=0; i--) { + elements[i] = new FastSparseSet[0]; + next[i] = new int[0]; + } + } + } + + public SFormsFastMapDirect(SFormsFastMapDirect map) { + for(int i=2;i>=0;i--) { + FastSparseSet<Integer>[] arr = map.elements[i]; + int[] arrnext = map.next[i]; + + int length = arr.length; + FastSparseSet<Integer>[] arrnew = new FastSparseSet[length]; + int[] arrnextnew = new int[length]; + + System.arraycopy(arr, 0, arrnew, 0, length); + System.arraycopy(arrnext, 0, arrnextnew, 0, length); + + elements[i] = arrnew; + next[i] = arrnextnew; + + size = map.size; + } + } + + public SFormsFastMapDirect getCopy() { + + SFormsFastMapDirect map = new SFormsFastMapDirect(false); + map.size = size; + + FastSparseSet[][] mapelements = map.elements; + int[][] mapnext = map.next; + + for(int i=2;i>=0;i--) { + FastSparseSet<Integer>[] arr = elements[i]; + int length = arr.length; + + if(length > 0) { + int[] arrnext = next[i]; + + FastSparseSet<Integer>[] arrnew = new FastSparseSet[length]; + int[] arrnextnew = new int[length]; + + System.arraycopy(arrnext, 0, arrnextnew, 0, length); + + mapelements[i] = arrnew; + mapnext[i] = arrnextnew; + + int pointer = 0; + do { + FastSparseSet<Integer> set = arr[pointer]; + if(set != null) { + arrnew[pointer] = set.getCopy(); + } + + pointer = arrnext[pointer]; + } while(pointer != 0); + + } else { + mapelements[i] = new FastSparseSet[0]; + mapnext[i] = new int[0]; + } + } + + return map; + } + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public void put(int key, FastSparseSet<Integer> value) { + putInternal(key, value, false); + } + + public void remove(int key) { + putInternal(key, null, true); + } + + public void removeAllFields() { + FastSparseSet<Integer>[] arr = elements[2]; + int[] arrnext = next[2]; + + for(int i=arr.length-1;i>=0;i--) { + FastSparseSet<Integer> val = arr[i]; + if(val != null) { + arr[i] = null; + size--; + } + arrnext[i] = 0; + } + } + + public void putInternal(final int key, final FastSparseSet<Integer> value, boolean remove) { + + int index = 0; + int ikey = key; + if(ikey < 0) { + index = 2; + ikey = -ikey; + } else if(ikey >= VarExprent.STACK_BASE) { + index = 1; + ikey -= VarExprent.STACK_BASE; + } + + FastSparseSet<Integer>[] arr = elements[index]; + if(ikey >= arr.length) { + if(remove) { + return; + } else { + arr = ensureCapacity(index, ikey+1, false); + } + } + + FastSparseSet<Integer> oldval = arr[ikey]; + arr[ikey] = value; + + int[] arrnext = next[index]; + + if(oldval == null && value != null) { + size++; + changeNext(arrnext, ikey, arrnext[ikey], ikey); + } else if(oldval != null && value == null) { + size--; + changeNext(arrnext, ikey, ikey, arrnext[ikey]); + } + } + + private void changeNext(int[] arrnext, int key, int oldnext, int newnext) { + for(int i=key-1;i>=0;i--) { + if(arrnext[i] == oldnext) { + arrnext[i] = newnext; + } else { + break; + } + } + } + + public boolean containsKey(int key) { + return get(key) != null; + } + + public FastSparseSet<Integer> get(int key) { + + int index = 0; + if(key < 0) { + index = 2; + key = -key; + } else if(key >= VarExprent.STACK_BASE) { + index = 1; + key -= VarExprent.STACK_BASE; + } + + FastSparseSet<Integer>[] arr = elements[index]; + + if(key < arr.length) { + return arr[key]; + } + return null; + } + + public void complement(SFormsFastMapDirect map) { + + for(int i=2;i>=0;i--) { + FastSparseSet<Integer>[] lstOwn = elements[i]; + + if(lstOwn.length == 0) { + continue; + } + + FastSparseSet<Integer>[] lstExtern = map.elements[i]; + int[] arrnext = next[i]; + + int pointer = 0; + do { + FastSparseSet<Integer> first = lstOwn[pointer]; + + if(first != null) { + if(pointer >= lstExtern.length) { + break; + } + FastSparseSet<Integer> second = lstExtern[pointer]; + + if(second != null) { + first.complement(second); + if(first.isEmpty()) { + lstOwn[pointer] = null; + size--; + changeNext(arrnext, pointer, pointer, arrnext[pointer]); + } + } + } + + pointer = arrnext[pointer]; + + } while(pointer != 0); + + } + + } + + public void intersection(SFormsFastMapDirect map) { + + for(int i=2;i>=0;i--) { + FastSparseSet<Integer>[] lstOwn = elements[i]; + + if(lstOwn.length == 0) { + continue; + } + + FastSparseSet<Integer>[] lstExtern = map.elements[i]; + int[] arrnext = next[i]; + + int pointer = 0; + do { + FastSparseSet<Integer> first = lstOwn[pointer]; + + if(first != null) { + FastSparseSet<Integer> second = null; + if(pointer < lstExtern.length) { + second = lstExtern[pointer]; + } + + if(second != null) { + first.intersection(second); + } + + if(second == null || first.isEmpty()) { + lstOwn[pointer] = null; + size--; + changeNext(arrnext, pointer, pointer, arrnext[pointer]); + } + } + + pointer = arrnext[pointer]; + + } while(pointer != 0); + + } + + } + + public void union(SFormsFastMapDirect map) { + + for(int i=2;i>=0;i--) { + FastSparseSet<Integer>[] lstExtern = map.elements[i]; + + if(lstExtern.length == 0) { + continue; + } + + FastSparseSet<Integer>[] lstOwn = elements[i]; + int[] arrnext = next[i]; + int[] arrnextExtern = map.next[i]; + + int pointer = 0; + do { + if(pointer >= lstOwn.length) { + lstOwn = ensureCapacity(i, lstExtern.length, true); + arrnext = next[i]; + } + + FastSparseSet<Integer> second = lstExtern[pointer]; + + if(second != null) { + FastSparseSet<Integer> first = lstOwn[pointer]; + + if(first == null) { + lstOwn[pointer] = second.getCopy(); + size++; + changeNext(arrnext, pointer, arrnext[pointer], pointer); + } else { + first.union(second); + } + } + + pointer = arrnextExtern[pointer]; + + } while(pointer != 0); + + } + + } + + public String toString() { + + StringBuilder buffer = new StringBuilder("{"); + + List<Entry<Integer, FastSparseSet<Integer>>> lst = entryList(); + if(lst != null) { + boolean first = true; + for(Entry<Integer, FastSparseSet<Integer>> entry : lst) { + if(!first) { + buffer.append(", "); + } else { + first = false; + } + + Set<Integer> set = entry.getValue().toPlainSet(); + buffer.append(entry.getKey()+"={"+set.toString()+"}"); + } + } + + buffer.append("}"); + return buffer.toString(); + } + + public List<Entry<Integer, FastSparseSet<Integer>>> entryList() { + List<Entry<Integer, FastSparseSet<Integer>>> list = new ArrayList<Entry<Integer, FastSparseSet<Integer>>>(); + + for(int i=2;i>=0;i--) { + int ikey = 0; + for(final FastSparseSet<Integer> ent : elements[i]) { + if(ent != null) { + final int key = i==0?ikey:(i==1?ikey+VarExprent.STACK_BASE:-ikey); + + list.add(new Entry<Integer, FastSparseSet<Integer>>() { + + private Integer var = key; + private FastSparseSet<Integer> val = ent; + + public Integer getKey() { + return var; + } + + public FastSparseSet<Integer> getValue() { + return val; + } + + public FastSparseSet<Integer> setValue(FastSparseSet<Integer> newvalue) { + return null; + } + }); + } + + ikey++; + } + } + + return list; + } + + private FastSparseSet<Integer>[] ensureCapacity(int index, int size, boolean exact) { + + FastSparseSet<Integer>[] arr = elements[index]; + int[] arrnext = next[index]; + + int minsize = size; + if(!exact) { + minsize = 2*arr.length/3 +1; + if(size > minsize) { + minsize = size; + } + } + + FastSparseSet<Integer>[] arrnew = new FastSparseSet[minsize]; + System.arraycopy(arr, 0, arrnew, 0, arr.length); + + int[] arrnextnew = new int[minsize]; + System.arraycopy(arrnext, 0, arrnextnew, 0, arrnext.length); + + elements[index] = arrnew; + next[index] = arrnextnew; + + return arrnew; + } + +} diff --git a/src/org/jetbrains/java/decompiler/util/SFormsFastMapOld.java b/src/org/jetbrains/java/decompiler/util/SFormsFastMapOld.java new file mode 100644 index 0000000..be3e7b7 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/SFormsFastMapOld.java @@ -0,0 +1,270 @@ +package org.jetbrains.java.decompiler.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; + +public class SFormsFastMapOld<E> { + + private List<ArrayList<Entry<Integer, E>>> lstElements = new ArrayList<ArrayList<Entry<Integer, E>>>(3); + + { + lstElements.add(new ArrayList<Entry<Integer, E>>()); + lstElements.add(new ArrayList<Entry<Integer, E>>()); + lstElements.add(new ArrayList<Entry<Integer, E>>()); + } + + public SFormsFastMapOld() {} + + public SFormsFastMapOld(SFormsFastMapOld<E> map) { + for(int i=2;i>=0;i--) { + lstElements.set(i, new ArrayList<Entry<Integer, E>>(map.lstElements.get(i))); + } + } + + public int size() { + int size = 0; + for(int i=2;i>=0;i--) { + size += lstElements.get(i).size(); + } + return size; + } + + public boolean isEmpty() { + + for(int i=2;i>=0;i--) { + if(!lstElements.get(i).isEmpty()) { + return false; + } + } + + return true; + } + + public void put(int key, E value) { + putInternal(key, value, false); + } + + public void remove(int key) { + putInternal(key, null, true); + } + + public void removeAllFields() { + lstElements.get(2).clear(); + } + + public void putInternal(final int key, final E value, boolean remove) { + + int index = 0; + int ikey = key; + if(ikey < 0) { + index = 2; + ikey = -ikey; + } else if(ikey >= VarExprent.STACK_BASE) { + index = 1; + ikey -= VarExprent.STACK_BASE; + } + + ArrayList<Entry<Integer, E>> lst = lstElements.get(index); + if(ikey >= lst.size()) { + if(remove) { + return; + } else { + ensureCapacity(lst, ikey+1, false); + } + } + + lst.set(ikey, value==null?null:new Entry<Integer, E>() { + + private Integer var = key; + private E val = value; + + public Integer getKey() { + return var; + } + + public E getValue() { + return val; + } + + public E setValue(E newvalue) { + val = newvalue; + return null; + }}); + } + + public boolean containsKey(int key) { + return get(key) != null; + } + + public E get(int key) { + + int index = 0; + if(key < 0) { + index = 2; + key = -key; + } else if(key >= VarExprent.STACK_BASE) { + index = 1; + key -= VarExprent.STACK_BASE; + } + + ArrayList<Entry<Integer, E>> lst = lstElements.get(index); + + Entry<Integer, E> ent; + if(key < lst.size() && (ent = lst.get(key)) != null) { + return ent.getValue(); + } + return null; + } + + public void union(SFormsFastMapOld<E> map, IElementsUnion<E> union) { + + for(int i=2;i>=0;i--) { + ArrayList<Entry<Integer, E>> lstOwn = lstElements.get(i); + ArrayList<Entry<Integer, E>> lstExtern = map.lstElements.get(i); + + int ownsize = lstOwn.size(); + int externsize = lstExtern.size(); + + int minsize = ownsize>externsize?externsize:ownsize; + + for(int j=minsize-1;j>=0;j--) { + Entry<Integer, E> second = lstExtern.get(j); + + if(second != null) { + Entry<Integer, E> first = lstOwn.get(j); + + if(first == null) { + putInternal(second.getKey(), union.copy(second.getValue()), false); + } else { + first.setValue(union.union(first.getValue(), second.getValue())); + } + } + } + + if(externsize > minsize) { +// ensureCapacity(lstOwn, externsize, true); +// lstOwn.addAll(lstExtern.subList(minsize, externsize)); + + for(int j=minsize;j<externsize;j++) { + Entry<Integer, E> second = lstExtern.get(j); +// if(first != null) { +// first.setValue(union.copy(first.getValue())); +// } + + if(second != null) { + putInternal(second.getKey(), union.copy(second.getValue()), false); + } +// lstOwn.add(lstExtern.get(j)); + } + } + } + + } + + public List<Entry<Integer, E>> entryList() { + List<Entry<Integer, E>> list = new ArrayList<Entry<Integer, E>>(); + + for(int i=2;i>=0;i--) { + for(Entry<Integer, E> ent : lstElements.get(i)) { + if(ent != null) { + list.add(ent); + } + } + } + + return list; + } + +// public SFormsFastMapIterator iterator() { +// return new SFormsFastMapIterator(); +// } + + private void ensureCapacity(ArrayList<Entry<Integer, E>> lst, int size, boolean exact) { + + if(!exact) { + int minsize = 2*lst.size()/3 +1; + if(minsize > size) { + size = minsize; + } + } + + lst.ensureCapacity(size); + for(int i=size-lst.size();i>0;i--) { + lst.add(null); + } + } + + public static interface IElementsUnion<E> { + public E union(E first, E second); + public E copy(E element); + } + +// public class SFormsFastMapIterator implements Iterator<Entry<Integer, E>> { +// +// private int[] pointer = new int[]{0, -1}; +// private int[] next_pointer = null; +// +// private int[] getNextIndex(int list, int index) { +// +// while(list < 3) { +// ArrayList<E> lst = lstElements.get(list); +// +// while(++index < lst.size()) { +// E element = lst.get(index); +// if(element != null) { +// return new int[] {list, index}; +// } +// } +// +// index = -1; +// list++; +// } +// +// return null; +// } +// +// public boolean hasNext() { +// next_pointer = getNextIndex(pointer[0], pointer[1]); +// return (next_pointer != null); +// } +// +// public Entry<Integer, E> next() { +// if(next_pointer != null) { +// pointer = next_pointer; +// } else { +// int[] nextpointer = getNextIndex(pointer[0], pointer[1]); +// if(nextpointer != null) { +// pointer = nextpointer; +// } else { +// return null; +// } +// } +// +// next_pointer = null; +// +// return new Entry<Integer, E>() { +// public Integer getKey() { +// return null; +// } +// +// public E getValue() { +// return null; +// } +// +// public E setValue(E value) { +// throw new RuntimeException("not implemented!"); +// } +// }; +// //lstElements.get(pointer[0]).get(pointer[1]); +// } +// +// public void remove() { +// throw new RuntimeException("not implemented!"); +// } +// +// } + +} diff --git a/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java b/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java new file mode 100644 index 0000000..8542019 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java @@ -0,0 +1,204 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; + +public class VBStyleCollection<E, K> extends ArrayList<E> { + + private HashMap<K, Integer> map = new HashMap<K, Integer>(); + + private ArrayList<K> lstKeys = new ArrayList<K>(); + + public VBStyleCollection() { + super(); + } + + public VBStyleCollection(int initialCapacity) { + super(initialCapacity); + lstKeys = new ArrayList<K>(initialCapacity); + map = new HashMap<K, Integer>(initialCapacity); + } + + public VBStyleCollection(Collection<E> c) { + super(c); + } + + public boolean add(E element) { + lstKeys.add(null); + super.add(element); + return true; + } + + public boolean remove(Object element) { // TODO: error on void remove(E element) + throw new RuntimeException("not implemented!"); + } + + public boolean addAll(Collection<? extends E> c) { + for(int i=c.size()-1;i>=0;i--) { + lstKeys.add(null); + } + return super.addAll(c); + } + + public void addAllWithKey(VBStyleCollection<E, K> c) { + for(int i=0;i<c.size();i++) { + addWithKey(c.get(i), c.getKey(i)); + } + } + + public void addAllWithKey(Collection<E> elements, Collection<K> keys) { + int index = super.size(); + + for(K key : keys) { + map.put(key, index++); + } + + super.addAll(elements); + lstKeys.addAll(keys); + } + + public void addWithKey(E element, K key) { + map.put(key, super.size()); + super.add(element); + lstKeys.add(key); + } + + // TODO: speed up the method + public E putWithKey(E element, K key) { + Integer index = map.get(key); + if (index == null) { + addWithKey(element, key); + } else { + return super.set(index, element); + } + return null; + } + + public void add(int index, E element) { + addToListIndex(index, 1); + lstKeys.add(index, null); + super.add(index, element); + } + + public void addWithKeyAndIndex(int index, E element, K key) { + addToListIndex(index, 1); + map.put(key, new Integer(index)); + super.add(index, element); + lstKeys.add(index, key); + } + + public void removeWithKey(K key) { + int index = ((Integer) map.get(key)).intValue(); + addToListIndex(index + 1, -1); + super.remove(index); + lstKeys.remove(index); + map.remove(key); + } + + public E remove(int index) { + addToListIndex(index + 1, -1); + Object obj = lstKeys.get(index); + if (obj != null) { + map.remove(obj); + } + lstKeys.remove(index); + return super.remove(index); + } + + public E getWithKey(K key) { + Integer index = map.get(key); + if (index == null) { + return null; + } + return super.get(index.intValue()); + } + + public int getIndexByKey(K key) { + return map.get(key).intValue(); + } + + public E getLast() { + return super.get(super.size()-1); + } + + public boolean containsKey(K key) { + return map.containsKey(key); + } + + public void clear() { + map.clear(); + lstKeys.clear(); + super.clear(); + } + + public VBStyleCollection<E, K> clone() { + VBStyleCollection<E, K> c = new VBStyleCollection<E, K>(); + c.addAll(new ArrayList<E>(this)); + c.setMap(new HashMap<K, Integer>(map)); + c.setLstKeys(new ArrayList<K>(lstKeys)); + return c; + } + + public void swap(int index1, int index2) { + + Collections.swap(this, index1, index2); + Collections.swap(lstKeys, index1, index2); + + K key = lstKeys.get(index1); + if(key!=null) { + map.put(key, new Integer(index1)); + } + + key = lstKeys.get(index2); + if(key!=null) { + map.put(key, new Integer(index2)); + } + + } + + public HashMap<K, Integer> getMap() { + return map; + } + + public void setMap(HashMap<K, Integer> map) { + this.map = map; + } + + public K getKey(int index) { + return lstKeys.get(index); + } + + public ArrayList<K> getLstKeys() { + return lstKeys; + } + + public void setLstKeys(ArrayList<K> lstKeys) { + this.lstKeys = lstKeys; + } + + private void addToListIndex(int index, int diff) { + for (int i = lstKeys.size() - 1; i >= index; i--) { + K obj = lstKeys.get(i); + if (obj != null) { + map.put(obj, new Integer(i + diff)); + } + } + } + +} |