github.com/go-xe2/third@v1.0.3/golang.org/x/text/internal/export/idna/trie.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package idna 6 7 // appendMapping appends the mapping for the respective rune. isMapped must be 8 // true. A mapping is a categorization of a rune as defined in UTS #46. 9 func (c info) appendMapping(b []byte, s string) []byte { 10 index := int(c >> indexShift) 11 if c&xorBit == 0 { 12 s := mappings[index:] 13 return append(b, s[1:s[0]+1]...) 14 } 15 b = append(b, s...) 16 if c&inlineXOR == inlineXOR { 17 // TODO: support and handle two-byte inline masks 18 b[len(b)-1] ^= byte(index) 19 } else { 20 for p := len(b) - int(xorData[index]); p < len(b); p++ { 21 index++ 22 b[p] ^= xorData[index] 23 } 24 } 25 return b 26 } 27 28 // Sparse block handling code. 29 30 type valueRange struct { 31 value uint16 // header: value:stride 32 lo, hi byte // header: lo:n 33 } 34 35 type sparseBlocks struct { 36 values []valueRange 37 offset []uint16 38 } 39 40 var idnaSparse = sparseBlocks{ 41 values: idnaSparseValues[:], 42 offset: idnaSparseOffset[:], 43 } 44 45 // Don't use newIdnaTrie to avoid unconditional linking in of the table. 46 var trie = &idnaTrie{} 47 48 // lookup determines the type of block n and looks up the value for b. 49 // For n < t.cutoff, the block is a simple lookup table. Otherwise, the block 50 // is a list of ranges with an accompanying value. Given a matching range r, 51 // the value for b is by r.value + (b - r.lo) * stride. 52 func (t *sparseBlocks) lookup(n uint32, b byte) uint16 { 53 offset := t.offset[n] 54 header := t.values[offset] 55 lo := offset + 1 56 hi := lo + uint16(header.lo) 57 for lo < hi { 58 m := lo + (hi-lo)/2 59 r := t.values[m] 60 if r.lo <= b && b <= r.hi { 61 return r.value + uint16(b-r.lo)*header.value 62 } 63 if b < r.lo { 64 hi = m 65 } else { 66 lo = m + 1 67 } 68 } 69 return 0 70 }