Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
641 lines
10 KiB
641 lines
10 KiB
package brotli |
|
|
|
const ( |
|
transformIdentity = 0 |
|
transformOmitLast1 = 1 |
|
transformOmitLast2 = 2 |
|
transformOmitLast3 = 3 |
|
transformOmitLast4 = 4 |
|
transformOmitLast5 = 5 |
|
transformOmitLast6 = 6 |
|
transformOmitLast7 = 7 |
|
transformOmitLast8 = 8 |
|
transformOmitLast9 = 9 |
|
transformUppercaseFirst = 10 |
|
transformUppercaseAll = 11 |
|
transformOmitFirst1 = 12 |
|
transformOmitFirst2 = 13 |
|
transformOmitFirst3 = 14 |
|
transformOmitFirst4 = 15 |
|
transformOmitFirst5 = 16 |
|
transformOmitFirst6 = 17 |
|
transformOmitFirst7 = 18 |
|
transformOmitFirst8 = 19 |
|
transformOmitFirst9 = 20 |
|
transformShiftFirst = 21 |
|
transformShiftAll = 22 + iota - 22 |
|
numTransformTypes |
|
) |
|
|
|
const transformsMaxCutOff = transformOmitLast9 |
|
|
|
type transforms struct { |
|
prefix_suffix_size uint16 |
|
prefix_suffix []byte |
|
prefix_suffix_map []uint16 |
|
num_transforms uint32 |
|
transforms []byte |
|
params []byte |
|
cutOffTransforms [transformsMaxCutOff + 1]int16 |
|
} |
|
|
|
func transformPrefixId(t *transforms, I int) byte { |
|
return t.transforms[(I*3)+0] |
|
} |
|
|
|
func transformType(t *transforms, I int) byte { |
|
return t.transforms[(I*3)+1] |
|
} |
|
|
|
func transformSuffixId(t *transforms, I int) byte { |
|
return t.transforms[(I*3)+2] |
|
} |
|
|
|
func transformPrefix(t *transforms, I int) []byte { |
|
return t.prefix_suffix[t.prefix_suffix_map[transformPrefixId(t, I)]:] |
|
} |
|
|
|
func transformSuffix(t *transforms, I int) []byte { |
|
return t.prefix_suffix[t.prefix_suffix_map[transformSuffixId(t, I)]:] |
|
} |
|
|
|
/* RFC 7932 transforms string data */ |
|
const kPrefixSuffix string = "\001 \002, \010 of the \004 of \002s \001.\005 and \004 " + "in \001\"\004 to \002\">\001\n\002. \001]\005 for \003 a \006 " + "that \001'\006 with \006 from \004 by \001(\006. T" + "he \004 on \004 as \004 is \004ing \002\n\t\001:\003ed " + "\002=\"\004 at \003ly \001,\002='\005.com/\007. This \005" + " not \003er \003al \004ful \004ive \005less \004es" + "t \004ize \002\xc2\xa0\004ous \005 the \002e \000" |
|
|
|
var kPrefixSuffixMap = [50]uint16{ |
|
0x00, |
|
0x02, |
|
0x05, |
|
0x0E, |
|
0x13, |
|
0x16, |
|
0x18, |
|
0x1E, |
|
0x23, |
|
0x25, |
|
0x2A, |
|
0x2D, |
|
0x2F, |
|
0x32, |
|
0x34, |
|
0x3A, |
|
0x3E, |
|
0x45, |
|
0x47, |
|
0x4E, |
|
0x55, |
|
0x5A, |
|
0x5C, |
|
0x63, |
|
0x68, |
|
0x6D, |
|
0x72, |
|
0x77, |
|
0x7A, |
|
0x7C, |
|
0x80, |
|
0x83, |
|
0x88, |
|
0x8C, |
|
0x8E, |
|
0x91, |
|
0x97, |
|
0x9F, |
|
0xA5, |
|
0xA9, |
|
0xAD, |
|
0xB2, |
|
0xB7, |
|
0xBD, |
|
0xC2, |
|
0xC7, |
|
0xCA, |
|
0xCF, |
|
0xD5, |
|
0xD8, |
|
} |
|
|
|
/* RFC 7932 transforms */ |
|
var kTransformsData = []byte{ |
|
49, |
|
transformIdentity, |
|
49, |
|
49, |
|
transformIdentity, |
|
0, |
|
0, |
|
transformIdentity, |
|
0, |
|
49, |
|
transformOmitFirst1, |
|
49, |
|
49, |
|
transformUppercaseFirst, |
|
0, |
|
49, |
|
transformIdentity, |
|
47, |
|
0, |
|
transformIdentity, |
|
49, |
|
4, |
|
transformIdentity, |
|
0, |
|
49, |
|
transformIdentity, |
|
3, |
|
49, |
|
transformUppercaseFirst, |
|
49, |
|
49, |
|
transformIdentity, |
|
6, |
|
49, |
|
transformOmitFirst2, |
|
49, |
|
49, |
|
transformOmitLast1, |
|
49, |
|
1, |
|
transformIdentity, |
|
0, |
|
49, |
|
transformIdentity, |
|
1, |
|
0, |
|
transformUppercaseFirst, |
|
0, |
|
49, |
|
transformIdentity, |
|
7, |
|
49, |
|
transformIdentity, |
|
9, |
|
48, |
|
transformIdentity, |
|
0, |
|
49, |
|
transformIdentity, |
|
8, |
|
49, |
|
transformIdentity, |
|
5, |
|
49, |
|
transformIdentity, |
|
10, |
|
49, |
|
transformIdentity, |
|
11, |
|
49, |
|
transformOmitLast3, |
|
49, |
|
49, |
|
transformIdentity, |
|
13, |
|
49, |
|
transformIdentity, |
|
14, |
|
49, |
|
transformOmitFirst3, |
|
49, |
|
49, |
|
transformOmitLast2, |
|
49, |
|
49, |
|
transformIdentity, |
|
15, |
|
49, |
|
transformIdentity, |
|
16, |
|
0, |
|
transformUppercaseFirst, |
|
49, |
|
49, |
|
transformIdentity, |
|
12, |
|
5, |
|
transformIdentity, |
|
49, |
|
0, |
|
transformIdentity, |
|
1, |
|
49, |
|
transformOmitFirst4, |
|
49, |
|
49, |
|
transformIdentity, |
|
18, |
|
49, |
|
transformIdentity, |
|
17, |
|
49, |
|
transformIdentity, |
|
19, |
|
49, |
|
transformIdentity, |
|
20, |
|
49, |
|
transformOmitFirst5, |
|
49, |
|
49, |
|
transformOmitFirst6, |
|
49, |
|
47, |
|
transformIdentity, |
|
49, |
|
49, |
|
transformOmitLast4, |
|
49, |
|
49, |
|
transformIdentity, |
|
22, |
|
49, |
|
transformUppercaseAll, |
|
49, |
|
49, |
|
transformIdentity, |
|
23, |
|
49, |
|
transformIdentity, |
|
24, |
|
49, |
|
transformIdentity, |
|
25, |
|
49, |
|
transformOmitLast7, |
|
49, |
|
49, |
|
transformOmitLast1, |
|
26, |
|
49, |
|
transformIdentity, |
|
27, |
|
49, |
|
transformIdentity, |
|
28, |
|
0, |
|
transformIdentity, |
|
12, |
|
49, |
|
transformIdentity, |
|
29, |
|
49, |
|
transformOmitFirst9, |
|
49, |
|
49, |
|
transformOmitFirst7, |
|
49, |
|
49, |
|
transformOmitLast6, |
|
49, |
|
49, |
|
transformIdentity, |
|
21, |
|
49, |
|
transformUppercaseFirst, |
|
1, |
|
49, |
|
transformOmitLast8, |
|
49, |
|
49, |
|
transformIdentity, |
|
31, |
|
49, |
|
transformIdentity, |
|
32, |
|
47, |
|
transformIdentity, |
|
3, |
|
49, |
|
transformOmitLast5, |
|
49, |
|
49, |
|
transformOmitLast9, |
|
49, |
|
0, |
|
transformUppercaseFirst, |
|
1, |
|
49, |
|
transformUppercaseFirst, |
|
8, |
|
5, |
|
transformIdentity, |
|
21, |
|
49, |
|
transformUppercaseAll, |
|
0, |
|
49, |
|
transformUppercaseFirst, |
|
10, |
|
49, |
|
transformIdentity, |
|
30, |
|
0, |
|
transformIdentity, |
|
5, |
|
35, |
|
transformIdentity, |
|
49, |
|
47, |
|
transformIdentity, |
|
2, |
|
49, |
|
transformUppercaseFirst, |
|
17, |
|
49, |
|
transformIdentity, |
|
36, |
|
49, |
|
transformIdentity, |
|
33, |
|
5, |
|
transformIdentity, |
|
0, |
|
49, |
|
transformUppercaseFirst, |
|
21, |
|
49, |
|
transformUppercaseFirst, |
|
5, |
|
49, |
|
transformIdentity, |
|
37, |
|
0, |
|
transformIdentity, |
|
30, |
|
49, |
|
transformIdentity, |
|
38, |
|
0, |
|
transformUppercaseAll, |
|
0, |
|
49, |
|
transformIdentity, |
|
39, |
|
0, |
|
transformUppercaseAll, |
|
49, |
|
49, |
|
transformIdentity, |
|
34, |
|
49, |
|
transformUppercaseAll, |
|
8, |
|
49, |
|
transformUppercaseFirst, |
|
12, |
|
0, |
|
transformIdentity, |
|
21, |
|
49, |
|
transformIdentity, |
|
40, |
|
0, |
|
transformUppercaseFirst, |
|
12, |
|
49, |
|
transformIdentity, |
|
41, |
|
49, |
|
transformIdentity, |
|
42, |
|
49, |
|
transformUppercaseAll, |
|
17, |
|
49, |
|
transformIdentity, |
|
43, |
|
0, |
|
transformUppercaseFirst, |
|
5, |
|
49, |
|
transformUppercaseAll, |
|
10, |
|
0, |
|
transformIdentity, |
|
34, |
|
49, |
|
transformUppercaseFirst, |
|
33, |
|
49, |
|
transformIdentity, |
|
44, |
|
49, |
|
transformUppercaseAll, |
|
5, |
|
45, |
|
transformIdentity, |
|
49, |
|
0, |
|
transformIdentity, |
|
33, |
|
49, |
|
transformUppercaseFirst, |
|
30, |
|
49, |
|
transformUppercaseAll, |
|
30, |
|
49, |
|
transformIdentity, |
|
46, |
|
49, |
|
transformUppercaseAll, |
|
1, |
|
49, |
|
transformUppercaseFirst, |
|
34, |
|
0, |
|
transformUppercaseFirst, |
|
33, |
|
0, |
|
transformUppercaseAll, |
|
30, |
|
0, |
|
transformUppercaseAll, |
|
1, |
|
49, |
|
transformUppercaseAll, |
|
33, |
|
49, |
|
transformUppercaseAll, |
|
21, |
|
49, |
|
transformUppercaseAll, |
|
12, |
|
0, |
|
transformUppercaseAll, |
|
5, |
|
49, |
|
transformUppercaseAll, |
|
34, |
|
0, |
|
transformUppercaseAll, |
|
12, |
|
0, |
|
transformUppercaseFirst, |
|
30, |
|
0, |
|
transformUppercaseAll, |
|
34, |
|
0, |
|
transformUppercaseFirst, |
|
34, |
|
} |
|
|
|
var kBrotliTransforms = transforms{ |
|
217, |
|
[]byte(kPrefixSuffix), |
|
kPrefixSuffixMap[:], |
|
121, |
|
kTransformsData, |
|
nil, /* no extra parameters */ |
|
[transformsMaxCutOff + 1]int16{0, 12, 27, 23, 42, 63, 56, 48, 59, 64}, |
|
} |
|
|
|
func getTransforms() *transforms { |
|
return &kBrotliTransforms |
|
} |
|
|
|
func toUpperCase(p []byte) int { |
|
if p[0] < 0xC0 { |
|
if p[0] >= 'a' && p[0] <= 'z' { |
|
p[0] ^= 32 |
|
} |
|
|
|
return 1 |
|
} |
|
|
|
/* An overly simplified uppercasing model for UTF-8. */ |
|
if p[0] < 0xE0 { |
|
p[1] ^= 32 |
|
return 2 |
|
} |
|
|
|
/* An arbitrary transform for three byte characters. */ |
|
p[2] ^= 5 |
|
|
|
return 3 |
|
} |
|
|
|
func shiftTransform(word []byte, word_len int, parameter uint16) int { |
|
/* Limited sign extension: scalar < (1 << 24). */ |
|
var scalar uint32 = (uint32(parameter) & 0x7FFF) + (0x1000000 - (uint32(parameter) & 0x8000)) |
|
if word[0] < 0x80 { |
|
/* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ |
|
scalar += uint32(word[0]) |
|
|
|
word[0] = byte(scalar & 0x7F) |
|
return 1 |
|
} else if word[0] < 0xC0 { |
|
/* Continuation / 10AAAAAA. */ |
|
return 1 |
|
} else if word[0] < 0xE0 { |
|
/* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ |
|
if word_len < 2 { |
|
return 1 |
|
} |
|
scalar += uint32(word[1]&0x3F | (word[0]&0x1F)<<6) |
|
word[0] = byte(0xC0 | (scalar>>6)&0x1F) |
|
word[1] = byte(uint32(word[1]&0xC0) | scalar&0x3F) |
|
return 2 |
|
} else if word[0] < 0xF0 { |
|
/* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ |
|
if word_len < 3 { |
|
return word_len |
|
} |
|
scalar += uint32(word[2])&0x3F | uint32(word[1]&0x3F)<<6 | uint32(word[0]&0x0F)<<12 |
|
word[0] = byte(0xE0 | (scalar>>12)&0x0F) |
|
word[1] = byte(uint32(word[1]&0xC0) | (scalar>>6)&0x3F) |
|
word[2] = byte(uint32(word[2]&0xC0) | scalar&0x3F) |
|
return 3 |
|
} else if word[0] < 0xF8 { |
|
/* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ |
|
if word_len < 4 { |
|
return word_len |
|
} |
|
scalar += uint32(word[3])&0x3F | uint32(word[2]&0x3F)<<6 | uint32(word[1]&0x3F)<<12 | uint32(word[0]&0x07)<<18 |
|
word[0] = byte(0xF0 | (scalar>>18)&0x07) |
|
word[1] = byte(uint32(word[1]&0xC0) | (scalar>>12)&0x3F) |
|
word[2] = byte(uint32(word[2]&0xC0) | (scalar>>6)&0x3F) |
|
word[3] = byte(uint32(word[3]&0xC0) | scalar&0x3F) |
|
return 4 |
|
} |
|
|
|
return 1 |
|
} |
|
|
|
func transformDictionaryWord(dst []byte, word []byte, len int, trans *transforms, transform_idx int) int { |
|
var idx int = 0 |
|
var prefix []byte = transformPrefix(trans, transform_idx) |
|
var type_ byte = transformType(trans, transform_idx) |
|
var suffix []byte = transformSuffix(trans, transform_idx) |
|
{ |
|
var prefix_len int = int(prefix[0]) |
|
prefix = prefix[1:] |
|
for { |
|
tmp1 := prefix_len |
|
prefix_len-- |
|
if tmp1 == 0 { |
|
break |
|
} |
|
dst[idx] = prefix[0] |
|
idx++ |
|
prefix = prefix[1:] |
|
} |
|
} |
|
{ |
|
var t int = int(type_) |
|
var i int = 0 |
|
if t <= transformOmitLast9 { |
|
len -= t |
|
} else if t >= transformOmitFirst1 && t <= transformOmitFirst9 { |
|
var skip int = t - (transformOmitFirst1 - 1) |
|
word = word[skip:] |
|
len -= skip |
|
} |
|
|
|
for i < len { |
|
dst[idx] = word[i] |
|
idx++ |
|
i++ |
|
} |
|
if t == transformUppercaseFirst { |
|
toUpperCase(dst[idx-len:]) |
|
} else if t == transformUppercaseAll { |
|
var uppercase []byte = dst |
|
uppercase = uppercase[idx-len:] |
|
for len > 0 { |
|
var step int = toUpperCase(uppercase) |
|
uppercase = uppercase[step:] |
|
len -= step |
|
} |
|
} else if t == transformShiftFirst { |
|
var param uint16 = uint16(trans.params[transform_idx*2]) + uint16(trans.params[transform_idx*2+1])<<8 |
|
shiftTransform(dst[idx-len:], int(len), param) |
|
} else if t == transformShiftAll { |
|
var param uint16 = uint16(trans.params[transform_idx*2]) + uint16(trans.params[transform_idx*2+1])<<8 |
|
var shift []byte = dst |
|
shift = shift[idx-len:] |
|
for len > 0 { |
|
var step int = shiftTransform(shift, int(len), param) |
|
shift = shift[step:] |
|
len -= step |
|
} |
|
} |
|
} |
|
{ |
|
var suffix_len int = int(suffix[0]) |
|
suffix = suffix[1:] |
|
for { |
|
tmp2 := suffix_len |
|
suffix_len-- |
|
if tmp2 == 0 { |
|
break |
|
} |
|
dst[idx] = suffix[0] |
|
idx++ |
|
suffix = suffix[1:] |
|
} |
|
return idx |
|
} |
|
}
|
|
|