| // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. | |
| package cases | |
| // This file contains definitions for interpreting the trie value of the case | |
| // trie generated by "go run gen*.go". It is shared by both the generator | |
| // program and the resultant package. Sharing is achieved by the generator | |
| // copying gen_trieval.go to trieval.go and changing what's above this comment. | |
| // info holds case information for a single rune. It is the value returned | |
| // by a trie lookup. Most mapping information can be stored in a single 16-bit | |
| // value. If not, for example when a rune is mapped to multiple runes, the value | |
| // stores some basic case data and an index into an array with additional data. | |
| // | |
| // The per-rune values have the following format: | |
| // | |
| // if (exception) { | |
| // 15..4 unsigned exception index | |
| // } else { | |
| // 15..8 XOR pattern or index to XOR pattern for case mapping | |
| // Only 13..8 are used for XOR patterns. | |
| // 7 inverseFold (fold to upper, not to lower) | |
| // 6 index: interpret the XOR pattern as an index | |
| // or isMid if case mode is cIgnorableUncased. | |
| // 5..4 CCC: zero (normal or break), above or other | |
| // } | |
| // 3 exception: interpret this value as an exception index | |
| // (TODO: is this bit necessary? Probably implied from case mode.) | |
| // 2..0 case mode | |
| // | |
| // For the non-exceptional cases, a rune must be either uncased, lowercase or | |
| // uppercase. If the rune is cased, the XOR pattern maps either a lowercase | |
| // rune to uppercase or an uppercase rune to lowercase (applied to the 10 | |
| // least-significant bits of the rune). | |
| // | |
| // See the definitions below for a more detailed description of the various | |
| // bits. | |
| type info uint16 | |
| const ( | |
| casedMask = 0x0003 | |
| fullCasedMask = 0x0007 | |
| ignorableMask = 0x0006 | |
| ignorableValue = 0x0004 | |
| inverseFoldBit = 1 << 7 | |
| isMidBit = 1 << 6 | |
| exceptionBit = 1 << 3 | |
| exceptionShift = 4 | |
| numExceptionBits = 12 | |
| xorIndexBit = 1 << 6 | |
| xorShift = 8 | |
| // There is no mapping if all xor bits and the exception bit are zero. | |
| hasMappingMask = 0xff80 | exceptionBit | |
| ) | |
| // The case mode bits encodes the case type of a rune. This includes uncased, | |
| // title, upper and lower case and case ignorable. (For a definition of these | |
| // terms see Chapter 3 of The Unicode Standard Core Specification.) In some rare | |
| // cases, a rune can be both cased and case-ignorable. This is encoded by | |
| // cIgnorableCased. A rune of this type is always lower case. Some runes are | |
| // cased while not having a mapping. | |
| // | |
| // A common pattern for scripts in the Unicode standard is for upper and lower | |
| // case runes to alternate for increasing rune values (e.g. the accented Latin | |
| // ranges starting from U+0100 and U+1E00 among others and some Cyrillic | |
| // characters). We use this property by defining a cXORCase mode, where the case | |
| // mode (always upper or lower case) is derived from the rune value. As the XOR | |
| // pattern for case mappings is often identical for successive runes, using | |
| // cXORCase can result in large series of identical trie values. This, in turn, | |
| // allows us to better compress the trie blocks. | |
| const ( | |
| cUncased info = iota // 000 | |
| cTitle // 001 | |
| cLower // 010 | |
| cUpper // 011 | |
| cIgnorableUncased // 100 | |
| cIgnorableCased // 101 // lower case if mappings exist | |
| cXORCase // 11x // case is cLower | ((rune&1) ^ x) | |
| maxCaseMode = cUpper | |
| ) | |
| func (c info) isCased() bool { | |
| return c&casedMask != 0 | |
| } | |
| func (c info) isCaseIgnorable() bool { | |
| return c&ignorableMask == ignorableValue | |
| } | |
| func (c info) isNotCasedAndNotCaseIgnorable() bool { | |
| return c&fullCasedMask == 0 | |
| } | |
| func (c info) isCaseIgnorableAndNotCased() bool { | |
| return c&fullCasedMask == cIgnorableUncased | |
| } | |
| func (c info) isMid() bool { | |
| return c&(fullCasedMask|isMidBit) == isMidBit|cIgnorableUncased | |
| } | |
| // The case mapping implementation will need to know about various Canonical | |
| // Combining Class (CCC) values. We encode two of these in the trie value: | |
| // cccZero (0) and cccAbove (230). If the value is cccOther, it means that | |
| // CCC(r) > 0, but not 230. A value of cccBreak means that CCC(r) == 0 and that | |
| // the rune also has the break category Break (see below). | |
| const ( | |
| cccBreak info = iota << 4 | |
| cccZero | |
| cccAbove | |
| cccOther | |
| cccMask = cccBreak | cccZero | cccAbove | cccOther | |
| ) | |
| const ( | |
| starter = 0 | |
| above = 230 | |
| iotaSubscript = 240 | |
| ) | |
| // The exceptions slice holds data that does not fit in a normal info entry. | |
| // The entry is pointed to by the exception index in an entry. It has the | |
| // following format: | |
| // | |
| // Header: | |
| // | |
| // byte 0: | |
| // 7..6 unused | |
| // 5..4 CCC type (same bits as entry) | |
| // 3 unused | |
| // 2..0 length of fold | |
| // | |
| // byte 1: | |
| // 7..6 unused | |
| // 5..3 length of 1st mapping of case type | |
| // 2..0 length of 2nd mapping of case type | |
| // | |
| // case 1st 2nd | |
| // lower -> upper, title | |
| // upper -> lower, title | |
| // title -> lower, upper | |
| // | |
| // Lengths with the value 0x7 indicate no value and implies no change. | |
| // A length of 0 indicates a mapping to zero-length string. | |
| // | |
| // Body bytes: | |
| // | |
| // case folding bytes | |
| // lowercase mapping bytes | |
| // uppercase mapping bytes | |
| // titlecase mapping bytes | |
| // closure mapping bytes (for NFKC_Casefold). (TODO) | |
| // | |
| // Fallbacks: | |
| // | |
| // missing fold -> lower | |
| // missing title -> upper | |
| // all missing -> original rune | |
| // | |
| // exceptions starts with a dummy byte to enforce that there is no zero index | |
| // value. | |
| const ( | |
| lengthMask = 0x07 | |
| lengthBits = 3 | |
| noChange = 0 | |
| ) | |
| // References to generated trie. | |
| var trie = newCaseTrie(0) | |
| var sparse = sparseBlocks{ | |
| values: sparseValues[:], | |
| offsets: sparseOffsets[:], | |
| } | |
| // Sparse block lookup code. | |
| // valueRange is an entry in a sparse block. | |
| type valueRange struct { | |
| value uint16 | |
| lo, hi byte | |
| } | |
| type sparseBlocks struct { | |
| values []valueRange | |
| offsets []uint16 | |
| } | |
| // lookup returns the value from values block n for byte b using binary search. | |
| func (s *sparseBlocks) lookup(n uint32, b byte) uint16 { | |
| lo := s.offsets[n] | |
| hi := s.offsets[n+1] | |
| for lo < hi { | |
| m := lo + (hi-lo)/2 | |
| r := s.values[m] | |
| if r.lo <= b && b <= r.hi { | |
| return r.value | |
| } | |
| if b < r.lo { | |
| hi = m | |
| } else { | |
| lo = m + 1 | |
| } | |
| } | |
| return 0 | |
| } | |
| // lastRuneForTesting is the last rune used for testing. Everything after this | |
| // is boring. | |
| const lastRuneForTesting = rune(0x1FFFF) |