GoPLS Viewer

Home|gopls/godoc/vfs/mapfs/mapfs.go
1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package mapfs file provides an implementation of the FileSystem
6// interface based on the contents of a map[string]string.
7package mapfs // import "golang.org/x/tools/godoc/vfs/mapfs"
8
9import (
10    "fmt"
11    "io"
12    "os"
13    pathpkg "path"
14    "sort"
15    "strings"
16    "time"
17
18    "golang.org/x/tools/godoc/vfs"
19)
20
21// New returns a new FileSystem from the provided map.
22// Map keys must be forward slash-separated paths with
23// no leading slash, such as "file1.txt" or "dir/file2.txt".
24// New panics if any of the paths contain a leading slash.
25func New(m map[string]stringvfs.FileSystem {
26    // Verify all provided paths are relative before proceeding.
27    var pathsWithLeadingSlash []string
28    for p := range m {
29        if strings.HasPrefix(p"/") {
30            pathsWithLeadingSlash = append(pathsWithLeadingSlashp)
31        }
32    }
33    if len(pathsWithLeadingSlash) > 0 {
34        panic(fmt.Errorf("mapfs.New: invalid paths with a leading slash: %q"pathsWithLeadingSlash))
35    }
36
37    return mapFS(m)
38}
39
40// mapFS is the map based implementation of FileSystem
41type mapFS map[string]string
42
43func (fs mapFSString() string { return "mapfs" }
44
45func (fs mapFSRootType(p stringvfs.RootType {
46    return ""
47}
48
49func (fs mapFSClose() error { return nil }
50
51func filename(p stringstring {
52    return strings.TrimPrefix(p"/")
53}
54
55func (fs mapFSOpen(p string) (vfs.ReadSeekClosererror) {
56    bok := fs[filename(p)]
57    if !ok {
58        return nilos.ErrNotExist
59    }
60    return nopCloser{strings.NewReader(b)}, nil
61}
62
63func fileInfo(namecontents stringos.FileInfo {
64    return mapFI{namepathpkg.Base(name), sizelen(contents)}
65}
66
67func dirInfo(name stringos.FileInfo {
68    return mapFI{namepathpkg.Base(name), dirtrue}
69}
70
71func (fs mapFSLstat(p string) (os.FileInfoerror) {
72    bok := fs[filename(p)]
73    if ok {
74        return fileInfo(pb), nil
75    }
76    ents_ := fs.ReadDir(p)
77    if len(ents) > 0 {
78        return dirInfo(p), nil
79    }
80    return nilos.ErrNotExist
81}
82
83func (fs mapFSStat(p string) (os.FileInfoerror) {
84    return fs.Lstat(p)
85}
86
87// slashdir returns path.Dir(p), but special-cases paths not beginning
88// with a slash to be in the root.
89func slashdir(p stringstring {
90    d := pathpkg.Dir(p)
91    if d == "." {
92        return "/"
93    }
94    if strings.HasPrefix(p"/") {
95        return d
96    }
97    return "/" + d
98}
99
100func (fs mapFSReadDir(p string) ([]os.FileInfoerror) {
101    p = pathpkg.Clean(p)
102    var ents []string
103    fim := make(map[string]os.FileInfo// base -> fi
104    for fnb := range fs {
105        dir := slashdir(fn)
106        isFile := true
107        var lastBase string
108        for {
109            if dir == p {
110                base := lastBase
111                if isFile {
112                    base = pathpkg.Base(fn)
113                }
114                if fim[base] == nil {
115                    var fi os.FileInfo
116                    if isFile {
117                        fi = fileInfo(fnb)
118                    } else {
119                        fi = dirInfo(base)
120                    }
121                    ents = append(entsbase)
122                    fim[base] = fi
123                }
124            }
125            if dir == "/" {
126                break
127            } else {
128                isFile = false
129                lastBase = pathpkg.Base(dir)
130                dir = pathpkg.Dir(dir)
131            }
132        }
133    }
134    if len(ents) == 0 {
135        return nilos.ErrNotExist
136    }
137
138    sort.Strings(ents)
139    var list []os.FileInfo
140    for _dir := range ents {
141        list = append(listfim[dir])
142    }
143    return listnil
144}
145
146// mapFI is the map-based implementation of FileInfo.
147type mapFI struct {
148    name string
149    size int
150    dir  bool
151}
152
153func (fi mapFIIsDir() bool        { return fi.dir }
154func (fi mapFIModTime() time.Time { return time.Time{} }
155func (fi mapFIMode() os.FileMode {
156    if fi.IsDir() {
157        return 0755 | os.ModeDir
158    }
159    return 0444
160}
161func (fi mapFIName() string     { return pathpkg.Base(fi.name) }
162func (fi mapFISize() int64      { return int64(fi.size) }
163func (fi mapFISys() interface{} { return nil }
164
165type nopCloser struct {
166    io.ReadSeeker
167}
168
169func (nc nopCloserClose() error { return nil }
170
MembersX
mapFS.Lstat.ents
mapFS.Stat.p
mapFS.ReadDir
mapFS.ReadDir.p
mapFS.ReadDir.RangeStmt_2524.BlockStmt.dir
mapFI.size
mapFI.ModTime
mapFS.Lstat
mapFS.String.fs
fileInfo
nopCloser.Close.nc
nopCloser.Close
fmt
mapFS.Open.p
mapFS.ReadDir.RangeStmt_2524.BlockStmt.BlockStmt.BlockStmt.BlockStmt.fi
mapFI.IsDir
mapFI.Sys
New
mapFS.ReadDir.RangeStmt_2524.fn
mapFS
mapFS.Lstat.p
mapFS.ReadDir.fim
mapFS.ReadDir.RangeStmt_2524.BlockStmt.lastBase
mapFS.ReadDir.list
nopCloser
mapFS.RootType.p
fileInfo.contents
mapFS.ReadDir.RangeStmt_2524.b
sort
mapFS.Close.fs
slashdir
mapFI.name
mapFS.RootType.fs
filename.p
mapFS.ReadDir.RangeStmt_2524.BlockStmt.BlockStmt.BlockStmt.base
mapFI
mapFI.IsDir.fi
mapFI.Mode.fi
mapFI.Name.fi
mapFI.Name
New.m
fileInfo.name
slashdir.p
mapFI.Mode
mapFS.RootType
mapFS.Stat.fs
mapFI.Size
mapFI.Sys.fi
vfs
slashdir.d
mapFS.ReadDir.RangeStmt_2524.BlockStmt.isFile
mapFI.dir
mapFI.ModTime.fi
mapFI.Size.fi
mapFS.Lstat.fs
mapFS.ReadDir.fs
dirInfo
filename
mapFS.Open.fs
mapFS.Open
mapFS.Stat
mapFS.ReadDir.ents
mapFS.String
New.pathsWithLeadingSlash
mapFS.Close
os
New.RangeStmt_832.p
dirInfo.name
mapFS.Lstat._
mapFS.ReadDir.RangeStmt_3139.dir
strings
pathpkg
time
io
Members
X