mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-02 11:54:36 +00:00
trunk contents moved to root
This commit is contained in:
197
libsrc/jpacker/src/com/jpacker/JPacker.java
Normal file
197
libsrc/jpacker/src/com/jpacker/JPacker.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import com.jpacker.exceptions.EmptyFileException;
|
||||
import jargs.gnu.CmdLineParser;
|
||||
import jargs.gnu.CmdLineParser.IllegalOptionValueException;
|
||||
import jargs.gnu.CmdLineParser.Option;
|
||||
import jargs.gnu.CmdLineParser.UnknownOptionException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPacker {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
CmdLineParser parser = new CmdLineParser();
|
||||
Option baseOpt = parser.addIntegerOption('b', "base");
|
||||
Option columnsOpt = parser.addIntegerOption('c', "column");
|
||||
Option helpOpt = parser.addBooleanOption('h', "help");
|
||||
Option minifyOpt = parser.addBooleanOption('m', "minify");
|
||||
Option outputFilenameOpt = parser.addStringOption('o', "output");
|
||||
Option quietOpt = parser.addBooleanOption('q', "quiet");
|
||||
Option shrinkVariablesOpt = parser.addBooleanOption('s', "shrink-variables");
|
||||
|
||||
Writer out = null;
|
||||
BufferedReader in = null;
|
||||
|
||||
try {
|
||||
if (args.length == 0) {
|
||||
throw new RuntimeException("No input file");
|
||||
}
|
||||
|
||||
parser.parse(args);
|
||||
|
||||
Boolean help = (Boolean) parser.getOptionValue(helpOpt);
|
||||
if (help != null && help.booleanValue()) {
|
||||
printUsage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
boolean minify = parser.getOptionValue(minifyOpt) != null;
|
||||
boolean shrinkVariables = parser.getOptionValue(shrinkVariablesOpt) != null;
|
||||
boolean quiet = parser.getOptionValue(quietOpt) != null;
|
||||
Integer base = (Integer) parser.getOptionValue(baseOpt);
|
||||
Integer columns = (Integer) parser.getOptionValue(columnsOpt);
|
||||
|
||||
if (parser.getRemainingArgs().length == 0) {
|
||||
throw new FileNotFoundException("No input file was provided");
|
||||
}
|
||||
|
||||
String inputFilename = parser.getRemainingArgs()[0];
|
||||
String outputFilename = (String) parser.getOptionValue(outputFilenameOpt);
|
||||
|
||||
JPackerExecuter executer;
|
||||
if (base == null) {
|
||||
executer = new JPackerExecuter(JPackerEncoding.NONE);
|
||||
} else {
|
||||
executer = new JPackerExecuter(getEncoding(baseOpt, base));
|
||||
}
|
||||
in = new BufferedReader(new FileReader(new File(inputFilename)));
|
||||
String unpacked = buildStringFromTextFile(in);
|
||||
if (unpacked.isEmpty()) {
|
||||
throw new EmptyFileException("The file is empty");
|
||||
}
|
||||
|
||||
String packed = executer.pack(unpacked, minify, shrinkVariables);
|
||||
|
||||
if (outputFilename == null) {
|
||||
out = new OutputStreamWriter(System.out);
|
||||
} else {
|
||||
out = new OutputStreamWriter(new FileOutputStream(outputFilename));
|
||||
}
|
||||
|
||||
if (columns != null) {
|
||||
packed = wrapLines(packed, columns);
|
||||
}
|
||||
|
||||
out.write(packed.replace("\n", System.getProperty("line.separator")));
|
||||
out.close();
|
||||
if (!quiet) {
|
||||
long endTime = System.currentTimeMillis();
|
||||
System.out.printf("Reduced to %.2f%% of its original size in %.4f seconds.\n",
|
||||
((double) packed.length() / (double) unpacked.length()) * 100,
|
||||
(double) (endTime - startTime) / 1000);
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("File not found: " + e.getLocalizedMessage());
|
||||
System.exit(1);
|
||||
} catch (IllegalOptionValueException e) {
|
||||
System.out.println("Illegal option: " + e.getValue() + " - " + e.getOption());
|
||||
System.exit(1);
|
||||
} catch (UnknownOptionException e) {
|
||||
printUsage();
|
||||
System.exit(1);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
System.exit(1);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printUsage() {
|
||||
System.out.println("\nUsage: java -jar jpacker-x.y.z.jar [options] [input file]\n\n"
|
||||
+ "Options\n"
|
||||
+ " -b, --base Encoding base. Options are: 10, 36, 52, 62 \n"
|
||||
+ " and 95. Ignored if --minify option is set.\n"
|
||||
+ " -c, --column <column> Insert a line break after the specified column \n"
|
||||
+ " number.\n"
|
||||
+ " -h, --help Displays this information.\n"
|
||||
+ " -m, --minify Minify only, do not obfuscate.\n"
|
||||
+ " --minify and --base values will be ignored.\n"
|
||||
+ " -o <file>, --output <file> Place the output into <file>.\n"
|
||||
+ " Defaults to stdout.\n"
|
||||
+ " -q, --quiet Quiet mode, no message.\n"
|
||||
+ " -s, --shrink-variables Shrink variables. Ignored if --minify option \n"
|
||||
+ " is set.\n");
|
||||
}
|
||||
|
||||
private static String wrapLines(String packedScript, Integer columns) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < packedScript.length(); i++) {
|
||||
int end = ((i + columns) > (packedScript.length()) ? packedScript.length() : i + columns);
|
||||
sb.append(packedScript.substring(i, end)).append(System.getProperty("line.separator"));
|
||||
i = end + 1;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String buildStringFromTextFile(BufferedReader reader) throws FileNotFoundException, IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = reader.readLine()) != null) {
|
||||
sb.append(s).append(System.getProperty("line.separator"));
|
||||
}
|
||||
reader.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static JPackerEncoding getEncoding(Option option, Integer base) throws IllegalOptionValueException {
|
||||
switch (base) {
|
||||
case 10:
|
||||
return JPackerEncoding.NUMERIC;
|
||||
case 36:
|
||||
return JPackerEncoding.MID;
|
||||
case 52:
|
||||
return JPackerEncoding.BASIC;
|
||||
case 62:
|
||||
return JPackerEncoding.NORMAL;
|
||||
case 95:
|
||||
return JPackerEncoding.HIGH_ASCII;
|
||||
default:
|
||||
throw new IllegalOptionValueException(option, "Encoding base option not valid");
|
||||
}
|
||||
}
|
||||
}
|
||||
75
libsrc/jpacker/src/com/jpacker/JPackerEncoding.java
Normal file
75
libsrc/jpacker/src/com/jpacker/JPackerEncoding.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import com.jpacker.encoders.BasicEncoder;
|
||||
import com.jpacker.encoders.Encoder;
|
||||
import com.jpacker.encoders.HighAsciiEncoder;
|
||||
import com.jpacker.encoders.MidEncoder;
|
||||
import com.jpacker.encoders.NormalEncoder;
|
||||
import com.jpacker.encoders.NumericEncoder;
|
||||
|
||||
/**
|
||||
* Enum of encoding levels
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public enum JPackerEncoding {
|
||||
|
||||
/**
|
||||
* No encoding
|
||||
*/
|
||||
NONE(0, "", null),
|
||||
/**
|
||||
* Base<sub>10</sub> : [0-9]
|
||||
*/
|
||||
NUMERIC(10, "String", new NumericEncoder()),
|
||||
/**
|
||||
* Base<sub>36</sub> : [0-z]
|
||||
*/
|
||||
MID(36, "function(c){return c.toString(a)}", new MidEncoder()),
|
||||
/**
|
||||
* Base<sub>52</sub> : [a-Z]
|
||||
*/
|
||||
BASIC(52, "function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>25?String.fromCharCode(c+39):String.fromCharCode(c+97));", new BasicEncoder()),
|
||||
/**
|
||||
* Base<sub>62</sub> : [0-Z]
|
||||
*/
|
||||
NORMAL(62, "function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))}", new NormalEncoder()),
|
||||
/**
|
||||
* Base<sub>95</sub> : [¡-ÿ]
|
||||
*/
|
||||
HIGH_ASCII(95, "function(c){return(c<a?\"\":e(c/a))String.fromCharCode(c%a+161)}", new HighAsciiEncoder());
|
||||
private final int encodingBase;
|
||||
private final String encode;
|
||||
private Encoder encoder;
|
||||
|
||||
JPackerEncoding(int encodingBase, String encode, Encoder encoder) {
|
||||
this.encodingBase = encodingBase;
|
||||
this.encode = encode;
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
public int getEncodingBase() {
|
||||
return encodingBase;
|
||||
}
|
||||
|
||||
public String getEncode() {
|
||||
return encode;
|
||||
}
|
||||
|
||||
public Encoder getEncoder() {
|
||||
return encoder;
|
||||
}
|
||||
}
|
||||
329
libsrc/jpacker/src/com/jpacker/JPackerExecuter.java
Normal file
329
libsrc/jpacker/src/com/jpacker/JPackerExecuter.java
Normal file
@@ -0,0 +1,329 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.jpacker.encoders.BasicEncoder;
|
||||
import com.jpacker.encoders.Encoder;
|
||||
import com.jpacker.strategies.DefaultReplacementStrategy;
|
||||
import com.jpacker.strategies.ReplacementStrategy;
|
||||
|
||||
/**
|
||||
* Packer class.
|
||||
*
|
||||
* Main jPacker class that packs the script.
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerExecuter {
|
||||
|
||||
private JPackerEncoding encoding;
|
||||
private static final String UNPACK = "eval(function(p,a,c,k,e,r){e=%5$s;if(!''.replace(/^/,String)){while(c--)r[%6$s]=k[c]"
|
||||
+ "||%6$s;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p."
|
||||
+ "replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('%1$s',%2$s,%3$s,'%4$s'.split('|'),0,{}))";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param encoding
|
||||
* The encoding level for this instance
|
||||
*/
|
||||
public JPackerExecuter(JPackerEncoding encoding) {
|
||||
setEncoding(encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the script
|
||||
*
|
||||
* @param script
|
||||
* The script to pack
|
||||
* @param minifyOnly
|
||||
* True if script should only be minified and not encoded and/or
|
||||
* its variables shrunk, false otherwise.
|
||||
* @param shrinkVariables
|
||||
* True if variables should be shrunk, false otherwise. If
|
||||
* minifyOnly is true, this option has no side effect.
|
||||
* @return The packed script
|
||||
*/
|
||||
public String pack(String script, boolean minifyOnly, boolean shrinkVariables) {
|
||||
script += "\n";
|
||||
script = minify(script);
|
||||
if (!minifyOnly) {
|
||||
if (shrinkVariables) {
|
||||
script = shrinkVariables(script);
|
||||
}
|
||||
if (encoding != JPackerEncoding.NONE) {
|
||||
script = encode(script);
|
||||
}
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
// zero encoding - just removal of whitespace and comments
|
||||
private String minify(String script) {
|
||||
JPackerParser parser = new JPackerParser();
|
||||
ReplacementStrategy defaultStrat = new DefaultReplacementStrategy();
|
||||
// protect data
|
||||
parser = addDataRegEx(parser);
|
||||
script = parser.exec(script, defaultStrat);
|
||||
// remove white-space
|
||||
parser = addWhiteSpaceRegEx(parser);
|
||||
script = parser.exec(script, defaultStrat);
|
||||
// clean
|
||||
parser = addCleanUpRegEx(parser);
|
||||
script = parser.exec(script, defaultStrat);
|
||||
// done
|
||||
return script;
|
||||
}
|
||||
|
||||
private JPackerParser addDataRegEx(JPackerParser parser) {
|
||||
final String COMMENT1 = "(\\/\\/|;;;)[^\\n]*";
|
||||
final String COMMENT2 = "\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/";
|
||||
final String REGEX = "\\/(\\\\[\\/\\\\]|[^*\\/])(\\\\.|[^\\/\\n\\\\])*\\/[gim]*";
|
||||
|
||||
// Packer.CONTINUE
|
||||
parser.remove("\\\\\\r?\\n");
|
||||
|
||||
parser.ignore("'(\\\\.|[^'\\\\])*'");
|
||||
parser.ignore("\"(\\\\.|[^\"\\\\])*\"");
|
||||
parser.ignore("\\/\\*@|@\\*\\/|\\/\\/@[^\\n]*\\n");
|
||||
parser.replace("(" + COMMENT1 + ")\\n\\s*(" + REGEX + ")?", "\n$3");
|
||||
parser.replace("(" + COMMENT2 + ")\\s*(" + REGEX + ")?", " $3");
|
||||
parser.replace("([\\[\\(\\^=,{}:;&|!*?])\\s*(" + REGEX + ")", "$1$2");
|
||||
return parser;
|
||||
}
|
||||
|
||||
private JPackerParser addCleanUpRegEx(JPackerParser parser) {
|
||||
parser.replace("\\(\\s*;\\s*;\\s*\\)", "(;;)");
|
||||
parser.ignore("throw[};]+[};]"); // safari 1.3 bug
|
||||
parser.replace(";+\\s*([};])", "$1");
|
||||
parser.remove(";;[^\\n\\r]+[\\n\\r]");
|
||||
return parser;
|
||||
}
|
||||
|
||||
private JPackerParser addWhiteSpaceRegEx(JPackerParser parser) {
|
||||
parser.replace("(\\d)\\s+(\\.\\s*[a-z\\$_\\[\\(])", "$1 $2");
|
||||
parser.replace("([+\\-])\\s+([+\\-])", "$1 $2");
|
||||
parser.replace("(\\b|\\$)\\s+(\\b|\\$)", "$1 $2");
|
||||
parser.replace("\\b\\s+\\$\\s+\\b", " $ ");
|
||||
parser.replace("\\$\\s+\\b", "$ ");
|
||||
parser.replace("\\b\\s+\\$", " $");
|
||||
parser.replace("\\b\\s+\\b", " ");
|
||||
parser.remove("\\s+");
|
||||
return parser;
|
||||
}
|
||||
|
||||
private String shrinkVariables(String script) {
|
||||
final Pattern pattern = Pattern.compile("^[^'\"]\\/");
|
||||
// identify blocks, particularly identify function blocks (which define
|
||||
// scope)
|
||||
Pattern blockPattern = Pattern.compile("(function\\s*[\\w$]*\\s*\\(\\s*([^\\)]*)\\s*\\)\\s*)?(\\{([^{}]*)\\})");
|
||||
List<String> blocks = new ArrayList<String>(); // store program blocks
|
||||
// (anything between
|
||||
// braces {})
|
||||
|
||||
final List<String> data = new ArrayList<String>(); // encoded strings
|
||||
// and regular
|
||||
// expressions
|
||||
|
||||
JPackerParser parser = new JPackerParser();
|
||||
parser = addDataRegEx(parser);
|
||||
script = parser.exec(script, new ReplacementStrategy() {
|
||||
|
||||
@Override
|
||||
public String replace(List<JPackerPattern> patterns, Matcher matcher) {
|
||||
String replacement = "#" + data.size();
|
||||
String string = matcher.group();
|
||||
if (pattern.matcher(string).find()) {
|
||||
replacement = string.charAt(0) + replacement;
|
||||
string = string.substring(1);
|
||||
}
|
||||
data.add(string);
|
||||
return replacement;
|
||||
}
|
||||
});
|
||||
|
||||
do {
|
||||
// put the blocks back
|
||||
Matcher blockMatcher = blockPattern.matcher(script);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (blockMatcher.find()) {
|
||||
blockMatcher.appendReplacement(sb, encodeBlock(blockMatcher, blocks));
|
||||
}
|
||||
blockMatcher.appendTail(sb);
|
||||
script = sb.toString();
|
||||
} while (blockPattern.matcher(script).find());
|
||||
|
||||
while (Pattern.compile("~(\\d+)~").matcher(script).find()) {
|
||||
script = decodeBlock(script, blocks);
|
||||
}
|
||||
// put strings and regular expressions back
|
||||
Matcher storeMatcher = Pattern.compile("#(\\d+)").matcher(script);
|
||||
StringBuffer sb2 = new StringBuffer();
|
||||
while (storeMatcher.find()) {
|
||||
int num = Integer.parseInt(storeMatcher.group(1));
|
||||
storeMatcher.appendReplacement(sb2, Matcher.quoteReplacement(data.get(num)));
|
||||
}
|
||||
storeMatcher.appendTail(sb2);
|
||||
|
||||
return sb2.toString();
|
||||
}
|
||||
|
||||
private String encode(String script) {
|
||||
JPackerWords words = new JPackerWords(script, encoding);
|
||||
|
||||
Pattern wordsPattern = Pattern.compile("\\w+");
|
||||
Matcher wordsMatcher = wordsPattern.matcher(script);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (wordsMatcher.find()) {
|
||||
JPackerWord tempWord = new JPackerWord(wordsMatcher.group());
|
||||
wordsMatcher.appendReplacement(sb, words.find(tempWord).getEncoded());
|
||||
}
|
||||
wordsMatcher.appendTail(sb);
|
||||
|
||||
int ascii = Math.min(Math.max(words.getWords().size(), 2), encoding.getEncodingBase());
|
||||
|
||||
String p = escape(sb.toString());
|
||||
String a = String.valueOf(ascii);
|
||||
String c = String.valueOf(words.getWords().size());
|
||||
String k = words.toString();
|
||||
String e = getEncode(ascii);
|
||||
String r = ascii > 10 ? "e(c)" : "c";
|
||||
|
||||
return new Formatter().format(UNPACK, p, a, c, k, e, r).toString();
|
||||
}
|
||||
|
||||
// encoder for program blocks
|
||||
private String encodeBlock(Matcher matcher, List<String> blocks) {
|
||||
|
||||
String block = matcher.group();
|
||||
String func = matcher.group(1);
|
||||
String args = matcher.group(2);
|
||||
|
||||
if (func != null && !func.isEmpty()) { // the block is a function block
|
||||
// decode the function block (THIS IS THE IMPORTANT BIT)
|
||||
// We are retrieving all sub-blocks and will re-parse them in light
|
||||
// of newly shrunk variables
|
||||
while (Pattern.compile("~(\\d+)~").matcher(block).find()) {
|
||||
block = decodeBlock(block, blocks);
|
||||
}
|
||||
|
||||
// create the list of variable and argument names
|
||||
Pattern varNamePattern = Pattern.compile("var\\s+[\\w$]+");
|
||||
Matcher varNameMatcher = varNamePattern.matcher(block);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (varNameMatcher.find()) {
|
||||
sb.append(varNameMatcher.group()).append(",");
|
||||
}
|
||||
|
||||
String vars = "";
|
||||
if (!sb.toString().isEmpty()) {
|
||||
vars = sb.deleteCharAt(sb.length() - 1).toString().replaceAll("var\\s+", "");
|
||||
}
|
||||
|
||||
String[] ids = concat(args.split("\\s*,\\s*"), vars.split("\\s*,\\s*"));
|
||||
Set<String> idList = new LinkedHashSet<String>();
|
||||
for (String s : ids) {
|
||||
if (!s.isEmpty()) {
|
||||
idList.add(s);
|
||||
}
|
||||
}
|
||||
// process each identifier
|
||||
int count = 0;
|
||||
String shortId;
|
||||
for (String id : idList) {
|
||||
id = id.trim();
|
||||
if (id.length() > 1) { // > 1 char
|
||||
id = Matcher.quoteReplacement(id);
|
||||
// find the next free short name (check everything in the
|
||||
// current scope)
|
||||
Encoder e = new BasicEncoder();
|
||||
do {
|
||||
shortId = e.encode(count++);
|
||||
} while (Pattern.compile("[^\\w$.]" + shortId + "[^\\w$:]").matcher(block).find());
|
||||
// replace the long name with the short name
|
||||
while (Pattern.compile("([^\\w$.])" + id + "([^\\w$:])").matcher(block).find()) {
|
||||
block = block.replaceAll("([^\\w$.])" + id + "([^\\w$:])", "$1" + shortId + "$2");
|
||||
}
|
||||
block = block.replaceAll("([^{,\\w$.])" + id + ":", "$1" + shortId + ":");
|
||||
}
|
||||
}
|
||||
}
|
||||
String replacement = "~" + blocks.size() + "~";
|
||||
blocks.add(block);
|
||||
return replacement;
|
||||
}
|
||||
|
||||
private String decodeBlock(String block, List<String> blocks) {
|
||||
Matcher encoded = Pattern.compile("~(\\d+)~").matcher(block);
|
||||
StringBuffer sbe = new StringBuffer();
|
||||
while (encoded.find()) {
|
||||
int num = Integer.parseInt(encoded.group(1));
|
||||
encoded.appendReplacement(sbe, Matcher.quoteReplacement(blocks.get(num)));
|
||||
}
|
||||
encoded.appendTail(sbe);
|
||||
return sbe.toString();
|
||||
}
|
||||
|
||||
private String[] concat(String[] a, String[] b) {
|
||||
String[] c = new String[a.length + b.length];
|
||||
System.arraycopy(a, 0, c, 0, a.length);
|
||||
System.arraycopy(b, 0, c, a.length, b.length);
|
||||
return c;
|
||||
}
|
||||
|
||||
private String getEncode(int ascii) {
|
||||
if (ascii > 96) {
|
||||
return JPackerEncoding.HIGH_ASCII.getEncode();
|
||||
} else if (ascii > 36) {
|
||||
return JPackerEncoding.NORMAL.getEncode();
|
||||
} else if (ascii > 10) {
|
||||
return JPackerEncoding.MID.getEncode();
|
||||
} else {
|
||||
return JPackerEncoding.NUMERIC.getEncode();
|
||||
}
|
||||
}
|
||||
|
||||
private String escape(String input) {
|
||||
// single quotes wrap the final string so escape them
|
||||
// also escape new lines required by conditional comments
|
||||
return input.replaceAll("([\\\\'])", "\\\\$1").replaceAll("[\\r\\n]+", "\\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encoding level. Options are: {@link JPackerEncoding#NONE},
|
||||
* {@link JPackerEncoding#NUMERIC}, {@link JPackerEncoding#MID},
|
||||
* {@link JPackerEncoding#NORMAL} and {@link JPackerEncoding#HIGH_ASCII}.
|
||||
*
|
||||
* @return The current encoding level
|
||||
*/
|
||||
public JPackerEncoding getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encoding level to use.
|
||||
*
|
||||
* @param encoding
|
||||
*/
|
||||
public final void setEncoding(JPackerEncoding encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
}
|
||||
182
libsrc/jpacker/src/com/jpacker/JPackerParser.java
Normal file
182
libsrc/jpacker/src/com/jpacker/JPackerParser.java
Normal file
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.jpacker.evaluators.DeleteEvaluator;
|
||||
import com.jpacker.evaluators.Evaluator;
|
||||
import com.jpacker.evaluators.IntegerEvaluator;
|
||||
import com.jpacker.evaluators.StringEvaluator;
|
||||
import com.jpacker.strategies.DefaultReplacementStrategy;
|
||||
import com.jpacker.strategies.ReplacementStrategy;
|
||||
|
||||
/**
|
||||
* Parser class that matches RegGrp.js.
|
||||
*
|
||||
* This class parses the script using the expressions added via
|
||||
* {@link #remove(String)}, {@link #ignore(String)},
|
||||
* {@link #replace(String,String)} and {@link #replace(String,Evaluator)}
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerParser {
|
||||
|
||||
private static Pattern GROUPS = Pattern.compile("\\(");
|
||||
private static Pattern SUB_REPLACE = Pattern.compile("\\$(\\d+)");
|
||||
private static Pattern INDEXED = Pattern.compile("^\\$\\d+$");
|
||||
private static Pattern ESCAPE = Pattern.compile("\\\\.");
|
||||
private static Pattern ESCAPE_BRACKETS = Pattern.compile("\\(\\?[:=!]|\\[[^\\]]+\\]");
|
||||
private static Pattern DELETED = Pattern.compile("\\x01[^\\x01]*\\x01");
|
||||
private static String IGNORE = "$0";
|
||||
private List<JPackerPattern> jpatterns = new ArrayList<JPackerPattern>();
|
||||
|
||||
/**
|
||||
* Add an expression to be removed
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression {@link String}
|
||||
*/
|
||||
public void remove(String expression) {
|
||||
replace(expression, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to be ignored
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression {@link String}
|
||||
*/
|
||||
public void ignore(String expression) {
|
||||
replace(expression, IGNORE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to be replaced with the replacement string
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression {@link String}
|
||||
* @param replacement
|
||||
* Replacement {@link String}. Use $1, $2, etc. for groups
|
||||
*/
|
||||
public void replace(String expression, String replacement) {
|
||||
if (replacement.isEmpty()) {
|
||||
replace(expression, new DeleteEvaluator());
|
||||
return;
|
||||
}
|
||||
Evaluator evaluator;
|
||||
// does the pattern deal with sub-expressions? and a simple lookup (e.g. $2)
|
||||
if (SUB_REPLACE.matcher(replacement).matches() && INDEXED.matcher(replacement).matches()) {
|
||||
evaluator = new IntegerEvaluator(Integer.parseInt(replacement.substring(1)));
|
||||
} else {
|
||||
evaluator = new StringEvaluator(replacement);
|
||||
}
|
||||
JPackerPattern jpattern = new JPackerPattern(expression, evaluator);
|
||||
// count the number of sub-expressions
|
||||
jpattern.setLength(countSubExpressions(expression));
|
||||
jpatterns.add(jpattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to be replaced using an {@link Evaluator} object
|
||||
*
|
||||
* @param expression
|
||||
* Regular expression String
|
||||
* @param evaluator
|
||||
* The {@link Evaluator} object
|
||||
*/
|
||||
public void replace(String expression, Evaluator evaluator) {
|
||||
JPackerPattern jpattern = new JPackerPattern(expression, evaluator);
|
||||
// count the number of sub-expressions
|
||||
jpattern.setLength(countSubExpressions(expression));
|
||||
jpatterns.add(jpattern);
|
||||
}
|
||||
|
||||
// builds the patterns into a single regular expression
|
||||
private Pattern buildPatterns() {
|
||||
StringBuilder rtrn = new StringBuilder();
|
||||
for (JPackerPattern jpattern : jpatterns) {
|
||||
rtrn.append(jpattern).append("|");
|
||||
}
|
||||
rtrn.deleteCharAt(rtrn.length() - 1);
|
||||
return Pattern.compile(rtrn.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the parser in order to parse the script with the expressions
|
||||
* added via {@link #remove(String)}, {@link #ignore(String)},
|
||||
* {@link #replace(String,String)} and {@link #replace(String,Evaluator)}
|
||||
*
|
||||
* @param input
|
||||
* The script to be parsed
|
||||
* @return The parsed script
|
||||
*/
|
||||
public String exec(String input) {
|
||||
return exec(input, new DefaultReplacementStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the parser in order to parse the script with the expressions
|
||||
* added via {@link #remove(String)}, {@link #ignore(String)},
|
||||
* {@link #replace(String,String)} and {@link #replace(String,Evaluator)}.
|
||||
* Using a {@link ReplacementStrategy} object, a custom replacement
|
||||
* algorithm can be used.
|
||||
*
|
||||
* @param input
|
||||
* The script to be parsed
|
||||
* @param strategy
|
||||
* The {@link ReplacementStrategy} object for custom replacement
|
||||
* @return The parsed script
|
||||
*/
|
||||
public String exec(String input, ReplacementStrategy strategy) {
|
||||
Matcher matcher = buildPatterns().matcher(input);
|
||||
StringBuffer sb = new StringBuffer(input.length());
|
||||
while (matcher.find()) {
|
||||
String rep = strategy.replace(jpatterns, matcher);
|
||||
if (rep != null && !rep.isEmpty()) {
|
||||
rep = Matcher.quoteReplacement(rep);
|
||||
}
|
||||
matcher.appendReplacement(sb, rep);
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return DELETED.matcher(sb).replaceAll("");
|
||||
}
|
||||
|
||||
// count the number of sub-expressions
|
||||
private int countSubExpressions(String expression) {
|
||||
int cont = 0;
|
||||
Matcher matcher = GROUPS.matcher(internalEscape(expression));
|
||||
while (matcher.find()) {
|
||||
cont++;
|
||||
}
|
||||
// - add 1 because each group is itself a sub-expression
|
||||
return cont + 1;
|
||||
}
|
||||
|
||||
private String internalEscape(String str) {
|
||||
return ESCAPE_BRACKETS.matcher(ESCAPE.matcher(str).replaceAll("")).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* The patterns added to this {@link JPackerParser} object as a {@link List}
|
||||
* of {@link JPackerPattern}
|
||||
*
|
||||
* @return The {@link List} of {@link JPackerPattern} objects
|
||||
*/
|
||||
public List<JPackerPattern> getJPatterns() {
|
||||
return jpatterns;
|
||||
}
|
||||
}
|
||||
65
libsrc/jpacker/src/com/jpacker/JPackerPattern.java
Normal file
65
libsrc/jpacker/src/com/jpacker/JPackerPattern.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import com.jpacker.evaluators.Evaluator;
|
||||
|
||||
/**
|
||||
* Wrapper class for each pattern
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerPattern {
|
||||
|
||||
private String expression;
|
||||
private Evaluator evaluator;
|
||||
private int length;
|
||||
|
||||
public JPackerPattern() {
|
||||
}
|
||||
|
||||
public JPackerPattern(String expression, Evaluator evaluator) {
|
||||
this.expression = expression;
|
||||
this.evaluator = evaluator;
|
||||
evaluator.setJPattern(this);
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public void setExpression(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Evaluator getEvaluator() {
|
||||
return evaluator;
|
||||
}
|
||||
|
||||
public void setEvaluator(Evaluator evaluator) {
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + expression + ")";
|
||||
}
|
||||
}
|
||||
98
libsrc/jpacker/src/com/jpacker/JPackerWord.java
Normal file
98
libsrc/jpacker/src/com/jpacker/JPackerWord.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
/**
|
||||
* Wrapper class for a keyword
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class JPackerWord {
|
||||
|
||||
private int count = 0;
|
||||
private String encoded = "";
|
||||
private int index = -1;
|
||||
private String word;
|
||||
private String replacement;
|
||||
|
||||
public JPackerWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getEncoded() {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
public void setEncoded(String encoded) {
|
||||
this.encoded = encoded;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
public void setWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public String getReplacement() {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public void setReplacement(String replacement) {
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final JPackerWord other = (JPackerWord) obj;
|
||||
if ((this.word == null) ? (other.word != null) : !this.word.equals(other.word)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 37 * hash + (this.word != null ? this.word.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return word;
|
||||
}
|
||||
}
|
||||
149
libsrc/jpacker/src/com/jpacker/JPackerWords.java
Normal file
149
libsrc/jpacker/src/com/jpacker/JPackerWords.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Wrapper class for a {@link JPackerWord} list built based on script's keywords (later
|
||||
* wrapped into a JPackerWord list)
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public final class JPackerWords {
|
||||
|
||||
private JPackerEncoding encoding;
|
||||
private static final Pattern WORDS = Pattern.compile("\\w+");
|
||||
private List<JPackerWord> words = new ArrayList<JPackerWord>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param script
|
||||
* The input script to look up for keywords
|
||||
* @param encoding
|
||||
* The encoding level to use
|
||||
*/
|
||||
public JPackerWords(String script, JPackerEncoding encoding) {
|
||||
this.encoding = encoding;
|
||||
Matcher matcher = WORDS.matcher(script);
|
||||
while (matcher.find()) {
|
||||
add(new JPackerWord(matcher.group()));
|
||||
}
|
||||
encode();
|
||||
}
|
||||
|
||||
private void add(JPackerWord word) {
|
||||
if (!words.contains(word)) {
|
||||
words.add(word);
|
||||
}
|
||||
JPackerWord w = find(word);
|
||||
w.setCount(w.getCount() + 1);
|
||||
}
|
||||
|
||||
private void encode() {
|
||||
// sort by frequency
|
||||
Collections.sort(words, new Comparator<JPackerWord>() {
|
||||
|
||||
@Override
|
||||
public int compare(JPackerWord x, JPackerWord y) {
|
||||
return y.getCount() - x.getCount();
|
||||
}
|
||||
});
|
||||
|
||||
// a dictionary of encoding base -> base10
|
||||
Map<String, Integer> encoded = new HashMap<String, Integer>();
|
||||
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
encoded.put(encoding.getEncoder().encode(i), i);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (JPackerWord word : words) {
|
||||
if (encoded.containsKey(word.getWord())) {
|
||||
word.setIndex(encoded.get(word.getWord()));
|
||||
word.setReplacement("");
|
||||
} else {
|
||||
while (words.contains(new JPackerWord(encoding.getEncoder().encode(index)))) {
|
||||
index++;
|
||||
}
|
||||
word.setIndex(index++);
|
||||
word.setReplacement(word.getWord());
|
||||
}
|
||||
word.setEncoded(encoding.getEncoder().encode(word.getIndex()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sort by encoding
|
||||
Collections.sort(words, new Comparator<JPackerWord>() {
|
||||
|
||||
@Override
|
||||
public int compare(JPackerWord x, JPackerWord y) {
|
||||
return x.getIndex() - y.getIndex();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a word in the JPackerWord list
|
||||
*
|
||||
* @param word
|
||||
* The JPackerWord object to find in the list
|
||||
* @return The JPackerWord object if found, null otherwise
|
||||
*/
|
||||
public JPackerWord find(JPackerWord word) {
|
||||
Iterator<JPackerWord> it = words.iterator();
|
||||
while (it.hasNext() == true) {
|
||||
JPackerWord pw = it.next();
|
||||
if (pw.equals(word)) {
|
||||
return pw;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of JPackerWord objects
|
||||
*
|
||||
* @return The list of JPackerWord objects
|
||||
*/
|
||||
public List<JPackerWord> getWords() {
|
||||
return words;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method has been overridden to return the list of JPackerWord objects
|
||||
* as a single String object separated by the '|' character
|
||||
*
|
||||
* @return A List of JPackerWord objects as a single String object separated
|
||||
* by the '|' character
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (JPackerWord word : words) {
|
||||
sb.append(word.getReplacement()).append('|');
|
||||
}
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
27
libsrc/jpacker/src/com/jpacker/encoders/BasicEncoder.java
Normal file
27
libsrc/jpacker/src/com/jpacker/encoders/BasicEncoder.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* Basic (base52) encoder: [a-Z]
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public class BasicEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public String encode(int c) {
|
||||
return (c < 52 ? "" : encode(c / 52)) + (((c = c % 52)) > 25 ? String.valueOf((char) (c + 39)) : String.valueOf((char) (c + 97)));
|
||||
}
|
||||
}
|
||||
23
libsrc/jpacker/src/com/jpacker/encoders/Encoder.java
Normal file
23
libsrc/jpacker/src/com/jpacker/encoders/Encoder.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* Encoder interface to build encoder objects of different base
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public interface Encoder {
|
||||
|
||||
public String encode(int code);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* High-Ascii (base95) encoder: [¡-ÿ] SHOULD BE USED WITH CAUTION! Not fully
|
||||
* tested.
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class HighAsciiEncoder implements Encoder {
|
||||
|
||||
private static String LOOKUP_95 = "¡¢£€¥Š§š©ª«¬®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
|
||||
|
||||
@Override
|
||||
public String encode(int code) {
|
||||
String encoded = "";
|
||||
int i = 0;
|
||||
do {
|
||||
int digit = (code / (int) Math.pow(95, i)) % 95;
|
||||
encoded = LOOKUP_95.charAt(digit) + encoded;
|
||||
code -= digit * (int) Math.pow(95, i++);
|
||||
} while (code > 0);
|
||||
return encoded;
|
||||
}
|
||||
}
|
||||
38
libsrc/jpacker/src/com/jpacker/encoders/MidEncoder.java
Normal file
38
libsrc/jpacker/src/com/jpacker/encoders/MidEncoder.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* Mid base36 encoder: [0-z]
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public class MidEncoder implements Encoder {
|
||||
|
||||
// lookups seemed like the easiest way to do this since
|
||||
// I don't know of an equivalent to .toString(36)
|
||||
private static String LOOKUP_36 = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
@Override
|
||||
public String encode(int code) {
|
||||
String encoded = "";
|
||||
int i = 0;
|
||||
do {
|
||||
int digit = (code / (int) Math.pow(36, i)) % 36;
|
||||
encoded = LOOKUP_36.charAt(digit) + encoded;
|
||||
code -= digit * (int) Math.pow(36, i++);
|
||||
} while (code > 0);
|
||||
return encoded;
|
||||
}
|
||||
}
|
||||
27
libsrc/jpacker/src/com/jpacker/encoders/NormalEncoder.java
Normal file
27
libsrc/jpacker/src/com/jpacker/encoders/NormalEncoder.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* Normal (base62) encoder: [0-Z]
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public class NormalEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public String encode(int c) {
|
||||
return (c < 62 ? "" : encode(c / 62)) + ((c = c % 62) > 35 ? String.valueOf((char) (c + 29)) : Integer.toString(c, 36));
|
||||
}
|
||||
}
|
||||
27
libsrc/jpacker/src/com/jpacker/encoders/NumericEncoder.java
Normal file
27
libsrc/jpacker/src/com/jpacker/encoders/NumericEncoder.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.encoders;
|
||||
|
||||
/**
|
||||
* Numeric (base10) encoder: [0-9]
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*
|
||||
*/
|
||||
public class NumericEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public String encode(int code) {
|
||||
return String.valueOf(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.evaluators;
|
||||
|
||||
import com.jpacker.JPackerPattern;
|
||||
|
||||
/**
|
||||
* Abstract class for {@link Evaluator} objects. Its purpose is to provide the
|
||||
* implementation of a getter and setter of a {@link JPackerPattern} object.
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public abstract class AbstractEvaluator implements Evaluator {
|
||||
|
||||
private JPackerPattern jpattern;
|
||||
|
||||
/**
|
||||
* Gets the {@link JPackerPattern} object
|
||||
*
|
||||
* @return The {@link JPackerPattern} object
|
||||
*/
|
||||
@Override
|
||||
public JPackerPattern getJPattern() {
|
||||
return jpattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link JPackerPattern} object for this {@link Evaluator} object
|
||||
*
|
||||
* @param jpattern
|
||||
* The {@link JPackerPattern} object to set
|
||||
*/
|
||||
@Override
|
||||
public void setJPattern(JPackerPattern jpattern) {
|
||||
this.jpattern = jpattern;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.evaluators;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* An {@link Evaluator} implementation to have a {@link String} matched by an
|
||||
* expression removed from the script
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class DeleteEvaluator extends AbstractEvaluator implements Evaluator {
|
||||
|
||||
@Override
|
||||
public String evaluate(Matcher matcher, int offset) {
|
||||
return "\u0001" + matcher.group(offset) + "\u0001";
|
||||
}
|
||||
}
|
||||
68
libsrc/jpacker/src/com/jpacker/evaluators/Evaluator.java
Normal file
68
libsrc/jpacker/src/com/jpacker/evaluators/Evaluator.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.evaluators;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import com.jpacker.JPackerParser;
|
||||
import com.jpacker.JPackerPattern;
|
||||
import com.jpacker.strategies.DefaultReplacementStrategy;
|
||||
|
||||
/**
|
||||
* After expressions have been added to a {@link JPackerParser} object and a
|
||||
* ReplacementStrategy has been set, each {@link JPackerPattern} should have an
|
||||
* {@link Evaluator} object that'll evaluate a certain match of a pattern
|
||||
* expression and return a suitable replacement String. Commonly, after all
|
||||
* expressions have been added the the {@link JPackerParser} object, a one-line
|
||||
* String that contains all expressions is created by the {@link JPackerParser}
|
||||
* object using the {@link JPackerParser#getJPatterns()} method. In the
|
||||
* {@link #evaluate(Matcher, int)} method, the offset integer parameter
|
||||
* represents the position in such String that corresponds to a
|
||||
* {@link JPackerPattern} object.
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public interface Evaluator {
|
||||
|
||||
/**
|
||||
* Sets the {@link JPackerPattern} object to use
|
||||
*
|
||||
* @param jpattern
|
||||
* The {@link JPackerPattern} object for the {@link Evaluator}
|
||||
* implementations to use
|
||||
*/
|
||||
public void setJPattern(JPackerPattern jpattern);
|
||||
|
||||
/**
|
||||
* Gets the {@link JPackerPattern} object
|
||||
*
|
||||
* @return The {@link JPackerPattern} object if it has been set, null
|
||||
* otherwise
|
||||
*/
|
||||
public JPackerPattern getJPattern();
|
||||
|
||||
/**
|
||||
* Evaluates the string matched by the {@link Matcher} object and returns a
|
||||
* suitable replacement String.
|
||||
*
|
||||
* @param matcher
|
||||
* The {@link Matcher} object that contains a match (and its
|
||||
* groups)
|
||||
* @param offset
|
||||
* The offset in the String object returned by the
|
||||
* {@link JPackerParser#getJPatterns()} method in the
|
||||
* {@link JPackerParser} object
|
||||
* @return A replacement string (either text or group expressions, i.e.: $1)
|
||||
* @see DefaultReplacementStrategy
|
||||
*/
|
||||
public String evaluate(Matcher matcher, int offset);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.evaluators;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* An {@link Evaluator} implementation for replacement {@link String} objects
|
||||
* such as "$1" or "$2". Must be a simple group reference (i.e.: NOT
|
||||
* "Hello $3 $2")
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class IntegerEvaluator extends AbstractEvaluator implements Evaluator {
|
||||
|
||||
private int replacement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param replacement
|
||||
* If replacement String is "$1" then 1 would be the replacement
|
||||
* parameter
|
||||
*/
|
||||
public IntegerEvaluator(int replacement) {
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String evaluate(Matcher matcher, int offset) {
|
||||
return matcher.group(replacement + offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.evaluators;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class StringEvaluator extends AbstractEvaluator implements Evaluator {
|
||||
|
||||
private String replacement;
|
||||
|
||||
public StringEvaluator(String replacement) {
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacement function for complicated lookups (e.g. Hello $3 $2)
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String evaluate(Matcher matcher, int offset) {
|
||||
int length = getJPattern().getLength();
|
||||
String result = replacement;
|
||||
while (length-- > 0) {
|
||||
String mg = matcher.group(offset + length);
|
||||
result = result.replace("$" + length, mg == null ? "" : mg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package com.jpacker.exceptions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author poly
|
||||
*/
|
||||
public class EmptyFileException extends IOException {
|
||||
|
||||
public EmptyFileException(){
|
||||
super();
|
||||
}
|
||||
|
||||
public EmptyFileException(String message){
|
||||
super(message);
|
||||
}
|
||||
|
||||
private EmptyFileException(String path, String reason) {
|
||||
super(path + ((reason == null)
|
||||
? ""
|
||||
: " (" + reason + ")"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Web: {@link http://jpacker.googlecode.com/}
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.strategies;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import com.jpacker.JPackerPattern;
|
||||
|
||||
/**
|
||||
* Default replacement strategy class.
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public class DefaultReplacementStrategy implements ReplacementStrategy {
|
||||
|
||||
/**
|
||||
* Default replacement function. Called once for each match found
|
||||
*
|
||||
* @param jpatterns
|
||||
* A List<JPackerPattern> that contains all
|
||||
* {@link JPackerPattern} objects that wrap expressions to be
|
||||
* evaluated
|
||||
* @param matcher
|
||||
* A {@link Matcher} object that corresponds to a match in the
|
||||
* script
|
||||
*/
|
||||
@Override
|
||||
public String replace(List<JPackerPattern> jpatterns, Matcher matcher) {
|
||||
int i = 1;
|
||||
// loop through the patterns
|
||||
for (JPackerPattern jpattern : jpatterns) {
|
||||
// do we have a result?
|
||||
if (isMatch(matcher.group(i))) {
|
||||
return jpattern.getEvaluator().evaluate(matcher, i);
|
||||
} else { // skip over references to sub-expressions
|
||||
i += jpattern.getLength();
|
||||
}
|
||||
}
|
||||
return matcher.group(); // should never be hit, but you never know
|
||||
}
|
||||
|
||||
// check that match is not an empty string
|
||||
private boolean isMatch(String match) {
|
||||
return match != null && !match.isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Packer version 3.0 (final)
|
||||
* Copyright 2004-2007, Dean Edwards
|
||||
* Web: {@link http://dean.edwards.name/}
|
||||
*
|
||||
* This software is licensed under the MIT license
|
||||
* Web: {@link http://www.opensource.org/licenses/mit-license}
|
||||
*
|
||||
* Ported to Java by Pablo Santiago based on C# version by Jesse Hansen, <twindagger2k @ msn.com>
|
||||
* Email: <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
package com.jpacker.strategies;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import com.jpacker.JPackerPattern;
|
||||
|
||||
/**
|
||||
* An interface to build replacement strategies
|
||||
*
|
||||
* @author Pablo Santiago <pablo.santiago @ gmail.com>
|
||||
*/
|
||||
public interface ReplacementStrategy {
|
||||
|
||||
/**
|
||||
* Replacement function. Called once for each match found
|
||||
*
|
||||
* @param patterns
|
||||
* A List<JPackerPattern> that contains all
|
||||
* {@link JPackerPattern} objects that wrap expressions to be
|
||||
* evaluated
|
||||
* @param matcher
|
||||
* A {@link Matcher} object that corresponds to a match in the
|
||||
* script
|
||||
*/
|
||||
public String replace(List<JPackerPattern> patterns, Matcher matcher);
|
||||
}
|
||||
Reference in New Issue
Block a user