package main import ( "log" "path" "strconv" "strings" ) func IsDir(s string) bool { return s[len(s)-1] == '/' } type ByName [][]string func (a ByName) Len() int { return len(a) } func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByName) Less(i, j int) bool { return namesCmp(a[i], a[j]) < 0 } func nameSplit(name string) []string { cols := strings.Split(name, "/") if IsDir(name) { cols = cols[:len(cols)-1] cols[len(cols)-1] += "/" } return cols } func nameJoin(name []string) (s string) { s = path.Join(name...) if IsDir(name[len(name)-1]) { s += "/" } return } func namesCmp(n1, n2 []string) int { min := len(n1) if len(n2) < min { min = len(n2) } var t1, t2 string for i := 0; i < min; i++ { t1 = strings.TrimSuffix(n1[i], "/") t2 = strings.TrimSuffix(n2[i], "/") if t1 < t2 { return -1 } if t1 > t2 { return +1 } } if len(n1) > len(n2) { return +1 } if len(n1) < len(n2) { return -1 } return 0 } func hasPrefix(name, prefix []string) bool { if len(name) < len(prefix) { return false } return namesCmp(name[:len(prefix)], prefix) == 0 } func deoctalize(s string) string { chars := make([]byte, 0, len(s)) for i := 0; i < len(s); i++ { if s[i] == '\\' { b, err := strconv.ParseUint("0"+s[i+1:i+1+3], 0, 8) if err != nil { log.Fatalln(err) } chars = append(chars, byte(b)) i += 3 } else { chars = append(chars, s[i]) } } return string(chars) }