You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

218 lines
6.4 KiB

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