Beispiel #1
0
// Scan is a support routine for fmt.Scanner; it sets z to the value of
// the scanned number. It accepts the decimal formats 'd' and 'f', and
// handles both equivalently. Bases 2, 8, 16 are not supported.
// The scale of z is the number of digits after the decimal point
// (including any trailing 0s), or 0 if there is no decimal point.
func (z *Dec) Scan(s fmt.ScanState, ch rune) error {
	if ch != 'd' && ch != 'f' && ch != 's' && ch != 'v' {
		return fmt.Errorf("Dec.Scan: invalid verb '%c'", ch)
	}
	s.SkipSpace()
	_, err := z.scan(s)
	return err
}
Beispiel #2
0
// Scan is a support routine for fmt.Scanner; it sets z to the value of
// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
func (z *Int) Scan(s fmt.ScanState, ch int) os.Error {
	s.SkipSpace() // skip leading space characters
	base := 0
	switch ch {
	case 'b':
		base = 2
	case 'o':
		base = 8
	case 'd':
		base = 10
	case 'x', 'X':
		base = 16
	case 's', 'v':
		// let scan determine the base
	default:
		return os.NewError("Int.Scan: invalid verb")
	}
	_, _, err := z.scan(s, base)
	return err
}
Beispiel #3
0
// Scan is a support routine for fmt.Scanner; it sets z to the value of
// the scanned number. It accepts formats whose verbs are supported by
// fmt.Scan for floating point values, which are:
// 'b' (binary), 'e', 'E', 'f', 'F', 'g' and 'G'.
// Scan doesn't handle ±Inf.
func (z *Float) Scan(s fmt.ScanState, ch rune) error {
	s.SkipSpace()
	_, _, err := z.scan(byteReader{s}, 0)
	return err
}
Beispiel #4
0
Datei: int.go Projekt: locusf/gmp
// Scan is a support routine for fmt.Scanner; it sets z to the value of
// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
func (z *Int) Scan(s fmt.ScanState, ch rune) error {
	s.SkipSpace() // skip leading space characters
	base := 0
	switch ch {
	case 'b':
		base = 2
	case 'o':
		base = 8
	case 'd':
		base = 10
	case 'x', 'X':
		base = 16
	case 's', 'v':
		// let scan determine the base
	case 'z':
		base = 60
	default:
		return errors.New("Int.Scan: invalid verb")
	}
	charset := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz."
	if base != 0 {
		charset = charset[:base]
	}

	// Read the number into in
	in := make([]byte, 0, 16)
	var err error
	var n int
	for {
		ch, n, err = s.ReadRune()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
		if n > 1 {
			// Wide character - must be the end
			s.UnreadRune()
			break
		}
		if len(in) == 0 {
			if ch == '+' {
				// Skip leading + as gmp doesn't understand them
				continue
			}
			if ch == '-' {
				goto ok
			}
		}
		if len(in) == 1 && base == 0 {
			if ch == 'b' || ch == 'x' {
				goto ok
			}
		}
		if !strings.ContainsRune(charset, ch) {
			// Bad character - end
			s.UnreadRune()
			break
		}
	ok:
		in = append(in, byte(ch))
	}

	// Use GMP to convert it as it is very efficient for large numbers
	z.doinit()
	// null terminate for C
	in = append(in, 0)
	if C.mpz_set_str(&z.i[0], (*C.char)(unsafe.Pointer(&in[0])), C.int(base)) < 0 {
		return errors.New("Int.Scan: failed")
	}
	return nil
}