import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
/**
* Compressed General Category and Numeric Value: Compressor
* <p>
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
* <p>
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
* <p>
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
* <p>
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
* <p>
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
public class Compress {
public static int PARA_BITS = 3;
public static int PARA_SIZE = 1 << PARA_BITS;
public static int MAX_PARA = (Character.MAX_CODE_POINT + 1) / PARA_SIZE;
public static int BLOCK_BITS = 6;
public static int BLOCK_SIZE = 1 << BLOCK_BITS;
public static int MAX_BLOCK = MAX_PARA / BLOCK_SIZE;
public static ArrayList<String> pool = new ArrayList<>();
public static ArrayList<String> pool2 = new ArrayList<>();
public static StringBuilder buf3 = new StringBuilder();
/**
* Compress the general category and numeric value.
*/
public static void compress() {
pool.clear();
pool2.clear();
StringBuilder buf = new StringBuilder();
StringBuilder buf2 = new StringBuilder();
buf3.setLength(0);
for (int k = 0; k < MAX_BLOCK; k++) {
buf2.setLength(0);
for (int i = 0; i < BLOCK_SIZE; i++) {
buf.setLength(0);
for (int j = 0; j < PARA_SIZE; j++) {
int ch = (k * BLOCK_SIZE + i) * PARA_SIZE + j;
int type = Character.getType(ch);
int val = Character.digit(ch, 36);
buf.append((char) (((val + 1) << 5) + type));
}
String res = buf.toString();
int index = register(pool, res);
buf2.append((char) index);
}
String res = buf2.toString();
int index = register(pool2, res);
buf3.append((char) index);
}
}
/**
* Deduplicate an array of usigned 16 bit values.
*
* @param pool The pool.
* @param key The array.
* @return The index.
*/
private static int register(ArrayList<String> pool, String key) {
int index = pool.indexOf(key);
if (index == -1) {
index = pool.size();
pool.add(key);
}
return index;
}
public static int LANG_DEFAULT = 0;
public static int LANG_CSHARP = 1;
public static int LANG_PYTHON = 2;
/**
* Print an array of unsigned 16 bit values.
*
* @param str The unsigned 16 bit values.
*/
public static void show(String str, Writer wr, int lang) throws IOException {
if (lang == LANG_CSHARP) {
wr.write("new short[] {");
} else {
wr.write('[');
}
for (int i = 0; i < str.length(); i++) {
if (i != 0)
wr.write(", ");
if (i != 0 && i % 16 == 0) {
wr.write("\n");
wr.write(" ");
}
wr.write(Integer.toString(str.charAt(i)));
}
if (lang == LANG_CSHARP) {
wr.write('}');
} else {
wr.write(']');
}
}
public static void show(String str, Writer wr) throws IOException {
show(str, wr, LANG_DEFAULT);
}
/**
* <p>Retrieve the specification version.</p>
*
* @return The specification version.
*/
public static double getVersion() {
String vers = System.getProperties().getProperty("java.specification.version");
return Double.parseDouble(vers);
}
public static void statistics(long ts, Writer wr, int lang) throws IOException {
long ts2 = System.currentTimeMillis();
String lc;
if (lang == LANG_PYTHON) {
wr.write("###\n");
lc = "# ";
} else {
wr.write("/**\n");
lc = " * ";
}
wr.write(lc + "Java Specification Version " + Compress.getVersion() + "\n");
wr.write(lc + "\n");
int alpha = Compress.pool.size() * Compress.PARA_SIZE;
int beta = Compress.pool2.size() * Compress.BLOCK_SIZE;
int gamma = Compress.MAX_BLOCK;
wr.write(lc + "pool.size()*PARA_SIZE= " + alpha + "\n");
wr.write(lc + "pool2.size()*BLOCK_SIZE= " + beta + "\n");
wr.write(lc + "MAX_BLOCK= " + gamma + "\n");
wr.write(lc + "Total= " + (alpha + beta + gamma) + "\n");
if (lang == LANG_PYTHON) {
wr.write("##\n");
} else {
wr.write(" */\n");
}
wr.write("\n");
System.out.println("Compression took " + (ts2 - ts) + " ms");
}
public static void statistics(long ts, Writer wr) throws IOException {
statistics(ts, wr, LANG_DEFAULT);
}
}