summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-kv
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-kv')
-rw-r--r--vendor/codeberg.org/gruf/go-kv/field.go2
-rw-r--r--vendor/codeberg.org/gruf/go-kv/field_fmt.go4
-rw-r--r--vendor/codeberg.org/gruf/go-kv/field_format.go2
-rw-r--r--vendor/codeberg.org/gruf/go-kv/format/format.go74
-rw-r--r--vendor/codeberg.org/gruf/go-kv/format/util.go47
-rw-r--r--vendor/codeberg.org/gruf/go-kv/util.go148
6 files changed, 174 insertions, 103 deletions
diff --git a/vendor/codeberg.org/gruf/go-kv/field.go b/vendor/codeberg.org/gruf/go-kv/field.go
index 86a53b173..79c43822a 100644
--- a/vendor/codeberg.org/gruf/go-kv/field.go
+++ b/vendor/codeberg.org/gruf/go-kv/field.go
@@ -75,7 +75,7 @@ type Field struct {
// Key returns the formatted key string of this Field.
func (f Field) Key() string {
buf := byteutil.Buffer{B: make([]byte, 0, bufsize/2)}
- AppendQuoteKey(&buf, f.K)
+ AppendQuote(&buf, f.K)
return buf.String()
}
diff --git a/vendor/codeberg.org/gruf/go-kv/field_fmt.go b/vendor/codeberg.org/gruf/go-kv/field_fmt.go
index fcdcc5e17..33cec482b 100644
--- a/vendor/codeberg.org/gruf/go-kv/field_fmt.go
+++ b/vendor/codeberg.org/gruf/go-kv/field_fmt.go
@@ -25,7 +25,7 @@ func (f Field) AppendFormat(buf *byteutil.Buffer, vbose bool) {
} else /* regular */ {
fmtstr = `%+v`
}
- AppendQuoteKey(buf, f.K)
+ AppendQuote(buf, f.K)
buf.WriteByte('=')
appendValuef(buf, fmtstr, f.V)
}
@@ -50,7 +50,7 @@ func appendValuef(buf *byteutil.Buffer, format string, args ...interface{}) {
fmtbuf.B = fmt.Appendf(fmtbuf.B, format, args...)
// Append quoted value to dst buffer
- AppendQuoteValue(buf, fmtbuf.String())
+ AppendQuote(buf, fmtbuf.String())
// Drop overly large capacity buffers
if fmtbuf.Cap() > int(^uint16(0)) {
diff --git a/vendor/codeberg.org/gruf/go-kv/field_format.go b/vendor/codeberg.org/gruf/go-kv/field_format.go
index 4fa7a8dcf..18f35a6b9 100644
--- a/vendor/codeberg.org/gruf/go-kv/field_format.go
+++ b/vendor/codeberg.org/gruf/go-kv/field_format.go
@@ -16,7 +16,7 @@ func (f Field) AppendFormat(buf *byteutil.Buffer, vbose bool) {
} else /* regular */ {
fmtstr = "{:v}"
}
- AppendQuoteKey(buf, f.K)
+ AppendQuote(buf, f.K)
buf.WriteByte('=')
format.Appendf(buf, fmtstr, f.V)
}
diff --git a/vendor/codeberg.org/gruf/go-kv/format/format.go b/vendor/codeberg.org/gruf/go-kv/format/format.go
index 7edc4475f..ab20e01f4 100644
--- a/vendor/codeberg.org/gruf/go-kv/format/format.go
+++ b/vendor/codeberg.org/gruf/go-kv/format/format.go
@@ -166,21 +166,21 @@ func (f format) AppendByte(b byte) {
// Always quoted
case f.Key():
f.Buffer.B = append(f.Buffer.B, '\'')
- f.Buffer.B = append(f.Buffer.B, byte2str(b)...)
+ f.Buffer.B = append(f.Buffer.B, Byte2Str(b)...)
f.Buffer.B = append(f.Buffer.B, '\'')
// Always quoted ASCII with type
case f.Verbose():
f._AppendPrimitiveTyped(func(f format) {
f.Buffer.B = append(f.Buffer.B, '\'')
- f.Buffer.B = append(f.Buffer.B, byte2str(b)...)
+ f.Buffer.B = append(f.Buffer.B, Byte2Str(b)...)
f.Buffer.B = append(f.Buffer.B, '\'')
})
// Always quoted
case f.Value():
f.Buffer.B = append(f.Buffer.B, '\'')
- f.Buffer.B = append(f.Buffer.B, byte2str(b)...)
+ f.Buffer.B = append(f.Buffer.B, Byte2Str(b)...)
f.Buffer.B = append(f.Buffer.B, '\'')
// Append as raw byte
@@ -195,16 +195,16 @@ func (f format) AppendBytes(b []byte) {
case b == nil:
f.AppendNil()
- // Handle bytes as string key
+ // Quoted only if spaces/requires escaping
case f.Key():
- f.AppendStringKey(b2s(b))
+ f.AppendStringSafe(b2s(b))
// Append as separate ASCII quoted bytes in slice
case f.Verbose():
f._AppendArrayTyped(func(f format) {
for i := 0; i < len(b); i++ {
f.Buffer.B = append(f.Buffer.B, '\'')
- f.Buffer.B = append(f.Buffer.B, byte2str(b[i])...)
+ f.Buffer.B = append(f.Buffer.B, Byte2Str(b[i])...)
f.Buffer.B = append(f.Buffer.B, `',`...)
}
if len(b) > 0 {
@@ -212,9 +212,9 @@ func (f format) AppendBytes(b []byte) {
}
})
- // Append as quoted string
+ // Quoted only if spaces/requires escaping
case f.Value():
- f.AppendStringQuoted(b2s(b))
+ f.AppendStringSafe(b2s(b))
// Append as raw bytes
default:
@@ -260,9 +260,9 @@ func (f format) AppendRunes(r []rune) {
case r == nil:
f.AppendNil()
- // Handle bytes as string key
+ // Quoted only if spaces/requires escaping
case f.Key():
- f.AppendStringKey(string(r))
+ f.AppendStringSafe(string(r))
// Append as separate ASCII quoted bytes in slice
case f.Verbose():
@@ -276,9 +276,9 @@ func (f format) AppendRunes(r []rune) {
}
})
- // Append as quoted string
+ // Quoted only if spaces/requires escaping
case f.Value():
- f.AppendStringQuoted(string(r))
+ f.AppendStringSafe(string(r))
// Append as raw bytes
default:
@@ -292,7 +292,7 @@ func (f format) AppendString(s string) {
switch {
// Quoted only if spaces/requires escaping
case f.Key():
- f.AppendStringKey(s)
+ f.AppendStringSafe(s)
// Always quoted with type
case f.Verbose():
@@ -300,9 +300,9 @@ func (f format) AppendString(s string) {
f.AppendStringQuoted(s)
})
- // Always quoted string
+ // Quoted only if spaces/requires escaping
case f.Value():
- f.AppendStringQuoted(s)
+ f.AppendStringSafe(s)
// All else
default:
@@ -310,15 +310,15 @@ func (f format) AppendString(s string) {
}
}
-func (f format) AppendStringKey(s string) {
- if len(s) > SingleTermLine || !strconv.CanBackquote(s) {
+func (f format) AppendStringSafe(s string) {
+ if len(s) > SingleTermLine || !IsSafeASCII(s) {
// Requires quoting AND escaping
f.Buffer.B = strconv.AppendQuote(f.Buffer.B, s)
} else if ContainsDoubleQuote(s) {
// Contains double quotes, needs escaping
f.Buffer.B = AppendEscape(f.Buffer.B, s)
- } else if len(s) < 1 || ContainsSpaceOrTab(s) {
- // Contains space, needs quotes
+ } else if len(s) == 0 || ContainsSpaceOrTab(s) {
+ // Contains space / empty, needs quotes
f.Buffer.B = append(f.Buffer.B, '"')
f.Buffer.B = append(f.Buffer.B, s...)
f.Buffer.B = append(f.Buffer.B, '"')
@@ -329,7 +329,7 @@ func (f format) AppendStringKey(s string) {
}
func (f format) AppendStringQuoted(s string) {
- if len(s) > SingleTermLine || !strconv.CanBackquote(s) {
+ if len(s) > SingleTermLine || !IsSafeASCII(s) {
// Requires quoting AND escaping
f.Buffer.B = strconv.AppendQuote(f.Buffer.B, s)
} else if ContainsDoubleQuote(s) {
@@ -760,7 +760,7 @@ func (f format) AppendStructFields(v reflect.Value, t reflect.Type) {
tfield := t.Field(i)
// Append field name
- f.AppendStringKey(tfield.Name)
+ f.AppendStringSafe(tfield.Name)
f.Buffer.B = append(f.Buffer.B, '=')
f.SetValue().AppendInterfaceOrReflectNext(vfield, tfield.Type)
@@ -811,7 +811,7 @@ func (f format) _AppendMethodType(method func() string, i interface{}) (ok bool)
switch {
// Append as key formatted
case f.Key():
- f.AppendStringKey(result)
+ f.AppendStringSafe(result)
// Append as always quoted
case f.Value():
@@ -890,33 +890,3 @@ func (f format) _AppendFieldType(appendFields func(format)) {
appendFields(f)
f.Buffer.B = append(f.Buffer.B, '}')
}
-
-// byte2str returns 'c' as a string, escaping if necessary.
-func byte2str(c byte) string {
- switch c {
- case '\a':
- return `\a`
- case '\b':
- return `\b`
- case '\f':
- return `\f`
- case '\n':
- return `\n`
- case '\r':
- return `\r`
- case '\t':
- return `\t`
- case '\v':
- return `\v`
- case '\'':
- return `\\`
- default:
- if c < ' ' {
- const hex = "0123456789abcdef"
- return `\x` +
- string(hex[c>>4]) +
- string(hex[c&0xF])
- }
- return string(c)
- }
-}
diff --git a/vendor/codeberg.org/gruf/go-kv/format/util.go b/vendor/codeberg.org/gruf/go-kv/format/util.go
index 674f81be5..b5c672ecb 100644
--- a/vendor/codeberg.org/gruf/go-kv/format/util.go
+++ b/vendor/codeberg.org/gruf/go-kv/format/util.go
@@ -18,11 +18,22 @@ const (
SingleTermLine = 256
)
+// IsSafeASCII checks whether string is printable (i.e. non-control char) ASCII text.
+func IsSafeASCII(str string) bool {
+ for _, r := range str {
+ if (r < ' ' && r != '\t') ||
+ r >= 0x7f {
+ return false
+ }
+ }
+ return true
+}
+
// ContainsSpaceOrTab checks if "s" contains space or tabs.
func ContainsSpaceOrTab(s string) bool {
- if i := strings.IndexByte(s, ' '); i != -1 {
+ if i := strings.IndexByte(s, ' '); i >= 0 {
return true // note using indexbyte as it is ASM.
- } else if i := strings.IndexByte(s, '\t'); i != -1 {
+ } else if i := strings.IndexByte(s, '\t'); i >= 0 {
return true
}
return false
@@ -30,7 +41,7 @@ func ContainsSpaceOrTab(s string) bool {
// ContainsDoubleQuote checks if "s" contains a double quote.
func ContainsDoubleQuote(s string) bool {
- return (strings.IndexByte(s, '"') != -1)
+ return (strings.IndexByte(s, '"') >= 0)
}
// AppendEscape will append 's' to 'dst' and escape any double quotes.
@@ -57,6 +68,36 @@ func AppendEscape(dst []byte, str string) []byte {
return dst
}
+// Byte2Str returns 'c' as a string, escaping if necessary.
+func Byte2Str(c byte) string {
+ switch c {
+ case '\a':
+ return `\a`
+ case '\b':
+ return `\b`
+ case '\f':
+ return `\f`
+ case '\n':
+ return `\n`
+ case '\r':
+ return `\r`
+ case '\t':
+ return `\t`
+ case '\v':
+ return `\v`
+ case '\'':
+ return `\\`
+ default:
+ if c < ' ' {
+ const hex = "0123456789abcdef"
+ return `\x` +
+ string(hex[c>>4]) +
+ string(hex[c&0xF])
+ }
+ return string(c)
+ }
+}
+
// isNil will safely check if 'v' is nil without dealing with weird Go interface nil bullshit.
func isNil(i interface{}) bool {
type eface struct{ _type, data unsafe.Pointer } //nolint
diff --git a/vendor/codeberg.org/gruf/go-kv/util.go b/vendor/codeberg.org/gruf/go-kv/util.go
index 3d249e5d4..dfd91ad9d 100644
--- a/vendor/codeberg.org/gruf/go-kv/util.go
+++ b/vendor/codeberg.org/gruf/go-kv/util.go
@@ -2,70 +2,130 @@ package kv
import (
"strconv"
+ "strings"
"codeberg.org/gruf/go-byteutil"
"codeberg.org/gruf/go-kv/format"
)
-// AppendQuoteKey will append and escape/quote a formatted key string.
-func AppendQuoteKey(buf *byteutil.Buffer, str string) {
+// AppendQuote will append (and escape/quote where necessary) a formatted field string.
+func AppendQuote(buf *byteutil.Buffer, str string) {
switch {
- case len(str) > format.SingleTermLine || !strconv.CanBackquote(str):
- // Append quoted and escaped string
- buf.B = strconv.AppendQuote(buf.B, str)
- case format.ContainsDoubleQuote(str):
- // Double quote and escape string
- buf.B = append(buf.B, '"')
- buf.B = format.AppendEscape(buf.B, str)
- buf.B = append(buf.B, '"')
- case len(str) < 1 || format.ContainsSpaceOrTab(str):
- // Double quote this string as-is
- buf.WriteString(`"` + str + `"`)
- default:
- // Append string as-is
- buf.WriteString(str)
- }
-}
+ case len(str) == 0:
+ // Append empty quotes.
+ buf.B = append(buf.B, `""`...)
+ return
-// AppendQuoteValue will append and escape/quote a formatted value string.
-func AppendQuoteValue(buf *byteutil.Buffer, str string) {
- switch {
- case len(str) > format.SingleTermLine || !strconv.CanBackquote(str):
- // Append quoted and escaped string
+ case len(str) == 1:
+ // Append quote single byte.
+ appendQuoteByte(buf, str[0])
+ return
+
+ case len(str) > format.SingleTermLine || !format.IsSafeASCII(str):
+ // Long line or contains non-ascii chars.
buf.B = strconv.AppendQuote(buf.B, str)
return
- case !doubleQuoted(str):
+
+ case !isQuoted(str):
+ // Single/double quoted already.
+
+ // Get space / tab indices (if any).
+ s := strings.IndexByte(str, ' ')
+ t := strings.IndexByte(str, '\t')
+
+ // Find first whitespace.
+ sp0 := smallest(s, t)
+ if sp0 < 0 {
+ break
+ }
+
+ // Check if str is enclosed by braces.
+ // (but without any key-value separator).
+ if (enclosedBy(str, sp0, '{', '}') ||
+ enclosedBy(str, sp0, '[', ']') ||
+ enclosedBy(str, sp0, '(', ')')) &&
+ strings.IndexByte(str, '=') < 0 {
+ break
+ }
+
if format.ContainsDoubleQuote(str) {
- // Double quote and escape string
+ // Contains double quote, double quote
+ // and append escaped existing.
buf.B = append(buf.B, '"')
buf.B = format.AppendEscape(buf.B, str)
buf.B = append(buf.B, '"')
return
- } else if format.ContainsSpaceOrTab(str) {
- // Double quote this string as-is
- buf.WriteString(`"` + str + `"`)
- return
}
+
+ // Quote un-enclosed spaces.
+ buf.B = append(buf.B, '"')
+ buf.B = append(buf.B, str...)
+ buf.B = append(buf.B, '"')
+ return
+ }
+
+ // Double quoted, enclosed in braces, or
+ // literally anything else: append as-is.
+ buf.B = append(buf.B, str...)
+ return
+}
+
+// appendEscapeByte will append byte to buffer, quoting and escaping where necessary.
+func appendQuoteByte(buf *byteutil.Buffer, c byte) {
+ switch c {
+ // Double quote space.
+ case ' ':
+ buf.B = append(buf.B, '"', c, '"')
+
+ // Escape + double quote.
+ case '\a':
+ buf.B = append(buf.B, '"', '\\', 'a', '"')
+ case '\b':
+ buf.B = append(buf.B, '"', '\\', 'b', '"')
+ case '\f':
+ buf.B = append(buf.B, '"', '\\', 'f', '"')
+ case '\n':
+ buf.B = append(buf.B, '"', '\\', 'n', '"')
+ case '\r':
+ buf.B = append(buf.B, '"', '\\', 'r', '"')
+ case '\t':
+ buf.B = append(buf.B, '"', '\\', 't', '"')
+ case '\v':
+ buf.B = append(buf.B, '"', '\\', 'v', '"')
+
+ // Append as-is.
+ default:
+ buf.B = append(buf.B, c)
}
+}
- // Append string as-is
- buf.WriteString(str)
+// isQuoted checks if string is single or double quoted.
+func isQuoted(str string) bool {
+ return (str[0] == '"' && str[len(str)-1] == '"') ||
+ (str[0] == '\'' && str[len(str)-1] == '\'')
+}
+
+// smallest attempts to return the smallest positive value of those given.
+func smallest(i1, i2 int) int {
+ if i1 >= 0 && (i2 < 0 || i1 < i2) {
+ return i1
+ }
+ return i2
}
-// doubleQuoted will return whether 'str' is double quoted.
-func doubleQuoted(str string) bool {
- if len(str) < 2 ||
- str[0] != '"' || str[len(str)-1] != '"' {
+// enclosedBy will check if given string is enclosed by end, and at least non-whitespace up to start.
+func enclosedBy(str string, sp int, start, end byte) bool {
+ // Check for ending char in string.
+ if str[len(str)-1] != end {
return false
}
- var delim bool
- for i := len(str) - 2; i >= 0; i-- {
- switch str[i] {
- case '\\':
- delim = !delim
- default:
- return !delim
- }
+
+ // Check for starting char in string.
+ i := strings.IndexByte(str, start)
+ if i < 0 {
+ return false
}
- return !delim
+
+ // Check before space.
+ return i < sp
}