gen_trieval.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright 2014 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. //go:build ignore
  5. // +build ignore
  6. package main
  7. // This file contains definitions for interpreting the trie value of the case
  8. // trie generated by "go run gen*.go". It is shared by both the generator
  9. // program and the resultant package. Sharing is achieved by the generator
  10. // copying gen_trieval.go to trieval.go and changing what's above this comment.
  11. // info holds case information for a single rune. It is the value returned
  12. // by a trie lookup. Most mapping information can be stored in a single 16-bit
  13. // value. If not, for example when a rune is mapped to multiple runes, the value
  14. // stores some basic case data and an index into an array with additional data.
  15. //
  16. // The per-rune values have the following format:
  17. //
  18. // if (exception) {
  19. // 15..4 unsigned exception index
  20. // } else {
  21. // 15..8 XOR pattern or index to XOR pattern for case mapping
  22. // Only 13..8 are used for XOR patterns.
  23. // 7 inverseFold (fold to upper, not to lower)
  24. // 6 index: interpret the XOR pattern as an index
  25. // or isMid if case mode is cIgnorableUncased.
  26. // 5..4 CCC: zero (normal or break), above or other
  27. // }
  28. // 3 exception: interpret this value as an exception index
  29. // (TODO: is this bit necessary? Probably implied from case mode.)
  30. // 2..0 case mode
  31. //
  32. // For the non-exceptional cases, a rune must be either uncased, lowercase or
  33. // uppercase. If the rune is cased, the XOR pattern maps either a lowercase
  34. // rune to uppercase or an uppercase rune to lowercase (applied to the 10
  35. // least-significant bits of the rune).
  36. //
  37. // See the definitions below for a more detailed description of the various
  38. // bits.
  39. type info uint16
  40. const (
  41. casedMask = 0x0003
  42. fullCasedMask = 0x0007
  43. ignorableMask = 0x0006
  44. ignorableValue = 0x0004
  45. inverseFoldBit = 1 << 7
  46. isMidBit = 1 << 6
  47. exceptionBit = 1 << 3
  48. exceptionShift = 4
  49. numExceptionBits = 12
  50. xorIndexBit = 1 << 6
  51. xorShift = 8
  52. // There is no mapping if all xor bits and the exception bit are zero.
  53. hasMappingMask = 0xff80 | exceptionBit
  54. )
  55. // The case mode bits encodes the case type of a rune. This includes uncased,
  56. // title, upper and lower case and case ignorable. (For a definition of these
  57. // terms see Chapter 3 of The Unicode Standard Core Specification.) In some rare
  58. // cases, a rune can be both cased and case-ignorable. This is encoded by
  59. // cIgnorableCased. A rune of this type is always lower case. Some runes are
  60. // cased while not having a mapping.
  61. //
  62. // A common pattern for scripts in the Unicode standard is for upper and lower
  63. // case runes to alternate for increasing rune values (e.g. the accented Latin
  64. // ranges starting from U+0100 and U+1E00 among others and some Cyrillic
  65. // characters). We use this property by defining a cXORCase mode, where the case
  66. // mode (always upper or lower case) is derived from the rune value. As the XOR
  67. // pattern for case mappings is often identical for successive runes, using
  68. // cXORCase can result in large series of identical trie values. This, in turn,
  69. // allows us to better compress the trie blocks.
  70. const (
  71. cUncased info = iota // 000
  72. cTitle // 001
  73. cLower // 010
  74. cUpper // 011
  75. cIgnorableUncased // 100
  76. cIgnorableCased // 101 // lower case if mappings exist
  77. cXORCase // 11x // case is cLower | ((rune&1) ^ x)
  78. maxCaseMode = cUpper
  79. )
  80. func (c info) isCased() bool {
  81. return c&casedMask != 0
  82. }
  83. func (c info) isCaseIgnorable() bool {
  84. return c&ignorableMask == ignorableValue
  85. }
  86. func (c info) isNotCasedAndNotCaseIgnorable() bool {
  87. return c&fullCasedMask == 0
  88. }
  89. func (c info) isCaseIgnorableAndNotCased() bool {
  90. return c&fullCasedMask == cIgnorableUncased
  91. }
  92. func (c info) isMid() bool {
  93. return c&(fullCasedMask|isMidBit) == isMidBit|cIgnorableUncased
  94. }
  95. // The case mapping implementation will need to know about various Canonical
  96. // Combining Class (CCC) values. We encode two of these in the trie value:
  97. // cccZero (0) and cccAbove (230). If the value is cccOther, it means that
  98. // CCC(r) > 0, but not 230. A value of cccBreak means that CCC(r) == 0 and that
  99. // the rune also has the break category Break (see below).
  100. const (
  101. cccBreak info = iota << 4
  102. cccZero
  103. cccAbove
  104. cccOther
  105. cccMask = cccBreak | cccZero | cccAbove | cccOther
  106. )
  107. const (
  108. starter = 0
  109. above = 230
  110. iotaSubscript = 240
  111. )
  112. // The exceptions slice holds data that does not fit in a normal info entry.
  113. // The entry is pointed to by the exception index in an entry. It has the
  114. // following format:
  115. //
  116. // Header
  117. // byte 0:
  118. // 7..6 unused
  119. // 5..4 CCC type (same bits as entry)
  120. // 3 unused
  121. // 2..0 length of fold
  122. //
  123. // byte 1:
  124. // 7..6 unused
  125. // 5..3 length of 1st mapping of case type
  126. // 2..0 length of 2nd mapping of case type
  127. //
  128. // case 1st 2nd
  129. // lower -> upper, title
  130. // upper -> lower, title
  131. // title -> lower, upper
  132. //
  133. // Lengths with the value 0x7 indicate no value and implies no change.
  134. // A length of 0 indicates a mapping to zero-length string.
  135. //
  136. // Body bytes:
  137. // case folding bytes
  138. // lowercase mapping bytes
  139. // uppercase mapping bytes
  140. // titlecase mapping bytes
  141. // closure mapping bytes (for NFKC_Casefold). (TODO)
  142. //
  143. // Fallbacks:
  144. // missing fold -> lower
  145. // missing title -> upper
  146. // all missing -> original rune
  147. //
  148. // exceptions starts with a dummy byte to enforce that there is no zero index
  149. // value.
  150. const (
  151. lengthMask = 0x07
  152. lengthBits = 3
  153. noChange = 0
  154. )
  155. // References to generated trie.
  156. var trie = newCaseTrie(0)
  157. var sparse = sparseBlocks{
  158. values: sparseValues[:],
  159. offsets: sparseOffsets[:],
  160. }
  161. // Sparse block lookup code.
  162. // valueRange is an entry in a sparse block.
  163. type valueRange struct {
  164. value uint16
  165. lo, hi byte
  166. }
  167. type sparseBlocks struct {
  168. values []valueRange
  169. offsets []uint16
  170. }
  171. // lookup returns the value from values block n for byte b using binary search.
  172. func (s *sparseBlocks) lookup(n uint32, b byte) uint16 {
  173. lo := s.offsets[n]
  174. hi := s.offsets[n+1]
  175. for lo < hi {
  176. m := lo + (hi-lo)/2
  177. r := s.values[m]
  178. if r.lo <= b && b <= r.hi {
  179. return r.value
  180. }
  181. if b < r.lo {
  182. hi = m
  183. } else {
  184. lo = m + 1
  185. }
  186. }
  187. return 0
  188. }
  189. // lastRuneForTesting is the last rune used for testing. Everything after this
  190. // is boring.
  191. const lastRuneForTesting = rune(0x1FFFF)