90 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package obj
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net/url"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
type QURL struct {
 | 
						|
	ID      uint64
 | 
						|
	URL     string
 | 
						|
	Created time.Time
 | 
						|
	IP      []byte
 | 
						|
	Browser string
 | 
						|
}
 | 
						|
 | 
						|
func (q *QURL) CheckValid() error {
 | 
						|
	if q == nil {
 | 
						|
		return fmt.Errorf("QURL is nil")
 | 
						|
	}
 | 
						|
 | 
						|
	if q.URL == "" {
 | 
						|
		return fmt.Errorf("URL may not be empty")
 | 
						|
	}
 | 
						|
 | 
						|
	u, err := url.Parse(q.URL)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	if u.Scheme == "" {
 | 
						|
		return fmt.Errorf("URLs must begin with a scheme (e.g. https:)")
 | 
						|
	}
 | 
						|
 | 
						|
	if u.Host == "" && u.RawQuery == "" && u.RawPath == "" && u.Fragment == "" {
 | 
						|
		return fmt.Errorf("URLs must contain a path, host, query or fragment element")
 | 
						|
	}
 | 
						|
 | 
						|
	if !u.IsAbs() {
 | 
						|
		return fmt.Errorf("Relative URLs are not allowed")
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
const alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 | 
						|
const alphalen = uint64(len(alpha))
 | 
						|
 | 
						|
func ToString(v uint64) string {
 | 
						|
	var r strings.Builder
 | 
						|
	var i uint64
 | 
						|
	for i = v; i >= alphalen; i = (i / alphalen) - 1 {
 | 
						|
		r.WriteByte(alpha[i%alphalen])
 | 
						|
	}
 | 
						|
	r.WriteByte(alpha[i])
 | 
						|
	return r.String()
 | 
						|
}
 | 
						|
 | 
						|
func FromString(s string) (uint64, error) {
 | 
						|
	var r uint64
 | 
						|
	vlen := uint64(len(s))
 | 
						|
 | 
						|
	for i := uint64(0); i < vlen; i++ {
 | 
						|
		x := strings.IndexByte(alpha, s[i])
 | 
						|
		if x == -1 {
 | 
						|
			return 0, fmt.Errorf("Invalid character [%s]", s[i])
 | 
						|
		}
 | 
						|
 | 
						|
		if i == 0 {
 | 
						|
			r += uint64(x)
 | 
						|
		} else {
 | 
						|
			r += (uint64(x+1) * pow(alphalen, i))
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return r, nil
 | 
						|
}
 | 
						|
 | 
						|
func pow(a, b uint64) uint64 {
 | 
						|
	p := uint64(1)
 | 
						|
	for b > 0 {
 | 
						|
		if b&1 != 0 {
 | 
						|
			p *= a
 | 
						|
		}
 | 
						|
		b >>= 1
 | 
						|
		a *= a
 | 
						|
	}
 | 
						|
	return p
 | 
						|
}
 |