/usr/share/gocode/src/github.com/ctdk/goiardi/util/strings.go is in golang-github-ctdk-goiardi-dev 0.11.2-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | /*
* Copyright (c) 2013-2016, Jeremy Bingham (<jeremy@goiardi.gl>)
*
* 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 util
import (
"fmt"
"regexp"
"strings"
)
// StringSlice makes it possible to scan Posgres arrays directly into a golang
// slice. Borrowed from https://gist.github.com/adharris/4163702.
type StringSlice []string
// Scan implements sql.Scanner for the StringSlice type.
func (s *StringSlice) Scan(src interface{}) error {
asBytes, ok := src.([]byte)
if !ok {
return error(New("Scan source was not []bytes"))
}
asString := string(asBytes)
parsed := parseArray(asString)
(*s) = StringSlice(parsed)
return nil
}
// construct a regexp to extract values:
var (
// unquoted array values must not contain: (" , \ { } whitespace NULL)
// and must be at least one char
unquotedChar = `[^",\\{}\s(NULL)]`
unquotedValue = fmt.Sprintf("(%s)+", unquotedChar)
// quoted array values are surrounded by double quotes, can be any
// character except " or \, which must be backslash escaped:
quotedChar = `[^"\\]|\\"|\\\\`
quotedValue = fmt.Sprintf("\"(%s)*\"", quotedChar)
// an array value may be either quoted or unquoted:
arrayValue = fmt.Sprintf("(?P<value>(%s|%s))", unquotedValue, quotedValue)
// Array values are separated with a comma IF there is more than one value:
arrayExp = regexp.MustCompile(fmt.Sprintf("((%s)(,)?)", arrayValue))
valueIndex int
)
// Find the index of the 'value' named expression
func init() {
for i, subexp := range arrayExp.SubexpNames() {
if subexp == "value" {
valueIndex = i
break
}
}
}
// Parse the output string from the array type.
// Regex used: (((?P<value>(([^",\\{}\s(NULL)])+|"([^"\\]|\\"|\\\\)*")))(,)?)
func parseArray(array string) []string {
results := make([]string, 0)
matches := arrayExp.FindAllStringSubmatch(array, -1)
for _, match := range matches {
s := match[valueIndex]
// the string _might_ be wrapped in quotes, so trim them:
s = strings.Trim(s, "\"")
results = append(results, s)
}
return results
}
// RemoveDupStrings removes duplicates from a slice of strings. The slice of
// strings must be sorted before it's used with this function.
func RemoveDupStrings(strs []string) []string {
for i, v := range strs {
// catches the case where we've sliced off all the duplicates,
// but if we don't break here checking the last element will
// needlessly keep marching down the remainder of the slice for
// no effect
if i > len(strs) {
break
}
j := 1
s := 0
for {
if i+j >= len(strs) {
break
}
if v == strs[i+j] {
j++
s++
} else {
break
}
}
if s == 0 {
continue
}
strs = delTwoPosElements(i+1, s, strs)
}
return strs
}
// DelSliceElement removes an element from a slice of strings.
func DelSliceElement(pos int, strs []string) []string {
return delTwoPosElements(pos, 1, strs)
}
func delTwoPosElements(pos int, skip int, strs []string) []string {
strs = append(strs[:pos], strs[pos+skip:]...)
return strs
}
|