func unbindValueURIAtTill()

in wfn/uri.go [165:277]


func unbindValueURIAtTill(s string, at int, till byte) (string, int, error) {
	if at >= len(s) || s[at] == till {
		return Any, at, nil
	}
	if s[at] == '-' {
		return NA, at + 1, nil
	}
	out := make([]byte, 0, len(s)*2) // assume the worst
	embedded := false
	i := at
loop:
	for ; i < len(s); i++ {
		switch s[i] {
		case till:
			break loop
		case '%':
			if i+3 > len(s) {
				return "", i, fmt.Errorf("unbind URI attribute: illegal percent-encoded value at %d: %q", i, s[i:])
			}
			codeStr := string(s[i : i+3])
			code, err := strconv.ParseInt(string(s[i+1:i+3]), 16, 8)
			if err != nil {
				return "", i, fmt.Errorf("unbind URI attribute: illegal percent-encoded value at %d: %q", i, s[i+1:i+3])
			}
			if code == 0x1 || code == 0x2 {
				if !(i == at || i == len(s)-3 || s[i+3] == till || // at the beginning or at the end of the string
					(!embedded && i > 2 && s[i-3:i] == codeStr || // not embedded and preceded by the same symbol
						(embedded && i+6 < len(s) && s[i+3:i+6] == codeStr))) { // embedded and followed by the same symbol
					return "", i, fmt.Errorf("unbind URI attribute: %%%02d is embedded into string %q", code, s)
				}
				switch code {
				case 0x1:
					out = append(out, '?')
				case 0x2:
					out = append(out, '*')
				}
				i += 2
				break
			}
			switch code {
			case 0x21:
				out = append(out, '\\', '!')
			case 0x22:
				out = append(out, '\\', '"')
			case 0x23:
				out = append(out, '\\', '#')
			case 0x24:
				out = append(out, '\\', '$')
			case 0x25:
				out = append(out, '\\', '%')
			case 0x26:
				out = append(out, '\\', '&')
			case 0x27:
				out = append(out, '\\', '\'')
			case 0x28:
				out = append(out, '\\', '(')
			case 0x29:
				out = append(out, '\\', ')')
			case 0x2a:
				out = append(out, '\\', '*')
			case 0x2b:
				out = append(out, '\\', '+')
			case 0x2c:
				out = append(out, '\\', ',')
			case 0x2f:
				out = append(out, '\\', '/')
			case 0x3a:
				out = append(out, '\\', ':')
			case 0x3b:
				out = append(out, '\\', ';')
			case 0x3c:
				out = append(out, '\\', '<')
			case 0x3d:
				out = append(out, '\\', '=')
			case 0x3e:
				out = append(out, '\\', '>')
			case 0x3f:
				out = append(out, '\\', '?')
			case 0x40:
				out = append(out, '\\', '@')
			case 0x5b:
				out = append(out, '\\', '[')
			case 0x5c:
				out = append(out, '\\', '\\')
			case 0x5d:
				out = append(out, '\\', ']')
			case 0x5e:
				out = append(out, '\\', '^')
			case 0x60:
				out = append(out, '\\', '`')
			case 0x7b:
				out = append(out, '\\', '{')
			case 0x7c:
				out = append(out, '\\', '|')
			case 0x7d:
				out = append(out, '\\', '}')
			case 0x7e:
				out = append(out, '\\', '~')
			default:
				return "", i, fmt.Errorf("unbind URI attribute: illegal percent-encoded value %q", s[i+1:i+3])
			}
			i += 2
			embedded = true
		case '.', '-', '~':
			out = append(out, '\\', s[i])
			embedded = true
		default:
			out = append(out, s[i])
			embedded = true
		}
	}
	return string(out), i, nil
}