Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions field.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,22 @@ type Field interface {
FieldWriter
FieldValueReader
}

//FieldGroupWriter is an interface for writing a FieldGroup
type FieldGroupWriter interface {
Tag() Tag
Write() TagValues
}

//FieldGroupReader is an interface for reading a FieldGroup
type FieldGroupReader interface {
Tag() Tag
Read(TagValues) (TagValues, error)
}

//FieldGroup is the interface implemented by all typed Groups in a Message
type FieldGroup interface {
Tag() Tag
Write() TagValues
Read(TagValues) (TagValues, error)
}
30 changes: 15 additions & 15 deletions field_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

//FieldMap is a collection of fix fields that make up a fix message.
type FieldMap struct {
tagLookup map[Tag][]tagValue
tagLookup map[Tag]TagValues
tagOrder
}

Expand Down Expand Up @@ -68,7 +68,7 @@ func trailerFieldOrder(i, j Tag) bool {
}

func (m *FieldMap) init(ordering tagOrder) {
m.tagLookup = make(map[Tag][]tagValue)
m.tagLookup = make(map[Tag]TagValues)
m.tagOrder = ordering
}

Expand Down Expand Up @@ -100,7 +100,7 @@ func (m FieldMap) GetField(tag Tag, parser FieldValueReader) MessageRejectError
return ConditionallyRequiredFieldMissing(tag)
}

if err := parser.Read(tagValues[0].Value); err != nil {
if err := parser.Read(tagValues[0].value); err != nil {
return IncorrectDataFormatForValue(tag)
}

Expand All @@ -126,46 +126,46 @@ func (m FieldMap) GetString(tag Tag) (string, MessageRejectError) {
}

//GetGroup is a Get function specific to Group Fields.
func (m FieldMap) GetGroup(parser *RepeatingGroup) MessageRejectError {
tagValues, ok := m.tagLookup[parser.Tag]
func (m FieldMap) GetGroup(parser FieldGroupReader) MessageRejectError {
tagValues, ok := m.tagLookup[parser.Tag()]
if !ok {
return ConditionallyRequiredFieldMissing(parser.Tag)
return ConditionallyRequiredFieldMissing(parser.Tag())
}

if _, err := parser.read(tagValues); err != nil {
if _, err := parser.Read(tagValues); err != nil {
if msgRejErr, ok := err.(MessageRejectError); ok {
return msgRejErr
}
return IncorrectDataFormatForValue(parser.Tag)
return IncorrectDataFormatForValue(parser.Tag())
}

return nil
}

//SetField sets the field with Tag tag
func (m FieldMap) SetField(tag Tag, field FieldValueWriter) FieldMap {
tValues := make([]tagValue, 1)
tValues := make(TagValues, 1)
tValues[0].init(tag, field.Write())
m.tagLookup[tag] = tValues
return m
}

//Clear purges all fields from field map
func (m *FieldMap) Clear() {
m.tagLookup = make(map[Tag][]tagValue)
m.tagLookup = make(map[Tag]TagValues)
}

//Set is a setter for fields
func (m FieldMap) Set(field FieldWriter) FieldMap {
tValues := make([]tagValue, 1)
tValues := make(TagValues, 1)
tValues[0].init(field.Tag(), field.Write())
m.tagLookup[field.Tag()] = tValues
return m
}

//SetGroup is a setter specific to group fields
func (m FieldMap) SetGroup(field RepeatingGroup) FieldMap {
m.tagLookup[field.Tag] = field.tagValues()
func (m FieldMap) SetGroup(field FieldGroupWriter) FieldMap {
m.tagLookup[field.Tag()] = field.Write()
return m
}

Expand Down Expand Up @@ -195,7 +195,7 @@ func (m FieldMap) total() int {
total := 0
for _, fields := range m.tagLookup {
for _, tv := range fields {
switch tv.Tag {
switch tv.tag {
case tagCheckSum: //tag does not contribute to total
default:
total += tv.total()
Expand All @@ -210,7 +210,7 @@ func (m FieldMap) length() int {
length := 0
for _, fields := range m.tagLookup {
for _, tv := range fields {
switch tv.Tag {
switch tv.tag {
case tagBeginString, tagBodyLength, tagCheckSum: //tags do not contribute to length
default:
length += tv.length()
Expand Down
2 changes: 1 addition & 1 deletion marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (e encoder) encodeValue(fixTag Tag, v reflect.Value, omitEmpty bool, defaul
panic("repeating group must be a slice of type struct")
}

repeatingGroup := RepeatingGroup{Tag: fixTag, GroupTemplate: buildGroupTemplate(elem)}
repeatingGroup := NewRepeatingGroup(fixTag, buildGroupTemplate(elem))

for i := 0; i < v.Len(); i++ {
group := repeatingGroup.Add()
Expand Down
8 changes: 4 additions & 4 deletions marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,14 @@ func TestMarshal_RepeatingGroups(t *testing.T) {
continue
}

groupField := quickfix.RepeatingGroup{Tag: test.groupTag, GroupTemplate: test.template}
if err := fixMsg.Body.GetGroup(&groupField); err != nil {
groupField := quickfix.NewRepeatingGroup(test.groupTag, test.template)
if err := fixMsg.Body.GetGroup(groupField); err != nil {
t.Error("Unexpected error", err)
continue
}

if len(groupField.Groups) != test.expectedGroupSize {
t.Errorf("Expected group %v to have size %v, got %v", test.groupTag, test.expectedGroupSize, len(groupField.Groups))
if groupField.Len() != test.expectedGroupSize {
t.Errorf("Expected group %v to have size %v, got %v", test.groupTag, test.expectedGroupSize, groupField.Len())
}
}
}
Expand Down
37 changes: 20 additions & 17 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Message struct {
bodyBytes []byte

//field bytes as they appear in the raw message
fields []tagValue
fields TagValues
}

//Marshal marshals the message itself
Expand Down Expand Up @@ -61,7 +61,7 @@ func ParseMessage(rawMessage []byte) (Message, error) {
fieldCount++
}
}
msg.fields = make([]tagValue, fieldCount)
msg.fields = make(TagValues, fieldCount)

fieldIndex := 0
var err error
Expand All @@ -71,23 +71,23 @@ func ParseMessage(rawMessage []byte) (Message, error) {
return msg, err
}

msg.Header.tagLookup[msg.fields[fieldIndex].Tag] = msg.fields[fieldIndex : fieldIndex+1]
msg.Header.tagLookup[msg.fields[fieldIndex].tag] = msg.fields[fieldIndex : fieldIndex+1]
fieldIndex++

parsedFieldBytes := &msg.fields[fieldIndex]
if rawMessage, err = extractSpecificField(parsedFieldBytes, tagBodyLength, rawMessage); err != nil {
return msg, err
}

msg.Header.tagLookup[parsedFieldBytes.Tag] = msg.fields[fieldIndex : fieldIndex+1]
msg.Header.tagLookup[parsedFieldBytes.tag] = msg.fields[fieldIndex : fieldIndex+1]
fieldIndex++

parsedFieldBytes = &msg.fields[fieldIndex]
if rawMessage, err = extractSpecificField(parsedFieldBytes, tagMsgType, rawMessage); err != nil {
return msg, err
}

msg.Header.tagLookup[parsedFieldBytes.Tag] = msg.fields[fieldIndex : fieldIndex+1]
msg.Header.tagLookup[parsedFieldBytes.tag] = msg.fields[fieldIndex : fieldIndex+1]
fieldIndex++

trailerBytes := []byte{}
Expand All @@ -100,16 +100,16 @@ func ParseMessage(rawMessage []byte) (Message, error) {
}

switch {
case parsedFieldBytes.Tag.IsHeader():
msg.Header.tagLookup[parsedFieldBytes.Tag] = msg.fields[fieldIndex : fieldIndex+1]
case parsedFieldBytes.Tag.IsTrailer():
msg.Trailer.tagLookup[parsedFieldBytes.Tag] = msg.fields[fieldIndex : fieldIndex+1]
case parsedFieldBytes.tag.IsHeader():
msg.Header.tagLookup[parsedFieldBytes.tag] = msg.fields[fieldIndex : fieldIndex+1]
case parsedFieldBytes.tag.IsTrailer():
msg.Trailer.tagLookup[parsedFieldBytes.tag] = msg.fields[fieldIndex : fieldIndex+1]
default:
foundBody = true
trailerBytes = rawMessage
msg.Body.tagLookup[parsedFieldBytes.Tag] = msg.fields[fieldIndex : fieldIndex+1]
msg.Body.tagLookup[parsedFieldBytes.tag] = msg.fields[fieldIndex : fieldIndex+1]
}
if parsedFieldBytes.Tag == tagCheckSum {
if parsedFieldBytes.tag == tagCheckSum {
break
}

Expand All @@ -127,15 +127,18 @@ func ParseMessage(rawMessage []byte) (Message, error) {

length := 0
for _, field := range msg.fields {
switch field.Tag {
switch field.tag {
case tagBeginString, tagBodyLength, tagCheckSum: //tags do not contribute to length
default:
length += field.length()
}
}

var bodyLength FIXInt
msg.Header.GetField(tagBodyLength, &bodyLength)
if err := msg.Header.GetField(tagBodyLength, &bodyLength); err != nil {
return msg, parseError{OrigError: err.Error()}
}

if length != int(bodyLength) {
return msg, parseError{OrigError: fmt.Sprintf("Incorrect Message Length, expected %d, got %d", bodyLength, length)}
}
Expand Down Expand Up @@ -181,20 +184,20 @@ func (m Message) reverseRoute() Message {
return reverseMsg
}

func extractSpecificField(field *tagValue, expectedTag Tag, buffer []byte) (remBuffer []byte, err error) {
func extractSpecificField(field *TagValue, expectedTag Tag, buffer []byte) (remBuffer []byte, err error) {
remBuffer, err = extractField(field, buffer)
switch {
case err != nil:
return
case field.Tag != expectedTag:
err = parseError{OrigError: fmt.Sprintf("extractSpecificField: Fields out of order, expected %d, got %d", expectedTag, field.Tag)}
case field.tag != expectedTag:
err = parseError{OrigError: fmt.Sprintf("extractSpecificField: Fields out of order, expected %d, got %d", expectedTag, field.tag)}
return
}

return
}

func extractField(parsedFieldBytes *tagValue, buffer []byte) (remBytes []byte, err error) {
func extractField(parsedFieldBytes *TagValue, buffer []byte) (remBytes []byte, err error) {
endIndex := bytes.IndexByte(buffer, '\001')
if endIndex == -1 {
err = parseError{OrigError: "extractField: No Trailing Delim in " + string(buffer)}
Expand Down
Loading