// 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 ( "unicode" "unicode/utf8" ) // foldName returns a folded string such that foldName(x) == foldName(y) // is identical to bytes.EqualFold(x, y). func foldName(in []byte) []byte { // This is inlinable to take advantage of "function outlining". var arr [32]byte // large enough for most JSON names return appendFoldedName(arr[:0], in) } func appendFoldedName(out, in []byte) []byte { for i := 0; i < len(in); { // Handle single-byte ASCII. if c := in[i]; c < utf8.RuneSelf { if 'a' <= c && c <= 'z' { c -= 'a' - 'A' } out = append(out, c) i++ continue } // Handle multi-byte Unicode. r, n := utf8.DecodeRune(in[i:]) out = utf8.AppendRune(out, foldRune(r)) i += n } return out } // foldRune is returns the smallest rune for all runes in the same fold set. func foldRune(r rune) rune { for { r2 := unicode.SimpleFold(r) if r2 <= r { return r2 } r = r2 } }