Copyright 2014 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package cases

import 
A context is used for iterating over source bytes, fetching case info and writing to a destination buffer. Casing operations may need more than one rune of context to decide how a rune should be cased. Casing implementations should call checkpoint on context whenever it is known to be safe to return the runes processed so far. It is recommended for implementations to not allow for more than 30 case ignorables as lookahead (analogous to the limit in norm) and to use state if unbounded lookahead is needed for cased runes.
type context struct {
	dst, src []byte
	atEOF    bool

	pDst int // pDst points past the last written rune in dst.
	pSrc int // pSrc points to the start of the currently scanned rune.
checkpoints safe to return in Transform, where nDst <= pDst and nSrc <= pSrc.
	nDst, nSrc int
	err        error

	sz   int  // size of current rune
	info info // case information of currently scanned rune
State preserved across calls to Transform.
	isMidWord bool // false if next cased letter needs to be title-cased.
}

func ( *context) () {
	.isMidWord = false
}
ret returns the return values for the Transform method. It checks whether there were insufficient bytes in src to complete and introduces an error accordingly, if necessary.
func ( *context) () (,  int,  error) {
	if .err != nil || .nSrc == len(.src) {
		return .nDst, .nSrc, .err
This point is only reached by mappers if there was no short destination buffer. This means that the source buffer was exhausted and that c.sz was set to 0 by next.
	if .atEOF && .pSrc == len(.src) {
		return .pDst, .pSrc, nil
	}
	return .nDst, .nSrc, transform.ErrShortSrc
}
retSpan returns the return values for the Span method. It checks whether there were insufficient bytes in src to complete and introduces an error accordingly, if necessary.
func ( *context) () ( int,  error) {
	, ,  := .ret()
	return , 
}
checkpoint sets the return value buffer points for Transform to the current positions.
func ( *context) () {
	if .err == nil {
		.nDst, .nSrc = .pDst, .pSrc+.sz
	}
}
unreadRune causes the last rune read by next to be reread on the next invocation of next. Only one unreadRune may be called after a call to next.
func ( *context) () {
	.sz = 0
}

func ( *context) () bool {
	.pSrc += .sz
	if .pSrc == len(.src) || .err != nil {
		.info, .sz = 0, 0
		return false
	}
	,  := trie.lookup(.src[.pSrc:])
	.info, .sz = info(), 
	if .sz == 0 {
A zero size means we have an incomplete rune. If we are atEOF, this means it is an illegal rune, which we will consume one byte at a time.
			.sz = 1
		} else {
			.err = transform.ErrShortSrc
			return false
		}
	}
	return true
}
writeBytes adds bytes to dst.
func ( *context) ( []byte) bool {
	if len(.dst)-.pDst < len() {
		.err = transform.ErrShortDst
		return false
This loop is faster than using copy.
	for ,  := range  {
		.dst[.pDst] = 
		.pDst++
	}
	return true
}
writeString writes the given string to dst.
func ( *context) ( string) bool {
	if len(.dst)-.pDst < len() {
		.err = transform.ErrShortDst
		return false
This loop is faster than using copy.
	for  := 0;  < len(); ++ {
		.dst[.pDst] = []
		.pDst++
	}
	return true
}
copy writes the current rune to dst.
func ( *context) () bool {
	return .writeBytes(.src[.pSrc : .pSrc+.sz])
}
copyXOR copies the current rune to dst and modifies it by applying the XOR pattern of the case info. It is the responsibility of the caller to ensure that this is a rune with a XOR pattern defined.
func ( *context) () bool {
	if !.copy() {
		return false
	}
Fast path for 6-bit XOR pattern, which covers most cases.
		.dst[.pDst-1] ^= byte(.info >> xorShift)
Interpret XOR bits as an index. TODO: test performance for unrolling this loop. Verify that we have at least two bytes and at most three.
		 := .info >> xorShift
		for  := .pDst - 1; ; -- {
			.dst[] ^= xorData[]
			--
			if xorData[] == 0 {
				break
			}
		}
	}
	return true
}
hasPrefix returns true if src[pSrc:] starts with the given string.
func ( *context) ( string) bool {
	 := .src[.pSrc:]
	if len() < len() {
		return false
	}
	for ,  := range [:len()] {
		if  != [] {
			return false
		}
	}
	return true
}
caseType returns an info with only the case bits, normalized to either cLower, cUpper, cTitle or cUncased.
func ( *context) () info {
	 := .info & 0x7
	if  < 4 {
		return 
	}
xor the last bit of the rune with the case type bits.
		 := .src[.pSrc+.sz-1]
		return info(&1) ^ &0x3
	}
	if  == cIgnorableCased {
		return cLower
	}
	return cUncased
}
lower writes the lowercase version of the current rune to dst.
func ( *context) bool {
	 := .caseType()
	if .info&hasMappingMask == 0 ||  == cLower {
		return .copy()
	}
	if .info&exceptionBit == 0 {
		return .copyXOR()
	}
	 := exceptions[.info>>exceptionShift:]
	 := 2 + [0]&lengthMask // size of header + fold string
	if  := ([1] >> lengthBits) & lengthMask;  != noChange {
		return .writeString([ : +])
	}
	return .copy()
}

func ( *context) bool {
	 := .caseType()
	if .info&hasMappingMask == 0 ||  == cLower {
		return true
	}
	if .info&exceptionBit == 0 {
		.err = transform.ErrEndOfSpan
		return false
	}
	 := exceptions[.info>>exceptionShift:]
	if  := ([1] >> lengthBits) & lengthMask;  != noChange {
		.err = transform.ErrEndOfSpan
		return false
	}
	return true
}
upper writes the uppercase version of the current rune to dst.
func ( *context) bool {
	 := .caseType()
	if .info&hasMappingMask == 0 ||  == cUpper {
		return .copy()
	}
	if .info&exceptionBit == 0 {
		return .copyXOR()
	}
	 := exceptions[.info>>exceptionShift:]
Get length of first special case mapping.
	 := ([1] >> lengthBits) & lengthMask
The first special case mapping is for lower. Set n to the second.
		if  == noChange {
			 = 0
		}
		,  = [1]&lengthMask, [:]
	}
	if  != noChange {
		return .writeString([ : +])
	}
	return .copy()
}
isUpper writes the isUppercase version of the current rune to dst.
func ( *context) bool {
	 := .caseType()
	if .info&hasMappingMask == 0 ||  == cUpper {
		return true
	}
	if .info&exceptionBit == 0 {
		.err = transform.ErrEndOfSpan
		return false
	}
Get length of first special case mapping.
	 := ([1] >> lengthBits) & lengthMask
	if  == cTitle {
		 = [1] & lengthMask
	}
	if  != noChange {
		.err = transform.ErrEndOfSpan
		return false
	}
	return true
}
title writes the title case version of the current rune to dst.
func ( *context) bool {
	 := .caseType()
	if .info&hasMappingMask == 0 ||  == cTitle {
		return .copy()
	}
	if .info&exceptionBit == 0 {
		if  == cLower {
			return .copyXOR()
		}
		return .copy()
Get the exception data.
	 := exceptions[.info>>exceptionShift:]
	 := 2 + [0]&lengthMask // size of header + fold string

	 := ([1] >> lengthBits) & lengthMask
	if  := [1] & lengthMask;  != noChange {
		if  != noChange {
			 = [:]
		}
		return .writeString([ : +])
	}
Use the uppercase version instead.
		return .writeString([ : +])
Already in correct case.
	return .copy()
}
isTitle reports whether the current rune is in title case.
func ( *context) bool {
	 := .caseType()
	if .info&hasMappingMask == 0 ||  == cTitle {
		return true
	}
	if .info&exceptionBit == 0 {
		if  == cLower {
			.err = transform.ErrEndOfSpan
			return false
		}
		return true
Get the exception data.
	 := exceptions[.info>>exceptionShift:]
	if  := [1] & lengthMask;  != noChange {
		.err = transform.ErrEndOfSpan
		return false
	}
	 := ([1] >> lengthBits) & lengthMask
	if  == cLower &&  != noChange {
		.err = transform.ErrEndOfSpan
		return false
	}
	return true
}
foldFull writes the foldFull version of the current rune to dst.
func ( *context) bool {
	if .info&hasMappingMask == 0 {
		return .copy()
	}
	 := .caseType()
	if .info&exceptionBit == 0 {
		if  != cLower || .info&inverseFoldBit != 0 {
			return .copyXOR()
		}
		return .copy()
	}
	 := exceptions[.info>>exceptionShift:]
	 := [0] & lengthMask
	if  == 0 {
		if  == cLower {
			return .copy()
		}
		 = ([1] >> lengthBits) & lengthMask
	}
	return .writeString([2 : 2+])
}
isFoldFull reports whether the current run is mapped to foldFull
func ( *context) bool {
	if .info&hasMappingMask == 0 {
		return true
	}
	 := .caseType()
	if .info&exceptionBit == 0 {
		if  != cLower || .info&inverseFoldBit != 0 {
			.err = transform.ErrEndOfSpan
			return false
		}
		return true
	}
	 := exceptions[.info>>exceptionShift:]
	 := [0] & lengthMask
	if  == 0 &&  == cLower {
		return true
	}
	.err = transform.ErrEndOfSpan
	return false