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  }