@@ -7,19 +7,49 @@ import (
7
7
"strconv"
8
8
)
9
9
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 )
13
22
}
14
23
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
16
45
type Group struct { FieldMap }
17
46
18
47
type RepeatingGroup struct {
19
48
GroupTemplate
20
49
Groups []Group
21
50
}
22
51
52
+ //Add appends a new group to the RepeatingGroup and returns the new Group
23
53
func (f * RepeatingGroup ) Add () Group {
24
54
var g Group
25
55
g .init (f .groupTagOrder ())
@@ -41,12 +71,11 @@ func (f RepeatingGroup) Write() []byte {
41
71
return bytes [:len (bytes )- 1 ]
42
72
}
43
73
44
- func (f RepeatingGroup ) findFieldInGroupTemplate (t Tag ) (field RepeatingGroupField , ok bool ) {
74
+ func (f RepeatingGroup ) findItemInGroupTemplate (t Tag ) (item GroupItem , ok bool ) {
45
75
for _ , templateField := range f .GroupTemplate {
46
- if t == templateField .Tag {
76
+ if t == templateField .Tag () {
47
77
ok = true
48
- field .Tag = templateField .Tag
49
- field .FieldValue = templateField .Clone ()
78
+ item = templateField
50
79
break
51
80
}
52
81
}
@@ -57,7 +86,7 @@ func (f RepeatingGroup) findFieldInGroupTemplate(t Tag) (field RepeatingGroupFie
57
86
func (f RepeatingGroup ) groupTagOrder () tagOrder {
58
87
tagMap := make (map [Tag ]int )
59
88
for i , f := range f .GroupTemplate {
60
- tagMap [f .Tag ] = i
89
+ tagMap [f .Tag () ] = i
61
90
}
62
91
63
92
return func (i , j Tag ) bool {
@@ -77,7 +106,7 @@ func (f RepeatingGroup) groupTagOrder() tagOrder {
77
106
}
78
107
79
108
func (f RepeatingGroup ) isDelimiter (t Tag ) bool {
80
- return t == f .GroupTemplate [0 ].Tag
109
+ return t == f .GroupTemplate [0 ].Tag ()
81
110
}
82
111
83
112
func (f * RepeatingGroup ) Read (tv TagValues ) (TagValues , error ) {
@@ -96,43 +125,28 @@ func (f *RepeatingGroup) Read(tv TagValues) (TagValues, error) {
96
125
var group Group
97
126
group .init (tagOrdering )
98
127
for len (tv ) > 0 {
99
- field , ok := f .findFieldInGroupTemplate (tv [0 ].Tag )
128
+ field , ok := f .findItemInGroupTemplate (tv [0 ].Tag )
100
129
if ! ok {
101
130
break
102
131
}
103
132
133
+ tvRange := tv
104
134
if tv , err = field .Read (tv ); err != nil {
105
135
return tv , err
106
136
}
107
137
108
- if f .isDelimiter (field .Tag ) {
138
+ if f .isDelimiter (field .Tag () ) {
109
139
group = Group {}
110
140
group .init (tagOrdering )
111
141
112
142
f .Groups = append (f .Groups , group )
113
143
}
114
144
115
- group .SetField ( field .Tag , field )
145
+ group .tagLookup [ tvRange [ 0 ] .Tag ] = tvRange
116
146
}
117
147
118
148
if len (f .Groups ) != expectedGroupSize {
119
149
return tv , fmt .Errorf ("Only found %v instead of %v expected groups, is template wrong?" , len (f .Groups ), expectedGroupSize )
120
150
}
121
151
return tv , err
122
152
}
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