BOCU.java
4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
* Decompiled with CFR 0_118.
*/
package com.adobe.agl.impl;
import com.adobe.agl.text.UCharacterIterator;
public class BOCU {
public static int compress(String source, byte[] buffer, int offset) {
int prev = 0;
UCharacterIterator iterator = UCharacterIterator.getInstance(source);
int codepoint = iterator.nextCodePoint();
while (codepoint != -1) {
prev = prev < 19968 || prev >= 40960 ? (prev & -128) - -80 : 30292;
offset = BOCU.writeDiff(codepoint - prev, buffer, offset);
prev = codepoint;
codepoint = iterator.nextCodePoint();
}
return offset;
}
public static int getCompressionLength(String source) {
int prev = 0;
int result = 0;
UCharacterIterator iterator = UCharacterIterator.getInstance(source);
int codepoint = iterator.nextCodePoint();
while (codepoint != -1) {
prev = prev < 19968 || prev >= 40960 ? (prev & -128) - -80 : 30292;
codepoint = iterator.nextCodePoint();
result += BOCU.lengthOfDiff(codepoint - prev);
prev = codepoint;
}
return result;
}
private static final long getNegDivMod(int number, int factor) {
int modulo = number % factor;
long result = number / factor;
if (modulo < 0) {
--result;
modulo += factor;
}
return result << 32 | (long)modulo;
}
private static final int writeDiff(int diff, byte[] buffer, int offset) {
if (diff >= -80) {
if (diff <= 80) {
buffer[offset++] = (byte)(129 + diff);
} else if (diff <= 10667) {
buffer[offset++] = (byte)(210 + diff / 253);
buffer[offset++] = (byte)(3 + diff % 253);
} else if (diff <= 192785) {
buffer[offset + 2] = (byte)(3 + diff % 253);
buffer[offset + 1] = (byte)(3 + (diff /= 253) % 253);
buffer[offset] = (byte)(252 + diff / 253);
offset += 3;
} else {
buffer[offset + 3] = (byte)(3 + diff % 253);
buffer[offset] = (byte)(3 + (diff /= 253) % 253);
buffer[offset + 1] = (byte)(3 + (diff /= 253) % 253);
buffer[offset] = -1;
offset += 4;
}
} else {
long division = BOCU.getNegDivMod(diff, 253);
int modulo = (int)division;
if (diff >= -10668) {
diff = (int)(division >> 32);
buffer[offset++] = (byte)(49 + diff);
buffer[offset++] = (byte)(3 + modulo);
} else if (diff >= -192786) {
buffer[offset + 2] = (byte)(3 + modulo);
diff = (int)(division >> 32);
division = BOCU.getNegDivMod(diff, 253);
modulo = (int)division;
diff = (int)(division >> 32);
buffer[offset + 1] = (byte)(3 + modulo);
buffer[offset] = (byte)(7 + diff);
offset += 3;
} else {
buffer[offset + 3] = (byte)(3 + modulo);
diff = (int)(division >> 32);
division = BOCU.getNegDivMod(diff, 253);
modulo = (int)division;
diff = (int)(division >> 32);
buffer[offset + 2] = (byte)(3 + modulo);
division = BOCU.getNegDivMod(diff, 253);
modulo = (int)division;
buffer[offset + 1] = (byte)(3 + modulo);
buffer[offset] = 3;
offset += 4;
}
}
return offset;
}
private static final int lengthOfDiff(int diff) {
if (diff >= -80) {
if (diff <= 80) {
return 1;
}
if (diff <= 10667) {
return 2;
}
if (diff <= 192785) {
return 3;
}
return 4;
}
if (diff >= -10668) {
return 2;
}
if (diff >= -192786) {
return 3;
}
return 4;
}
}