mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-22 16:36:27 +01:00
d5c180e680
It is better developing vmctl tool in VictoriaMetrics repository, so it could be released together with the rest of vmutils tools such as vmalert, vmagent, vmbackup, vmrestore and vmauth.
116 lines
2.3 KiB
Go
116 lines
2.3 KiB
Go
// Package escape contains utilities for escaping parts of InfluxQL
|
|
// and InfluxDB line protocol.
|
|
package escape // import "github.com/influxdata/influxdb/pkg/escape"
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
)
|
|
|
|
// Codes is a map of bytes to be escaped.
|
|
var Codes = map[byte][]byte{
|
|
',': []byte(`\,`),
|
|
'"': []byte(`\"`),
|
|
' ': []byte(`\ `),
|
|
'=': []byte(`\=`),
|
|
}
|
|
|
|
// Bytes escapes characters on the input slice, as defined by Codes.
|
|
func Bytes(in []byte) []byte {
|
|
for b, esc := range Codes {
|
|
in = bytes.Replace(in, []byte{b}, esc, -1)
|
|
}
|
|
return in
|
|
}
|
|
|
|
const escapeChars = `," =`
|
|
|
|
// IsEscaped returns whether b has any escaped characters,
|
|
// i.e. whether b seems to have been processed by Bytes.
|
|
func IsEscaped(b []byte) bool {
|
|
for len(b) > 0 {
|
|
i := bytes.IndexByte(b, '\\')
|
|
if i < 0 {
|
|
return false
|
|
}
|
|
|
|
if i+1 < len(b) && strings.IndexByte(escapeChars, b[i+1]) >= 0 {
|
|
return true
|
|
}
|
|
b = b[i+1:]
|
|
}
|
|
return false
|
|
}
|
|
|
|
// AppendUnescaped appends the unescaped version of src to dst
|
|
// and returns the resulting slice.
|
|
func AppendUnescaped(dst, src []byte) []byte {
|
|
var pos int
|
|
for len(src) > 0 {
|
|
next := bytes.IndexByte(src[pos:], '\\')
|
|
if next < 0 || pos+next+1 >= len(src) {
|
|
return append(dst, src...)
|
|
}
|
|
|
|
if pos+next+1 < len(src) && strings.IndexByte(escapeChars, src[pos+next+1]) >= 0 {
|
|
if pos+next > 0 {
|
|
dst = append(dst, src[:pos+next]...)
|
|
}
|
|
src = src[pos+next+1:]
|
|
pos = 0
|
|
} else {
|
|
pos += next + 1
|
|
}
|
|
}
|
|
|
|
return dst
|
|
}
|
|
|
|
// Unescape returns a new slice containing the unescaped version of in.
|
|
func Unescape(in []byte) []byte {
|
|
if len(in) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if bytes.IndexByte(in, '\\') == -1 {
|
|
return in
|
|
}
|
|
|
|
i := 0
|
|
inLen := len(in)
|
|
|
|
// The output size will be no more than inLen. Preallocating the
|
|
// capacity of the output is faster and uses less memory than
|
|
// letting append() do its own (over)allocation.
|
|
out := make([]byte, 0, inLen)
|
|
|
|
for {
|
|
if i >= inLen {
|
|
break
|
|
}
|
|
if in[i] == '\\' && i+1 < inLen {
|
|
switch in[i+1] {
|
|
case ',':
|
|
out = append(out, ',')
|
|
i += 2
|
|
continue
|
|
case '"':
|
|
out = append(out, '"')
|
|
i += 2
|
|
continue
|
|
case ' ':
|
|
out = append(out, ' ')
|
|
i += 2
|
|
continue
|
|
case '=':
|
|
out = append(out, '=')
|
|
i += 2
|
|
continue
|
|
}
|
|
}
|
|
out = append(out, in[i])
|
|
i += 1
|
|
}
|
|
return out
|
|
}
|