Source file src/encoding/json/fold.go

     1  // Copyright 2013 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  
     5  //go:build !goexperiment.jsonv2
     6  
     7  package json
     8  
     9  import (
    10  	"unicode"
    11  	"unicode/utf8"
    12  )
    13  
    14  // foldName returns a folded string such that foldName(x) == foldName(y)
    15  // is identical to bytes.EqualFold(x, y).
    16  func foldName(in []byte) []byte {
    17  	// This is inlinable to take advantage of "function outlining".
    18  	var arr [32]byte // large enough for most JSON names
    19  	return appendFoldedName(arr[:0], in)
    20  }
    21  
    22  func appendFoldedName(out, in []byte) []byte {
    23  	for i := 0; i < len(in); {
    24  		// Handle single-byte ASCII.
    25  		if c := in[i]; c < utf8.RuneSelf {
    26  			if 'a' <= c && c <= 'z' {
    27  				c -= 'a' - 'A'
    28  			}
    29  			out = append(out, c)
    30  			i++
    31  			continue
    32  		}
    33  		// Handle multi-byte Unicode.
    34  		r, n := utf8.DecodeRune(in[i:])
    35  		out = utf8.AppendRune(out, foldRune(r))
    36  		i += n
    37  	}
    38  	return out
    39  }
    40  
    41  // foldRune is returns the smallest rune for all runes in the same fold set.
    42  func foldRune(r rune) rune {
    43  	for {
    44  		r2 := unicode.SimpleFold(r)
    45  		if r2 <= r {
    46  			return r2
    47  		}
    48  		r = r2
    49  	}
    50  }
    51  

View as plain text