git.sophuwu.com > gophuwu   
              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
}