escape.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package url
  2. import "strings"
  3. var tblEscapeURLQuery = [128]byte{
  4. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  5. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  6. 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
  7. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
  8. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  9. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0,
  12. }
  13. // The code below is mostly borrowed from the standard Go url package
  14. const upperhex = "0123456789ABCDEF"
  15. func escape(s string, table *[128]byte, spaceToPlus bool) string {
  16. spaceCount, hexCount := 0, 0
  17. for i := 0; i < len(s); i++ {
  18. c := s[i]
  19. if c > 127 || table[c] == 0 {
  20. if c == ' ' && spaceToPlus {
  21. spaceCount++
  22. } else {
  23. hexCount++
  24. }
  25. }
  26. }
  27. if spaceCount == 0 && hexCount == 0 {
  28. return s
  29. }
  30. var sb strings.Builder
  31. hexBuf := [3]byte{'%', 0, 0}
  32. sb.Grow(len(s) + 2*hexCount)
  33. for i := 0; i < len(s); i++ {
  34. switch c := s[i]; {
  35. case c == ' ' && spaceToPlus:
  36. sb.WriteByte('+')
  37. case c > 127 || table[c] == 0:
  38. hexBuf[1] = upperhex[c>>4]
  39. hexBuf[2] = upperhex[c&15]
  40. sb.Write(hexBuf[:])
  41. default:
  42. sb.WriteByte(c)
  43. }
  44. }
  45. return sb.String()
  46. }