// List lists a bucket, all objects Key starts with prefix, delimiter segments // Key, thus the returned commonprefixes (think a generalized filepath // structure, where / is the delimiter, a commonprefix is a subdir) func (root hier) List(owner s3intf.Owner, bucket, prefix, delimiter, marker string, limit, skip int) ( objects []s3intf.Object, commonprefixes []string, truncated bool, err error) { dh, e := os.Open(filepath.Join(string(root), owner.ID(), bucket)) if e != nil { err = e return } defer dh.Close() var ( infos []os.FileInfo key, etag string md5hash []byte ok bool ) objects = make([]s3intf.Object, 0, 64) f := s3intf.NewListFilter(prefix, delimiter, marker, limit, skip) OUTER: for { infos, e = dh.Readdir(limit) if e != nil { if e == io.EOF { break } err = e return } for _, fi := range infos { if key, _, _, md5hash, err = decodeFilename(fi.Name()); err != nil { return } if ok, e = f.Check(key); e != nil { if e == io.EOF { break OUTER } err = fmt.Errorf("error checking %s: %s", key, e) return } else if ok { if md5hash != nil && len(md5hash) == 16 { etag = hex.EncodeToString(md5hash) } else { etag = "" } objects = append(objects, s3intf.Object{Key: string(key), Owner: owner, ETag: etag, LastModified: fi.ModTime(), Size: fi.Size()}) } } } commonprefixes, truncated = f.Result() return }
// List lists a bucket, all objects Key starts with prefix, delimiter segments // Key, thus the returned commonprefixes (think a generalized filepath // structure, where / is the delimiter, a commonprefix is a subdir) func (m master) List(owner s3intf.Owner, bucket, prefix, delimiter, marker string, limit, skip int) ( objects []s3intf.Object, commonprefixes []string, truncated bool, err error) { m.Lock() o, ok := m.owners[owner.ID()] if !ok { m.Unlock() err = fmt.Errorf("unknown owner %s", owner.ID()) return } o.Lock() b, ok := o.buckets[bucket] o.Unlock() m.Unlock() if !ok { err = fmt.Errorf("unknown bucket %s", bucket) return } err = nil enum, e := b.db.SeekFirst() if e != nil { if e == io.EOF { //empty return } err = fmt.Errorf("error getting first: %s", e) return } var ( key, val []byte vi = new(weedutils.ValInfo) etag string ) objects = make([]s3intf.Object, 0, 64) f := s3intf.NewListFilter(prefix, delimiter, marker, limit, skip) for { if key, val, e = enum.Next(); e != nil { if e == io.EOF { break } err = fmt.Errorf("error seeking next: %s", e) return } //log.Printf("key=%q", key) if ok, e = f.Check(string(key)); e != nil { if e == io.EOF { break } err = fmt.Errorf("error checking %s: %s", key, e) return } else if ok { if err = vi.Decode(val); err != nil { return } if vi.MD5 != nil && len(vi.MD5) == 16 { etag = hex.EncodeToString(vi.MD5) } else { etag = "" } objects = append(objects, s3intf.Object{Key: string(key), Owner: owner, ETag: etag, LastModified: vi.Created, Size: vi.Size}) } } commonprefixes, truncated = f.Result() return }