View Javadoc
1   /* Copyright 2015 Google Inc. All Rights Reserved.
2   
3      Distributed under MIT license.
4      See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5   */
6   
7   package org.htmlunit.util.brotli;
8   
9   import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_READ_FAILED;
10  import static org.htmlunit.util.brotli.BrotliError.BROTLI_OK;
11  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC;
12  
13  import java.io.ByteArrayInputStream;
14  import java.io.IOException;
15  import java.io.InputStream;
16  import java.io.UnsupportedEncodingException;
17  import java.nio.Buffer;
18  import java.nio.ByteBuffer;
19  
20  /**
21   * A set of utility methods.
22   */
23  @SuppressWarnings("all")
24  final class Utils {
25  
26    private static final byte[] BYTE_ZEROES = new byte[1024];
27  
28    private static final int[] INT_ZEROES = new int[1024];
29  
30    /**
31     * Fills byte array with zeroes.
32     *
33     * <p> Current implementation uses {@link System#arraycopy}, so it should be used for length not
34     * less than 16.
35     *
36     * @param dest array to fill with zeroes
37     * @param start the first item to fill
38     * @param end the last item to fill (exclusive)
39     */
40    static void fillBytesWithZeroes(byte[] dest, int start, int end) {
41      int cursor = start;
42      while (cursor < end) {
43        int step = Math.min(cursor + 1024, end) - cursor;
44        System.arraycopy(BYTE_ZEROES, 0, dest, cursor, step);
45        cursor += step;
46      }
47    }
48  
49    /**
50     * Fills int array with zeroes.
51     *
52     * <p> Current implementation uses {@link System#arraycopy}, so it should be used for length not
53     * less than 16.
54     *
55     * @param dest array to fill with zeroes
56     * @param start the first item to fill
57     * @param end the last item to fill (exclusive)
58     */
59    static void fillIntsWithZeroes(int[] dest, int start, int end) {
60      int cursor = start;
61      while (cursor < end) {
62        int step = Math.min(cursor + 1024, end) - cursor;
63        System.arraycopy(INT_ZEROES, 0, dest, cursor, step);
64        cursor += step;
65      }
66    }
67  
68    static void copyBytes(byte[] dst, int target, byte[] src, int start, int end) {
69      System.arraycopy(src, start, dst, target, end - start);
70    }
71  
72    static void copyBytesWithin(byte[] bytes, int target, int start, int end) {
73      System.arraycopy(bytes, start, bytes, target, end - start);
74    }
75  
76    static int readInput(State s, byte[] dst, int offset, int length) {
77      try {
78        return s.input.read(dst, offset, length);
79      } catch (IOException e) {
80        return makeError(s, BROTLI_ERROR_READ_FAILED);
81      }
82    }
83  
84    static InputStream makeEmptyInput() {
85      return new ByteArrayInputStream(new byte[0]);
86    }
87  
88    static void closeInput(State s) throws IOException {
89      s.input.close();
90      s.input = makeEmptyInput();
91    }
92  
93    static byte[] toUsAsciiBytes(String src) {
94      try {
95        // NB: String#getBytes(String) is present in JDK 1.1, while other variants require JDK 1.6 and
96        // above.
97        return src.getBytes("US-ASCII");
98      } catch (UnsupportedEncodingException e) {
99        throw new RuntimeException(e); // cannot happen
100     }
101   }
102 
103   static int[] toUtf8Runes(String src) {
104     int[] result = new int[src.length()];
105     for (int i = 0; i < src.length(); i++) {
106       result[i] = src.charAt(i);
107     }
108     return result;
109   }
110 
111   static ByteBuffer asReadOnlyBuffer(ByteBuffer src) {
112     return src.asReadOnlyBuffer();
113   }
114 
115   static int isReadOnly(ByteBuffer src) {
116     return src.isReadOnly() ? 1 : 0;
117   }
118 
119   static int isDirect(ByteBuffer src) {
120     return src.isDirect() ? 1 : 0;
121   }
122 
123   // Crazy pills factory: code compiled for JDK8 does not work on JRE9.
124   static void flipBuffer(Buffer buffer) {
125     buffer.flip();
126   }
127 
128   static int isDebugMode() {
129     boolean assertsEnabled = Boolean.parseBoolean(System.getProperty("BROTLI_ENABLE_ASSERTS"));
130     return assertsEnabled ? 1 : 0;
131   }
132 
133   // See BitReader.LOG_BITNESS
134   static int getLogBintness() {
135     boolean isLongExpensive = Boolean.parseBoolean(System.getProperty("BROTLI_32_BIT_CPU"));
136     return isLongExpensive ? 5 : 6;
137   }
138 
139   static int shr32(int x, int y) {
140     return x >>> y;
141   }
142 
143   static long shr64(long x, int y) {
144     return x >>> y;
145   }
146 
147   static int min(int a, int b) {
148     return Math.min(a, b);
149   }
150 
151   static int makeError(State s, int code) {
152     if (code >= BROTLI_OK) {
153       return code;
154     }
155     if (s.runningState >= 0) {
156       s.runningState = code;  // Only the first error is remembered.
157     }
158     // TODO(eustas): expand codes to messages, if ever necessary.
159     if (code <= BROTLI_PANIC) {
160       throw new IllegalStateException("Brotli error code: " + code);
161     }
162     throw new BrotliRuntimeException("Error code: " + code);
163   }
164 }