/
geolocation.go
139 lines (118 loc) · 3.19 KB
/
geolocation.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
128
129
130
131
132
133
134
135
136
137
138
139
package types
import (
"bytes"
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
)
// for convenience (calculate once only)
var (
allGeoEnumRegionsList []Geolocation
allGeoEnumRegions int32
)
// initialize convenience vars at start-up
func init() {
var geoAmount int
for _, geoloc := range Geolocation_value {
if geoloc != int32(Geolocation_GLS) && geoloc != int32(Geolocation_GL) {
geoAmount += 1
allGeoEnumRegions |= geoloc
}
}
for i := 0; i < geoAmount; i++ {
allGeoEnumRegionsList = append(allGeoEnumRegionsList, Geolocation(1<<i))
}
}
// IsValidProviderGeoEnum tests the validity of a given geolocation
func IsValidProviderGeoEnum(geoloc int32) bool {
if geoloc == int32(Geolocation_GL) {
return true
}
return geoloc != int32(Geolocation_GLS) && (geoloc & ^allGeoEnumRegions) == 0
}
// IsValidProviderGeoEnum tests the validity of a given geolocation
func IsValidGeoEnum(geoloc int32) bool {
if geoloc == int32(Geolocation_GL) {
return true
}
return (geoloc & ^allGeoEnumRegions) == 0
}
// IsGeoEnumSingleBit returns true if at most one bit is set
func IsGeoEnumSingleBit(geoloc int32) bool {
return (geoloc & (geoloc - 1)) == 0
}
// ParseGeoEnum parses a string into GeoEnum bitmask.
// The string may be a number or a comma-separated geolocations codes.
func ParseGeoEnum(arg string) (geoloc int32, err error) {
geoloc64, err := strconv.ParseUint(arg, 10, 32)
geoloc = int32(geoloc64)
if err == nil {
if !IsValidProviderGeoEnum(geoloc) {
return 0, fmt.Errorf("invalid geolocation value: %s", arg)
}
return geoloc, nil
}
split := strings.Split(arg, ",")
for _, s := range split {
val, ok := Geolocation_value[s]
if !ok {
return 0, fmt.Errorf("invalid geolocation code: %s", s)
}
geoloc |= val
}
return geoloc, nil
}
func GetAllGeolocations() []Geolocation {
return allGeoEnumRegionsList
}
func GetGeolocationsFromUint(geoloc int32) []Geolocation {
geoList := []Geolocation{}
allGeos := GetAllGeolocations()
if geoloc == int32(Geolocation_GL) {
return allGeoEnumRegionsList
} else {
for i := 0; i < len(allGeos); i++ {
if (geoloc>>i)&1 == 1 {
geoList = append(geoList, Geolocation(1<<i))
}
}
}
return geoList
}
// allows unmarshaling parser func
func (g Geolocation) MarshalJSON() ([]byte, error) {
buffer := bytes.NewBufferString(`"`)
buffer.WriteString(Geolocation_name[int32(g)])
buffer.WriteString(`"`)
return buffer.Bytes(), nil
}
// UnmarshalJSON unmashals a quoted json string to the enum value
func (g *Geolocation) UnmarshalJSON(b []byte) error {
var j string
err := json.Unmarshal(b, &j)
if err != nil {
return err
}
// Note that if the string cannot be found then it will be set to the zero value, 'Created' in this case.
*g = Geolocation(Geolocation_value[j])
return nil
}
func PrintGeolocations() string {
var geos []int32
for _, geoInt := range Geolocation_value {
geos = append(geos, geoInt)
}
sort.SliceStable(geos, func(i, j int) bool {
return geos[i] < geos[j]
})
var geosStr []string
for _, geoInt := range geos {
if geoInt == int32(Geolocation_GLS) {
continue
}
geosStr = append(geosStr, Geolocation_name[geoInt]+": 0x"+strconv.FormatInt(int64(geoInt), 16))
}
return strings.Join(geosStr, ", ")
}