Files
oikos/vendor/github.com/yosida95/uritemplate/v3/escape.go
dtoro febc153b7f
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled
fix: add involves edge from task to agent:nomos at creation
Plus sync vendor directory for Docker build compatibility.
2026-08-11 22:03:12 +02:00

191 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (C) 2016 Kohei YOSHIDA. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of The BSD 3-Clause License
// that can be found in the LICENSE file.
package uritemplate
import (
"strings"
"unicode"
"unicode/utf8"
)
var (
hex = []byte("0123456789ABCDEF")
// reserved = gen-delims / sub-delims
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
// sub-delims = "!" / "$" / "&" / "" / "(" / ")"
// / "*" / "+" / "," / ";" / "="
rangeReserved = &unicode.RangeTable{
R16: []unicode.Range16{
{Lo: 0x21, Hi: 0x21, Stride: 1}, // '!'
{Lo: 0x23, Hi: 0x24, Stride: 1}, // '#' - '$'
{Lo: 0x26, Hi: 0x2C, Stride: 1}, // '&' - ','
{Lo: 0x2F, Hi: 0x2F, Stride: 1}, // '/'
{Lo: 0x3A, Hi: 0x3B, Stride: 1}, // ':' - ';'
{Lo: 0x3D, Hi: 0x3D, Stride: 1}, // '='
{Lo: 0x3F, Hi: 0x40, Stride: 1}, // '?' - '@'
{Lo: 0x5B, Hi: 0x5B, Stride: 1}, // '['
{Lo: 0x5D, Hi: 0x5D, Stride: 1}, // ']'
},
LatinOffset: 9,
}
reReserved = `\x21\x23\x24\x26-\x2c\x2f\x3a\x3b\x3d\x3f\x40\x5b\x5d`
// ALPHA = %x41-5A / %x61-7A
// DIGIT = %x30-39
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
rangeUnreserved = &unicode.RangeTable{
R16: []unicode.Range16{
{Lo: 0x2D, Hi: 0x2E, Stride: 1}, // '-' - '.'
{Lo: 0x30, Hi: 0x39, Stride: 1}, // '0' - '9'
{Lo: 0x41, Hi: 0x5A, Stride: 1}, // 'A' - 'Z'
{Lo: 0x5F, Hi: 0x5F, Stride: 1}, // '_'
{Lo: 0x61, Hi: 0x7A, Stride: 1}, // 'a' - 'z'
{Lo: 0x7E, Hi: 0x7E, Stride: 1}, // '~'
},
}
reUnreserved = `\x2d\x2e\x30-\x39\x41-\x5a\x5f\x61-\x7a\x7e`
)
type runeClass uint8
const (
runeClassU runeClass = 1 << iota
runeClassR
runeClassPctE
runeClassLast
runeClassUR = runeClassU | runeClassR
)
var runeClassNames = []string{
"U",
"R",
"pct-encoded",
}
func (rc runeClass) String() string {
ret := make([]string, 0, len(runeClassNames))
for i, j := 0, runeClass(1); j < runeClassLast; j <<= 1 {
if rc&j == j {
ret = append(ret, runeClassNames[i])
}
i++
}
return strings.Join(ret, "+")
}
func pctEncode(w *strings.Builder, r rune) {
if s := r >> 24 & 0xff; s > 0 {
w.Write([]byte{'%', hex[s/16], hex[s%16]})
}
if s := r >> 16 & 0xff; s > 0 {
w.Write([]byte{'%', hex[s/16], hex[s%16]})
}
if s := r >> 8 & 0xff; s > 0 {
w.Write([]byte{'%', hex[s/16], hex[s%16]})
}
if s := r & 0xff; s > 0 {
w.Write([]byte{'%', hex[s/16], hex[s%16]})
}
}
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
func ishex(c byte) bool {
switch {
case '0' <= c && c <= '9':
return true
case 'a' <= c && c <= 'f':
return true
case 'A' <= c && c <= 'F':
return true
default:
return false
}
}
func pctDecode(s string) string {
size := len(s)
for i := 0; i < len(s); {
switch s[i] {
case '%':
size -= 2
i += 3
default:
i++
}
}
if size == len(s) {
return s
}
buf := make([]byte, size)
j := 0
for i := 0; i < len(s); {
switch c := s[i]; c {
case '%':
buf[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
i += 3
j++
default:
buf[j] = c
i++
j++
}
}
return string(buf)
}
type escapeFunc func(*strings.Builder, string) error
func escapeLiteral(w *strings.Builder, v string) error {
w.WriteString(v)
return nil
}
func escapeExceptU(w *strings.Builder, v string) error {
for i := 0; i < len(v); {
r, size := utf8.DecodeRuneInString(v[i:])
if r == utf8.RuneError {
return errorf(i, "invalid encoding")
}
if unicode.Is(rangeUnreserved, r) {
w.WriteRune(r)
} else {
pctEncode(w, r)
}
i += size
}
return nil
}
func escapeExceptUR(w *strings.Builder, v string) error {
for i := 0; i < len(v); {
r, size := utf8.DecodeRuneInString(v[i:])
if r == utf8.RuneError {
return errorf(i, "invalid encoding")
}
// TODO(yosida95): is pct-encoded triplets allowed here?
if unicode.In(r, rangeUnreserved, rangeReserved) {
w.WriteRune(r)
} else {
pctEncode(w, r)
}
i += size
}
return nil
}