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 132 133 134 135 136 137 138 139 140 141 142 143 144
|
package segment
import (
"bytes"
"fmt"
"reflect"
"strings"
"github.com/mitch000001/go-hbci/element"
)
const (
senderBank = "I"
senderUser = "K"
senderBoth = "K/I"
)
type Segment interface {
Header() *element.SegmentHeader
SetPosition(func() int)
String() string
}
type ClientSegment interface {
Segment
Marshaler
}
type BankSegment interface {
Segment
Unmarshaler
}
type CommonSegment interface {
Segment
Marshaler
Unmarshaler
}
type basicSegment interface {
Version() int
ID() string
referencedId() string
sender() string
elements() []element.DataElement
}
type Marshaler interface {
MarshalHBCI() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalHBCI([]byte) error
}
func SegmentFromHeaderBytes(headerBytes []byte, seg basicSegment) (*segment, error) {
header := &element.SegmentHeader{}
err := header.UnmarshalHBCI(headerBytes)
if err != nil {
return nil, fmt.Errorf("Error while unmarshaling segment header: %v", err)
}
return NewBasicSegmentWithHeader(header, seg), nil
}
func NewReferencingBasicSegment(position int, ref int, seg basicSegment) *segment {
header := element.NewReferencingSegmentHeader(seg.ID(), position, seg.Version(), ref)
return NewBasicSegmentWithHeader(header, seg)
}
func NewBasicSegment(position int, seg basicSegment) *segment {
header := element.NewSegmentHeader(seg.ID(), position, seg.Version())
return NewBasicSegmentWithHeader(header, seg)
}
func NewBasicSegmentWithHeader(header *element.SegmentHeader, seg basicSegment) *segment {
return &segment{header: header, segment: seg}
}
type segment struct {
segment basicSegment
header *element.SegmentHeader
}
func (s *segment) String() string {
elementStrings := make([]string, len(s.segment.elements())+1)
elementStrings[0] = s.header.String()
for i, de := range s.segment.elements() {
val := reflect.ValueOf(de)
if val.IsValid() && !val.IsNil() {
elementStrings[i+1] = de.String()
}
}
return strings.Join(elementStrings, "+") + "'"
}
func (s *segment) MarshalHBCI() ([]byte, error) {
elementBytes := make([][]byte, len(s.segment.elements())+1)
headerBytes, err := s.header.MarshalHBCI()
if err != nil {
return nil, err
}
elementBytes[0] = headerBytes
for i, de := range s.segment.elements() {
val := reflect.ValueOf(de)
if val.IsValid() && !val.IsNil() {
marshaled, err := de.MarshalHBCI()
if err != nil {
return nil, err
}
elementBytes[i+1] = marshaled
}
}
marshaled := bytes.Join(elementBytes, []byte("+"))
marshaled = bytes.TrimRight(marshaled, "+")
marshaled = append(marshaled, '\'')
return marshaled, nil
}
func (s *segment) DataElements() []element.DataElement {
var dataElements []element.DataElement
dataElements = append(dataElements, s.header)
dataElements = append(dataElements, s.segment.elements()...)
return dataElements
}
func (s *segment) Header() *element.SegmentHeader {
return s.header
}
func (s *segment) ID() string {
return s.header.ID.Val()
}
func (s *segment) Version() int {
return s.header.Version.Val()
}
func (s *segment) SetPosition(positionFn func() int) {
s.header.SetPosition(positionFn())
}
func (s *segment) SetReference(ref int) {
s.header.SetReference(ref)
}
|