|
- // Copyright (c) 2014 Couchbase, Inc.
- //
- // 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 analysis
-
- import (
- "bytes"
- "unicode/utf8"
- )
-
- func DeleteRune(in []rune, pos int) []rune {
- if pos >= len(in) {
- return in
- }
- copy(in[pos:], in[pos+1:])
- return in[:len(in)-1]
- }
-
- func InsertRune(in []rune, pos int, r rune) []rune {
- // create a new slice 1 rune larger
- rv := make([]rune, len(in)+1)
- // copy the characters before the insert pos
- copy(rv[0:pos], in[0:pos])
- // set the inserted rune
- rv[pos] = r
- // copy the characters after the insert pos
- copy(rv[pos+1:], in[pos:])
- return rv
- }
-
- // BuildTermFromRunesOptimistic will build a term from the provided runes
- // AND optimistically attempt to encode into the provided buffer
- // if at any point it appears the buffer is too small, a new buffer is
- // allocated and that is used instead
- // this should be used in cases where frequently the new term is the same
- // length or shorter than the original term (in number of bytes)
- func BuildTermFromRunesOptimistic(buf []byte, runes []rune) []byte {
- rv := buf
- used := 0
- for _, r := range runes {
- nextLen := utf8.RuneLen(r)
- if used+nextLen > len(rv) {
- // alloc new buf
- buf = make([]byte, len(runes)*utf8.UTFMax)
- // copy work we've already done
- copy(buf, rv[:used])
- rv = buf
- }
- written := utf8.EncodeRune(rv[used:], r)
- used += written
- }
- return rv[:used]
- }
-
- func BuildTermFromRunes(runes []rune) []byte {
- return BuildTermFromRunesOptimistic(make([]byte, len(runes)*utf8.UTFMax), runes)
- }
-
- func TruncateRunes(input []byte, num int) []byte {
- runes := bytes.Runes(input)
- runes = runes[:len(runes)-num]
- out := BuildTermFromRunes(runes)
- return out
- }
-
- func RunesEndsWith(input []rune, suffix string) bool {
- inputLen := len(input)
- suffixRunes := []rune(suffix)
- suffixLen := len(suffixRunes)
- if suffixLen > inputLen {
- return false
- }
-
- for i := suffixLen - 1; i >= 0; i-- {
- if input[inputLen-(suffixLen-i)] != suffixRunes[i] {
- return false
- }
- }
-
- return true
- }
|