aboutsummaryrefslogtreecommitdiff
path: root/java/org/brotli/dec/Dictionary.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/org/brotli/dec/Dictionary.java')
-rw-r--r--java/org/brotli/dec/Dictionary.java43
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;
}