github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/bazil.org/fuse/fs/tree.go (about)

     1  // FUSE directory tree, for servers that wish to use it with the service loop.
     2  
     3  package fs
     4  
     5  import (
     6  	"os"
     7  	pathpkg "path"
     8  	"strings"
     9  )
    10  
    11  import (
    12  	"camlistore.org/third_party/bazil.org/fuse"
    13  )
    14  
    15  // A Tree implements a basic read-only directory tree for FUSE.
    16  // The Nodes contained in it may still be writable.
    17  type Tree struct {
    18  	tree
    19  }
    20  
    21  func (t *Tree) Root() (Node, fuse.Error) {
    22  	return &t.tree, nil
    23  }
    24  
    25  // Add adds the path to the tree, resolving to the given node.
    26  // If path or a prefix of path has already been added to the tree,
    27  // Add panics.
    28  //
    29  // Add is only safe to call before starting to serve requests.
    30  func (t *Tree) Add(path string, node Node) {
    31  	path = pathpkg.Clean("/" + path)[1:]
    32  	elems := strings.Split(path, "/")
    33  	dir := Node(&t.tree)
    34  	for i, elem := range elems {
    35  		dt, ok := dir.(*tree)
    36  		if !ok {
    37  			panic("fuse: Tree.Add for " + strings.Join(elems[:i], "/") + " and " + path)
    38  		}
    39  		n := dt.lookup(elem)
    40  		if n != nil {
    41  			if i+1 == len(elems) {
    42  				panic("fuse: Tree.Add for " + path + " conflicts with " + elem)
    43  			}
    44  			dir = n
    45  		} else {
    46  			if i+1 == len(elems) {
    47  				dt.add(elem, node)
    48  			} else {
    49  				dir = &tree{}
    50  				dt.add(elem, dir)
    51  			}
    52  		}
    53  	}
    54  }
    55  
    56  type treeDir struct {
    57  	name string
    58  	node Node
    59  }
    60  
    61  type tree struct {
    62  	dir []treeDir
    63  }
    64  
    65  func (t *tree) lookup(name string) Node {
    66  	for _, d := range t.dir {
    67  		if d.name == name {
    68  			return d.node
    69  		}
    70  	}
    71  	return nil
    72  }
    73  
    74  func (t *tree) add(name string, n Node) {
    75  	t.dir = append(t.dir, treeDir{name, n})
    76  }
    77  
    78  func (t *tree) Attr() fuse.Attr {
    79  	return fuse.Attr{Mode: os.ModeDir | 0555}
    80  }
    81  
    82  func (t *tree) Lookup(name string, intr Intr) (Node, fuse.Error) {
    83  	n := t.lookup(name)
    84  	if n != nil {
    85  		return n, nil
    86  	}
    87  	return nil, fuse.ENOENT
    88  }
    89  
    90  func (t *tree) ReadDir(intr Intr) ([]fuse.Dirent, fuse.Error) {
    91  	var out []fuse.Dirent
    92  	for _, d := range t.dir {
    93  		out = append(out, fuse.Dirent{Name: d.name})
    94  	}
    95  	return out, nil
    96  }