Пример #1
0
// convertFloat converts the string to a float64value.
func (s *ss) convertFloat(str string, n int) float64 {
	if p := strings.Index(str, "p"); p >= 0 {
		// Atof doesn't handle power-of-2 exponents,
		// but they're easy to evaluate.
		f, err := strconv.AtofN(str[:p], n)
		if err != nil {
			// Put full string into error.
			if e, ok := err.(*strconv.NumError); ok {
				e.Num = str
			}
			s.error(err)
		}
		n, err := strconv.Atoi(str[p+1:])
		if err != nil {
			// Put full string into error.
			if e, ok := err.(*strconv.NumError); ok {
				e.Num = str
			}
			s.error(err)
		}
		return math.Ldexp(f, n)
	}
	f, err := strconv.AtofN(str, n)
	if err != nil {
		s.error(err)
	}
	return f
}
Пример #2
0
// convertFloat converts the string to a float64value.
func (s *ss) convertFloat(str string, n int) float64 {
	f, err := strconv.AtofN(str, n)
	if err != nil {
		s.error(err)
	}
	return f
}
Пример #3
0
// literalStore decodes a literal stored in item into v.
func (d *decodeState) literalStore(item []byte, v reflect.Value) {
	// Check for unmarshaler.
	wantptr := item[0] == 'n' // null
	unmarshaler, pv := d.indirect(v, wantptr)
	if unmarshaler != nil {
		err := unmarshaler.UnmarshalJSON(item)
		if err != nil {
			d.error(err)
		}
		return
	}
	v = pv

	switch c := item[0]; c {
	case 'n': // null
		switch v.Kind() {
		default:
			d.saveError(&UnmarshalTypeError{"null", v.Type()})
		case reflect.Interface, reflect.Ptr, reflect.Map:
			v.Set(reflect.Zero(v.Type()))
		}

	case 't', 'f': // true, false
		value := c == 't'
		switch v.Kind() {
		default:
			d.saveError(&UnmarshalTypeError{"bool", v.Type()})
		case reflect.Bool:
			v.SetBool(value)
		case reflect.Interface:
			v.Set(reflect.ValueOf(value))
		}

	case '"': // string
		s, ok := unquoteBytes(item)
		if !ok {
			d.error(errPhase)
		}
		switch v.Kind() {
		default:
			d.saveError(&UnmarshalTypeError{"string", v.Type()})
		case reflect.Slice:
			if v.Type() != byteSliceType {
				d.saveError(&UnmarshalTypeError{"string", v.Type()})
				break
			}
			b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
			n, err := base64.StdEncoding.Decode(b, s)
			if err != nil {
				d.saveError(err)
				break
			}
			v.Set(reflect.ValueOf(b[0:n]))
		case reflect.String:
			v.SetString(string(s))
		case reflect.Interface:
			v.Set(reflect.ValueOf(string(s)))
		}

	default: // number
		if c != '-' && (c < '0' || c > '9') {
			d.error(errPhase)
		}
		s := string(item)
		switch v.Kind() {
		default:
			d.error(&UnmarshalTypeError{"number", v.Type()})
		case reflect.Interface:
			n, err := strconv.Atof64(s)
			if err != nil {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.Set(reflect.ValueOf(n))

		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			n, err := strconv.Atoi64(s)
			if err != nil || v.OverflowInt(n) {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.SetInt(n)

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
			n, err := strconv.Atoui64(s)
			if err != nil || v.OverflowUint(n) {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.SetUint(n)

		case reflect.Float32, reflect.Float64:
			n, err := strconv.AtofN(s, v.Type().Bits())
			if err != nil || v.OverflowFloat(n) {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.SetFloat(n)
		}
	}
}
Пример #4
0
// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
// The first byte of the literal has been read already
// (that's how the caller knows it's a literal).
func (d *decodeState) literal(v reflect.Value) {
	// All bytes inside literal return scanContinue op code.
	start := d.off - 1
	op := d.scanWhile(scanContinue)

	// Scan read one byte too far; back up.
	d.off--
	d.scan.undo(op)
	item := d.data[start:d.off]

	// Check for unmarshaler.
	wantptr := item[0] == 'n' // null
	unmarshaler, pv := d.indirect(v, wantptr)
	if unmarshaler != nil {
		err := unmarshaler.UnmarshalJSON(item)
		if err != nil {
			d.error(err)
		}
		return
	}
	v = pv

	switch c := item[0]; c {
	case 'n': // null
		switch v.(type) {
		default:
			d.saveError(&UnmarshalTypeError{"null", v.Type()})
		case *reflect.InterfaceValue, *reflect.PtrValue, *reflect.MapValue:
			v.SetValue(nil)
		}

	case 't', 'f': // true, false
		value := c == 't'
		switch v := v.(type) {
		default:
			d.saveError(&UnmarshalTypeError{"bool", v.Type()})
		case *reflect.BoolValue:
			v.Set(value)
		case *reflect.InterfaceValue:
			v.Set(reflect.NewValue(value))
		}

	case '"': // string
		s, ok := unquote(item)
		if !ok {
			d.error(errPhase)
		}
		switch v := v.(type) {
		default:
			d.saveError(&UnmarshalTypeError{"string", v.Type()})
		case *reflect.StringValue:
			v.Set(s)
		case *reflect.InterfaceValue:
			v.Set(reflect.NewValue(s))
		}

	default: // number
		if c != '-' && (c < '0' || c > '9') {
			d.error(errPhase)
		}
		s := string(item)
		switch v := v.(type) {
		default:
			d.error(&UnmarshalTypeError{"number", v.Type()})
		case *reflect.InterfaceValue:
			n, err := strconv.Atof64(s)
			if err != nil {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.Set(reflect.NewValue(n))

		case *reflect.IntValue:
			n, err := strconv.Atoi64(s)
			if err != nil || v.Overflow(n) {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.Set(n)

		case *reflect.UintValue:
			n, err := strconv.Atoui64(s)
			if err != nil || v.Overflow(n) {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.Set(n)

		case *reflect.FloatValue:
			n, err := strconv.AtofN(s, v.Type().Bits())
			if err != nil || v.Overflow(n) {
				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
				break
			}
			v.Set(n)
		}
	}
}
Пример #5
0
func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
	tok := p.next()
	if tok.err != nil {
		return tok.err
	}
	if tok.value == "" {
		return p.errorf("unexpected EOF")
	}

	switch fv := v; fv.Kind() {
	case reflect.Slice:
		at := v.Type()
		if at.Elem().Kind() == reflect.Uint8 {
			// Special case for []byte
			if tok.value[0] != '"' {
				// Deliberately written out here, as the error after
				// this switch statement would write "invalid []byte: ...",
				// which is not as user-friendly.
				return p.errorf("invalid string: %v", tok.value)
			}
			bytes := []byte(tok.unquoted)
			fv.Set(reflect.ValueOf(bytes))
			return nil
		}
		// Repeated field. May already exist.
		flen := fv.Len()
		if flen == fv.Cap() {
			nav := reflect.MakeSlice(at, flen, 2*flen+1)
			reflect.Copy(nav, fv)
			fv.Set(nav)
		}
		fv.SetLen(flen + 1)

		// Read one.
		p.back()
		return p.readAny(fv.Index(flen), props)
	case reflect.Bool:
		// Either "true", "false", 1 or 0.
		switch tok.value {
		case "true", "1":
			fv.SetBool(true)
			return nil
		case "false", "0":
			fv.SetBool(false)
			return nil
		}
	case reflect.Float32, reflect.Float64:
		if f, err := strconv.AtofN(tok.value, fv.Type().Bits()); err == nil {
			fv.SetFloat(f)
			return nil
		}
	case reflect.Int32:
		if x, err := strconv.Atoi64(tok.value); err == nil && minInt32 <= x && x <= maxInt32 {
			fv.SetInt(x)
			return nil
		}
		if len(props.Enum) == 0 {
			break
		}
		m, ok := enumValueMaps[props.Enum]
		if !ok {
			break
		}
		x, ok := m[tok.value]
		if !ok {
			break
		}
		fv.SetInt(int64(x))
		return nil
	case reflect.Int64:
		if x, err := strconv.Atoi64(tok.value); err == nil {
			fv.SetInt(x)
			return nil
		}
	case reflect.Ptr:
		// A basic field (indirected through pointer), or a repeated message/group
		p.back()
		fv.Set(reflect.New(fv.Type().Elem()))
		return p.readAny(fv.Elem(), props)
	case reflect.String:
		if tok.value[0] == '"' {
			fv.SetString(tok.unquoted)
			return nil
		}
	case reflect.Struct:
		var terminator string
		switch tok.value {
		case "{":
			terminator = "}"
		case "<":
			terminator = ">"
		default:
			return p.errorf("expected '{' or '<', found %q", tok.value)
		}
		return p.readStruct(fv, terminator)
	case reflect.Uint32:
		if x, err := strconv.Atoui64(tok.value); err == nil && x <= maxUint32 {
			fv.SetUint(uint64(x))
			return nil
		}
	case reflect.Uint64:
		if x, err := strconv.Atoui64(tok.value); err == nil {
			fv.SetUint(x)
			return nil
		}
	}
	return p.errorf("invalid %v: %v", v.Type(), tok.value)
}