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