66 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright (C) 2024  Umorpha Systems
 | 
						|
// SPDX-License-Identifier: AGPL-3.0-or-later
 | 
						|
 | 
						|
package gitcache
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"regexp"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
func NormalizeURL(url string) string {
 | 
						|
	// > Clients MUST strip a trailing `/`, if present, from the
 | 
						|
	// > user supplied `$GIT_URL` string
 | 
						|
	// -- gitprotocol-http(5)
 | 
						|
	url = strings.TrimRight(url, "/")
 | 
						|
	return url
 | 
						|
}
 | 
						|
 | 
						|
func ValidateURL(url string) bool {
 | 
						|
	return NormalizeURL(url) != ""
 | 
						|
}
 | 
						|
 | 
						|
func URL2NS(url string) string {
 | 
						|
	url = NormalizeURL(url)
 | 
						|
 | 
						|
	var id strings.Builder
 | 
						|
	id.Grow(len(url))
 | 
						|
	for i := 0; i < len(url); i++ {
 | 
						|
		b := url[i]
 | 
						|
		switch {
 | 
						|
		case b == '!', // our own escape
 | 
						|
			// see: git-check-ref-format(1)
 | 
						|
			b <= ' ', b == '\x7F', // never: ASCII control characters
 | 
						|
			b == '~', b == '^', b == ':', // never: gitrevision meaning
 | 
						|
			b == '?', b == '*', b == '[', // never: refspec pattern
 | 
						|
			b == '\\',                    // never: backslash
 | 
						|
			b == '.', b == '@', b == '/': // sometimes: special rules
 | 
						|
			fmt.Fprintf(&id, "!%02x", b)
 | 
						|
		default:
 | 
						|
			id.WriteByte(b)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return id.String()
 | 
						|
}
 | 
						|
 | 
						|
var reEsc = regexp.MustCompile("![0-9a-f]{2}")
 | 
						|
 | 
						|
func hex2int(h byte) byte {
 | 
						|
	switch {
 | 
						|
	case '0' <= h && h <= '9':
 | 
						|
		return h - '0'
 | 
						|
	case 'a' <= h && h <= 'f':
 | 
						|
		return h - 'a' + 0xa
 | 
						|
	default:
 | 
						|
		panic("should not happen")
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func NS2URL(id string) string {
 | 
						|
	return reEsc.ReplaceAllStringFunc(id, func(esc string) string {
 | 
						|
		b := hex2int(esc[1])<<4 | hex2int(esc[2])
 | 
						|
		return string([]byte{b})
 | 
						|
	})
 | 
						|
}
 |