From 37706fc9ffb3c5dee3e652fc0d8eef613e4af2d3 Mon Sep 17 00:00:00 2001 From: 13981712066 Date: Fri, 15 Oct 2021 14:11:52 +0800 Subject: [PATCH 1/4] For MessagePack Add github.com/tinylib/msgp --- .gitignore | 1 + decimal_gen.go | 35 +++++++++++++++++++++++++++++++++++ go.mod | 2 ++ 3 files changed, 38 insertions(+) create mode 100644 decimal_gen.go diff --git a/.gitignore b/.gitignore index ff36b98..783412a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # IntelliJ .idea/ *.iml +*.sum # VS code *.code-workspace diff --git a/decimal_gen.go b/decimal_gen.go new file mode 100644 index 0000000..1e07ee4 --- /dev/null +++ b/decimal_gen.go @@ -0,0 +1,35 @@ +package decimal + +// Code generated by github.com/tinylib/msgp DO NOT EDIT. + +import ( + "github.com/tinylib/msgp/msgp" +) + +// MarshalMsg implements msgp.Marshaler +func (z Decimal) MarshalMsg(b []byte) (o []byte, err error) { + o = msgp.Require(b, z.Msgsize()) + o = msgp.AppendFloat64(o, z.InexactFloat64()) + return +} + +// UnmarshalMsg implements msgp.Unmarshaler +func (z *Decimal) UnmarshalMsg(bts []byte) (o []byte, err error) { + { + var zb0001 float64 + zb0001, bts, err = msgp.ReadFloat64Bytes(bts) + if err != nil { + err = msgp.WrapError(err) + return + } + (*z) = NewFromFloat(zb0001) + } + o = bts + return +} + +// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message +func (z Decimal) Msgsize() (s int) { + s = msgp.Float64Size + return +} diff --git a/go.mod b/go.mod index ae1b7aa..57b6f1d 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/shopspring/decimal go 1.13 + +require github.com/tinylib/msgp v1.1.6 From bc0ec03c775cc22134e8c6a64f963cd781c6c367 Mon Sep 17 00:00:00 2001 From: 13981712066 Date: Fri, 15 Oct 2021 14:20:41 +0800 Subject: [PATCH 2/4] rename package to piyongcai --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 57b6f1d..96cfa8d 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/shopspring/decimal +module github.com/piyongcai/decimal go 1.13 From 54fa4711909f4c68cb1cfdecf77c961381d3ebba Mon Sep 17 00:00:00 2001 From: 13981712066 Date: Sun, 17 Oct 2021 19:47:28 +0800 Subject: [PATCH 3/4] remove github.com/tinylib/msgp --- decimal_gen.go | 253 ++++++++++++++++++++++++++++++++++++++++++++---- decimal_test.go | 16 +++ go.mod | 2 - 3 files changed, 250 insertions(+), 21 deletions(-) diff --git a/decimal_gen.go b/decimal_gen.go index 1e07ee4..117bf0e 100644 --- a/decimal_gen.go +++ b/decimal_gen.go @@ -1,35 +1,250 @@ package decimal -// Code generated by github.com/tinylib/msgp DO NOT EDIT. - import ( - "github.com/tinylib/msgp/msgp" + "errors" ) +// const ( +// first3 = 0xe0 +// last5 = 0x1f +// +// mfixstr uint8 = 0xa0 +// mstr8 uint8 = 0xd9 +// mstr16 uint8 = 0xda +// mstr32 uint8 = 0xdb +// +// stringPrefixSize = 5 +// ) + +var ( + errShortBytes = errors.New("msgp: too few bytes left to read object") + //bigEndian = binary.BigEndian +) + + // MarshalMsg implements msgp.Marshaler func (z Decimal) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - o = msgp.AppendFloat64(o, z.InexactFloat64()) - return + o = require(b, z.Msgsize()) + str := z.String() + sz := len(str) + if sz > 30 { + sz = 30 + if str[29] == '.' { + sz = 29 + } + + str = str[:sz] + } + + o, n := ensure(b, 1+sz) + o[n] = byte(0xa0 | sz) + n++ + + return o[:n+copy(o[n:], str)], nil } // UnmarshalMsg implements msgp.Unmarshaler -func (z *Decimal) UnmarshalMsg(bts []byte) (o []byte, err error) { - { - var zb0001 float64 - zb0001, bts, err = msgp.ReadFloat64Bytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - (*z) = NewFromFloat(zb0001) +func (z *Decimal) UnmarshalMsg(b []byte) (o []byte, err error) { + l := len(b) + if l < 1 { + return nil, errShortBytes + } + + sz := int(b[0] & 0x1f) + if len(b[1:]) < sz { + err = errShortBytes + return + } + if *z, err = NewFromString(string(b[1 : sz+1])); err == nil { + o = b[sz:] } - o = bts return } // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z Decimal) Msgsize() (s int) { - s = msgp.Float64Size - return +func (z Decimal) Msgsize() int { + return 31 } +// +// // MarshalMsg implements msgp.Marshaler +// func (z Decimal) MarshalMsg(b []byte) (o []byte, err error) { +// o = require(b, z.Msgsize()) +// o = appendString(o, z.String()) +// return +// } +// +// // UnmarshalMsg implements msgp.Unmarshaler +// func (z *Decimal) UnmarshalMsg(b []byte) (o []byte, err error) { +// v, bts, err := readString(b) +// if err != nil { +// return +// } +// d, err := NewFromString(string(v)) +// if err == nil { +// *z = d +// o = bts +// } +// +// return +// } +// +// // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message +// func (z Decimal) Msgsize() (s int) { +// s = stringPrefixSize + len(z.String()) +// return +// } + +// Require ensures that cap(old)-len(old) >= extra. +func require(old []byte, extra int) []byte { + l := len(old) + c := cap(old) + r := l + extra + if c >= r { + return old + } else if l == 0 { + return make([]byte, 0, extra) + } + // the new size is the greater + // of double the old capacity + // and the sum of the old length + // and the number of new bytes + // necessary. + c <<= 1 + if c < r { + c = r + } + n := make([]byte, l, c) + copy(n, old) + return n +} + +// ensure 'sz' extra bytes in 'b' btw len(b) and cap(b) +func ensure(b []byte, sz int) ([]byte, int) { + l := len(b) + c := cap(b) + if c-l < sz { + o := make([]byte, (2*c)+sz) // exponential growth + n := copy(o, b) + return o[:n+sz], n + } + return b[:l+sz], l +} + +// // AppendString appends a string as a MessagePack 'str' to the slice +// func appendString(b []byte, s string) []byte { +// sz := len(s) +// var n int +// var o []byte +// switch { +// case sz <= 31: +// o, n = ensure(b, 1+sz) +// o[n] = wfixstr(uint8(sz)) +// n++ +// case sz <= math.MaxUint8: +// o, n = ensure(b, 2+sz) +// prefixu8(o[n:], mstr8, uint8(sz)) +// n += 2 +// case sz <= math.MaxUint16: +// o, n = ensure(b, 3+sz) +// prefixu16(o[n:], mstr16, uint16(sz)) +// n += 3 +// default: +// o, n = ensure(b, 5+sz) +// prefixu32(o[n:], mstr32, uint32(sz)) +// n += 5 +// } +// return o[:n+copy(o[n:], s)] +// } +// +// func wfixstr(u uint8) byte { +// return (u & last5) | mfixstr +// } +// +// // write prefix and uint8 +// func prefixu8(b []byte, pre byte, sz uint8) { +// b[0] = pre +// b[1] = sz +// } +// +// // write prefix and big-endian uint16 +// func prefixu16(b []byte, pre byte, sz uint16) { +// b[0] = pre +// b[1] = byte(sz >> 8) +// b[2] = byte(sz) +// } +// +// // write prefix and big-endian uint32 +// func prefixu32(b []byte, pre byte, sz uint32) { +// b[0] = pre +// b[1] = byte(sz >> 24) +// b[2] = byte(sz >> 16) +// b[3] = byte(sz >> 8) +// b[4] = byte(sz) +// } +// +// // readString reads a messagepack string field +// // without copying. The returned []byte points +// // to the same memory as the input slice. +// // Possible errors: +// // - ErrShortBytes (b not long enough) +// func readString(b []byte) (v []byte, o []byte, err error) { +// l := len(b) +// if l < 1 { +// return nil, nil, ErrShortBytes +// } +// +// lead := b[0] +// var read int +// +// if isfixstr(lead) { +// read = int(rfixstr(lead)) +// b = b[1:] +// } else { +// switch lead { +// case mstr8: +// if l < 2 { +// err = ErrShortBytes +// return +// } +// read = int(b[1]) +// b = b[2:] +// +// case mstr16: +// if l < 3 { +// err = ErrShortBytes +// return +// } +// read = int(bigEndian.Uint16(b[1:])) +// b = b[3:] +// +// case mstr32: +// if l < 5 { +// err = ErrShortBytes +// return +// } +// read = int(bigEndian.Uint32(b[1:])) +// b = b[5:] +// +// default: +// err = fmt.Errorf(`msgp: attempted to decode type 'str' with method for %d`, lead) +// return +// } +// } +// +// if len(b) < read { +// err = ErrShortBytes +// return +// } +// +// v = b[0:read] +// o = b[read:] +// return +// } +// +// func isfixstr(b byte) bool { +// return b&first3 == mfixstr +// } +// +// func rfixstr(b byte) uint8 { +// return b & last5 +// } diff --git a/decimal_test.go b/decimal_test.go index b53b68b..0573369 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -2,6 +2,7 @@ package decimal import ( "database/sql/driver" + "encoding/base64" "encoding/json" "encoding/xml" "fmt" @@ -3316,3 +3317,18 @@ func ExampleNewFromFloat() { //0.123123123123123 //-10000000000000 } + +func TestMsgPack(t *testing.T) { + d, _ := NewFromString("79228162514264337593543950334.123222") + out, err := d.MarshalMsg(nil) + if err != nil { + t.Fatal(err) + } + t.Log(base64.StdEncoding.EncodeToString(out)) + + var d2 = Decimal{} + if _, err = d2.UnmarshalMsg(out); err != nil { + t.Fatal(err) + } + t.Log(d2.String()) +} diff --git a/go.mod b/go.mod index 96cfa8d..bead680 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,3 @@ module github.com/piyongcai/decimal go 1.13 - -require github.com/tinylib/msgp v1.1.6 From 519f778aec45721769bba379d713600111486473 Mon Sep 17 00:00:00 2001 From: 13981712066 Date: Tue, 23 Nov 2021 16:16:27 +0800 Subject: [PATCH 4/4] add MsgPack Marshal And Unmarshal function --- decimal_gen.go | 172 ++----------------------------------------------- 1 file changed, 6 insertions(+), 166 deletions(-) diff --git a/decimal_gen.go b/decimal_gen.go index 117bf0e..4378102 100644 --- a/decimal_gen.go +++ b/decimal_gen.go @@ -4,28 +4,15 @@ import ( "errors" ) -// const ( -// first3 = 0xe0 -// last5 = 0x1f -// -// mfixstr uint8 = 0xa0 -// mstr8 uint8 = 0xd9 -// mstr16 uint8 = 0xda -// mstr32 uint8 = 0xdb -// -// stringPrefixSize = 5 -// ) - var ( errShortBytes = errors.New("msgp: too few bytes left to read object") - //bigEndian = binary.BigEndian ) // MarshalMsg implements msgp.Marshaler -func (z Decimal) MarshalMsg(b []byte) (o []byte, err error) { - o = require(b, z.Msgsize()) - str := z.String() +func (d Decimal) MarshalMsg(b []byte) (o []byte, err error) { + o = require(b, d.Msgsize()) + str := d.String() sz := len(str) if sz > 30 { sz = 30 @@ -44,7 +31,7 @@ func (z Decimal) MarshalMsg(b []byte) (o []byte, err error) { } // UnmarshalMsg implements msgp.Unmarshaler -func (z *Decimal) UnmarshalMsg(b []byte) (o []byte, err error) { +func (d *Decimal) UnmarshalMsg(b []byte) (o []byte, err error) { l := len(b) if l < 1 { return nil, errShortBytes @@ -55,44 +42,16 @@ func (z *Decimal) UnmarshalMsg(b []byte) (o []byte, err error) { err = errShortBytes return } - if *z, err = NewFromString(string(b[1 : sz+1])); err == nil { + if *d, err = NewFromString(string(b[1 : sz+1])); err == nil { o = b[sz:] } return } // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z Decimal) Msgsize() int { +func (d Decimal) Msgsize() int { return 31 } -// -// // MarshalMsg implements msgp.Marshaler -// func (z Decimal) MarshalMsg(b []byte) (o []byte, err error) { -// o = require(b, z.Msgsize()) -// o = appendString(o, z.String()) -// return -// } -// -// // UnmarshalMsg implements msgp.Unmarshaler -// func (z *Decimal) UnmarshalMsg(b []byte) (o []byte, err error) { -// v, bts, err := readString(b) -// if err != nil { -// return -// } -// d, err := NewFromString(string(v)) -// if err == nil { -// *z = d -// o = bts -// } -// -// return -// } -// -// // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -// func (z Decimal) Msgsize() (s int) { -// s = stringPrefixSize + len(z.String()) -// return -// } // Require ensures that cap(old)-len(old) >= extra. func require(old []byte, extra int) []byte { @@ -129,122 +88,3 @@ func ensure(b []byte, sz int) ([]byte, int) { } return b[:l+sz], l } - -// // AppendString appends a string as a MessagePack 'str' to the slice -// func appendString(b []byte, s string) []byte { -// sz := len(s) -// var n int -// var o []byte -// switch { -// case sz <= 31: -// o, n = ensure(b, 1+sz) -// o[n] = wfixstr(uint8(sz)) -// n++ -// case sz <= math.MaxUint8: -// o, n = ensure(b, 2+sz) -// prefixu8(o[n:], mstr8, uint8(sz)) -// n += 2 -// case sz <= math.MaxUint16: -// o, n = ensure(b, 3+sz) -// prefixu16(o[n:], mstr16, uint16(sz)) -// n += 3 -// default: -// o, n = ensure(b, 5+sz) -// prefixu32(o[n:], mstr32, uint32(sz)) -// n += 5 -// } -// return o[:n+copy(o[n:], s)] -// } -// -// func wfixstr(u uint8) byte { -// return (u & last5) | mfixstr -// } -// -// // write prefix and uint8 -// func prefixu8(b []byte, pre byte, sz uint8) { -// b[0] = pre -// b[1] = sz -// } -// -// // write prefix and big-endian uint16 -// func prefixu16(b []byte, pre byte, sz uint16) { -// b[0] = pre -// b[1] = byte(sz >> 8) -// b[2] = byte(sz) -// } -// -// // write prefix and big-endian uint32 -// func prefixu32(b []byte, pre byte, sz uint32) { -// b[0] = pre -// b[1] = byte(sz >> 24) -// b[2] = byte(sz >> 16) -// b[3] = byte(sz >> 8) -// b[4] = byte(sz) -// } -// -// // readString reads a messagepack string field -// // without copying. The returned []byte points -// // to the same memory as the input slice. -// // Possible errors: -// // - ErrShortBytes (b not long enough) -// func readString(b []byte) (v []byte, o []byte, err error) { -// l := len(b) -// if l < 1 { -// return nil, nil, ErrShortBytes -// } -// -// lead := b[0] -// var read int -// -// if isfixstr(lead) { -// read = int(rfixstr(lead)) -// b = b[1:] -// } else { -// switch lead { -// case mstr8: -// if l < 2 { -// err = ErrShortBytes -// return -// } -// read = int(b[1]) -// b = b[2:] -// -// case mstr16: -// if l < 3 { -// err = ErrShortBytes -// return -// } -// read = int(bigEndian.Uint16(b[1:])) -// b = b[3:] -// -// case mstr32: -// if l < 5 { -// err = ErrShortBytes -// return -// } -// read = int(bigEndian.Uint32(b[1:])) -// b = b[5:] -// -// default: -// err = fmt.Errorf(`msgp: attempted to decode type 'str' with method for %d`, lead) -// return -// } -// } -// -// if len(b) < read { -// err = ErrShortBytes -// return -// } -// -// v = b[0:read] -// o = b[read:] -// return -// } -// -// func isfixstr(b byte) bool { -// return b&first3 == mfixstr -// } -// -// func rfixstr(b byte) uint8 { -// return b & last5 -// }