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 } }