trie.go 1.8 KB

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