|
Packit Service |
4d2de5 |
package ini
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
import (
|
|
Packit Service |
4d2de5 |
"fmt"
|
|
Packit Service |
4d2de5 |
)
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// getStringValue will return a quoted string and the amount
|
|
Packit Service |
4d2de5 |
// of bytes read
|
|
Packit Service |
4d2de5 |
//
|
|
Packit Service |
4d2de5 |
// an error will be returned if the string is not properly formatted
|
|
Packit Service |
4d2de5 |
func getStringValue(b []rune) (int, error) {
|
|
Packit Service |
4d2de5 |
if b[0] != '"' {
|
|
Packit Service |
4d2de5 |
return 0, NewParseError("strings must start with '\"'")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
endQuote := false
|
|
Packit Service |
4d2de5 |
i := 1
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
for ; i < len(b) && !endQuote; i++ {
|
|
Packit Service |
4d2de5 |
if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
|
|
Packit Service |
4d2de5 |
endQuote = true
|
|
Packit Service |
4d2de5 |
break
|
|
Packit Service |
4d2de5 |
} else if escaped {
|
|
Packit Service |
4d2de5 |
/*c, err := getEscapedByte(b[i])
|
|
Packit Service |
4d2de5 |
if err != nil {
|
|
Packit Service |
4d2de5 |
return 0, err
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
b[i-1] = c
|
|
Packit Service |
4d2de5 |
b = append(b[:i], b[i+1:]...)
|
|
Packit Service |
4d2de5 |
i--*/
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
continue
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if !endQuote {
|
|
Packit Service |
4d2de5 |
return 0, NewParseError("missing '\"' in string value")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return i + 1, nil
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// getBoolValue will return a boolean and the amount
|
|
Packit Service |
4d2de5 |
// of bytes read
|
|
Packit Service |
4d2de5 |
//
|
|
Packit Service |
4d2de5 |
// an error will be returned if the boolean is not of a correct
|
|
Packit Service |
4d2de5 |
// value
|
|
Packit Service |
4d2de5 |
func getBoolValue(b []rune) (int, error) {
|
|
Packit Service |
4d2de5 |
if len(b) < 4 {
|
|
Packit Service |
4d2de5 |
return 0, NewParseError("invalid boolean value")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
n := 0
|
|
Packit Service |
4d2de5 |
for _, lv := range literalValues {
|
|
Packit Service |
4d2de5 |
if len(lv) > len(b) {
|
|
Packit Service |
4d2de5 |
continue
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if isLitValue(lv, b) {
|
|
Packit Service |
4d2de5 |
n = len(lv)
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if n == 0 {
|
|
Packit Service |
4d2de5 |
return 0, NewParseError("invalid boolean value")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return n, nil
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// getNumericalValue will return a numerical string, the amount
|
|
Packit Service |
4d2de5 |
// of bytes read, and the base of the number
|
|
Packit Service |
4d2de5 |
//
|
|
Packit Service |
4d2de5 |
// an error will be returned if the number is not of a correct
|
|
Packit Service |
4d2de5 |
// value
|
|
Packit Service |
4d2de5 |
func getNumericalValue(b []rune) (int, int, error) {
|
|
Packit Service |
4d2de5 |
if !isDigit(b[0]) {
|
|
Packit Service |
4d2de5 |
return 0, 0, NewParseError("invalid digit value")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
i := 0
|
|
Packit Service |
4d2de5 |
helper := numberHelper{}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
loop:
|
|
Packit Service |
4d2de5 |
for negativeIndex := 0; i < len(b); i++ {
|
|
Packit Service |
4d2de5 |
negativeIndex++
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if !isDigit(b[i]) {
|
|
Packit Service |
4d2de5 |
switch b[i] {
|
|
Packit Service |
4d2de5 |
case '-':
|
|
Packit Service |
4d2de5 |
if helper.IsNegative() || negativeIndex != 1 {
|
|
Packit Service |
4d2de5 |
return 0, 0, NewParseError("parse error '-'")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
n := getNegativeNumber(b[i:])
|
|
Packit Service |
4d2de5 |
i += (n - 1)
|
|
Packit Service |
4d2de5 |
helper.Determine(b[i])
|
|
Packit Service |
4d2de5 |
continue
|
|
Packit Service |
4d2de5 |
case '.':
|
|
Packit Service |
4d2de5 |
if err := helper.Determine(b[i]); err != nil {
|
|
Packit Service |
4d2de5 |
return 0, 0, err
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
case 'e', 'E':
|
|
Packit Service |
4d2de5 |
if err := helper.Determine(b[i]); err != nil {
|
|
Packit Service |
4d2de5 |
return 0, 0, err
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
negativeIndex = 0
|
|
Packit Service |
4d2de5 |
case 'b':
|
|
Packit Service |
4d2de5 |
if helper.numberFormat == hex {
|
|
Packit Service |
4d2de5 |
break
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
fallthrough
|
|
Packit Service |
4d2de5 |
case 'o', 'x':
|
|
Packit Service |
4d2de5 |
if i == 0 && b[i] != '0' {
|
|
Packit Service |
4d2de5 |
return 0, 0, NewParseError("incorrect base format, expected leading '0'")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if i != 1 {
|
|
Packit Service |
4d2de5 |
return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if err := helper.Determine(b[i]); err != nil {
|
|
Packit Service |
4d2de5 |
return 0, 0, err
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
default:
|
|
Packit Service |
4d2de5 |
if isWhitespace(b[i]) {
|
|
Packit Service |
4d2de5 |
break loop
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if isNewline(b[i:]) {
|
|
Packit Service |
4d2de5 |
break loop
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if !(helper.numberFormat == hex && isHexByte(b[i])) {
|
|
Packit Service |
4d2de5 |
if i+2 < len(b) && !isNewline(b[i:i+2]) {
|
|
Packit Service |
4d2de5 |
return 0, 0, NewParseError("invalid numerical character")
|
|
Packit Service |
4d2de5 |
} else if !isNewline([]rune{b[i]}) {
|
|
Packit Service |
4d2de5 |
return 0, 0, NewParseError("invalid numerical character")
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
break loop
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return helper.Base(), i, nil
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// isDigit will return whether or not something is an integer
|
|
Packit Service |
4d2de5 |
func isDigit(b rune) bool {
|
|
Packit Service |
4d2de5 |
return b >= '0' && b <= '9'
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func hasExponent(v []rune) bool {
|
|
Packit Service |
4d2de5 |
return contains(v, 'e') || contains(v, 'E')
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func isBinaryByte(b rune) bool {
|
|
Packit Service |
4d2de5 |
switch b {
|
|
Packit Service |
4d2de5 |
case '0', '1':
|
|
Packit Service |
4d2de5 |
return true
|
|
Packit Service |
4d2de5 |
default:
|
|
Packit Service |
4d2de5 |
return false
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func isOctalByte(b rune) bool {
|
|
Packit Service |
4d2de5 |
switch b {
|
|
Packit Service |
4d2de5 |
case '0', '1', '2', '3', '4', '5', '6', '7':
|
|
Packit Service |
4d2de5 |
return true
|
|
Packit Service |
4d2de5 |
default:
|
|
Packit Service |
4d2de5 |
return false
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func isHexByte(b rune) bool {
|
|
Packit Service |
4d2de5 |
if isDigit(b) {
|
|
Packit Service |
4d2de5 |
return true
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
return (b >= 'A' && b <= 'F') ||
|
|
Packit Service |
4d2de5 |
(b >= 'a' && b <= 'f')
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func getValue(b []rune) (int, error) {
|
|
Packit Service |
4d2de5 |
i := 0
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
for i < len(b) {
|
|
Packit Service |
4d2de5 |
if isNewline(b[i:]) {
|
|
Packit Service |
4d2de5 |
break
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if isOp(b[i:]) {
|
|
Packit Service |
4d2de5 |
break
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
valid, n, err := isValid(b[i:])
|
|
Packit Service |
4d2de5 |
if err != nil {
|
|
Packit Service |
4d2de5 |
return 0, err
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
if !valid {
|
|
Packit Service |
4d2de5 |
break
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
i += n
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return i, nil
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// getNegativeNumber will return a negative number from a
|
|
Packit Service |
4d2de5 |
// byte slice. This will iterate through all characters until
|
|
Packit Service |
4d2de5 |
// a non-digit has been found.
|
|
Packit Service |
4d2de5 |
func getNegativeNumber(b []rune) int {
|
|
Packit Service |
4d2de5 |
if b[0] != '-' {
|
|
Packit Service |
4d2de5 |
return 0
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
i := 1
|
|
Packit Service |
4d2de5 |
for ; i < len(b); i++ {
|
|
Packit Service |
4d2de5 |
if !isDigit(b[i]) {
|
|
Packit Service |
4d2de5 |
return i
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return i
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
// isEscaped will return whether or not the character is an escaped
|
|
Packit Service |
4d2de5 |
// character.
|
|
Packit Service |
4d2de5 |
func isEscaped(value []rune, b rune) bool {
|
|
Packit Service |
4d2de5 |
if len(value) == 0 {
|
|
Packit Service |
4d2de5 |
return false
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
switch b {
|
|
Packit Service |
4d2de5 |
case '\'': // single quote
|
|
Packit Service |
4d2de5 |
case '"': // quote
|
|
Packit Service |
4d2de5 |
case 'n': // newline
|
|
Packit Service |
4d2de5 |
case 't': // tab
|
|
Packit Service |
4d2de5 |
case '\\': // backslash
|
|
Packit Service |
4d2de5 |
default:
|
|
Packit Service |
4d2de5 |
return false
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return value[len(value)-1] == '\\'
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func getEscapedByte(b rune) (rune, error) {
|
|
Packit Service |
4d2de5 |
switch b {
|
|
Packit Service |
4d2de5 |
case '\'': // single quote
|
|
Packit Service |
4d2de5 |
return '\'', nil
|
|
Packit Service |
4d2de5 |
case '"': // quote
|
|
Packit Service |
4d2de5 |
return '"', nil
|
|
Packit Service |
4d2de5 |
case 'n': // newline
|
|
Packit Service |
4d2de5 |
return '\n', nil
|
|
Packit Service |
4d2de5 |
case 't': // table
|
|
Packit Service |
4d2de5 |
return '\t', nil
|
|
Packit Service |
4d2de5 |
case '\\': // backslash
|
|
Packit Service |
4d2de5 |
return '\\', nil
|
|
Packit Service |
4d2de5 |
default:
|
|
Packit Service |
4d2de5 |
return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
func removeEscapedCharacters(b []rune) []rune {
|
|
Packit Service |
4d2de5 |
for i := 0; i < len(b); i++ {
|
|
Packit Service |
4d2de5 |
if isEscaped(b[:i], b[i]) {
|
|
Packit Service |
4d2de5 |
c, err := getEscapedByte(b[i])
|
|
Packit Service |
4d2de5 |
if err != nil {
|
|
Packit Service |
4d2de5 |
return b
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
b[i-1] = c
|
|
Packit Service |
4d2de5 |
b = append(b[:i], b[i+1:]...)
|
|
Packit Service |
4d2de5 |
i--
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
}
|
|
Packit Service |
4d2de5 |
|
|
Packit Service |
4d2de5 |
return b
|
|
Packit Service |
4d2de5 |
}
|