Update dependencies
This commit is contained in:
202
vendor/go4.org/mem/LICENSE
generated
vendored
Normal file
202
vendor/go4.org/mem/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
3
vendor/go4.org/mem/README.md
generated
vendored
Normal file
3
vendor/go4.org/mem/README.md
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# go4.org/mem
|
||||
|
||||
See https://godoc.org/go4.org/mem
|
||||
103
vendor/go4.org/mem/fields.go
generated
vendored
Normal file
103
vendor/go4.org/mem/fields.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 2020 The Go4 AUTHORS
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package mem
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
|
||||
|
||||
// AppendFields is like strings.Fields, but is append-like and uses a mem.RO instead of a string.
|
||||
func AppendFields(dst []RO, m RO) []RO {
|
||||
s := m.m
|
||||
|
||||
// Copied from the Go standard library (BSD license).
|
||||
|
||||
// First count the fields.
|
||||
// This is an exact count if s is ASCII, otherwise it is an approximation.
|
||||
n := 0
|
||||
wasSpace := 1
|
||||
// setBits is used to track which bits are set in the bytes of s.
|
||||
setBits := uint8(0)
|
||||
for i := 0; i < len(s); i++ {
|
||||
r := s[i]
|
||||
setBits |= r
|
||||
isSpace := int(asciiSpace[r])
|
||||
n += wasSpace & ^isSpace
|
||||
wasSpace = isSpace
|
||||
}
|
||||
|
||||
if setBits >= utf8.RuneSelf {
|
||||
// Some runes in the input string are not ASCII.
|
||||
return AppendFieldsFunc(dst, m, unicode.IsSpace)
|
||||
}
|
||||
// ASCII fast path
|
||||
fieldStart := 0
|
||||
i := 0
|
||||
// Skip spaces in the front of the input.
|
||||
for i < len(s) && asciiSpace[s[i]] != 0 {
|
||||
i++
|
||||
}
|
||||
fieldStart = i
|
||||
for i < len(s) {
|
||||
if asciiSpace[s[i]] == 0 {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
dst = append(dst, RO{m: s[fieldStart:i]})
|
||||
i++
|
||||
// Skip spaces in between fields.
|
||||
for i < len(s) && asciiSpace[s[i]] != 0 {
|
||||
i++
|
||||
}
|
||||
fieldStart = i
|
||||
}
|
||||
if fieldStart < len(s) { // Last field might end at EOF.
|
||||
dst = append(dst, RO{m: s[fieldStart:]})
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// AppendFieldsFunc is like strings.FieldsFunc, but is append-like and uses a mem.RO instead of a string.
|
||||
func AppendFieldsFunc(dst []RO, m RO, f func(rune) bool) []RO {
|
||||
s := string(m.m)
|
||||
|
||||
// Find the field start and end indices.
|
||||
wasField := false
|
||||
fromIndex := 0
|
||||
for i, rune := range s {
|
||||
if f(rune) {
|
||||
if wasField {
|
||||
dst = append(dst, RO{m: unsafeString(s[fromIndex:i])})
|
||||
wasField = false
|
||||
}
|
||||
} else {
|
||||
if !wasField {
|
||||
fromIndex = i
|
||||
wasField = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Last field might end at EOF.
|
||||
if wasField {
|
||||
dst = append(dst, RO{m: unsafeString(s[fromIndex:len(s)])})
|
||||
}
|
||||
return dst
|
||||
}
|
||||
132
vendor/go4.org/mem/fold.go
generated
vendored
Normal file
132
vendor/go4.org/mem/fold.go
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright 2020 The Go4 AUTHORS
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package mem // import "go4.org/mem"
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// equalFoldRune compares a and b runes whether they fold equally.
|
||||
//
|
||||
// The code comes from strings.EqualFold, but shortened to only one rune.
|
||||
func equalFoldRune(sr, tr rune) bool {
|
||||
if sr == tr {
|
||||
return true
|
||||
}
|
||||
// Make sr < tr to simplify what follows.
|
||||
if tr < sr {
|
||||
sr, tr = tr, sr
|
||||
}
|
||||
// Fast check for ASCII.
|
||||
if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
|
||||
// ASCII, and sr is upper case. tr must be lower case.
|
||||
if tr == sr+'a'-'A' {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// General case. SimpleFold(x) returns the next equivalent rune > x
|
||||
// or wraps around to smaller values.
|
||||
r := unicode.SimpleFold(sr)
|
||||
for r != sr && r < tr {
|
||||
r = unicode.SimpleFold(r)
|
||||
}
|
||||
if r == tr {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasPrefixFold is like HasPrefix but uses Unicode case-folding,
|
||||
// matching case insensitively.
|
||||
func HasPrefixFold(s, prefix RO) bool {
|
||||
if strings.HasPrefix(s.str(), prefix.str()) {
|
||||
// Exact case fast path.
|
||||
return true
|
||||
}
|
||||
for _, pr := range prefix.str() {
|
||||
if s.Len() == 0 {
|
||||
return false
|
||||
}
|
||||
// step with s, too
|
||||
sr, size := utf8.DecodeRuneInString(s.str())
|
||||
if sr == utf8.RuneError {
|
||||
return false
|
||||
}
|
||||
s = s.SliceFrom(size)
|
||||
if !equalFoldRune(sr, pr) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasSuffixFold is like HasSuffix but uses Unicode case-folding,
|
||||
// matching case insensitively.
|
||||
func HasSuffixFold(s, suffix RO) bool {
|
||||
if suffix.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
if strings.HasSuffix(s.str(), suffix.str()) {
|
||||
// Exact case fast path.
|
||||
return true
|
||||
}
|
||||
// count the runes and bytes in s, but only until rune count of suffix
|
||||
bo, so := s.Len(), suffix.Len()
|
||||
for bo > 0 && so > 0 {
|
||||
r, size := utf8.DecodeLastRuneInString(s.str()[:bo])
|
||||
if r == utf8.RuneError {
|
||||
return false
|
||||
}
|
||||
bo -= size
|
||||
|
||||
sr, size := utf8.DecodeLastRuneInString(suffix.str()[:so])
|
||||
if sr == utf8.RuneError {
|
||||
return false
|
||||
}
|
||||
so -= size
|
||||
|
||||
if !equalFoldRune(r, sr) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return so == 0
|
||||
}
|
||||
|
||||
// ContainsFold is like Contains but uses Unicode case-folding for a case insensitive substring search.
|
||||
func ContainsFold(s, substr RO) bool {
|
||||
if substr.Len() == 0 || strings.Contains(s.str(), substr.str()) {
|
||||
// Easy cases.
|
||||
return true
|
||||
}
|
||||
if s.Len() == 0 {
|
||||
return false
|
||||
}
|
||||
firstRune := rune(substr.At(0)) // Len != 0 checked above
|
||||
if firstRune >= utf8.RuneSelf {
|
||||
firstRune, _ = utf8.DecodeRuneInString(substr.str())
|
||||
}
|
||||
for i, rune := range s.str() {
|
||||
if equalFoldRune(rune, firstRune) && HasPrefixFold(s.SliceFrom(i), substr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
313
vendor/go4.org/mem/mem.go
generated
vendored
Normal file
313
vendor/go4.org/mem/mem.go
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
Copyright 2020 The Go4 AUTHORS
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mem provides the mem.RO type that allows you to cheaply pass &
|
||||
// access either a read-only []byte or a string.
|
||||
package mem // import "go4.org/mem"
|
||||
|
||||
import (
|
||||
"hash/maphash"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// RO is a read-only view of some bytes of memory. It may be be backed
|
||||
// by a string or []byte. Notably, unlike a string, the memory is not
|
||||
// guaranteed to be immutable. While the length is fixed, the
|
||||
// underlying bytes might change if interleaved with code that's
|
||||
// modifying the underlying memory.
|
||||
//
|
||||
// RO is a value type that's the same size of a Go string. Its various
|
||||
// methods should inline & compile to the equivalent operations
|
||||
// working on a string or []byte directly.
|
||||
//
|
||||
// Unlike a Go string, RO is not 'comparable' (it can't be a map key
|
||||
// or support ==). Use its Equal method to compare. This is done so an
|
||||
// RO backed by a later-mutating []byte doesn't break invariants in
|
||||
// Go's map implementation.
|
||||
type RO struct {
|
||||
_ [0]func() // not comparable; don't want to be a map key or support ==
|
||||
m unsafeString
|
||||
}
|
||||
|
||||
// str returns the unsafeString as a string. Only for use with standard
|
||||
// library funcs known to not let the string escape, as it doesn't
|
||||
// obey the language/runtime's expectations of a real string (it can
|
||||
// change underfoot).
|
||||
func (r RO) str() string { return string(r.m) }
|
||||
|
||||
// Len returns len(r).
|
||||
func (r RO) Len() int { return len(r.m) }
|
||||
|
||||
// At returns r[i].
|
||||
func (r RO) At(i int) byte { return r.m[i] }
|
||||
|
||||
// Slice returns r[from:to].
|
||||
func (r RO) Slice(from, to int) RO { return RO{m: r.m[from:to]} }
|
||||
|
||||
// SliceFrom returns r[from:].
|
||||
func (r RO) SliceFrom(from int) RO { return RO{m: r.m[from:]} }
|
||||
|
||||
// SliceTo returns r[:to].
|
||||
func (r RO) SliceTo(to int) RO { return RO{m: r.m[:to]} }
|
||||
|
||||
// Copy copies up to len(dest) bytes into dest from r and returns the
|
||||
// number of bytes copied, the min(r.Len(), len(dest)).
|
||||
func (r RO) Copy(dest []byte) int { return copy(dest, r.m) }
|
||||
|
||||
// Equal reports whether r and r2 are the same length and contain the
|
||||
// same bytes.
|
||||
func (r RO) Equal(r2 RO) bool { return r.m == r2.m }
|
||||
|
||||
// EqualString reports whether r and s are the same length and contain
|
||||
// the same bytes.
|
||||
func (r RO) EqualString(s string) bool { return r.str() == s }
|
||||
|
||||
// EqualBytes reports whether r and b are the same length and contain
|
||||
// the same bytes.
|
||||
func (r RO) EqualBytes(b []byte) bool { return r.str() == string(b) }
|
||||
|
||||
// Less reports whether r < r2.
|
||||
func (r RO) Less(r2 RO) bool { return r.str() < r2.str() }
|
||||
|
||||
var builderPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(strings.Builder)
|
||||
},
|
||||
}
|
||||
|
||||
// StringCopy returns m's contents in a newly allocated string.
|
||||
func (r RO) StringCopy() string {
|
||||
buf := builderPool.Get().(*strings.Builder)
|
||||
defer builderPool.Put(buf)
|
||||
defer buf.Reset()
|
||||
buf.WriteString(r.str())
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
var seed = maphash.MakeSeed()
|
||||
|
||||
// MapHash returns a hash of r's contents using runtime/maphash.
|
||||
// The hash is stable for the lifetime of a process.
|
||||
func (r RO) MapHash() uint64 {
|
||||
var hash maphash.Hash
|
||||
hash.SetSeed(seed)
|
||||
hash.WriteString(r.str())
|
||||
return hash.Sum64()
|
||||
}
|
||||
|
||||
// ParseInt returns a signed integer from m, using strconv.ParseInt.
|
||||
func ParseInt(m RO, base, bitSize int) (int64, error) {
|
||||
return strconv.ParseInt(m.str(), base, bitSize)
|
||||
}
|
||||
|
||||
// ParseUint returns a unsigned integer from m, using strconv.ParseUint.
|
||||
func ParseUint(m RO, base, bitSize int) (uint64, error) {
|
||||
return strconv.ParseUint(m.str(), base, bitSize)
|
||||
}
|
||||
|
||||
// ParseFloat returns a float from, using strconv.ParseFloat.
|
||||
func ParseFloat(m RO, bitSize int) (float64, error) {
|
||||
return strconv.ParseFloat(m.str(), bitSize)
|
||||
}
|
||||
|
||||
// Append appends m to dest, and returns the possibly-reallocated
|
||||
// dest.
|
||||
func Append(dest []byte, m RO) []byte { return append(dest, m.m...) }
|
||||
|
||||
// Contains reports whether substr is within m.
|
||||
func Contains(m, substr RO) bool { return strings.Contains(m.str(), substr.str()) }
|
||||
|
||||
// EqualFold reports whether s and t, interpreted as UTF-8 strings,
|
||||
// are equal under Unicode case-folding, which is a more general form
|
||||
// of case-insensitivity.
|
||||
func EqualFold(m, m2 RO) bool { return strings.EqualFold(m.str(), m2.str()) }
|
||||
|
||||
// HasPrefix reports whether m starts with prefix.
|
||||
func HasPrefix(m, prefix RO) bool { return strings.HasPrefix(m.str(), prefix.str()) }
|
||||
|
||||
// HasSuffix reports whether m ends with suffix.
|
||||
func HasSuffix(m, suffix RO) bool { return strings.HasSuffix(m.str(), suffix.str()) }
|
||||
|
||||
// Index returns the index of the first instance of substr in m, or -1
|
||||
// if substr is not present in m.
|
||||
func Index(m, substr RO) int { return strings.Index(m.str(), substr.str()) }
|
||||
|
||||
// IndexByte returns the index of the first instance of c in m, or -1
|
||||
// if c is not present in m.
|
||||
func IndexByte(m RO, c byte) int { return strings.IndexByte(m.str(), c) }
|
||||
|
||||
// LastIndexByte returns the index into m of the last Unicode code
|
||||
// point satisfying f(c), or -1 if none do.
|
||||
func LastIndexByte(m RO, c byte) int { return strings.LastIndexByte(m.str(), c) }
|
||||
|
||||
// LastIndex returns the index of the last instance of substr in m, or
|
||||
// -1 if substr is not present in m.
|
||||
func LastIndex(m, substr RO) int { return strings.LastIndex(m.str(), substr.str()) }
|
||||
|
||||
// TrimSpace returns a slice of the string s, with all leading and
|
||||
// trailing white space removed, as defined by Unicode.
|
||||
func TrimSpace(m RO) RO { return S(strings.TrimSpace(m.str())) }
|
||||
|
||||
// TrimSuffix returns m without the provided trailing suffix.
|
||||
// If m doesn't end with suffix, m is returned unchanged.
|
||||
func TrimSuffix(m, suffix RO) RO {
|
||||
return S(strings.TrimSuffix(m.str(), suffix.str()))
|
||||
}
|
||||
|
||||
// TrimPrefix returns m without the provided leading prefix.
|
||||
// If m doesn't start with prefix, m is returned unchanged.
|
||||
func TrimPrefix(m, prefix RO) RO {
|
||||
return S(strings.TrimPrefix(m.str(), prefix.str()))
|
||||
}
|
||||
|
||||
// TrimRightCutset returns a slice of m with all trailing Unicode code
|
||||
// points contained in cutset removed.
|
||||
//
|
||||
// To remove a suffix, use TrimSuffix instead.
|
||||
func TrimRightCutset(m, cutset RO) RO {
|
||||
return S(strings.TrimRight(m.str(), cutset.str()))
|
||||
}
|
||||
|
||||
// TrimLeftCutset returns a slice of m with all leading Unicode code
|
||||
// points contained in cutset removed.
|
||||
//
|
||||
// To remove a prefix, use TrimPrefix instead.
|
||||
func TrimLeftCutset(m, cutset RO) RO {
|
||||
return S(strings.TrimLeft(m.str(), cutset.str()))
|
||||
}
|
||||
|
||||
// TrimCutset returns a slice of the string s with all leading and
|
||||
// trailing Unicode code points contained in cutset removed.
|
||||
func TrimCutset(m, cutset RO) RO {
|
||||
return S(strings.Trim(m.str(), cutset.str()))
|
||||
}
|
||||
|
||||
// TrimFunc returns a slice of m with all leading and trailing Unicode
|
||||
// code points c satisfying f(c) removed.
|
||||
func TrimFunc(m RO, f func(rune) bool) RO {
|
||||
return S(strings.TrimFunc(m.str(), f))
|
||||
}
|
||||
|
||||
// TrimRightFunc returns a slice of m with all trailing Unicode
|
||||
// code points c satisfying f(c) removed.
|
||||
func TrimRightFunc(m RO, f func(rune) bool) RO {
|
||||
return S(strings.TrimRightFunc(m.str(), f))
|
||||
}
|
||||
|
||||
// TrimLeftFunc returns a slice of m with all leading Unicode
|
||||
// code points c satisfying f(c) removed.
|
||||
func TrimLeftFunc(m RO, f func(rune) bool) RO {
|
||||
return S(strings.TrimLeftFunc(m.str(), f))
|
||||
}
|
||||
|
||||
// Documentation for UTF-8 related functions copied from Go's unicode/utf8 package. (BSD license)
|
||||
|
||||
// DecodeRune unpacks the first UTF-8 encoding in m and returns the rune and
|
||||
// its width in bytes. If m is empty it returns (utf8.RuneError, 0). Otherwise, if
|
||||
// the encoding is invalid, it returns (utf8.RuneError, 1). Both are impossible
|
||||
// results for correct, non-empty UTF-8.
|
||||
//
|
||||
// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
|
||||
// out of range, or is not the shortest possible UTF-8 encoding for the
|
||||
// value. No other validation is performed.
|
||||
func DecodeRune(m RO) (r rune, size int) {
|
||||
return utf8.DecodeRuneInString(m.str())
|
||||
}
|
||||
|
||||
// DecodeLastRune unpacks the last UTF-8 encoding in m and returns the rune and
|
||||
// its width in bytes. If m is empty it returns (utf8.RuneError, 0). Otherwise, if
|
||||
// the encoding is invalid, it returns (utf8.RuneError, 1). Both are impossible
|
||||
// results for correct, non-empty UTF-8.
|
||||
//
|
||||
// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
|
||||
// out of range, or is not the shortest possible UTF-8 encoding for the
|
||||
// value. No other validation is performed.
|
||||
func DecodeLastRune(m RO) (r rune, size int) {
|
||||
return utf8.DecodeLastRuneInString(m.str())
|
||||
}
|
||||
|
||||
// FullRune reports whether the bytes in m begin with a full UTF-8 encoding of a rune.
|
||||
// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
|
||||
func FullRune(m RO) bool {
|
||||
return utf8.FullRuneInString(m.str())
|
||||
}
|
||||
|
||||
// RuneCount returns the number of UTF-8 encoded runes in m. Erroneous and short
|
||||
// encodings are treated as single runes of width 1 byte.
|
||||
func RuneCount(m RO) int {
|
||||
return utf8.RuneCountInString(m.str())
|
||||
}
|
||||
|
||||
// ValidUTF8 reports whether m consists entirely of valid UTF-8 encoded runes.
|
||||
func ValidUTF8(m RO) bool {
|
||||
return utf8.ValidString(m.str())
|
||||
}
|
||||
|
||||
// NewReader returns a new Reader that reads from m.
|
||||
func NewReader(m RO) *Reader {
|
||||
return &Reader{sr: strings.NewReader(m.str())}
|
||||
}
|
||||
|
||||
// Reader is like a bytes.Reader or strings.Reader.
|
||||
type Reader struct {
|
||||
sr *strings.Reader
|
||||
}
|
||||
|
||||
func (r *Reader) Len() int { return r.sr.Len() }
|
||||
func (r *Reader) Size() int64 { return r.sr.Size() }
|
||||
func (r *Reader) Read(b []byte) (int, error) { return r.sr.Read(b) }
|
||||
func (r *Reader) ReadAt(b []byte, off int64) (int, error) { return r.sr.ReadAt(b, off) }
|
||||
func (r *Reader) ReadByte() (byte, error) { return r.sr.ReadByte() }
|
||||
func (r *Reader) ReadRune() (ch rune, size int, err error) { return r.sr.ReadRune() }
|
||||
func (r *Reader) Seek(offset int64, whence int) (int64, error) { return r.sr.Seek(offset, whence) }
|
||||
|
||||
// TODO: add Reader.WriteTo, but don't use strings.Reader.WriteTo because it uses io.WriteString, leaking our unsafe string
|
||||
|
||||
// unsafeString is a string that's not really a Go string.
|
||||
// It might be pointing into a []byte. Don't let it escape to callers.
|
||||
// We contain the unsafety to this package.
|
||||
type unsafeString string
|
||||
|
||||
// stringHeader is a safer version of reflect.StringHeader.
|
||||
// See https://github.com/golang/go/issues/40701.
|
||||
type stringHeader struct {
|
||||
P *byte
|
||||
Len int
|
||||
}
|
||||
|
||||
// S returns a read-only view of the string s.
|
||||
//
|
||||
// The compiler should compile this call to nothing. Think of it as a
|
||||
// free type conversion. The returned RO view is the same size as a
|
||||
// string.
|
||||
func S(s string) RO { return RO{m: unsafeString(s)} }
|
||||
|
||||
// B returns a read-only view of the byte slice b.
|
||||
//
|
||||
// The compiler should compile this call to nothing. Think of it as a
|
||||
// free type conversion. The returned value is actually smaller than a
|
||||
// []byte though (16 bytes instead of 24 bytes on 64-bit
|
||||
// architectures).
|
||||
func B(b []byte) RO {
|
||||
if len(b) == 0 {
|
||||
return RO{m: ""}
|
||||
}
|
||||
return RO{m: *(*unsafeString)(unsafe.Pointer(&stringHeader{&b[0], len(b)}))}
|
||||
}
|
||||
Reference in New Issue
Block a user