File: segment.go

package info (click to toggle)
golang-github-mitch000001-go-hbci 0.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 2,468 kB
  • sloc: java: 1,092; makefile: 5
file content (144 lines) | stat: -rw-r--r-- 3,208 bytes parent folder | download
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)
}