You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.8 KiB

  1. package filer
  2. import (
  3. "context"
  4. "github.com/chrislusf/seaweedfs/weed/util"
  5. "path/filepath"
  6. "strings"
  7. )
  8. func splitPattern(pattern string) (prefix string, restPattern string, hasUpper bool) {
  9. for i := 0; i < len(pattern); i++ {
  10. hasUpper = hasUpper || ('A' <= pattern[i] && pattern[i] <= 'Z')
  11. }
  12. position := strings.Index(pattern, "*")
  13. if position >= 0 {
  14. return pattern[:position], pattern[position:], hasUpper
  15. }
  16. position = strings.Index(pattern, "?")
  17. if position >= 0 {
  18. return pattern[:position], pattern[position:], hasUpper
  19. }
  20. return "", restPattern, hasUpper
  21. }
  22. func (f *Filer) ListDirectoryEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, namePattern string) (entries []*Entry, err error) {
  23. if strings.HasSuffix(string(p), "/") && len(p) > 1 {
  24. p = p[0 : len(p)-1]
  25. }
  26. prefix, restNamePattern, hasUpper := splitPattern(namePattern)
  27. var missedCount int
  28. var lastFileName string
  29. entries, missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, startFileName, inclusive, limit, prefix, restNamePattern, hasUpper)
  30. for missedCount > 0 && err == nil {
  31. var makeupEntries []*Entry
  32. makeupEntries, missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, lastFileName, false, missedCount, prefix, restNamePattern, hasUpper)
  33. for _, entry := range makeupEntries {
  34. entries = append(entries, entry)
  35. }
  36. }
  37. return entries, err
  38. }
  39. func (f *Filer) doListPatternMatchedEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix, restNamePattern string, hasUpper bool) (matchedEntries []*Entry, missedCount int, lastFileName string, err error) {
  40. var foundEntries []*Entry
  41. foundEntries, lastFileName, err = f.doListValidEntries(ctx, p, startFileName, inclusive, limit, prefix)
  42. if err != nil {
  43. return
  44. }
  45. if len(restNamePattern) == 0 {
  46. return foundEntries, 0, lastFileName, nil
  47. }
  48. for _, entry := range foundEntries {
  49. nameToTest := strings.ToLower(entry.Name())
  50. if matched, matchErr := filepath.Match(restNamePattern, nameToTest[len(prefix):]); matchErr == nil && matched {
  51. matchedEntries = append(matchedEntries, entry)
  52. } else {
  53. missedCount++
  54. }
  55. }
  56. return
  57. }
  58. func (f *Filer) doListValidEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix string) (entries []*Entry, lastFileName string, err error) {
  59. var makeupEntries []*Entry
  60. var expiredCount int
  61. entries, expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, startFileName, inclusive, limit, prefix)
  62. for expiredCount > 0 && err == nil {
  63. makeupEntries, expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, lastFileName, false, expiredCount, prefix)
  64. if err == nil {
  65. entries = append(entries, makeupEntries...)
  66. }
  67. }
  68. return
  69. }