github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/third_party/code.google.com/p/rsc/fuse/tree.go (about) 1 // +build linux darwin 2 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // FUSE directory tree, for servers that wish to use it with the service loop. 8 9 package fuse 10 11 import ( 12 "os" 13 pathpkg "path" 14 "strings" 15 ) 16 17 // A Tree implements a basic directory tree for FUSE. 18 type Tree struct { 19 tree 20 } 21 22 func (t *Tree) Root() (Node, Error) { 23 return &t.tree, nil 24 } 25 26 // Add adds the path to the tree, resolving to the given node. 27 // If path or a prefix of path has already been added to the tree, 28 // Add panics. 29 func (t *Tree) Add(path string, node Node) { 30 path = pathpkg.Clean("/" + path)[1:] 31 elems := strings.Split(path, "/") 32 dir := Node(&t.tree) 33 for i, elem := range elems { 34 dt, ok := dir.(*tree) 35 if !ok { 36 panic("fuse: Tree.Add for " + strings.Join(elems[:i], "/") + " and " + path) 37 } 38 n := dt.lookup(elem) 39 if n != nil { 40 if i+1 == len(elems) { 41 panic("fuse: Tree.Add for " + path + " conflicts with " + elem) 42 } 43 dir = n 44 } else { 45 if i+1 == len(elems) { 46 dt.add(elem, node) 47 } else { 48 dir = &tree{} 49 dt.add(elem, dir) 50 } 51 } 52 } 53 } 54 55 type treeDir struct { 56 name string 57 node Node 58 } 59 60 type tree struct { 61 dir []treeDir 62 } 63 64 func (t *tree) lookup(name string) Node { 65 for _, d := range t.dir { 66 if d.name == name { 67 return d.node 68 } 69 } 70 return nil 71 } 72 73 func (t *tree) add(name string, n Node) { 74 t.dir = append(t.dir, treeDir{name, n}) 75 } 76 77 func (t *tree) Attr() Attr { 78 return Attr{Mode: os.ModeDir | 0555} 79 } 80 81 func (t *tree) Lookup(name string, intr Intr) (Node, Error) { 82 n := t.lookup(name) 83 if n != nil { 84 return n, nil 85 } 86 return nil, ENOENT 87 } 88 89 func (t *tree) ReadDir(intr Intr) ([]Dirent, Error) { 90 var out []Dirent 91 for _, d := range t.dir { 92 out = append(out, Dirent{Name: d.name}) 93 } 94 return out, nil 95 }