-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathaddress.go
108 lines (90 loc) · 1.65 KB
/
address.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
package aprs
import (
"errors"
"fmt"
"strconv"
"strings"
)
var (
ErrAddressInvalid = errors.New(`aprs: invalid address`)
)
type Address struct {
Call string
SSID int
Repeated bool
}
func (a Address) EqualTo(b *Address) bool {
return b != nil && a.Call == b.Call && a.SSID == b.SSID
}
func (a Address) String() string {
var r = ""
if a.Repeated {
r = "*"
}
if a.SSID == 0 {
return a.Call + r
}
return fmt.Sprintf("%s-%d%s", a.Call, a.SSID, r)
}
func (a Address) Secret() int16 {
var h = int16(0x73e2)
var c = a.Call
if len(c)%2 > 0 {
c += "\x00"
}
for i := 0; i < len(c); i += 2 {
h ^= int16(c[i]) << 8
h ^= int16(c[i+1])
}
return h & 0x7fff
}
func ParseAddress(s string) (*Address, error) {
r := strings.HasSuffix(s, "*")
if r {
s = s[:len(s)-1]
}
p := strings.Split(strings.ToUpper(s), "-")
if len(p) == 0 || len(p) > 2 {
return nil, ErrAddressInvalid
}
a := &Address{Call: p[0], Repeated: r}
if len(p) == 2 {
var i int64
i, err := strconv.ParseInt(p[1], 10, 32)
if err != nil || i > 16 {
return nil, ErrAddressInvalid
}
a.SSID = int(i)
}
return a, nil
}
func MustParseAddress(s string) *Address {
a, err := ParseAddress(s)
if err != nil {
panic(err)
}
return a
}
type Path []*Address
func (p Path) String() string {
var s = make([]string, len(p))
for i, a := range p {
s[i] = a.String()
}
return strings.Join(s, ",")
}
func ParsePath(p string) (Path, error) {
ss := strings.Split(p, ",")
if len(ss) == 0 {
return nil, nil
}
var err error
as := make(Path, len(ss))
for i, s := range ss {
as[i], err = ParseAddress(s)
if err != nil {
return nil, err
}
}
return as, nil
}