tkcashgame_v4/pkg/entity/url.go

120 lines
2.2 KiB
Go

package entity
import (
"encoding/json"
"net/url"
"sort"
"strings"
)
type UrlValue map[string]string
func QueryToMap(query string) (result UrlValue) {
result = UrlValue{}
var value url.Values
fUrl, _ := url.Parse(query)
if fUrl.Scheme == "" {
q, _ := url.ParseQuery(query)
value = q
} else {
value = fUrl.Query()
}
for k, v := range value {
result[k] = v[0]
}
return result
}
func (value *UrlValue) Reader() *strings.Reader {
b, _ := json.Marshal(value)
return strings.NewReader(string(b))
}
func (value *UrlValue) Body() *strings.Reader {
return strings.NewReader(value.Encode())
}
func (value UrlValue) JsonString() string {
b, _ := json.Marshal(value)
return string(b)
}
func (value *UrlValue) Encode() string {
values := url.Values{}
for k, v := range *value {
values.Set(k, v)
}
return values.Encode()
}
func (value UrlValue) Query() string {
var buf strings.Builder
keys := make([]string, 0, len(value))
for k := range value {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := value[k]
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(k)
buf.WriteByte('=')
buf.WriteString(v)
}
return buf.String()
}
func UrlMergeQuery(rawUrl, query string) string {
q, _ := url.Parse(rawUrl)
rawKeys, rawValues := parseQuery(q.RawQuery)
keys, values := parseQuery(query)
for idx, k := range keys {
value := values[idx]
cidx := containsIndex(rawKeys, k)
if cidx == -1 {
rawKeys = append(rawKeys, k)
rawValues = append(rawValues, value)
} else {
rawValues[cidx] = value
}
}
rawQuery := []string{}
for idx, key := range rawKeys {
rawQuery = append(rawQuery, key+"="+rawValues[idx])
}
q.RawQuery = strings.Join(rawQuery, "&")
return q.String()
}
func parseQuery(query string) (keys, values []string) {
for query != "" {
key := query
if i := strings.IndexAny(key, "&;"); i >= 0 {
key, query = key[:i], key[i+1:]
} else {
query = ""
}
if key == "" {
continue
}
value := ""
if i := strings.Index(key, "="); i >= 0 {
key, value = key[:i], key[i+1:]
}
keys = append(keys, key)
values = append(values, value)
}
return
}
func containsIndex(list []string, elem string) int {
for idx, v := range list {
if elem == v {
return idx
}
}
return -1
}