Match() partially works (have to check for optional parameters) + GetMatch() works as well

This commit is contained in:
xdrm-brackets 2018-04-26 15:01:18 +02:00
parent 63b5125e6c
commit d6a9411bb1
2 changed files with 132 additions and 2 deletions

View File

@ -30,7 +30,7 @@ func Build(s string) (*Scheme, error){
return nil, err
}
/* (5) Optimise */
/* (5) Optimise structure */
opti, err := sch.optimise()
if err != nil {
return nil, err
@ -39,3 +39,132 @@ func Build(s string) (*Scheme, error){
return &opti, nil
}
// Match returns if the given URI is matched by the scheme
func (s Scheme) Match(str string) bool {
/* (1) Nothing -> match all */
if len(s) == 0 { return true }
/* (2) Init variables */
wc := make(Scheme, 0, maxMatch) // conrains wildcards
clr := str // contains cleared input string
minOff := 0 // minimum offset
/* (3) Iterate over strings */
for _, m := range s {
ls := len(m.pat)
// if not string -> ignore
if ls == 0 {
wc = append(wc, m)
continue
}
// get offset if contained, else -1
off := strings.Index(clr, m.pat)
if off < 0 { return false }
// if invalid offset range -> fail
if off < minOff { return false }
// check if trailing '/'
slash := 0
if off+ls < len(clr) && clr[off+ls] == '/' {
slash = 1
}
// exclude this string (+trailing slash if set)
// fmt.Printf("remove: '%s'\n", clr[off:off+ls+slash])
beg, end := clr[:off], clr[off+ls+slash:]
clr = fmt.Sprintf("%s//%s", beg, end)
// fmt.Printf("clr: '%s'\n", clr)
// update offset range
minOff = len(beg) + 2 - 1 // +2 slash separators
// -1 because strings begin with 1 slash already
}
/* (4) If no wildcard -> match */
if len(wc) == 0 {
return true
}
// flush wildcard buffers
for _, w := range wc { w.buf = nil }
/* (5) Break the clear string apart */
matches := strings.Split(clr, "//")[1:]
// fail if missing matches
if len(matches) < len(wc) {
return false
}
nwc := 0
for _, m := range matches {
// ignore empty
if len(m) == 0 { continue }
// no matcher for this match
if nwc >= len(wc){ return false }
// split by '/'
parts := strings.Split(m, "/")
// if required and missing -> does not match
if wc[nwc].req && len(parts) < 1 {
return false
}
// if not multi but multi -> does not match
if !wc[nwc].mul && len(parts) > 1 {
return false
}
// store into wilcard matcher
wc[nwc].buf = parts
// increment wildcard count
nwc++
}
return true
}
// GetMatch returns the indexed match (excluding string matchers)
func (s Scheme) GetMatch(n uint8) ([]string, error) {
/* (1) Index out of range */
if n > uint8(len(s)) {
return nil, fmt.Errorf("Index out of range")
}
/* (2) Iterate to find index (exclude strings) */
ni := -1
for i, l := 0, len(s) ; i < l ; i++ {
// ignore strings
if len(s[i].pat) > 0 { continue }
// increment match counter : ni
ni++
// if expected index -> return matches
if uint8(ni) == n {
return s[i].buf, nil
}
}
/* (3) If nothing found -> return empty set */
return nil, fmt.Errorf("Index out of range (max: %d)", ni)
}

View File

@ -27,7 +27,8 @@ type matcher struct {
pat string // pattern to match (empty if wildcard)
req bool // whether it is required
mul bool // whether multiple matches are allowed
buf []string // matched content
buf []string // matched content (when matching)
}