Compresses the specified text. Returns the original text if the packed text is not shorter. @param text text to be packed @return packed or original text
(final byte[] text)
| 24 | * @return packed or original text |
| 25 | */ |
| 26 | public static byte[] pack(final byte[] text) { |
| 27 | // only compress texts with more than 4 characters |
| 28 | final int tl = text.length - 1; |
| 29 | if(tl < 4) return text; |
| 30 | |
| 31 | // store length at beginning of array |
| 32 | final byte[] bytes = new byte[tl]; |
| 33 | int size = Num.set(bytes, tl + 1); |
| 34 | |
| 35 | // find lower-case and non-ascii characters |
| 36 | int lc = 0, uc = 0, out = 0; |
| 37 | for(final byte t : text) { |
| 38 | lc += t >= 'A' && t <= 'Z' ? -1 : 1; |
| 39 | uc += t >= 0 ? 1 : -1; |
| 40 | } |
| 41 | // too many non-ascii characters: skip compression |
| 42 | if(uc < 0) return text; |
| 43 | |
| 44 | // first bit: packer version (0), second bit: mapping type (upper/lower case) |
| 45 | final byte[] map; |
| 46 | if(lc >= 0) { |
| 47 | out = 2; |
| 48 | map = PACK1; |
| 49 | } else { |
| 50 | map = PACK2; |
| 51 | } |
| 52 | |
| 53 | // loop through and compress all characters |
| 54 | int in, off = 2; |
| 55 | for(final byte t : text) { |
| 56 | final int b = t >= 0 ? map[t] : t, s; |
| 57 | if(b >= 0x00 && b < 0x08) { // 1 xxx |
| 58 | in = 1 | b << 1; |
| 59 | s = 4; |
| 60 | } else if(b >= 0x08 && b < 0x10) { // 01 xxx |
| 61 | in = 2 | b << 2; |
| 62 | s = 5; |
| 63 | } else if(b >= 0x10 && b < 0x20) { // 001 xxxx |
| 64 | in = 4 | b << 3; |
| 65 | s = 7; |
| 66 | } else if(b >= 0x20 && b < 0x40) { // 0001 xxxxx |
| 67 | in = 8 | b << 4; |
| 68 | s = 9; |
| 69 | } else { // 0000 xxxxxxxx |
| 70 | in = b << 4; |
| 71 | s = 12; |
| 72 | } |
| 73 | for(int i = 0; i < s; i++) { |
| 74 | out |= (in & 1) << off; |
| 75 | in >>>= 1; |
| 76 | off = off + 1 & 7; |
| 77 | if(off == 0) { |
| 78 | // skip compression if packed array gets too large |
| 79 | if(size == tl) return text; |
| 80 | bytes[size++] = (byte) out; |
| 81 | out = 0; |
| 82 | } |
| 83 | } |