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 5package 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. 9func (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 30type valueRange struct { 31 value uint16 // header: value:stride 32 lo, hi byte // header: lo:n 33} 34 35type sparseBlocks struct { 36 values []valueRange 37 offset []uint16 38} 39 40var idnaSparse = sparseBlocks{ 41 values: idnaSparseValues[:], 42 offset: idnaSparseOffset[:], 43} 44 45// Don't use newIdnaTrie to avoid unconditional linking in of the table. 46var 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. 52func (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} 71