-
Notifications
You must be signed in to change notification settings - Fork 0
/
charset.go
127 lines (108 loc) · 2.5 KB
/
charset.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
package goaccepts
import (
"sort"
"strconv"
"strings"
)
// CharsetResult of the accepts header
type CharsetResult struct {
// Charset ...
Charset string
// Weight ...
Weight float64
// i ...
i int
}
func parseAcceptCharset(accept string) []CharsetResult {
res := []CharsetResult{}
accepts := strings.Split(accept, ",")
j := 0
for i := 0; i < len(accepts); i++ {
charset := parseCharset(strings.Trim(accepts[i], " "), i)
if charset != nil {
n := findC(res, charset.Charset)
if n == -1 {
res = append(res[:j], append([]CharsetResult{*charset}, res[j:]...)...)
j = j + 1
}
}
}
return res
}
func parseCharset(str string, i int) *CharsetResult {
if str == "*" {
return &CharsetResult{
Charset: str,
Weight: 100.0,
i: i,
}
}
weight := 1.0
params := strings.Split(str, ";")
if len(params) > 1 {
p := strings.Split(params[1], "=")
if strings.ToLower(p[0]) == "q" {
weight, _ = strconv.ParseFloat(p[1], 64)
}
}
charset := params[0]
return &CharsetResult{
Charset: charset,
Weight: weight,
i: i,
}
}
func parseCharsets(accept interface{}) []CharsetResult {
// no header = *
val := "*"
if accept != nil {
val = accept.(string)
}
accepts := parseAcceptCharset(val)
// sorted list of all languages
filteredList := filterC(accepts, func(spec CharsetResult) bool {
return spec.Weight > 0
})
sort.SliceStable(filteredList, func(i, j int) bool {
return filteredList[i].Weight > filteredList[j].Weight
})
return filteredList
}
// Charsets - Get the list of accepted charsets from an Accept-Charset header.
// https://tools.ietf.org/html/rfc2616#section-14.4
func Charsets(accept interface{}) []string {
charsets := parseCharsets(accept)
fullList := mapC(charsets, func(spec CharsetResult) string {
return spec.Charset
})
return fullList
}
// CharsetsDetails - Get the list of accepted charsets from an Accept-Charset header.
// https://tools.ietf.org/html/rfc2616#section-14.2
func CharsetsDetails(accept interface{}) []CharsetResult {
return parseCharsets(accept)
}
func filterC(vs []CharsetResult, f func(CharsetResult) bool) []CharsetResult {
vsf := make([]CharsetResult, 0)
for _, v := range vs {
if f(v) {
vsf = append(vsf, v)
}
}
return vsf
}
func mapC(vs []CharsetResult, f func(CharsetResult) string) []string {
vsf := make([]string, 0)
for _, v := range vs {
vsf = append(vsf, f(v))
}
return vsf
}
func findC(a []CharsetResult, x string) int {
for i, n := range a {
if x == n.Charset {
return i
}
}
return -1
}