Skip to content

Commit

Permalink
hscan adds support for i386 platform (redis#1652)
Browse files Browse the repository at this point in the history
* hscan adds support for i386 platform

Signed-off-by: monkey <[email protected]>

* update go.sum

Signed-off-by: monkey <[email protected]>

* detect overflow of scan

Signed-off-by: monkey <[email protected]>

* restore the return value type of decoderFunc to error

Signed-off-by: monkey <[email protected]>

* fix clean

Signed-off-by: monkey <[email protected]>

* fix clean

Signed-off-by: monkey <[email protected]>

Co-authored-by: Monkey <[email protected]>
  • Loading branch information
monkey92t and Monkey authored Feb 9, 2021
1 parent fd6fac1 commit 27df231
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 41 deletions.
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down Expand Up @@ -62,12 +60,11 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand All @@ -77,6 +74,7 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
Expand Down
78 changes: 64 additions & 14 deletions internal/hscan/hscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ var (
decoders = []decoderFunc{
reflect.Bool: decodeBool,
reflect.Int: decodeInt,
reflect.Int8: decodeInt,
reflect.Int16: decodeInt,
reflect.Int32: decodeInt,
reflect.Int64: decodeInt,
reflect.Int8: decodeInt8,
reflect.Int16: decodeInt16,
reflect.Int32: decodeInt32,
reflect.Int64: decodeInt64,
reflect.Uint: decodeUint,
reflect.Uint8: decodeUint,
reflect.Uint16: decodeUint,
reflect.Uint32: decodeUint,
reflect.Uint64: decodeUint,
reflect.Float32: decodeFloat,
reflect.Float64: decodeFloat,
reflect.Uint8: decodeUint8,
reflect.Uint16: decodeUint16,
reflect.Uint32: decodeUint32,
reflect.Uint64: decodeUint64,
reflect.Float32: decodeFloat32,
reflect.Float64: decodeFloat64,
reflect.Complex64: decodeUnsupported,
reflect.Complex128: decodeUnsupported,
reflect.Array: decodeUnsupported,
Expand Down Expand Up @@ -106,26 +106,76 @@ func decodeBool(f reflect.Value, s string) error {
return nil
}

func decodeInt8(f reflect.Value, s string) error {
return decodeNumber(f, s, 8)
}

func decodeInt16(f reflect.Value, s string) error {
return decodeNumber(f, s, 16)
}

func decodeInt32(f reflect.Value, s string) error {
return decodeNumber(f, s, 32)
}

func decodeInt64(f reflect.Value, s string) error {
return decodeNumber(f, s, 64)
}

func decodeInt(f reflect.Value, s string) error {
v, err := strconv.ParseInt(s, 10, 0)
return decodeNumber(f, s, 0)
}

func decodeNumber(f reflect.Value, s string, bitSize int) error {
v, err := strconv.ParseInt(s, 10, bitSize)
if err != nil {
return err
}
f.SetInt(v)
return nil
}

func decodeUint8(f reflect.Value, s string) error {
return decodeUnsignedNumber(f, s, 8)
}

func decodeUint16(f reflect.Value, s string) error {
return decodeUnsignedNumber(f, s, 16)
}

func decodeUint32(f reflect.Value, s string) error {
return decodeUnsignedNumber(f, s, 32)
}

func decodeUint64(f reflect.Value, s string) error {
return decodeUnsignedNumber(f, s, 64)
}

func decodeUint(f reflect.Value, s string) error {
v, err := strconv.ParseUint(s, 10, 0)
return decodeUnsignedNumber(f, s, 0)
}

func decodeUnsignedNumber(f reflect.Value, s string, bitSize int) error {
v, err := strconv.ParseUint(s, 10, bitSize)
if err != nil {
return err
}
f.SetUint(v)
return nil
}

func decodeFloat(f reflect.Value, s string) error {
v, err := strconv.ParseFloat(s, 0)
func decodeFloat32(f reflect.Value, s string) error {
v, err := strconv.ParseFloat(s, 32)
if err != nil {
return err
}
f.SetFloat(v)
return nil
}

// although the default is float64, but we better define it.
func decodeFloat64(f reflect.Value, s string) error {
v, err := strconv.ParseFloat(s, 64)
if err != nil {
return err
}
Expand Down
101 changes: 81 additions & 20 deletions internal/hscan/hscan_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package hscan

import (
"math"
"strconv"
"testing"

. "github.com/onsi/ginkgo"
Expand All @@ -11,12 +13,21 @@ type data struct {
Omit string `redis:"-"`
Empty string

String string `redis:"string"`
Bytes []byte `redis:"byte"`
Int int `redis:"int"`
Uint uint `redis:"uint"`
Float float32 `redis:"float"`
Bool bool `redis:"bool"`
String string `redis:"string"`
Bytes []byte `redis:"byte"`
Int int `redis:"int"`
Int8 int8 `redis:"int8"`
Int16 int16 `redis:"int16"`
Int32 int32 `redis:"int32"`
Int64 int64 `redis:"int64"`
Uint uint `redis:"uint"`
Uint8 uint8 `redis:"uint8"`
Uint16 uint16 `redis:"uint16"`
Uint32 uint32 `redis:"uint32"`
Uint64 uint64 `redis:"uint64"`
Float float32 `redis:"float"`
Float64 float64 `redis:"float64"`
Bool bool `redis:"bool"`
}

type i []interface{}
Expand All @@ -43,23 +54,70 @@ var _ = Describe("Scan", func() {
Expect(Scan(data{}, i{"key", "string"}, i{nil, nil})).To(HaveOccurred())
})

It("number out of range", func() {
f := func(v uint64) string {
return strconv.FormatUint(v, 10) + "1"
}
keys := i{"int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "float64"}
vals := i{
f(math.MaxInt8), f(math.MaxInt16), f(math.MaxInt32), f(math.MaxInt64),
f(math.MaxUint8), f(math.MaxUint16), f(math.MaxUint32), strconv.FormatUint(math.MaxUint64, 10) + "1",
"13.4028234663852886e+38", "11.79769313486231570e+308",
}
for k, v := range keys {
var d data
Expect(Scan(&d, i{v}, i{vals[k]})).To(HaveOccurred())
}

//success
f = func(v uint64) string {
return strconv.FormatUint(v, 10)
}
keys = i{"int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "float64"}
vals = i{
f(math.MaxInt8), f(math.MaxInt16), f(math.MaxInt32), f(math.MaxInt64),
f(math.MaxUint8), f(math.MaxUint16), f(math.MaxUint32), strconv.FormatUint(math.MaxUint64, 10),
"3.40282346638528859811704183484516925440e+38", "1.797693134862315708145274237317043567981e+308",
}
var d data
Expect(Scan(&d, keys, vals)).NotTo(HaveOccurred())
Expect(d).To(Equal(data{
Int8: math.MaxInt8,
Int16: math.MaxInt16,
Int32: math.MaxInt32,
Int64: math.MaxInt64,
Uint8: math.MaxUint8,
Uint16: math.MaxUint16,
Uint32: math.MaxUint32,
Uint64: math.MaxUint64,
Float: math.MaxFloat32,
Float64: math.MaxFloat64,
}))
})

It("scans good values", func() {
var d data

// non-tagged fields.
Expect(Scan(&d, i{"key"}, i{"value"})).NotTo(HaveOccurred())
Expect(d).To(Equal(data{}))

keys := i{"string", "byte", "int", "uint", "float", "bool"}
vals := i{"str!", "bytes!", "123", "456", "123.456", "1"}
keys := i{"string", "byte", "int", "int64", "uint", "uint64", "float", "float64", "bool"}
vals := i{
"str!", "bytes!", "123", "123456789123456789", "456", "987654321987654321",
"123.456", "123456789123456789.987654321987654321", "1",
}
Expect(Scan(&d, keys, vals)).NotTo(HaveOccurred())
Expect(d).To(Equal(data{
String: "str!",
Bytes: []byte("bytes!"),
Int: 123,
Uint: 456,
Float: 123.456,
Bool: true,
String: "str!",
Bytes: []byte("bytes!"),
Int: 123,
Int64: 123456789123456789,
Uint: 456,
Uint64: 987654321987654321,
Float: 123.456,
Float64: 1.2345678912345678e+17,
Bool: true,
}))

// Scan a different type with the same values to test that
Expand All @@ -85,12 +143,15 @@ var _ = Describe("Scan", func() {

Expect(Scan(&d, i{"string", "float", "bool"}, i{"", "1", "t"})).NotTo(HaveOccurred())
Expect(d).To(Equal(data{
String: "",
Bytes: []byte("bytes!"),
Int: 123,
Uint: 456,
Float: 1.0,
Bool: true,
String: "",
Bytes: []byte("bytes!"),
Int: 123,
Int64: 123456789123456789,
Uint: 456,
Uint64: 987654321987654321,
Float: 1.0,
Float64: 1.2345678912345678e+17,
Bool: true,
}))
})

Expand Down
8 changes: 7 additions & 1 deletion internal/hscan/structmap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hscan

import (
"fmt"
"reflect"
"strings"
"sync"
Expand Down Expand Up @@ -83,5 +84,10 @@ func (s StructValue) Scan(key string, value string) error {
if !ok {
return nil
}
return field.fn(s.value.Field(field.index), value)
if err := field.fn(s.value.Field(field.index), value); err != nil {
t := s.value.Type()
return fmt.Errorf("cannot scan redis.result %s into struct field %s.%s of type %s, error-%s",
value, t.Name(), t.Field(field.index).Name, t.Field(field.index).Type, err.Error())
}
return nil
}

0 comments on commit 27df231

Please sign in to comment.