github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/utils.go (about) 1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 package gin 6 7 import ( 8 "encoding/xml" 9 "github.com/hellobchain/newcryptosm/http" 10 "os" 11 "path" 12 "reflect" 13 "runtime" 14 "strings" 15 ) 16 17 // BindKey indicates a default bind key. 18 const BindKey = "_gin-gonic/gin/bindkey" 19 20 // Bind is a helper function for given interface object and returns a Gin middleware. 21 func Bind(val interface{}) HandlerFunc { 22 value := reflect.ValueOf(val) 23 if value.Kind() == reflect.Ptr { 24 panic(`Bind struct can not be a pointer. Example: 25 Use: gin.Bind(Struct{}) instead of gin.Bind(&Struct{}) 26 `) 27 } 28 typ := value.Type() 29 30 return func(c *Context) { 31 obj := reflect.New(typ).Interface() 32 if c.Bind(obj) == nil { 33 c.Set(BindKey, obj) 34 } 35 } 36 } 37 38 // WrapF is a helper function for wrapping http.HandlerFunc and returns a Gin middleware. 39 func WrapF(f http.HandlerFunc) HandlerFunc { 40 return func(c *Context) { 41 f(c.Writer, c.Request) 42 } 43 } 44 45 // WrapH is a helper function for wrapping http.Handler and returns a Gin middleware. 46 func WrapH(h http.Handler) HandlerFunc { 47 return func(c *Context) { 48 h.ServeHTTP(c.Writer, c.Request) 49 } 50 } 51 52 // H is a shortcut for map[string]interface{} 53 type H map[string]interface{} 54 55 // MarshalXML allows type H to be used with xml.Marshal. 56 func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 57 start.Name = xml.Name{ 58 Space: "", 59 Local: "map", 60 } 61 if err := e.EncodeToken(start); err != nil { 62 return err 63 } 64 for key, value := range h { 65 elem := xml.StartElement{ 66 Name: xml.Name{Space: "", Local: key}, 67 Attr: []xml.Attr{}, 68 } 69 if err := e.EncodeElement(value, elem); err != nil { 70 return err 71 } 72 } 73 74 return e.EncodeToken(xml.EndElement{Name: start.Name}) 75 } 76 77 func assert1(guard bool, text string) { 78 if !guard { 79 panic(text) 80 } 81 } 82 83 func filterFlags(content string) string { 84 for i, char := range content { 85 if char == ' ' || char == ';' { 86 return content[:i] 87 } 88 } 89 return content 90 } 91 92 func chooseData(custom, wildcard interface{}) interface{} { 93 if custom != nil { 94 return custom 95 } 96 if wildcard != nil { 97 return wildcard 98 } 99 panic("negotiation config is invalid") 100 } 101 102 func parseAccept(acceptHeader string) []string { 103 parts := strings.Split(acceptHeader, ",") 104 out := make([]string, 0, len(parts)) 105 for _, part := range parts { 106 if i := strings.IndexByte(part, ';'); i > 0 { 107 part = part[:i] 108 } 109 if part = strings.TrimSpace(part); part != "" { 110 out = append(out, part) 111 } 112 } 113 return out 114 } 115 116 func lastChar(str string) uint8 { 117 if str == "" { 118 panic("The length of the string can't be 0") 119 } 120 return str[len(str)-1] 121 } 122 123 func nameOfFunction(f interface{}) string { 124 return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() 125 } 126 127 func joinPaths(absolutePath, relativePath string) string { 128 if relativePath == "" { 129 return absolutePath 130 } 131 132 finalPath := path.Join(absolutePath, relativePath) 133 if lastChar(relativePath) == '/' && lastChar(finalPath) != '/' { 134 return finalPath + "/" 135 } 136 return finalPath 137 } 138 139 func resolveAddress(addr []string) string { 140 switch len(addr) { 141 case 0: 142 if port := os.Getenv("PORT"); port != "" { 143 debugPrint("Environment variable PORT=\"%s\"", port) 144 return ":" + port 145 } 146 debugPrint("Environment variable PORT is undefined. Using port :8080 by default") 147 return ":8080" 148 case 1: 149 return addr[0] 150 default: 151 panic("too many parameters") 152 } 153 }