fold.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * Copyright 2014 Paul Querna
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. /* Portions of this file are on Go stdlib's encoding/json/fold.go */
  18. // Copyright 2009 The Go Authors. All rights reserved.
  19. // Use of this source code is governed by a BSD-style
  20. // license that can be found in the LICENSE file.
  21. package v1
  22. import (
  23. "unicode/utf8"
  24. )
  25. const (
  26. caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
  27. kelvin = '\u212a'
  28. smallLongEss = '\u017f'
  29. )
  30. // equalFoldRight is a specialization of bytes.EqualFold when s is
  31. // known to be all ASCII (including punctuation), but contains an 's',
  32. // 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
  33. // See comments on foldFunc.
  34. func EqualFoldRight(s, t []byte) bool {
  35. for _, sb := range s {
  36. if len(t) == 0 {
  37. return false
  38. }
  39. tb := t[0]
  40. if tb < utf8.RuneSelf {
  41. if sb != tb {
  42. sbUpper := sb & caseMask
  43. if 'A' <= sbUpper && sbUpper <= 'Z' {
  44. if sbUpper != tb&caseMask {
  45. return false
  46. }
  47. } else {
  48. return false
  49. }
  50. }
  51. t = t[1:]
  52. continue
  53. }
  54. // sb is ASCII and t is not. t must be either kelvin
  55. // sign or long s; sb must be s, S, k, or K.
  56. tr, size := utf8.DecodeRune(t)
  57. switch sb {
  58. case 's', 'S':
  59. if tr != smallLongEss {
  60. return false
  61. }
  62. case 'k', 'K':
  63. if tr != kelvin {
  64. return false
  65. }
  66. default:
  67. return false
  68. }
  69. t = t[size:]
  70. }
  71. if len(t) > 0 {
  72. return false
  73. }
  74. return true
  75. }
  76. // asciiEqualFold is a specialization of bytes.EqualFold for use when
  77. // s is all ASCII (but may contain non-letters) and contains no
  78. // special-folding letters.
  79. // See comments on foldFunc.
  80. func AsciiEqualFold(s, t []byte) bool {
  81. if len(s) != len(t) {
  82. return false
  83. }
  84. for i, sb := range s {
  85. tb := t[i]
  86. if sb == tb {
  87. continue
  88. }
  89. if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
  90. if sb&caseMask != tb&caseMask {
  91. return false
  92. }
  93. } else {
  94. return false
  95. }
  96. }
  97. return true
  98. }
  99. // simpleLetterEqualFold is a specialization of bytes.EqualFold for
  100. // use when s is all ASCII letters (no underscores, etc) and also
  101. // doesn't contain 'k', 'K', 's', or 'S'.
  102. // See comments on foldFunc.
  103. func SimpleLetterEqualFold(s, t []byte) bool {
  104. if len(s) != len(t) {
  105. return false
  106. }
  107. for i, b := range s {
  108. if b&caseMask != t[i]&caseMask {
  109. return false
  110. }
  111. }
  112. return true
  113. }