// Copyright 2013 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 json

import (
	
	
)

const (
	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII.
	kelvin       = '\u212a'
	smallLongEss = '\u017f'
)

// foldFunc returns one of four different case folding equivalence
// functions, from most general (and slow) to fastest:
//
// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
// 3) asciiEqualFold, no special, but includes non-letters (including _)
// 4) simpleLetterEqualFold, no specials, no non-letters.
//
// The letters S and K are special because they map to 3 runes, not just 2:
//  * S maps to s and to U+017F 'ſ' Latin small letter long s
//  * k maps to K and to U+212A 'K' Kelvin sign
// See https://play.golang.org/p/tTxjOc0OGo
//
// The returned function is specialized for matching against s and
// should only be given s. It's not curried for performance reasons.
func foldFunc( []byte) func(,  []byte) bool {
	 := false
	 := false // special letter
	for ,  := range  {
		if  >= utf8.RuneSelf {
			return bytes.EqualFold
		}
		 :=  & caseMask
		if  < 'A' ||  > 'Z' {
			 = true
		} else if  == 'K' ||  == 'S' {
			// See above for why these letters are special.
			 = true
		}
	}
	if  {
		return equalFoldRight
	}
	if  {
		return asciiEqualFold
	}
	return simpleLetterEqualFold
}

// equalFoldRight is a specialization of bytes.EqualFold when s is
// known to be all ASCII (including punctuation), but contains an 's',
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
// See comments on foldFunc.
func equalFoldRight(,  []byte) bool {
	for ,  := range  {
		if len() == 0 {
			return false
		}
		 := [0]
		if  < utf8.RuneSelf {
			if  !=  {
				 :=  & caseMask
				if 'A' <=  &&  <= 'Z' {
					if  != &caseMask {
						return false
					}
				} else {
					return false
				}
			}
			 = [1:]
			continue
		}
		// sb is ASCII and t is not. t must be either kelvin
		// sign or long s; sb must be s, S, k, or K.
		,  := utf8.DecodeRune()
		switch  {
		case 's', 'S':
			if  != smallLongEss {
				return false
			}
		case 'k', 'K':
			if  != kelvin {
				return false
			}
		default:
			return false
		}
		 = [:]

	}
	if len() > 0 {
		return false
	}
	return true
}

// asciiEqualFold is a specialization of bytes.EqualFold for use when
// s is all ASCII (but may contain non-letters) and contains no
// special-folding letters.
// See comments on foldFunc.
func asciiEqualFold(,  []byte) bool {
	if len() != len() {
		return false
	}
	for ,  := range  {
		 := []
		if  ==  {
			continue
		}
		if ('a' <=  &&  <= 'z') || ('A' <=  &&  <= 'Z') {
			if &caseMask != &caseMask {
				return false
			}
		} else {
			return false
		}
	}
	return true
}

// simpleLetterEqualFold is a specialization of bytes.EqualFold for
// use when s is all ASCII letters (no underscores, etc) and also
// doesn't contain 'k', 'K', 's', or 'S'.
// See comments on foldFunc.
func simpleLetterEqualFold(,  []byte) bool {
	if len() != len() {
		return false
	}
	for ,  := range  {
		if &caseMask != []&caseMask {
			return false
		}
	}
	return true
}