113
package parsers
import (
"errors"
"io"
"runtime"
)
func ParseInt(s string) (int, error) {
n := 0
if len(s) == 0 {
return 0, errors.New("empty string cannot be parsed to int")
}
sign := 1
if s[0] == '-' {
sign = -1
s = s[1:]
}
for _, r := range s {
if r < '0' || r > '9' {
return n * sign, errors.New("invalid character in string, must be a digit")
}
n = n*10 + int(r-'0')
}
n *= sign
return n, nil
}
func ParseFloat(s string) (float64, error) {
if len(s) == 0 {
return 0, errors.New("empty string cannot be parsed to float")
}
n := 0.0
sign := 1.0
if s[0] == '-' {
sign = -1.0
s = s[1:]
}
decimalPoint := false
factor := 1.0
for _, r := range s {
if r == '.' {
if decimalPoint {
return n * sign, errors.New("multiple decimal points in string")
}
decimalPoint = true
continue
}
if r < '0' || r > '9' {
return n * sign, errors.New("invalid character in string, must be a digit or decimal point")
}
if decimalPoint {
factor *= 10.0
n += float64(r-'0') / factor
} else {
n = n*10 + float64(r-'0')
}
}
n *= sign
return n, nil
}
func ParseBool(s string) (bool, error) {
switch s {
case "true", "1", "yes", "on":
return true, nil
case "false", "0", "no", "off":
return false, nil
default:
return false, errors.New("invalid boolean string, must be true/false, 1/0, yes/no, on/off")
}
}
func ReadLine(reader io.Reader) ([]byte, error) {
var buf [1]byte
var ret []byte
for {
n, err := reader.Read(buf[:])
if n > 0 {
switch buf[0] {
case '\b':
if len(ret) > 0 {
ret = ret[:len(ret)-1]
}
case '\n':
if runtime.GOOS != "windows" {
return ret, nil
}
// otherwise ignore \n
case '\r':
if runtime.GOOS == "windows" {
return ret, nil
}
// otherwise ignore \r
default:
ret = append(ret, buf[0])
}
continue
}
if err != nil {
if err == io.EOF && len(ret) > 0 {
return ret, nil
}
return ret, err
}
}
}
func ReadLineString(reader io.Reader) (string, error) {
line, err := ReadLine(reader)
return string(line), err
}