Skip to content

Commit 072f29e

Browse files
authored
Merge pull request #223 from cbusbey/fix_decimal
FIX decimal
2 parents 4f585c8 + ec8645b commit 072f29e

File tree

9 files changed

+913
-57
lines changed

9 files changed

+913
-57
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fmt:
77
go fmt ./...
88

99
vet:
10-
go vet $(go list ./... | grep -v /vendor)
10+
go vet `go list ./... | grep -v /vendor | grep -v fix4 | grep -v fix5 | grep -v fixt`
1111

1212
lint:
1313
go get github.com/golang/lint/golint
@@ -17,7 +17,7 @@ test:
1717
go test -v -cover . ./datadictionary ./internal
1818

1919
_build_all:
20-
go build -v ./...
20+
go build -v `go list ./... | grep -v /vendor`
2121

2222
build_accept:
2323
cd _test; go build -o echo_server

cmd/generate-fix/generate-fix.go

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strconv"
1111
"strings"
1212
"sync"
13+
"text/template"
1314

1415
"github.com/quickfixgo/quickfix/cmd/generate-fix/internal"
1516
"github.com/quickfixgo/quickfix/datadictionary"
@@ -53,48 +54,28 @@ type component struct {
5354
}
5455

5556
func genHeader(pkg string, spec *datadictionary.DataDictionary) {
56-
defer waitGroup.Done()
57-
writer := new(bytes.Buffer)
5857
c := component{
5958
Package: pkg,
6059
Name: "Header",
6160
MessageDef: spec.Header,
6261
FIXSpec: spec,
6362
}
64-
if err := internal.HeaderTemplate.Execute(writer, c); err != nil {
65-
errors <- err
66-
return
67-
}
68-
69-
if err := internal.WriteFile(path.Join(pkg, "header.generated.go"), writer.String()); err != nil {
70-
errors <- err
71-
}
63+
gen(internal.HeaderTemplate, path.Join(pkg, "header.generated.go"), c)
7264
}
7365

7466
func genTrailer(pkg string, spec *datadictionary.DataDictionary) {
75-
defer waitGroup.Done()
76-
writer := new(bytes.Buffer)
7767
c := component{
7868
Package: pkg,
7969
Name: "Trailer",
8070
MessageDef: spec.Trailer,
8171
}
82-
if err := internal.TrailerTemplate.Execute(writer, c); err != nil {
83-
errors <- err
84-
return
85-
}
86-
87-
if err := internal.WriteFile(path.Join(pkg, "trailer.generated.go"), writer.String()); err != nil {
88-
errors <- err
89-
}
72+
gen(internal.TrailerTemplate, path.Join(pkg, "trailer.generated.go"), c)
9073
}
9174

9275
func genMessage(fixPkg string, spec *datadictionary.DataDictionary, msg *datadictionary.MessageDef) {
93-
defer waitGroup.Done()
9476
pkgName := strings.ToLower(msg.Name)
9577
transportPkg := getTransportPackageName(spec)
9678

97-
writer := new(bytes.Buffer)
9879
c := component{
9980
Package: pkgName,
10081
FIXPackage: fixPkg,
@@ -104,54 +85,31 @@ func genMessage(fixPkg string, spec *datadictionary.DataDictionary, msg *datadic
10485
MessageDef: msg,
10586
}
10687

107-
if err := internal.MessageTemplate.Execute(writer, c); err != nil {
108-
errors <- err
109-
return
110-
}
111-
112-
if err := internal.WriteFile(path.Join(fixPkg, pkgName, msg.Name+".generated.go"), writer.String()); err != nil {
113-
errors <- err
114-
}
88+
gen(internal.MessageTemplate, path.Join(fixPkg, pkgName, msg.Name+".generated.go"), c)
11589
}
11690

11791
func genTags() {
118-
defer waitGroup.Done()
119-
writer := new(bytes.Buffer)
120-
121-
if err := internal.TagTemplate.Execute(writer, internal.GlobalFieldTypes); err != nil {
122-
errors <- err
123-
return
124-
}
125-
126-
if err := internal.WriteFile("tag/tag_numbers.generated.go", writer.String()); err != nil {
127-
errors <- err
128-
}
92+
gen(internal.TagTemplate, "tag/tag_numbers.generated.go", internal.GlobalFieldTypes)
12993
}
13094

13195
func genFields() {
132-
defer waitGroup.Done()
133-
writer := new(bytes.Buffer)
134-
135-
if err := internal.FieldTemplate.Execute(writer, internal.GlobalFieldTypes); err != nil {
136-
errors <- err
137-
return
138-
}
139-
140-
if err := internal.WriteFile("field/fields.generated.go", writer.String()); err != nil {
141-
errors <- err
142-
}
96+
gen(internal.FieldTemplate, "field/fields.generated.go", internal.GlobalFieldTypes)
14397
}
14498

14599
func genEnums() {
100+
gen(internal.EnumTemplate, "enum/enums.generated.go", internal.GlobalFieldTypes)
101+
}
102+
103+
func gen(t *template.Template, fileOut string, data interface{}) {
146104
defer waitGroup.Done()
147105
writer := new(bytes.Buffer)
148106

149-
if err := internal.EnumTemplate.Execute(writer, internal.GlobalFieldTypes); err != nil {
107+
if err := t.Execute(writer, data); err != nil {
150108
errors <- err
151109
return
152110
}
153111

154-
if err := internal.WriteFile("enum/enums.generated.go", writer.String()); err != nil {
112+
if err := internal.WriteFile(fileOut, writer.String()); err != nil {
155113
errors <- err
156114
}
157115
}

fix_decimal.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package quickfix
2+
3+
import "github.com/shopspring/decimal"
4+
5+
//FIXDecimal is a FIX Float Value that implements an arbitrary precision fixed-point decimal. Implements FieldValue
6+
type FIXDecimal struct {
7+
decimal.Decimal
8+
9+
//Scale is the number of digits after the decimal point when Writing the field value as a FIX value
10+
Scale int32
11+
}
12+
13+
func (d FIXDecimal) Write() []byte {
14+
return []byte(d.Decimal.StringFixed(d.Scale))
15+
}
16+
17+
func (d *FIXDecimal) Read(bytes []byte) (err error) {
18+
d.Decimal, err = decimal.NewFromString(string(bytes))
19+
return
20+
}

fix_decimal_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package quickfix
2+
3+
import (
4+
"testing"
5+
6+
"github.com/shopspring/decimal"
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestFIXDecimalWrite(t *testing.T) {
12+
var tests = []struct {
13+
decimal FIXDecimal
14+
expected string
15+
}{
16+
{decimal: FIXDecimal{Decimal: decimal.New(-1243456, -4), Scale: 4}, expected: "-124.3456"},
17+
{decimal: FIXDecimal{Decimal: decimal.New(-1243456, -4), Scale: 5}, expected: "-124.34560"},
18+
{decimal: FIXDecimal{Decimal: decimal.New(-1243456, -4), Scale: 0}, expected: "-124"},
19+
}
20+
21+
for _, test := range tests {
22+
b := test.decimal.Write()
23+
assert.Equal(t, test.expected, string(b))
24+
}
25+
}
26+
27+
func TestFIXDecimalRead(t *testing.T) {
28+
var tests = []struct {
29+
bytes string
30+
expected decimal.Decimal
31+
expectError bool
32+
}{
33+
{bytes: "15", expected: decimal.New(15, 0)},
34+
{bytes: "15.000", expected: decimal.New(15, 0)},
35+
{bytes: "15.001", expected: decimal.New(15001, -3)},
36+
{bytes: "-15.001", expected: decimal.New(-15001, -3)},
37+
{bytes: "blah", expectError: true},
38+
{bytes: "+200.00", expected: decimal.New(200, 0)},
39+
}
40+
41+
for _, test := range tests {
42+
var field FIXDecimal
43+
44+
err := field.Read([]byte(test.bytes))
45+
require.Equal(t, test.expectError, err != nil)
46+
47+
if !test.expectError {
48+
assert.True(t, test.expected.Equals(field.Decimal), "Expected %s got %s", test.expected, field.Decimal)
49+
}
50+
}
51+
}

fix_float_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ func BenchmarkFloatRead(b *testing.B) {
5151
val := []byte("15.1234")
5252
for i := 0; i < b.N; i++ {
5353
var field FIXFloat
54-
field.Read(val)
54+
_ = field.Read(val)
5555
}
5656
}

vendor/github.com/shopspring/decimal/LICENSE

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/shopspring/decimal/README.md

Lines changed: 124 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)