-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathsegment.go
131 lines (119 loc) · 3.62 KB
/
segment.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package gox12
import (
"bytes"
"fmt"
"strings"
)
type Segment struct {
SegmentId string
Composites []Composite
}
type Composite []string
type ElementValue struct {
X12Path X12Path
Value string
}
func NewSegment(line string, elementTerm byte, subelementTerm byte, repTerm byte) Segment {
fields := strings.Split(line, string(elementTerm))
segmentId := fields[0]
comps := make([]Composite, len(fields)-1)
for i, v := range fields[1:] {
c := strings.Split(v, string(subelementTerm))
comps[i] = c
}
return Segment{segmentId, comps}
}
// GetValue returns the string value of the simple element at the x12path
// Acts like golang maps, if not found, returns default value with found==false
// X12 Path indices are 1-based
func (s *Segment) GetValue(x12path string) (val string, found bool, err error) {
var xpath *X12Path
if xpath, err = ParseX12Path(x12path); err != nil {
return "", false, err
}
if xpath.SegmentId != "" && s.SegmentId != xpath.SegmentId {
return "", false, fmt.Errorf("Looking for Segment ID[%s], mine is [%s]", xpath.SegmentId, s.SegmentId)
}
if xpath.ElementIdx == 0 {
return "", false, fmt.Errorf("No element index specified for [%s]", x12path)
}
myEleIdx := xpath.ElementIdx - 1
var mySubeleIdx int
if xpath.SubelementIdx == 0 {
if myEleIdx < len(s.Composites) && len(s.Composites[myEleIdx]) > 1 {
return "", false, fmt.Errorf("This is a composite but no sub-element index was specified for [%s]", x12path)
}
mySubeleIdx = 0
} else {
mySubeleIdx = xpath.SubelementIdx - 1
}
if myEleIdx < len(s.Composites) {
if mySubeleIdx < len(s.Composites[myEleIdx]) {
return s.Composites[myEleIdx][mySubeleIdx], true, nil
}
}
return "", false, nil
}
func (s *Segment) SetValue(x12path, val string) (err error) {
var xpath *X12Path
if xpath, err = ParseX12Path(x12path); err != nil {
return err
}
if xpath.SegmentId != "" && s.SegmentId != xpath.SegmentId {
return fmt.Errorf("Looking for Segment ID[%s], mine is [%s]", xpath.SegmentId, s.SegmentId)
}
if xpath.ElementIdx == 0 {
return fmt.Errorf("No element index specified for [%s]", x12path)
}
myEleIdx := xpath.ElementIdx - 1
var mySubeleIdx int
if xpath.SubelementIdx == 0 {
if myEleIdx < len(s.Composites) && len(s.Composites[myEleIdx]) > 1 {
return fmt.Errorf("This is a composite but no sub-element index was specified for [%s]", x12path)
}
mySubeleIdx = 0
} else {
mySubeleIdx = xpath.SubelementIdx - 1
}
if myEleIdx < len(s.Composites) {
if mySubeleIdx < len(s.Composites[myEleIdx]) {
s.Composites[myEleIdx][mySubeleIdx] = val
}
}
return nil
}
func (s *Segment) GetAllValues() <-chan ElementValue {
ch := make(chan ElementValue)
go func() {
for i, comp := range s.Composites {
for j, elem := range comp {
x12path := X12Path{SegmentId: s.SegmentId, ElementIdx: i + 1, SubelementIdx: j + 1}
ev := ElementValue{x12path, elem}
//ch <- new(ElementValue{new(X12Path{SegmentId: s.SegmentId, ElementIdx: i+1, SubelementIdx: j+1}), elem})
ch <- ev
}
}
close(ch)
}()
return ch
}
// Default formatting
func (s *Segment) String() string {
return s.Format('*', ':', '^')
}
func (s *Segment) Format(elementTerm byte, subelementTerm byte, repTerm byte) string {
var buf bytes.Buffer
buf.WriteString(s.SegmentId)
for _, comp := range s.Composites {
buf.WriteByte(elementTerm)
buf.WriteString(formatComposite(comp, subelementTerm, repTerm))
}
return buf.String()
}
func formatComposite(c Composite, subelementTerm byte, repTerm byte) string {
return strings.Join(c, string(subelementTerm))
}
//func splitComposite(f2 string, term string) (ret []string) {
// ret = strings.Split(f2, term)
// return
//}