diff options
Diffstat (limited to 'java/org/brotli/dec/Dictionary.java')
-rw-r--r-- | java/org/brotli/dec/Dictionary.java | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/java/org/brotli/dec/Dictionary.java b/java/org/brotli/dec/Dictionary.java index a6867b7..043572f 100644 --- a/java/org/brotli/dec/Dictionary.java +++ b/java/org/brotli/dec/Dictionary.java @@ -18,7 +18,12 @@ import java.nio.ByteBuffer; * once in each classworld). To avoid this, it is enough to call {@link #getData()} proactively. */ public final class Dictionary { - private static volatile ByteBuffer data; + static final int MIN_DICTIONARY_WORD_LENGTH = 4; + static final int MAX_DICTIONARY_WORD_LENGTH = 31; + + private static ByteBuffer data; + static final int[] offsets = new int[32]; + static final int[] sizeBits = new int[32]; private static class DataLoader { static final boolean OK; @@ -34,10 +39,44 @@ public final class Dictionary { } } - public static void setData(ByteBuffer data) { + public static void setData(ByteBuffer data, int[] sizeBits) { if (!data.isDirect() || !data.isReadOnly()) { throw new BrotliRuntimeException("data must be a direct read-only byte buffer"); } + // TODO: is that so? + if (sizeBits.length > MAX_DICTIONARY_WORD_LENGTH) { + throw new BrotliRuntimeException( + "sizeBits length must be at most " + MAX_DICTIONARY_WORD_LENGTH); + } + for (int i = 0; i < MIN_DICTIONARY_WORD_LENGTH; ++i) { + if (sizeBits[i] != 0) { + throw new BrotliRuntimeException("first " + MIN_DICTIONARY_WORD_LENGTH + " must be 0"); + } + } + int[] dictionaryOffsets = Dictionary.offsets; + int[] dictionarySizeBits = Dictionary.sizeBits; + System.arraycopy(sizeBits, 0, dictionarySizeBits, 0, sizeBits.length); + int pos = 0; + int limit = data.capacity(); + for (int i = 0; i < sizeBits.length; ++i) { + dictionaryOffsets[i] = pos; + int bits = dictionarySizeBits[i]; + if (bits != 0) { + if (bits >= 31) { + throw new BrotliRuntimeException("sizeBits values must be less than 31"); + } + pos += i << bits; + if (pos <= 0 || pos > limit) { + throw new BrotliRuntimeException("sizeBits is inconsistent: overflow"); + } + } + } + for (int i = sizeBits.length; i < 32; ++i) { + dictionaryOffsets[i] = pos; + } + if (pos != limit) { + throw new BrotliRuntimeException("sizeBits is inconsistent: underflow"); + } Dictionary.data = data; } |