mirror of
https://github.com/google/brotli.git
synced 2026-07-08 17:56:58 +00:00
Comb UTF-8 literal processing
PiperOrigin-RevId: 770672448
This commit is contained in:
committed by
Copybara-Service
parent
405b434d85
commit
3efb30f96b
@@ -39,6 +39,7 @@ final class DictionaryData {
|
||||
String skipFlip, int[] sizeBits, String sizeBitsData) {
|
||||
// Initialize lower 7 bits of every byte in the dictionary.
|
||||
final byte[] dict = Utils.toUsAsciiBytes(data0 + data1);
|
||||
final int[] skipFlipRunes = Utils.toUtf8Runes(skipFlip);
|
||||
if (DICTIONARY_DATA_DEBUG != 0) {
|
||||
if (dict.length != dictionary.capacity()) {
|
||||
throw new RuntimeException("Corrupted brotli dictionary");
|
||||
@@ -47,10 +48,10 @@ final class DictionaryData {
|
||||
|
||||
// Toggle high bit using run-length delta encoded "skipFlip".
|
||||
int offset = 0;
|
||||
final int n = skipFlip.length() >> 1;
|
||||
final int n = skipFlipRunes.length >> 1;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
final int skip = (int) skipFlip.charAt(2 * i) - 36;
|
||||
final int flip = (int) skipFlip.charAt(2 * i + 1) - 36;
|
||||
final int skip = skipFlipRunes[2 * i] - 36;
|
||||
final int flip = skipFlipRunes[2 * i + 1] - 36;
|
||||
for (int j = 0; j < skip; ++j) {
|
||||
dict[offset] = (byte) ((int) dict[offset] ^ 3);
|
||||
offset++;
|
||||
|
||||
@@ -76,11 +76,12 @@ final class Transform {
|
||||
|
||||
private static void unpackTransforms(byte[] prefixSuffix,
|
||||
int[] prefixSuffixHeads, int[] transforms, String prefixSuffixSrc, String transformsSrc) {
|
||||
final int n = prefixSuffixSrc.length();
|
||||
final int[] prefixSuffixBytes = Utils.toUtf8Runes(prefixSuffixSrc);
|
||||
final int n = prefixSuffixBytes.length;
|
||||
int index = 1;
|
||||
int j = 0;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
final int c = (int) prefixSuffixSrc.charAt(i);
|
||||
final int c = prefixSuffixBytes[i];
|
||||
if (c == 35) { // == #
|
||||
prefixSuffixHeads[index++] = j;
|
||||
} else {
|
||||
|
||||
@@ -99,6 +99,14 @@ final class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
static int[] toUtf8Runes(String src) {
|
||||
int[] result = new int[src.length()];
|
||||
for (int i = 0; i < src.length(); i++) {
|
||||
result[i] = (int) src.charAt(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static ByteBuffer asReadOnlyBuffer(ByteBuffer src) {
|
||||
return src.asReadOnlyBuffer();
|
||||
}
|
||||
|
||||
@@ -1312,11 +1312,12 @@ internal class Transforms {
|
||||
}
|
||||
|
||||
private fun unpackTransforms(prefixSuffix: ByteArray, prefixSuffixHeads: IntArray, transforms: IntArray, prefixSuffixSrc: String, transformsSrc: String): Unit {
|
||||
val n: Int = prefixSuffixSrc.length;
|
||||
val prefixSuffixBytes: IntArray = toUtf8Runes(prefixSuffixSrc);
|
||||
val n: Int = prefixSuffixBytes.size;
|
||||
var index: Int = 1;
|
||||
var j: Int = 0;
|
||||
for (i: Int in 0 until n) {
|
||||
val c: Int = prefixSuffixSrc[i].code.toInt();
|
||||
val c: Int = prefixSuffixBytes[i];
|
||||
if (c == 35) {
|
||||
prefixSuffixHeads[index++] = j;
|
||||
} else {
|
||||
@@ -1945,11 +1946,12 @@ fun setData(newData: ByteBuffer, newSizeBits: IntArray): Unit {
|
||||
|
||||
private fun unpackDictionaryData(dictionary: ByteBuffer, data0: String, data1: String, skipFlip: String, sizeBits: IntArray, sizeBitsData: String): Unit {
|
||||
val dict: ByteArray = toUsAsciiBytes(data0 + data1);
|
||||
val skipFlipRunes: IntArray = toUtf8Runes(skipFlip);
|
||||
var offset: Int = 0;
|
||||
val n: Int = skipFlip.length shr 1;
|
||||
val n: Int = skipFlipRunes.size shr 1;
|
||||
for (i: Int in 0 until n) {
|
||||
val skip: Int = skipFlip[2 * i].code.toInt() - 36;
|
||||
val flip: Int = skipFlip[2 * i + 1].code.toInt() - 36;
|
||||
val skip: Int = skipFlipRunes[2 * i] - 36;
|
||||
val flip: Int = skipFlipRunes[2 * i + 1] - 36;
|
||||
for (j: Int in 0 until skip) {
|
||||
dict[offset] = (dict[offset].toInt() xor 3).toByte();
|
||||
offset++;
|
||||
@@ -2015,6 +2017,15 @@ internal fun toUsAsciiBytes(src: String): ByteArray {
|
||||
return src.toByteArray(Charsets.US_ASCII);
|
||||
}
|
||||
|
||||
internal fun toUtf8Runes(src: String): IntArray {
|
||||
var len: Int = src.length;
|
||||
var result: IntArray = IntArray(size = len);
|
||||
for (i: Int in 0 until len) {
|
||||
result[i] = src[i].code.toInt();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal fun flipBuffer(buffer: Buffer): Unit {
|
||||
buffer.flip();
|
||||
}
|
||||
|
||||
24
js/decode.js
24
js/decode.js
@@ -1574,11 +1574,12 @@ let makeBrotliDecode = () => {
|
||||
* @return {void}
|
||||
*/
|
||||
function unpackTransforms(prefixSuffix, prefixSuffixHeads, transforms, prefixSuffixSrc, transformsSrc) {
|
||||
const /** @type {number} */ n = prefixSuffixSrc.length;
|
||||
const /** @type {!Int32Array} */ prefixSuffixBytes = toUtf8Runes(prefixSuffixSrc);
|
||||
const /** @type {number} */ n = prefixSuffixBytes.length;
|
||||
let /** @type {number} */ index = 1;
|
||||
let /** @type {number} */ j = 0;
|
||||
for (let /** @type {number} */ i = 0; i < n; ++i) {
|
||||
const /** @type {number} */ c = prefixSuffixSrc.charCodeAt(i);
|
||||
const /** @type {number} */ c = prefixSuffixBytes[i];
|
||||
if (c === 35) {
|
||||
prefixSuffixHeads[index++] = j;
|
||||
} else {
|
||||
@@ -2290,11 +2291,12 @@ let makeBrotliDecode = () => {
|
||||
*/
|
||||
function unpackDictionaryData(dictionary, data0, data1, skipFlip, sizeBits, sizeBitsData) {
|
||||
const /** @type {!Int8Array} */ dict = toUsAsciiBytes(data0 + data1);
|
||||
const /** @type {!Int32Array} */ skipFlipRunes = toUtf8Runes(skipFlip);
|
||||
let /** @type {number} */ offset = 0;
|
||||
const /** @type {number} */ n = skipFlip.length >> 1;
|
||||
const /** @type {number} */ n = skipFlipRunes.length >> 1;
|
||||
for (let /** @type {number} */ i = 0; i < n; ++i) {
|
||||
const /** @type {number} */ skip = skipFlip.charCodeAt(2 * i) - 36;
|
||||
const /** @type {number} */ flip = skipFlip.charCodeAt(2 * i + 1) - 36;
|
||||
const /** @type {number} */ skip = skipFlipRunes[2 * i] - 36;
|
||||
const /** @type {number} */ flip = skipFlipRunes[2 * i + 1] - 36;
|
||||
for (let /** @type {number} */ j = 0; j < skip; ++j) {
|
||||
dict[offset] = dict[offset] ^ 3;
|
||||
offset++;
|
||||
@@ -2374,6 +2376,18 @@ let makeBrotliDecode = () => {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* @param {string} src
|
||||
* @return {!Int32Array}
|
||||
*/
|
||||
function toUtf8Runes(src) {
|
||||
const /** @type {number} */ n = src.length;
|
||||
const /** @type {!Int32Array} */ result = new Int32Array(n);
|
||||
for (let /** @type {number} */ i = 0; i < n; ++i) {
|
||||
result[i] = src.charCodeAt(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* @param {!State} s
|
||||
* @param {number} code
|
||||
|
||||
2
js/decode.min.js
vendored
2
js/decode.min.js
vendored
File diff suppressed because one or more lines are too long
20
js/decode.ts
20
js/decode.ts
@@ -1328,11 +1328,12 @@ class Transforms {
|
||||
|
||||
const RFC_TRANSFORMS = new Transforms(121, 167, 50);
|
||||
function unpackTransforms(prefixSuffix: Int8Array, prefixSuffixHeads: Int32Array, transforms: Int32Array, prefixSuffixSrc: string, transformsSrc: string): void {
|
||||
const n: number = prefixSuffixSrc.length;
|
||||
const prefixSuffixBytes: Int32Array = toUtf8Runes(prefixSuffixSrc);
|
||||
const n: number = prefixSuffixBytes.length;
|
||||
let index = 1;
|
||||
let j = 0;
|
||||
for (let i = 0; i < n; ++i) {
|
||||
const c: number = prefixSuffixSrc.charCodeAt(i);
|
||||
const c: number = prefixSuffixBytes[i];
|
||||
if (c === 35) {
|
||||
prefixSuffixHeads[index++] = j;
|
||||
} else {
|
||||
@@ -1858,11 +1859,12 @@ function setData(newData: ByteBuffer, newSizeBits: Int32Array): void {
|
||||
|
||||
function unpackDictionaryData(dictionary: ByteBuffer, data0: string, data1: string, skipFlip: string, sizeBits: Int32Array, sizeBitsData: string): void {
|
||||
const dict: Int8Array = toUsAsciiBytes(data0 + data1);
|
||||
const skipFlipRunes: Int32Array = toUtf8Runes(skipFlip);
|
||||
let offset = 0;
|
||||
const n: number = skipFlip.length >> 1;
|
||||
const n: number = skipFlipRunes.length >> 1;
|
||||
for (let i = 0; i < n; ++i) {
|
||||
const skip: number = skipFlip.charCodeAt(2 * i) - 36;
|
||||
const flip: number = skipFlip.charCodeAt(2 * i + 1) - 36;
|
||||
const skip: number = skipFlipRunes[2 * i] - 36;
|
||||
const flip: number = skipFlipRunes[2 * i + 1] - 36;
|
||||
for (let j = 0; j < skip; ++j) {
|
||||
dict[offset] = dict[offset] ^ 3;
|
||||
offset++;
|
||||
@@ -1918,6 +1920,14 @@ function toUsAsciiBytes(src: string): Int8Array {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function toUtf8Runes(src: string): Int32Array {
|
||||
const n: number = src.length;
|
||||
const result = new Int32Array(n);
|
||||
for (let i = 0; i < n; ++i) {
|
||||
result[i] = src.charCodeAt(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function makeError(s: State, code: number): number {
|
||||
if (code >= 0) {
|
||||
return code;
|
||||
|
||||
Reference in New Issue
Block a user