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  }