mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			218 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// 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)
 |