-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdiversion.go
113 lines (104 loc) · 2.13 KB
/
diversion.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
// Copyright 2011, Shelby Ramsey. All rights reserved.
// Copyright 2018, Eugen Biegler. All rights reserved.
// Use of this code is governed by a BSD license that can be
// found in the LICENSE.txt file.
package sipparser
// Imports from the go standard library
import (
"errors"
"fmt"
)
type parseDivStateFn func(d *Diversion) parseDivStateFn
type Diversion struct {
Error error
Val string
Name string
URI *URI
Counter string
Reason string
Privacy string
Params []*Param
}
func (r *Diversion) addParam(s string) {
p := getParam(s)
switch {
case p.Param == "reason":
r.Reason = p.Val
case p.Param == "privacy":
r.Privacy = p.Val
case p.Param == "counter":
r.Counter = p.Val
default:
switch {
case r.Params == nil:
r.Params = []*Param{p}
default:
r.Params = append(r.Params, p)
}
}
}
func (d *Diversion) parse() {
for state := parseDiv; state != nil; {
state = state(d)
}
}
func parseDiv(d *Diversion) parseDivStateFn {
if d.Error != nil {
return nil
}
d.Name, _ = getName(d.Val)
return parseDivGetUri
}
func parseDivGetUri(d *Diversion) parseDivStateFn {
left := 0
right := 0
for i := range d.Val {
if d.Val[i] == '<' && left == 0 {
left = i
}
if d.Val[i] == '>' && right == 0 {
right = i
}
}
if left < right {
d.URI = ParseURI(d.Val[left+1 : right])
if d.URI.Error != nil {
d.Error = fmt.Errorf("parseDivGetUri err: received err getting uri: %v", d.URI.Error)
return nil
}
return parseDivGetParams
}
d.Error = errors.New("parseDivGetUri err: could not locate bracks in uri")
return nil
}
func parseDivGetParams(d *Diversion) parseDivStateFn {
var pos []int
right := 0
for i := range d.Val {
if d.Val[i] == '>' && right == 0 {
right = i
}
}
if len(d.Val) > right+1 {
pos = make([]int, 0)
for i := range d.Val[right+1:] {
if d.Val[right+1:][i] == ';' {
pos = append(pos, i)
}
}
}
if pos == nil {
return nil
}
for i := range pos {
if len(pos)-1 == i {
if len(d.Val[right+1:])-1 > pos[i]+1 {
d.addParam(d.Val[right+1:][pos[i]+1:])
}
}
if len(pos)-1 > i {
d.addParam(d.Val[right+1:][pos[i]+1 : pos[i+1]])
}
}
return nil
}