Skip to content

Commit dfe95cf

Browse files
author
Chris Busbey
committed
message cap, removed cruft
1 parent e5f1ded commit dfe95cf

16 files changed

+107
-111
lines changed

field.go

+2-10
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,14 @@ type FieldValueWriter interface {
88

99
//FieldValueReader is an interface for reading field values
1010
type FieldValueReader interface {
11-
//Parameter to Read is TagValues. For most fields, only the first TagValue will be required.
12-
//The length of the slice extends from the TagValue mapped to the field to be read through the
13-
//following fields. This can be useful for FieldValues made up of repeating groups.
14-
//
15-
//The Read function returns the remaining TagValues not processed by the FieldValue. If there was a
16-
//problem reading the field, an error may be returned
17-
Read(TagValues) (TagValues, error)
11+
//Reads the contents of the []byte into FieldValue. Returns an error if there are issues in the data processing
12+
Read([]byte) error
1813
}
1914

2015
//The FieldValue interface is used to write/extract typed field values to/from raw bytes
2116
type FieldValue interface {
2217
FieldValueWriter
2318
FieldValueReader
24-
25-
//Returns a new FieldValue cloned from this one
26-
Clone() FieldValue
2719
}
2820

2921
//FieldWriter is an interface for a writing a field

field_map.go

+13
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ func (m FieldMap) GetField(tag Tag, parser FieldValueReader) MessageRejectError
9696
return conditionallyRequiredFieldMissing(tag)
9797
}
9898

99+
if err := parser.Read(tagValues[0].Value); err != nil {
100+
return incorrectDataFormatForValue(tag)
101+
}
102+
103+
return nil
104+
}
105+
106+
func (m FieldMap) GetGroupField(tag Tag, parser *RepeatingGroup) MessageRejectError {
107+
tagValues, ok := m.tagLookup[tag]
108+
if !ok {
109+
return conditionallyRequiredFieldMissing(tag)
110+
}
111+
99112
if _, err := parser.Read(tagValues); err != nil {
100113
return incorrectDataFormatForValue(tag)
101114
}

fix_boolean.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,17 @@ func NewFIXBoolean(val bool) *FIXBoolean {
1313
return &b
1414
}
1515

16-
func (f *FIXBoolean) Read(tv TagValues) (TagValues, error) {
17-
bytes := tv[0].Value
16+
func (f *FIXBoolean) Read(bytes []byte) error {
1817
switch string(bytes) {
1918
case "Y":
2019
*f = true
2120
case "N":
2221
*f = false
2322
default:
24-
return tv, errors.New("Invalid Value for bool: " + string(bytes))
23+
return errors.New("Invalid Value for bool: " + string(bytes))
2524
}
2625

27-
return tv[1:], nil
26+
return nil
2827
}
2928

3029
func (f FIXBoolean) Write() []byte {
@@ -34,8 +33,3 @@ func (f FIXBoolean) Write() []byte {
3433

3534
return []byte("N")
3635
}
37-
38-
func (f FIXBoolean) Clone() FieldValue {
39-
clone := f
40-
return &clone
41-
}

fix_boolean_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestFIXBooleanFieldRead(t *testing.T) {
3737

3838
for _, test := range tests {
3939
var val FIXBoolean
40-
_, err := val.Read([]TagValue{TagValue{Value: test.bytes}})
40+
err := val.Read(test.bytes)
4141

4242
if test.expectError && err == nil {
4343
t.Errorf("Expected error for %v", test.bytes)

fix_float.go

+4-10
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,22 @@ func NewFIXFloat(val float64) *FIXFloat {
1515
return &f
1616
}
1717

18-
func (f *FIXFloat) Read(tv TagValues) (TagValues, error) {
19-
bytes := tv[0].Value
18+
func (f *FIXFloat) Read(bytes []byte) error {
2019
val, err := strconv.ParseFloat(string(bytes), 64)
2120
if err != nil {
22-
return tv, err
21+
return err
2322
}
2423

2524
//strconv allows values like "+100.00", which is not allowed for FIX float types
2625
if valid, _ := regexp.MatchString("^[0-9.-]+$", string(bytes)); !valid {
27-
return tv, fmt.Errorf("invalid value %v", string(bytes))
26+
return fmt.Errorf("invalid value %v", string(bytes))
2827
}
2928

3029
*f = FIXFloat(val)
3130

32-
return tv[1:], err
31+
return err
3332
}
3433

3534
func (f FIXFloat) Write() []byte {
3635
return []byte(strconv.FormatFloat(float64(f), 'f', -1, 64))
3736
}
38-
39-
func (f FIXFloat) Clone() FieldValue {
40-
clone := f
41-
return &clone
42-
}

fix_float_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestFloatRead(t *testing.T) {
3535

3636
for _, test := range tests {
3737
var field FIXFloat
38-
if _, err := field.Read([]TagValue{TagValue{Value: test.bytes}}); err != nil {
38+
if err := field.Read(test.bytes); err != nil {
3939
if !test.expectError {
4040
t.Errorf("UnExpected '%v'", err)
4141
}

fix_int.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,15 @@ func NewFIXInt(val int) *FIXInt {
5252
return &i
5353
}
5454

55-
func (f *FIXInt) Read(tv TagValues) (TagValues, error) {
56-
i, err := atoi(tv[0].Value)
55+
func (f *FIXInt) Read(bytes []byte) error {
56+
i, err := atoi(bytes)
5757
if err != nil {
58-
return tv, err
58+
return err
5959
}
6060
*f = FIXInt(i)
61-
return tv[1:], nil
61+
return nil
6262
}
6363

6464
func (f FIXInt) Write() []byte {
6565
return []byte(strconv.Itoa(int(f)))
6666
}
67-
68-
func (f FIXInt) Clone() FieldValue {
69-
clone := f
70-
return &clone
71-
}

fix_int_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func TestInt_Write(t *testing.T) {
1515

1616
func TestInt_Read(t *testing.T) {
1717
var field FIXInt
18-
_, err := field.Read([]TagValue{TagValue{Value: []byte("15")}})
18+
err := field.Read([]byte("15"))
1919

2020
if err != nil {
2121
t.Error("Unexpected error", err)
@@ -25,7 +25,7 @@ func TestInt_Read(t *testing.T) {
2525
t.Error("unexpected value", field)
2626
}
2727

28-
_, err = field.Read([]TagValue{TagValue{Value: []byte("blah")}})
28+
err = field.Read([]byte("blah"))
2929

3030
if err == nil {
3131
t.Error("expected error")
@@ -37,6 +37,6 @@ func BenchmarkInt_Read(b *testing.B) {
3737
var field FIXInt
3838

3939
for i := 0; i < b.N; i++ {
40-
field.Read([]TagValue{TagValue{Value: intBytes}})
40+
field.Read(intBytes)
4141
}
4242
}

fix_string.go

+3-8
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@ func (f FIXString) String() string {
1313
return string(f)
1414
}
1515

16-
func (f *FIXString) Read(tv TagValues) (TagValues, error) {
17-
*f = FIXString(tv[0].Value)
18-
return tv[1:], nil
16+
func (f *FIXString) Read(bytes []byte) (err error) {
17+
*f = FIXString(bytes)
18+
return
1919
}
2020

2121
func (f FIXString) Write() []byte {
2222
return []byte(f)
2323
}
24-
25-
func (f FIXString) Clone() FieldValue {
26-
clone := f
27-
return &clone
28-
}

fix_string_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func TestFIXStringRead(t *testing.T) {
3333

3434
for _, test := range tests {
3535
var field FIXString
36-
_, err := field.Read([]TagValue{TagValue{Value: test.bytes}})
36+
err := field.Read(test.bytes)
3737

3838
if test.expectError && err == nil {
3939
t.Errorf("Expected error for %v", test.bytes)

fix_utc_timestamp.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@ const (
1515
utcTimestampNoMillisFormat = "20060102-15:04:05"
1616
)
1717

18-
func (f *FIXUTCTimestamp) Read(tv TagValues) (TagValues, error) {
19-
bytes := tv[0].Value
18+
func (f *FIXUTCTimestamp) Read(bytes []byte) error {
2019
var err error
2120
//with millisecs
2221
if f.Value, err = time.Parse(utcTimestampFormat, string(bytes)); err == nil {
23-
return tv[1:], nil
22+
return nil
2423
}
2524

2625
//w/o millisecs
2726
if f.Value, err = time.Parse(utcTimestampNoMillisFormat, string(bytes)); err != nil {
28-
return tv, err
27+
return err
2928
}
3029

31-
return tv[1:], nil
30+
return nil
3231
}
3332

3433
func (f FIXUTCTimestamp) Write() []byte {
@@ -38,7 +37,3 @@ func (f FIXUTCTimestamp) Write() []byte {
3837

3938
return []byte(f.Value.UTC().Format(utcTimestampFormat))
4039
}
41-
42-
func (f FIXUTCTimestamp) Clone() FieldValue {
43-
return &FIXUTCTimestamp{f.Value, f.NoMillis}
44-
}

parser.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (p *parser) ReadMessage() ([]byte, error) {
114114
return []byte{}, err
115115
}
116116

117-
msgBytes := p.buffer[:index]
117+
msgBytes := p.buffer[:index:index]
118118
p.buffer = p.buffer[index:]
119119

120120
return msgBytes, nil

parser_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ func TestParser_ReadMessage(t *testing.T) {
128128
t.Errorf("Expected %v got %v", tc.expectedBytes, string(msg))
129129
}
130130

131+
if len(tc.expectedBytes) != cap(msg) {
132+
t.Errorf("Expected capacity %v got %v", len(tc.expectedBytes), cap(msg))
133+
}
134+
131135
if cap(parser.buffer) != tc.expectedBufferCap {
132136
t.Errorf("Expected capacity %v got %v", tc.expectedBufferCap, cap(parser.buffer))
133137
}

repeating_group.go

+43-29
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,49 @@ import (
77
"strconv"
88
)
99

10-
type RepeatingGroupField struct {
11-
Tag
12-
FieldValue
10+
//GroupItem interface is used to construct repeating group templates
11+
type GroupItem interface {
12+
//Tag returns the tag identifying this GroupItem
13+
Tag() Tag
14+
15+
//Parameter to Read is TagValues. For most fields, only the first TagValue will be required.
16+
//The length of the slice extends from the TagValue mapped to the field to be read through the
17+
//following fields. This can be useful for GroupItems made up of repeating groups.
18+
//
19+
//The Read function returns the remaining TagValues not processed by the GroupItem. If there was a
20+
//problem reading the field, an error may be returned
21+
Read(TagValues) (TagValues, error)
1322
}
1423

15-
type GroupTemplate []RepeatingGroupField
24+
type protoGroupElement struct {
25+
tagMethod func() Tag
26+
}
27+
28+
func (t protoGroupElement) Tag() Tag { return t.tagMethod() }
29+
func (t protoGroupElement) Read(tv TagValues) (TagValues, error) {
30+
if tv[0].Tag == t.tagMethod() {
31+
return tv[1:], nil
32+
}
33+
34+
return tv, nil
35+
}
36+
37+
//GroupElement returns a GroupItem made up of a single field
38+
func GroupElement(tag Tag) GroupItem {
39+
t := struct{ protoGroupElement }{}
40+
t.tagMethod = func() Tag { return tag }
41+
return t
42+
}
43+
44+
type GroupTemplate []GroupItem
1645
type Group struct{ FieldMap }
1746

1847
type RepeatingGroup struct {
1948
GroupTemplate
2049
Groups []Group
2150
}
2251

52+
//Add appends a new group to the RepeatingGroup and returns the new Group
2353
func (f *RepeatingGroup) Add() Group {
2454
var g Group
2555
g.init(f.groupTagOrder())
@@ -41,12 +71,11 @@ func (f RepeatingGroup) Write() []byte {
4171
return bytes[:len(bytes)-1]
4272
}
4373

44-
func (f RepeatingGroup) findFieldInGroupTemplate(t Tag) (field RepeatingGroupField, ok bool) {
74+
func (f RepeatingGroup) findItemInGroupTemplate(t Tag) (item GroupItem, ok bool) {
4575
for _, templateField := range f.GroupTemplate {
46-
if t == templateField.Tag {
76+
if t == templateField.Tag() {
4777
ok = true
48-
field.Tag = templateField.Tag
49-
field.FieldValue = templateField.Clone()
78+
item = templateField
5079
break
5180
}
5281
}
@@ -57,7 +86,7 @@ func (f RepeatingGroup) findFieldInGroupTemplate(t Tag) (field RepeatingGroupFie
5786
func (f RepeatingGroup) groupTagOrder() tagOrder {
5887
tagMap := make(map[Tag]int)
5988
for i, f := range f.GroupTemplate {
60-
tagMap[f.Tag] = i
89+
tagMap[f.Tag()] = i
6190
}
6291

6392
return func(i, j Tag) bool {
@@ -77,7 +106,7 @@ func (f RepeatingGroup) groupTagOrder() tagOrder {
77106
}
78107

79108
func (f RepeatingGroup) isDelimiter(t Tag) bool {
80-
return t == f.GroupTemplate[0].Tag
109+
return t == f.GroupTemplate[0].Tag()
81110
}
82111

83112
func (f *RepeatingGroup) Read(tv TagValues) (TagValues, error) {
@@ -96,43 +125,28 @@ func (f *RepeatingGroup) Read(tv TagValues) (TagValues, error) {
96125
var group Group
97126
group.init(tagOrdering)
98127
for len(tv) > 0 {
99-
field, ok := f.findFieldInGroupTemplate(tv[0].Tag)
128+
field, ok := f.findItemInGroupTemplate(tv[0].Tag)
100129
if !ok {
101130
break
102131
}
103132

133+
tvRange := tv
104134
if tv, err = field.Read(tv); err != nil {
105135
return tv, err
106136
}
107137

108-
if f.isDelimiter(field.Tag) {
138+
if f.isDelimiter(field.Tag()) {
109139
group = Group{}
110140
group.init(tagOrdering)
111141

112142
f.Groups = append(f.Groups, group)
113143
}
114144

115-
group.SetField(field.Tag, field)
145+
group.tagLookup[tvRange[0].Tag] = tvRange
116146
}
117147

118148
if len(f.Groups) != expectedGroupSize {
119149
return tv, fmt.Errorf("Only found %v instead of %v expected groups, is template wrong?", len(f.Groups), expectedGroupSize)
120150
}
121151
return tv, err
122152
}
123-
124-
func (f RepeatingGroup) Clone() FieldValue {
125-
var clone RepeatingGroup
126-
clone.GroupTemplate = make(GroupTemplate, len(f.GroupTemplate))
127-
clone.Groups = make([]Group, len(f.Groups))
128-
129-
for i, field := range f.GroupTemplate {
130-
clone.GroupTemplate[i] = RepeatingGroupField{field.Tag, field.FieldValue.Clone()}
131-
}
132-
133-
for i, group := range f.Groups {
134-
clone.Groups[i].init(group.tagOrder)
135-
}
136-
137-
return &clone
138-
}

0 commit comments

Comments
 (0)