mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-02 22:17:10 +08:00

* adding mqtt benchmark tool Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * adding mqtt benchmark tool - vendoring Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add mtls support Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update readme Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * tool for channel provision, reorganize code Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * adding config toml Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * tool for channel provision, adding ssl cert gen Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add config toml Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add readme for provision Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update readme Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove some printing Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add test configs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove some dead code, and sort comments Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * replace statistics lib Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * replace statistics lib Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cobra and viper Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * styling changes Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * styling changes Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * styling changes Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove statistic lib Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * change type visibility Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove empty line Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update vendor Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update deps Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * rename variable Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * small changes, adding comments Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * error handling Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com>
114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
// Parsing keys handling both bare and quoted keys.
|
|
|
|
package toml
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"unicode"
|
|
)
|
|
|
|
// Convert the bare key group string to an array.
|
|
// The input supports double quotation and single quotation,
|
|
// but escape sequences are not supported. Lexers must unescape them beforehand.
|
|
func parseKey(key string) ([]string, error) {
|
|
runes := []rune(key)
|
|
var groups []string
|
|
|
|
if len(key) == 0 {
|
|
return nil, errors.New("empty key")
|
|
}
|
|
|
|
idx := 0
|
|
for idx < len(runes) {
|
|
for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
|
|
// skip leading whitespace
|
|
}
|
|
if idx >= len(runes) {
|
|
break
|
|
}
|
|
r := runes[idx]
|
|
if isValidBareChar(r) {
|
|
// parse bare key
|
|
startIdx := idx
|
|
endIdx := -1
|
|
idx++
|
|
for idx < len(runes) {
|
|
r = runes[idx]
|
|
if isValidBareChar(r) {
|
|
idx++
|
|
} else if r == '.' {
|
|
endIdx = idx
|
|
break
|
|
} else if isSpace(r) {
|
|
endIdx = idx
|
|
for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
|
|
// skip trailing whitespace
|
|
}
|
|
if idx < len(runes) && runes[idx] != '.' {
|
|
return nil, fmt.Errorf("invalid key character after whitespace: %c", runes[idx])
|
|
}
|
|
break
|
|
} else {
|
|
return nil, fmt.Errorf("invalid bare key character: %c", r)
|
|
}
|
|
}
|
|
if endIdx == -1 {
|
|
endIdx = idx
|
|
}
|
|
groups = append(groups, string(runes[startIdx:endIdx]))
|
|
} else if r == '\'' {
|
|
// parse single quoted key
|
|
idx++
|
|
startIdx := idx
|
|
for {
|
|
if idx >= len(runes) {
|
|
return nil, fmt.Errorf("unclosed single-quoted key")
|
|
}
|
|
r = runes[idx]
|
|
if r == '\'' {
|
|
groups = append(groups, string(runes[startIdx:idx]))
|
|
idx++
|
|
break
|
|
}
|
|
idx++
|
|
}
|
|
} else if r == '"' {
|
|
// parse double quoted key
|
|
idx++
|
|
startIdx := idx
|
|
for {
|
|
if idx >= len(runes) {
|
|
return nil, fmt.Errorf("unclosed double-quoted key")
|
|
}
|
|
r = runes[idx]
|
|
if r == '"' {
|
|
groups = append(groups, string(runes[startIdx:idx]))
|
|
idx++
|
|
break
|
|
}
|
|
idx++
|
|
}
|
|
} else if r == '.' {
|
|
idx++
|
|
if idx >= len(runes) {
|
|
return nil, fmt.Errorf("unexpected end of key")
|
|
}
|
|
r = runes[idx]
|
|
if !isValidBareChar(r) && r != '\'' && r != '"' && r != ' ' {
|
|
return nil, fmt.Errorf("expecting key part after dot")
|
|
}
|
|
} else {
|
|
return nil, fmt.Errorf("invalid key character: %c", r)
|
|
}
|
|
}
|
|
if len(groups) == 0 {
|
|
return nil, fmt.Errorf("empty key")
|
|
}
|
|
return groups, nil
|
|
}
|
|
|
|
func isValidBareChar(r rune) bool {
|
|
return isAlphanumeric(r) || r == '-' || unicode.IsNumber(r)
|
|
}
|