func (uri *Pkcs11URI) SetPathAttribute(name, value string) error {
	return uri.setAttribute(uri.pathAttributes, name, value)
}
SetPathAttribute sets the value for a path attribute; this function may return an error
if the given value cannot be pct-unescaped
package pkcs11uri
import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)
type Pkcs11URI struct {
	pathAttributes  map[string]string
	queryAttributes map[string]string
	moduleDirectories []string
	allowedModulePaths []string
	allowAnyModule bool
	env map[string]string
}
const hex = "0123456789ABCDEF"
func escapeAll(s string) string {
	res := make([]byte, len(s)*3)
	j := 0
	for i := 0; i < len(s); i++ {
		c := s[i]
		res[j] = '%'
		res[j+1] = hex[c>>4]
		res[j+2] = hex[c&0xf]
		j += 3
	}
	return string(res)
}
func escape(s string, isPath bool) string {
	res := make([]byte, len(s)*3)
	j := 0
	for i := 0; i < len(s); i++ {
		c := s[i]
		if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') {
			res[j] = c
		} else if isPath && c == '&' {
			res[j] = c
		} else if !isPath && (c == '/' || c == '?' || c == '|') {
			res[j] = c
		} else {
			switch c {
			case '-', '.', '_', '~':  
				res[j] = c
			case ':', '[', ']', '@', '!', '$', '\'', '(', ')', '*', '+', ',', '=':
				res[j] = c
			default:
				res[j] = '%'
				res[j+1] = hex[c>>4]
				res[j+2] = hex[c&0xf]
				j += 2
			}
		}
		j++
	}
	return string(res[:j])
}
func New() *Pkcs11URI {
	return &Pkcs11URI{
		pathAttributes:  make(map[string]string),
		queryAttributes: make(map[string]string),
		env:             make(map[string]string),
	}
}
func (uri *Pkcs11URI) setAttribute(attrMap map[string]string, name, value string) error {
	v, err := url.PathUnescape(value)
	if err != nil {
		return err
	}
	attrMap[name] = v
	return nil
}
func (uri *Pkcs11URI) GetPathAttribute(name string, pctencode bool) (string, bool) {
	v, ok := uri.pathAttributes[name]
	if ok && pctencode {
		v = escape(v, true)
	}
	return v, ok
}