@@ -6,10 +6,13 @@ import (
66 "time"
77)
88
9- //FieldMap is a collection of fix fields that make up a fix message.
10- type FieldMap struct {
11- tagLookup map [Tag ]TagValues
12- tagOrder
9+ //tagValues stores a slice of TagValues
10+ type tagValues struct {
11+ tvs []TagValue
12+ }
13+
14+ func (f * tagValues ) Tag () Tag {
15+ return f .tvs [0 ].tag
1316}
1417
1518// tagOrder true if tag i should occur before tag j
@@ -24,6 +27,12 @@ func (t tagSort) Len() int { return len(t.tags) }
2427func (t tagSort ) Swap (i , j int ) { t .tags [i ], t .tags [j ] = t .tags [j ], t .tags [i ] }
2528func (t tagSort ) Less (i , j int ) bool { return t .compare (t .tags [i ], t .tags [j ]) }
2629
30+ //FieldMap is a collection of fix fields that make up a fix message.
31+ type FieldMap struct {
32+ tagLookup map [Tag ]* tagValues
33+ tagSort
34+ }
35+
2736// ascending tags
2837func normalFieldOrder (i , j Tag ) bool { return i < j }
2938
@@ -32,8 +41,8 @@ func (m *FieldMap) init() {
3241}
3342
3443func (m * FieldMap ) initWithOrdering (ordering tagOrder ) {
35- m .tagLookup = make (map [Tag ]TagValues )
36- m .tagOrder = ordering
44+ m .tagLookup = make (map [Tag ]* tagValues )
45+ m .compare = ordering
3746}
3847
3948//Tags returns all of the Field Tags in this FieldMap
@@ -64,7 +73,7 @@ func (m FieldMap) GetField(tag Tag, parser FieldValueReader) MessageRejectError
6473 return ConditionallyRequiredFieldMissing (tag )
6574 }
6675
67- if err := parser .Read (tagValues [0 ].value ); err != nil {
76+ if err := parser .Read (tagValues . tvs [0 ].value ); err != nil {
6877 return IncorrectDataFormatForValue (tag )
6978 }
7079
@@ -78,7 +87,7 @@ func (m FieldMap) GetBytes(tag Tag) ([]byte, MessageRejectError) {
7887 return nil , ConditionallyRequiredFieldMissing (tag )
7988 }
8089
81- return tagValues [0 ].value , nil
90+ return tagValues . tvs [0 ].value , nil
8291}
8392
8493//GetBool is a GetField wrapper for bool fields
@@ -136,7 +145,7 @@ func (m FieldMap) GetGroup(parser FieldGroupReader) MessageRejectError {
136145 return ConditionallyRequiredFieldMissing (parser .Tag ())
137146 }
138147
139- if _ , err := parser .Read (tagValues ); err != nil {
148+ if _ , err := parser .Read (tagValues . tvs ); err != nil {
140149 if msgRejErr , ok := err .(MessageRejectError ); ok {
141150 return msgRejErr
142151 }
@@ -147,65 +156,80 @@ func (m FieldMap) GetGroup(parser FieldGroupReader) MessageRejectError {
147156}
148157
149158//SetField sets the field with Tag tag
150- func (m FieldMap ) SetField (tag Tag , field FieldValueWriter ) FieldMap {
151- tValues := make ( TagValues , 1 )
152- tValues [ 0 ]. init ( tag , field . Write () )
153- m . tagLookup [ tag ] = tValues
159+ func (m * FieldMap ) SetField (tag Tag , field FieldValueWriter ) * FieldMap {
160+ tValues := m . getOrCreate ( tag )
161+ tValues . tvs = make ([] TagValue , 1 )
162+ tValues . tvs [ 0 ]. init ( tag , field . Write ())
154163 return m
155164}
156165
157166//SetBool is a SetField wrapper for bool fields
158- func (m FieldMap ) SetBool (tag Tag , value bool ) FieldMap {
167+ func (m * FieldMap ) SetBool (tag Tag , value bool ) * FieldMap {
159168 return m .SetField (tag , FIXBoolean (value ))
160169}
161170
162171//SetInt is a SetField wrapper for int fields
163- func (m FieldMap ) SetInt (tag Tag , value int ) FieldMap {
172+ func (m * FieldMap ) SetInt (tag Tag , value int ) * FieldMap {
164173 return m .SetField (tag , FIXInt (value ))
165174}
166175
167176//SetString is a SetField wrapper for string fields
168- func (m FieldMap ) SetString (tag Tag , value string ) FieldMap {
177+ func (m * FieldMap ) SetString (tag Tag , value string ) * FieldMap {
169178 return m .SetField (tag , FIXString (value ))
170179}
171180
172181//Clear purges all fields from field map
173182func (m * FieldMap ) Clear () {
183+ m .tags = m .tags [0 :0 ]
174184 for k := range m .tagLookup {
175185 delete (m .tagLookup , k )
176186 }
177187}
178188
189+ func (m * FieldMap ) add (f * tagValues ) {
190+ if _ , ok := m .tagLookup [f .Tag ()]; ! ok {
191+ m .tags = append (m .tags , f .Tag ())
192+ }
193+
194+ m .tagLookup [f .Tag ()] = f
195+ }
196+
197+ func (m * FieldMap ) getOrCreate (tag Tag ) * tagValues {
198+ if f , ok := m .tagLookup [tag ]; ok {
199+ return f
200+ }
201+
202+ f := new (tagValues )
203+ m .tagLookup [tag ] = f
204+ m .tags = append (m .tags , tag )
205+ return f
206+ }
207+
179208//Set is a setter for fields
180- func (m FieldMap ) Set (field FieldWriter ) FieldMap {
181- tValues := make (TagValues , 1 )
182- tValues [0 ].init (field .Tag (), field .Write ())
209+ func (m * FieldMap ) Set (field FieldWriter ) * FieldMap {
210+ tValues := m .getOrCreate (field .Tag ())
211+ tValues .tvs = make ([]TagValue , 1 )
212+ tValues .tvs [0 ].init (field .Tag (), field .Write ())
183213 m .tagLookup [field .Tag ()] = tValues
184214 return m
185215}
186216
187217//SetGroup is a setter specific to group fields
188- func (m FieldMap ) SetGroup (field FieldGroupWriter ) FieldMap {
189- m .tagLookup [field .Tag ()] = field .Write ()
218+ func (m * FieldMap ) SetGroup (field FieldGroupWriter ) * FieldMap {
219+ f := m .getOrCreate (field .Tag ())
220+ f .tvs = field .Write ()
190221 return m
191222}
192223
193- func (m FieldMap ) sortedTags () []Tag {
194- sortedTags := make ([]Tag , len (m .tagLookup ))
195- for tag := range m .tagLookup {
196- sortedTags = append (sortedTags , tag )
197- }
198-
199- sort .Sort (tagSort {sortedTags , m .tagOrder })
200- return sortedTags
224+ func (m * FieldMap ) sortedTags () []Tag {
225+ sort .Sort (m )
226+ return m .tags
201227}
202228
203229func (m FieldMap ) write (buffer * bytes.Buffer ) {
204- tags := m .sortedTags ()
205-
206- for _ , tag := range tags {
230+ for _ , tag := range m .sortedTags () {
207231 if fields , ok := m .tagLookup [tag ]; ok {
208- for _ , tv := range fields {
232+ for _ , tv := range fields . tvs {
209233 buffer .Write (tv .bytes )
210234 }
211235 }
@@ -215,7 +239,7 @@ func (m FieldMap) write(buffer *bytes.Buffer) {
215239func (m FieldMap ) total () int {
216240 total := 0
217241 for _ , fields := range m .tagLookup {
218- for _ , tv := range fields {
242+ for _ , tv := range fields . tvs {
219243 switch tv .tag {
220244 case tagCheckSum : //tag does not contribute to total
221245 default :
@@ -230,7 +254,7 @@ func (m FieldMap) total() int {
230254func (m FieldMap ) length () int {
231255 length := 0
232256 for _ , fields := range m .tagLookup {
233- for _ , tv := range fields {
257+ for _ , tv := range fields . tvs {
234258 switch tv .tag {
235259 case tagBeginString , tagBodyLength , tagCheckSum : //tags do not contribute to length
236260 default :
0 commit comments