mirror of
https://github.com/revanced/Apktool.git
synced 2025-01-07 18:45:58 +01:00
Post smali 2.0.6 cleanup
- fix smaliDecoder/AccessorTest to use new DexFileFactory params - remove unneeded ds/tree files - cleanup unmerged lines
This commit is contained in:
parent
4cc5f07fd2
commit
1fb87e3e4c
@ -59,29 +59,10 @@ task fatJar (type: Jar) {
|
|||||||
manifest {
|
manifest {
|
||||||
attributes('Main-Class': 'org.jf.baksmali.main')
|
attributes('Main-Class': 'org.jf.baksmali.main')
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD:brut.apktool.smali/baksmali/build.gradle
|
|
||||||
=======
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
if (!System.getProperty('os.name').toLowerCase().contains('windows')) {
|
|
||||||
ant.symlink(link: file("${destinationDir}/baksmali.jar"), resource: archivePath, overwrite: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.getByPath('build').dependsOn(fatJar)
|
tasks.getByPath('build').dependsOn(fatJar)
|
||||||
|
|
||||||
uploadArchives {
|
|
||||||
repositories.mavenDeployer {
|
|
||||||
pom.project {
|
|
||||||
description 'baksmali is a disassembler for dalvik bytecode'
|
|
||||||
scm {
|
|
||||||
url 'https://github.com/JesusFreke/smali/tree/master/baksmali'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>>>>>> f0c481a... Use single-quotes in build.gradle files when double-quotes aren't needed:baksmali/build.gradle
|
|
||||||
}
|
|
||||||
|
|
||||||
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: fatJar) {
|
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: fatJar) {
|
||||||
def outFile = fatJar.destinationDir.getPath() + '/' + fatJar.baseName + '-' + fatJar.version + '-small' + '.' + fatJar.extension
|
def outFile = fatJar.destinationDir.getPath() + '/' + fatJar.baseName + '-' + fatJar.version + '-small' + '.' + fatJar.extension
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
boolean isResourceId = writeCommentIfResourceId(writer);
|
boolean isResourceId = writeCommentIfResourceId(writer);
|
||||||
if (!isResourceId) writeCommentIfLikelyFloat(writer);
|
if (!isResourceId) writeCommentIfLikelyFloat(writer);
|
||||||
}
|
}
|
||||||
return true;
|
break;
|
||||||
case Format21t:
|
case Format21t:
|
||||||
case Format31t:
|
case Format31t:
|
||||||
writeOpcode(writer);
|
writeOpcode(writer);
|
||||||
|
@ -39,7 +39,7 @@ if (!('release' in gradle.startParameter.taskNames)) {
|
|||||||
def versionSuffix
|
def versionSuffix
|
||||||
try {
|
try {
|
||||||
def git = org.eclipse.jgit.api.Git.open(file('../.'))
|
def git = org.eclipse.jgit.api.Git.open(file('../.'))
|
||||||
def head = git.getRepository().getRef("HEAD")
|
def head = git.getRepository().getRef('HEAD')
|
||||||
versionSuffix = head.getObjectId().abbreviate(8).name()
|
versionSuffix = head.getObjectId().abbreviate(8).name()
|
||||||
|
|
||||||
if (!git.status().call().clean) {
|
if (!git.status().call().clean) {
|
||||||
@ -83,8 +83,9 @@ subprojects {
|
|||||||
commons_cli: 'commons-cli:commons-cli:1.2',
|
commons_cli: 'commons-cli:commons-cli:1.2',
|
||||||
jflex: 'de.jflex:jflex:1.4.3',
|
jflex: 'de.jflex:jflex:1.4.3',
|
||||||
jflex_plugin: 'co.tomlee.gradle.plugins:gradle-jflex-plugin:0.0.1',
|
jflex_plugin: 'co.tomlee.gradle.plugins:gradle-jflex-plugin:0.0.1',
|
||||||
proguard_gradle: 'net.sf.proguard:proguard-gradle:5.1'
|
proguard_gradle: 'net.sf.proguard:proguard-gradle:5.1',
|
||||||
]
|
dx: 'com.google.android.tools:dx:1.7'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
@ -79,7 +79,7 @@ public class AccessorTest {
|
|||||||
public void testAccessors() throws IOException {
|
public void testAccessors() throws IOException {
|
||||||
URL url = AccessorTest.class.getClassLoader().getResource("accessorTest.dex");
|
URL url = AccessorTest.class.getClassLoader().getResource("accessorTest.dex");
|
||||||
Assert.assertNotNull(url);
|
Assert.assertNotNull(url);
|
||||||
DexFile f = DexFileFactory.loadDexFile(url.getFile(), 15);
|
DexFile f = DexFileFactory.loadDexFile(url.getFile(), 15, false);
|
||||||
|
|
||||||
SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getClasses());
|
SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getClasses());
|
||||||
|
|
||||||
|
@ -92,15 +92,6 @@ task fatJar (type: Jar) {
|
|||||||
manifest {
|
manifest {
|
||||||
attributes('Main-Class': 'org.jf.smali.main')
|
attributes('Main-Class': 'org.jf.smali.main')
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD:brut.apktool.smali/smali/build.gradle
|
|
||||||
=======
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
if (!System.getProperty('os.name').toLowerCase().contains('windows')) {
|
|
||||||
ant.symlink(link: file("${destinationDir}/smali.jar"), resource: archivePath, overwrite: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>>>>>> f0c481a... Use single-quotes in build.gradle files when double-quotes aren't needed:smali/build.gradle
|
|
||||||
}
|
}
|
||||||
tasks.getByPath('build').dependsOn(fatJar)
|
tasks.getByPath('build').dependsOn(fatJar)
|
||||||
|
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2008 Tahseen Ur Rehman
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ds.tree;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* excepion thrown if a duplicate key is inserted in a {@link RadixTree}
|
|
||||||
*
|
|
||||||
* @author Tahseen Ur Rehman
|
|
||||||
* email: tahseen.ur.rehman {at.spam.me.not} gmail.com
|
|
||||||
*/
|
|
||||||
public class DuplicateKeyException extends RuntimeException
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 3141795907493885706L;
|
|
||||||
|
|
||||||
public DuplicateKeyException(String msg)
|
|
||||||
{
|
|
||||||
super(msg);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2008 Tahseen Ur Rehman
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ds.tree;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface represent the operation of a radix tree. A radix tree,
|
|
||||||
* Patricia trie/tree, or crit bit tree is a specialized set data structure
|
|
||||||
* based on the trie that is used to store a set of strings. In contrast with a
|
|
||||||
* regular trie, the edges of a Patricia trie are labelled with sequences of
|
|
||||||
* characters rather than with single characters. These can be strings of
|
|
||||||
* characters, bit strings such as integers or IP addresses, or generally
|
|
||||||
* arbitrary sequences of objects in lexicographical order. Sometimes the names
|
|
||||||
* radix tree and crit bit tree are only applied to trees storing integers and
|
|
||||||
* Patricia trie is retained for more general inputs, but the structure works
|
|
||||||
* the same way in all cases.
|
|
||||||
*
|
|
||||||
* @author Tahseen Ur Rehman
|
|
||||||
* email: tahseen.ur.rehman {at.spam.me.not} gmail.com
|
|
||||||
*/
|
|
||||||
public interface RadixTree<T> {
|
|
||||||
/**
|
|
||||||
* Insert a new string key and its value to the tree.
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
* The string key of the object
|
|
||||||
* @param value
|
|
||||||
* The value that need to be stored corresponding to the given
|
|
||||||
* key.
|
|
||||||
* @throws DuplicateKeyException
|
|
||||||
*/
|
|
||||||
public void insert(String key, T value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a key and its associated value from the tree.
|
|
||||||
* @param key The key of the node that need to be deleted
|
|
||||||
* @return True if the key was deleted, false if not found
|
|
||||||
*/
|
|
||||||
public boolean delete(String key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a value based on its corresponding key.
|
|
||||||
*
|
|
||||||
* @param key The key for which to search the tree.
|
|
||||||
* @return The value corresponding to the key. null if iot can not find the key
|
|
||||||
*/
|
|
||||||
public T find(String key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find an existing entry and replace it's value. If no existing entry, do nothing
|
|
||||||
*
|
|
||||||
* @param key The key for which to search the tree.
|
|
||||||
* @param value The value to set for the entry
|
|
||||||
* @return true if an entry was found for the given key, false if not found
|
|
||||||
*/
|
|
||||||
public boolean replace(String key, final T value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the tree contains any entry corresponding to the given key.
|
|
||||||
*
|
|
||||||
* @param key The key that needto be searched in the tree.
|
|
||||||
* @return retun true if the key is present in the tree otherwise false
|
|
||||||
*/
|
|
||||||
public boolean contains(String key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for all the keys that start with given prefix. limiting the results based on the supplied limit.
|
|
||||||
*
|
|
||||||
* @param prefix The prefix for which keys need to be search
|
|
||||||
* @param recordLimit The limit for the results
|
|
||||||
* @return The list of values those key start with the given prefix
|
|
||||||
*/
|
|
||||||
public ArrayList<T> searchPrefix(String prefix, int recordLimit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the size of the Radix tree
|
|
||||||
* @return the size of the tree
|
|
||||||
*/
|
|
||||||
public long getSize();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete the a prefix to the point where ambiguity starts.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* If a tree contain "blah1", "blah2"
|
|
||||||
* complete("b") -> return "blah"
|
|
||||||
*
|
|
||||||
* @param prefix The prefix we want to complete
|
|
||||||
* @return The unambiguous completion of the string.
|
|
||||||
*/
|
|
||||||
public String complete(String prefix);
|
|
||||||
}
|
|
@ -1,462 +0,0 @@
|
|||||||
/*
|
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2008 Tahseen Ur Rehman, Javid Jamae
|
|
||||||
|
|
||||||
http://code.google.com/p/radixtree/
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ds.tree;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Formattable;
|
|
||||||
import java.util.Formatter;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Queue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation for Radix tree {@link RadixTree}
|
|
||||||
*
|
|
||||||
* @author Tahseen Ur Rehman (tahseen.ur.rehman {at.spam.me.not} gmail.com)
|
|
||||||
* @author Javid Jamae
|
|
||||||
* @author Dennis Heidsiek
|
|
||||||
*/
|
|
||||||
public class RadixTreeImpl<T> implements RadixTree<T>, Formattable {
|
|
||||||
|
|
||||||
protected RadixTreeNode<T> root;
|
|
||||||
|
|
||||||
protected long size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Radix Tree with only the default node root.
|
|
||||||
*/
|
|
||||||
public RadixTreeImpl() {
|
|
||||||
root = new RadixTreeNode<T>();
|
|
||||||
root.setKey("");
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T find(String key) {
|
|
||||||
Visitor<T,T> visitor = new VisitorImpl<T,T>() {
|
|
||||||
|
|
||||||
public void visit(String key, RadixTreeNode<T> parent,
|
|
||||||
RadixTreeNode<T> node) {
|
|
||||||
if (node.isReal())
|
|
||||||
result = node.getValue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
visit(key, visitor);
|
|
||||||
|
|
||||||
return visitor.getResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean replace(String key, final T value) {
|
|
||||||
Visitor<T,T> visitor = new VisitorImpl<T,T>() {
|
|
||||||
public void visit(String key, RadixTreeNode<T> parent, RadixTreeNode<T> node) {
|
|
||||||
if (node.isReal()) {
|
|
||||||
node.setValue(value);
|
|
||||||
result = value;
|
|
||||||
} else {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
visit(key, visitor);
|
|
||||||
|
|
||||||
return visitor.getResult() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean delete(String key) {
|
|
||||||
Visitor<T, Boolean> visitor = new VisitorImpl<T, Boolean>(Boolean.FALSE) {
|
|
||||||
public void visit(String key, RadixTreeNode<T> parent,
|
|
||||||
RadixTreeNode<T> node) {
|
|
||||||
result = node.isReal();
|
|
||||||
|
|
||||||
// if it is a real node
|
|
||||||
if (result) {
|
|
||||||
// If there no children of the node we need to
|
|
||||||
// delete it from the its parent children list
|
|
||||||
if (node.getChildern().size() == 0) {
|
|
||||||
Iterator<RadixTreeNode<T>> it = parent.getChildern()
|
|
||||||
.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
if (it.next().getKey().equals(node.getKey())) {
|
|
||||||
it.remove();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if parent is not real node and has only one child
|
|
||||||
// then they need to be merged.
|
|
||||||
if (parent.getChildern().size() == 1
|
|
||||||
&& parent.isReal() == false) {
|
|
||||||
mergeNodes(parent, parent.getChildern().get(0));
|
|
||||||
}
|
|
||||||
} else if (node.getChildern().size() == 1) {
|
|
||||||
// we need to merge the only child of this node with
|
|
||||||
// itself
|
|
||||||
mergeNodes(node, node.getChildern().get(0));
|
|
||||||
} else { // we jus need to mark the node as non real.
|
|
||||||
node.setReal(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge a child into its parent node. Operation only valid if it is
|
|
||||||
* only child of the parent node and parent node is not a real node.
|
|
||||||
*
|
|
||||||
* @param parent
|
|
||||||
* The parent Node
|
|
||||||
* @param child
|
|
||||||
* The child Node
|
|
||||||
*/
|
|
||||||
private void mergeNodes(RadixTreeNode<T> parent,
|
|
||||||
RadixTreeNode<T> child) {
|
|
||||||
parent.setKey(parent.getKey() + child.getKey());
|
|
||||||
parent.setReal(child.isReal());
|
|
||||||
parent.setValue(child.getValue());
|
|
||||||
parent.setChildern(child.getChildern());
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
visit(key, visitor);
|
|
||||||
|
|
||||||
if(visitor.getResult()) {
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
return visitor.getResult().booleanValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see ds.tree.RadixTree#insert(java.lang.String, java.lang.Object)
|
|
||||||
*/
|
|
||||||
public void insert(String key, T value) throws DuplicateKeyException {
|
|
||||||
try {
|
|
||||||
insert(key, root, value);
|
|
||||||
} catch (DuplicateKeyException e) {
|
|
||||||
// re-throw the exception with 'key' in the message
|
|
||||||
throw new DuplicateKeyException("Duplicate key: '" + key + "'");
|
|
||||||
}
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively insert the key in the radix tree.
|
|
||||||
*
|
|
||||||
* @param key The key to be inserted
|
|
||||||
* @param node The current node
|
|
||||||
* @param value The value associated with the key
|
|
||||||
* @throws DuplicateKeyException If the key already exists in the database.
|
|
||||||
*/
|
|
||||||
private void insert(String key, RadixTreeNode<T> node, T value)
|
|
||||||
throws DuplicateKeyException {
|
|
||||||
|
|
||||||
int numberOfMatchingCharacters = node.getNumberOfMatchingCharacters(key);
|
|
||||||
|
|
||||||
// we are either at the root node
|
|
||||||
// or we need to go down the tree
|
|
||||||
if (node.getKey().equals("") == true || numberOfMatchingCharacters == 0 || (numberOfMatchingCharacters < key.length() && numberOfMatchingCharacters >= node.getKey().length())) {
|
|
||||||
boolean flag = false;
|
|
||||||
String newText = key.substring(numberOfMatchingCharacters, key.length());
|
|
||||||
for (RadixTreeNode<T> child : node.getChildern()) {
|
|
||||||
if (child.getKey().startsWith(newText.charAt(0) + "")) {
|
|
||||||
flag = true;
|
|
||||||
insert(newText, child, value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// just add the node as the child of the current node
|
|
||||||
if (flag == false) {
|
|
||||||
RadixTreeNode<T> n = new RadixTreeNode<T>();
|
|
||||||
n.setKey(newText);
|
|
||||||
n.setReal(true);
|
|
||||||
n.setValue(value);
|
|
||||||
|
|
||||||
node.getChildern().add(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// there is a exact match just make the current node as data node
|
|
||||||
else if (numberOfMatchingCharacters == key.length() && numberOfMatchingCharacters == node.getKey().length()) {
|
|
||||||
if (node.isReal() == true) {
|
|
||||||
throw new DuplicateKeyException("Duplicate key");
|
|
||||||
}
|
|
||||||
|
|
||||||
node.setReal(true);
|
|
||||||
node.setValue(value);
|
|
||||||
}
|
|
||||||
// This node need to be split as the key to be inserted
|
|
||||||
// is a prefix of the current node key
|
|
||||||
else if (numberOfMatchingCharacters > 0 && numberOfMatchingCharacters < node.getKey().length()) {
|
|
||||||
RadixTreeNode<T> n1 = new RadixTreeNode<T>();
|
|
||||||
n1.setKey(node.getKey().substring(numberOfMatchingCharacters, node.getKey().length()));
|
|
||||||
n1.setReal(node.isReal());
|
|
||||||
n1.setValue(node.getValue());
|
|
||||||
n1.setChildern(node.getChildern());
|
|
||||||
|
|
||||||
node.setKey(key.substring(0, numberOfMatchingCharacters));
|
|
||||||
node.setReal(false);
|
|
||||||
node.setChildern(new ArrayList<RadixTreeNode<T>>());
|
|
||||||
node.getChildern().add(n1);
|
|
||||||
|
|
||||||
if(numberOfMatchingCharacters < key.length()) {
|
|
||||||
RadixTreeNode<T> n2 = new RadixTreeNode<T>();
|
|
||||||
n2.setKey(key.substring(numberOfMatchingCharacters, key.length()));
|
|
||||||
n2.setReal(true);
|
|
||||||
n2.setValue(value);
|
|
||||||
|
|
||||||
node.getChildern().add(n2);
|
|
||||||
} else {
|
|
||||||
node.setValue(value);
|
|
||||||
node.setReal(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this key need to be added as the child of the current node
|
|
||||||
else {
|
|
||||||
RadixTreeNode<T> n = new RadixTreeNode<T>();
|
|
||||||
n.setKey(node.getKey().substring(numberOfMatchingCharacters, node.getKey().length()));
|
|
||||||
n.setChildern(node.getChildern());
|
|
||||||
n.setReal(node.isReal());
|
|
||||||
n.setValue(node.getValue());
|
|
||||||
|
|
||||||
node.setKey(key);
|
|
||||||
node.setReal(true);
|
|
||||||
node.setValue(value);
|
|
||||||
|
|
||||||
node.getChildern().add(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<T> searchPrefix(String key, int recordLimit) {
|
|
||||||
ArrayList<T> keys = new ArrayList<T>();
|
|
||||||
|
|
||||||
RadixTreeNode<T> node = searchPefix(key, root);
|
|
||||||
|
|
||||||
if (node != null) {
|
|
||||||
if (node.isReal()) {
|
|
||||||
keys.add(node.getValue());
|
|
||||||
}
|
|
||||||
getNodes(node, keys, recordLimit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getNodes(RadixTreeNode<T> parent, ArrayList<T> keys, int limit) {
|
|
||||||
Queue<RadixTreeNode<T>> queue = new LinkedList<RadixTreeNode<T>>();
|
|
||||||
|
|
||||||
queue.addAll(parent.getChildern());
|
|
||||||
|
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
RadixTreeNode<T> node = queue.remove();
|
|
||||||
if (node.isReal() == true) {
|
|
||||||
keys.add(node.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys.size() == limit) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.addAll(node.getChildern());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RadixTreeNode<T> searchPefix(String key, RadixTreeNode<T> node) {
|
|
||||||
RadixTreeNode<T> result = null;
|
|
||||||
|
|
||||||
int numberOfMatchingCharacters = node.getNumberOfMatchingCharacters(key);
|
|
||||||
|
|
||||||
if (numberOfMatchingCharacters == key.length() && numberOfMatchingCharacters <= node.getKey().length()) {
|
|
||||||
result = node;
|
|
||||||
} else if (node.getKey().equals("") == true
|
|
||||||
|| (numberOfMatchingCharacters < key.length() && numberOfMatchingCharacters >= node.getKey().length())) {
|
|
||||||
String newText = key.substring(numberOfMatchingCharacters, key.length());
|
|
||||||
for (RadixTreeNode<T> child : node.getChildern()) {
|
|
||||||
if (child.getKey().startsWith(newText.charAt(0) + "")) {
|
|
||||||
result = searchPefix(newText, child);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(String key) {
|
|
||||||
Visitor<T, Boolean> visitor = new VisitorImpl<T,Boolean>(Boolean.FALSE) {
|
|
||||||
public void visit(String key, RadixTreeNode<T> parent,
|
|
||||||
RadixTreeNode<T> node) {
|
|
||||||
result = node.isReal();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
visit(key, visitor);
|
|
||||||
|
|
||||||
return visitor.getResult().booleanValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* visit the node those key matches the given key
|
|
||||||
* @param key The key that need to be visited
|
|
||||||
* @param visitor The visitor object
|
|
||||||
*/
|
|
||||||
public <R> void visit(String key, Visitor<T, R> visitor) {
|
|
||||||
if (root != null) {
|
|
||||||
visit(key, visitor, null, root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* recursively visit the tree based on the supplied "key". calls the Visitor
|
|
||||||
* for the node those key matches the given prefix
|
|
||||||
*
|
|
||||||
* @param prefix
|
|
||||||
* The key o prefix to search in the tree
|
|
||||||
* @param visitor
|
|
||||||
* The Visitor that will be called if a node with "key" as its
|
|
||||||
* key is found
|
|
||||||
* @param node
|
|
||||||
* The Node from where onward to search
|
|
||||||
*/
|
|
||||||
private <R> void visit(String prefix, Visitor<T, R> visitor,
|
|
||||||
RadixTreeNode<T> parent, RadixTreeNode<T> node) {
|
|
||||||
|
|
||||||
int numberOfMatchingCharacters = node.getNumberOfMatchingCharacters(prefix);
|
|
||||||
|
|
||||||
// if the node key and prefix match, we found a match!
|
|
||||||
if (numberOfMatchingCharacters == prefix.length() && numberOfMatchingCharacters == node.getKey().length()) {
|
|
||||||
visitor.visit(prefix, parent, node);
|
|
||||||
} else if (node.getKey().equals("") == true // either we are at the
|
|
||||||
// root
|
|
||||||
|| (numberOfMatchingCharacters < prefix.length() && numberOfMatchingCharacters >= node.getKey().length())) { // OR we need to
|
|
||||||
// traverse the childern
|
|
||||||
String newText = prefix.substring(numberOfMatchingCharacters, prefix.length());
|
|
||||||
for (RadixTreeNode<T> child : node.getChildern()) {
|
|
||||||
// recursively search the child nodes
|
|
||||||
if (child.getKey().startsWith(newText.charAt(0) + "")) {
|
|
||||||
visit(newText, visitor, node, child);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the Trie on console.
|
|
||||||
*
|
|
||||||
* WARNING! Do not use this for a large Trie, it's for testing purpose only.
|
|
||||||
* @see #formatTo
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void display() {
|
|
||||||
formatNodeTo(new Formatter(System.out), 0, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
private void display(int level, RadixTreeNode<T> node) {
|
|
||||||
formatNodeTo(new Formatter(System.out), level, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WARNING! Do not use this for a large Trie, it's for testing purpose only.
|
|
||||||
*/
|
|
||||||
private void formatNodeTo(Formatter f, int level, RadixTreeNode<T> node) {
|
|
||||||
for (int i = 0; i < level; i++) {
|
|
||||||
f.format(" ");
|
|
||||||
}
|
|
||||||
f.format("|");
|
|
||||||
for (int i = 0; i < level; i++) {
|
|
||||||
f.format("-");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.isReal() == true)
|
|
||||||
f.format("%s[%s]*%n", node.getKey(), node.getValue());
|
|
||||||
else
|
|
||||||
f.format("%s%n", node.getKey());
|
|
||||||
|
|
||||||
for (RadixTreeNode<T> child : node.getChildern()) {
|
|
||||||
formatNodeTo(f, level + 1, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a textual representation of this tree to the given formatter.
|
|
||||||
*
|
|
||||||
* Currently, all options are simply ignored.
|
|
||||||
*
|
|
||||||
* WARNING! Do not use this for a large Trie, it's for testing purpose only.
|
|
||||||
*/
|
|
||||||
public void formatTo(Formatter formatter, int flags, int width, int precision) {
|
|
||||||
formatNodeTo(formatter, 0, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete the a prefix to the point where ambiguity starts.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* If a tree contain "blah1", "blah2"
|
|
||||||
* complete("b") -> return "blah"
|
|
||||||
*
|
|
||||||
* @param prefix The prefix we want to complete
|
|
||||||
* @return The unambiguous completion of the string.
|
|
||||||
*/
|
|
||||||
public String complete(String prefix) {
|
|
||||||
return complete(prefix, root, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String complete(String key, RadixTreeNode<T> node, String base) {
|
|
||||||
int i = 0;
|
|
||||||
int keylen = key.length();
|
|
||||||
int nodelen = node.getKey().length();
|
|
||||||
|
|
||||||
while (i < keylen && i < nodelen) {
|
|
||||||
if (key.charAt(i) != node.getKey().charAt(i)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == keylen && i <= nodelen) {
|
|
||||||
return base + node.getKey();
|
|
||||||
}
|
|
||||||
else if (nodelen == 0 || (i < keylen && i >= nodelen)) {
|
|
||||||
String beginning = key.substring(0, i);
|
|
||||||
String ending = key.substring(i, keylen);
|
|
||||||
for (RadixTreeNode<T> child : node.getChildern()) {
|
|
||||||
if (child.getKey().startsWith(ending.charAt(0) + "")) {
|
|
||||||
return complete(ending, child, base + beginning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2008 Tahseen Ur Rehman
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ds.tree;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a node of a Radix tree {@link RadixTreeImpl}
|
|
||||||
*
|
|
||||||
* @author Tahseen Ur Rehman
|
|
||||||
* @email tahseen.ur.rehman {at.spam.me.not} gmail.com
|
|
||||||
* @param <T>
|
|
||||||
*/
|
|
||||||
class RadixTreeNode<T> {
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
private List<RadixTreeNode<T>> childern;
|
|
||||||
|
|
||||||
private boolean real;
|
|
||||||
|
|
||||||
private T value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* intailize the fields with default values to avoid null reference checks
|
|
||||||
* all over the places
|
|
||||||
*/
|
|
||||||
public RadixTreeNode() {
|
|
||||||
key = "";
|
|
||||||
childern = new ArrayList<RadixTreeNode<T>>();
|
|
||||||
real = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValue(T data) {
|
|
||||||
this.value = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKey(String value) {
|
|
||||||
this.key = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReal() {
|
|
||||||
return real;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReal(boolean datanode) {
|
|
||||||
this.real = datanode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<RadixTreeNode<T>> getChildern() {
|
|
||||||
return childern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildern(List<RadixTreeNode<T>> childern) {
|
|
||||||
this.childern = childern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumberOfMatchingCharacters(String key) {
|
|
||||||
int numberOfMatchingCharacters = 0;
|
|
||||||
while (numberOfMatchingCharacters < key.length() && numberOfMatchingCharacters < this.getKey().length()) {
|
|
||||||
if (key.charAt(numberOfMatchingCharacters) != this.getKey().charAt(numberOfMatchingCharacters)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
numberOfMatchingCharacters++;
|
|
||||||
}
|
|
||||||
return numberOfMatchingCharacters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
The MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2008 Tahseen Ur Rehman, Javid Jamae
|
|
||||||
|
|
||||||
http://code.google.com/p/radixtree/
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ds.tree;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The visitor interface that is used by {@link RadixTreeImpl} for perfroming
|
|
||||||
* task on a searched node.
|
|
||||||
*
|
|
||||||
* @author Tahseen Ur Rehman (tahseen.ur.rehman {at.spam.me.not} gmail.com)
|
|
||||||
* @author Javid Jamae
|
|
||||||
* @author Dennis Heidsiek
|
|
||||||
* @param <T>
|
|
||||||
* @param <R>
|
|
||||||
*/
|
|
||||||
public interface Visitor<T, R> {
|
|
||||||
/**
|
|
||||||
* This method gets called by {@link RadixTreeImpl#visit(String, Visitor) visit}
|
|
||||||
* when it finds a node matching the key given to it.
|
|
||||||
*
|
|
||||||
* @param key The key that matched the node
|
|
||||||
* @param parent The parent of the node being visited
|
|
||||||
* @param node The node that is being visited
|
|
||||||
*/
|
|
||||||
public void visit(String key, RadixTreeNode<T> parent, RadixTreeNode<T> node);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The visitor can store any type of result object, depending on the context of
|
|
||||||
* what it is being used for.
|
|
||||||
*
|
|
||||||
* @return The result captured by the visitor.
|
|
||||||
*/
|
|
||||||
public R getResult();
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package ds.tree;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple standard implementation for a {@link Visitor}.
|
|
||||||
*
|
|
||||||
* @author Dennis Heidsiek
|
|
||||||
* @param <T>
|
|
||||||
* @param <R>
|
|
||||||
*/
|
|
||||||
public abstract class VisitorImpl<T, R> implements Visitor<T, R> {
|
|
||||||
|
|
||||||
protected R result;
|
|
||||||
|
|
||||||
public VisitorImpl() {
|
|
||||||
this.result = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VisitorImpl(R initialValue) {
|
|
||||||
this.result = initialValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public R getResult() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public void visit(String key, RadixTreeNode<T> parent, RadixTreeNode<T> node);
|
|
||||||
}
|
|
@ -91,7 +91,7 @@ public class SmaliDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the dex
|
// create the dex
|
||||||
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(mApkFile, mDexFile, mApi);
|
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(mApkFile, mDexFile, mApi, false);
|
||||||
|
|
||||||
if (dexFile.isOdexFile()) {
|
if (dexFile.isOdexFile()) {
|
||||||
throw new AndrolibException("Warning: You are disassembling an odex file without deodexing it.");
|
throw new AndrolibException("Warning: You are disassembling an odex file without deodexing it.");
|
||||||
|
@ -93,7 +93,6 @@ subprojects {
|
|||||||
commons_cli: 'commons-cli:commons-cli:1.2',
|
commons_cli: 'commons-cli:commons-cli:1.2',
|
||||||
commons_io: 'commons-io:commons-io:2.4',
|
commons_io: 'commons-io:commons-io:2.4',
|
||||||
commons_lang: 'org.apache.commons:commons-lang3:3.1',
|
commons_lang: 'org.apache.commons:commons-lang3:3.1',
|
||||||
dx: 'com.google.android.tools:dx:1.7',
|
|
||||||
findbugs: 'com.google.code.findbugs:jsr305:1.3.9',
|
findbugs: 'com.google.code.findbugs:jsr305:1.3.9',
|
||||||
guava: 'com.google.guava:guava:14.0',
|
guava: 'com.google.guava:guava:14.0',
|
||||||
jflex: 'de.jflex:jflex:1.4.3',
|
jflex: 'de.jflex:jflex:1.4.3',
|
||||||
|
Loading…
Reference in New Issue
Block a user