github.com/iosif02/goja_nodejs@v1.0.1/url/escape.go (about) 1 package url 2 3 import "strings" 4 5 var tblEscapeURLQuery = [128]byte{ 6 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 10 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 14 } 15 16 var tblEscapeURLQueryParam = [128]byte{ 17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 20 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 21 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 23 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 24 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 25 } 26 27 // The code below is mostly borrowed from the standard Go url package 28 29 const upperhex = "0123456789ABCDEF" 30 31 func ishex(c byte) bool { 32 switch { 33 case '0' <= c && c <= '9': 34 return true 35 case 'a' <= c && c <= 'f': 36 return true 37 case 'A' <= c && c <= 'F': 38 return true 39 } 40 return false 41 } 42 43 func unhex(c byte) byte { 44 switch { 45 case '0' <= c && c <= '9': 46 return c - '0' 47 case 'a' <= c && c <= 'f': 48 return c - 'a' + 10 49 case 'A' <= c && c <= 'F': 50 return c - 'A' + 10 51 } 52 return 0 53 } 54 55 func escape(s string, table *[128]byte, spaceToPlus bool) string { 56 spaceCount, hexCount := 0, 0 57 for i := 0; i < len(s); i++ { 58 c := s[i] 59 if c > 127 || table[c] == 0 { 60 if c == ' ' && spaceToPlus { 61 spaceCount++ 62 } else { 63 hexCount++ 64 } 65 } 66 } 67 68 if spaceCount == 0 && hexCount == 0 { 69 return s 70 } 71 72 var sb strings.Builder 73 hexBuf := [3]byte{'%', 0, 0} 74 75 sb.Grow(len(s) + 2*hexCount) 76 77 for i := 0; i < len(s); i++ { 78 switch c := s[i]; { 79 case c == ' ' && spaceToPlus: 80 sb.WriteByte('+') 81 case c > 127 || table[c] == 0: 82 hexBuf[1] = upperhex[c>>4] 83 hexBuf[2] = upperhex[c&15] 84 sb.Write(hexBuf[:]) 85 default: 86 sb.WriteByte(c) 87 } 88 } 89 return sb.String() 90 } 91 92 func unescapeSearchParam(s string) string { 93 n := 0 94 hasPlus := false 95 for i := 0; i < len(s); { 96 switch s[i] { 97 case '%': 98 if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) { 99 i++ 100 continue 101 } 102 n++ 103 i += 3 104 case '+': 105 hasPlus = true 106 i++ 107 default: 108 i++ 109 } 110 } 111 112 if n == 0 && !hasPlus { 113 return s 114 } 115 116 var t strings.Builder 117 t.Grow(len(s) - 2*n) 118 for i := 0; i < len(s); i++ { 119 switch s[i] { 120 case '%': 121 if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) { 122 t.WriteByte('%') 123 } else { 124 t.WriteByte(unhex(s[i+1])<<4 | unhex(s[i+2])) 125 i += 2 126 } 127 case '+': 128 t.WriteByte(' ') 129 default: 130 t.WriteByte(s[i]) 131 } 132 } 133 return t.String() 134 }