|
14 | 14 | public class Base32768Decoder { |
15 | 15 | Base32768Decoder() {} |
16 | 16 |
|
17 | | - private static final int SEVEN_BITS_CP_FINAL = 0x29F; |
18 | | - |
19 | 17 | private static final char INVALID = 0xFFFF; |
20 | 18 | private static final char FLAG7 = 0x8000; |
21 | 19 |
|
22 | | - private static final char[] DECODE = new char[1 << 16]; |
23 | | - private static final byte[] LAST_BITS = new byte[1 << 16]; |
| 20 | + private static final int TABLE_SIZE = 0xa840 + 32; // 43104 (max CODES_15 codepoint + 32) |
| 21 | + private static final char[] DECODE = new char[TABLE_SIZE]; |
| 22 | + private static final byte[] LAST_BITS = new byte[TABLE_SIZE]; |
24 | 23 |
|
25 | 24 | private static final VarHandle VH_LONG_BE = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN); |
26 | 25 |
|
@@ -48,22 +47,15 @@ public class Base32768Decoder { |
48 | 47 | LAST_BITS[cp] = 15; |
49 | 48 | } |
50 | 49 | } |
51 | | - |
52 | | - // surrogate 明示無効化 |
53 | | - for (int cp = 0xD800; cp <= 0xDFFF; cp++) { |
54 | | - DECODE[cp] = INVALID; |
55 | | - LAST_BITS[cp] = 0; |
56 | | - } |
57 | 50 | } |
58 | 51 |
|
59 | 52 | private static int calcBufferLength(String src) { |
60 | | - int srcCodePointCount = src.codePointCount(0, src.length()); |
61 | | - |
62 | | - int offset = src.offsetByCodePoints(0, srcCodePointCount - 1); |
63 | | - int lastCodePoint = src.codePointAt(offset); |
64 | | - boolean isSevenBitsCode = lastCodePoint <= SEVEN_BITS_CP_FINAL; |
65 | | - |
66 | | - return (isSevenBitsCode ? (srcCodePointCount - 1) * 15 + 7 : srcCodePointCount * 15) / 8; |
| 53 | + if (src.isEmpty()) return 0; |
| 54 | + final int n = src.length(); |
| 55 | + final char last = src.charAt(n - 1); |
| 56 | + final int lastBits = (last < TABLE_SIZE) ? (LAST_BITS[last] & 0xFF) : 0; |
| 57 | + if (lastBits == 0) throw new IllegalBase32768TextException(n - 1, last); |
| 58 | + return ((n - 1) * 15 + lastBits) >>> 3; |
67 | 59 | } |
68 | 60 |
|
69 | 61 | /** |
@@ -133,7 +125,7 @@ public byte[] decode(String src) { |
133 | 125 | if (n == 0) return new byte[0]; |
134 | 126 |
|
135 | 127 | final char last = src.charAt(n - 1); |
136 | | - final int lastBits = LAST_BITS[last] & 0xFF; |
| 128 | + final int lastBits = (last < TABLE_SIZE) ? (LAST_BITS[last] & 0xFF) : 0; |
137 | 129 | if (lastBits == 0) throw new IllegalBase32768TextException(n - 1, last); |
138 | 130 |
|
139 | 131 | final int outLen = ((n - 1) * 15 + lastBits) >>> 3; |
@@ -254,7 +246,6 @@ public byte[] decode(String src) { |
254 | 246 |
|
255 | 247 | if (bitCount > 0 && (acc & ((1L << bitCount) - 1)) != ((1L << bitCount) - 1)) { |
256 | 248 | long actual = acc & ((1L << bitCount) - 1); |
257 | | - long expected = (1L << bitCount) - 1; |
258 | 249 | throw new IllegalBase32768TextException("Bad padding at position " + (n - 1) + ": expected " + bitCount + " bits of 1s, got 0b" + Long.toBinaryString(actual)); |
259 | 250 | } |
260 | 251 |
|
|
0 commit comments