1
0
mirror of https://github.com/golang/go synced 2024-10-04 05:31:21 -06:00

godoc: fix zip file directory lookup

Also: remove left-over println calls.

R=bradfitz
CC=golang-dev
https://golang.org/cl/4807042
This commit is contained in:
Robert Griesemer 2011-07-20 16:22:13 -07:00
parent 816c972ff0
commit 4c03bf9c59
2 changed files with 30 additions and 18 deletions

View File

@ -61,7 +61,6 @@ func (f *httpZipFile) Stat() (*os.FileInfo, os.Error) {
} }
func (f *httpZipFile) Readdir(count int) ([]os.FileInfo, os.Error) { func (f *httpZipFile) Readdir(count int) ([]os.FileInfo, os.Error) {
println("Readdir", f.info.Name)
if f.info.IsRegular() { if f.info.IsRegular() {
return nil, fmt.Errorf("Readdir called for regular file: %s", f.info.Name) return nil, fmt.Errorf("Readdir called for regular file: %s", f.info.Name)
} }
@ -134,14 +133,15 @@ type httpZipFS struct {
} }
func (fs *httpZipFS) Open(abspath string) (http.File, os.Error) { func (fs *httpZipFS) Open(abspath string) (http.File, os.Error) {
name := path.Join(fs.root, abspath) name := path.Join(fs.root, abspath) // name is clean
index := fs.list.lookup(name) index, exact := fs.list.lookup(name)
if index < 0 { if index < 0 {
return nil, fmt.Errorf("file not found: %s", abspath) return nil, fmt.Errorf("file not found: %s", abspath)
} }
if f := fs.list[index]; f.Name == name { if exact {
// exact match found - must be a file // exact match found - must be a file
f := fs.list[index]
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
return nil, err return nil, err
@ -159,7 +159,6 @@ func (fs *httpZipFS) Open(abspath string) (http.File, os.Error) {
} }
// not an exact match - must be a directory // not an exact match - must be a directory
println("opened directory", abspath, len(fs.list[index:]))
return &httpZipFile{ return &httpZipFile{
os.FileInfo{ os.FileInfo{
Name: abspath, Name: abspath,

View File

@ -73,22 +73,23 @@ func (fs *zipFS) Close() os.Error {
} }
func zipPath(name string) string { func zipPath(name string) string {
name = path.Clean(name)
if !path.IsAbs(name) { if !path.IsAbs(name) {
panic(fmt.Sprintf("stat: not an absolute path: %s", name)) panic(fmt.Sprintf("stat: not an absolute path: %s", name))
} }
return name[1:] // strip '/' return name[1:] // strip leading '/'
} }
func (fs *zipFS) stat(abspath string) (int, zipFI, os.Error) { func (fs *zipFS) stat(abspath string) (int, zipFI, os.Error) {
i := fs.list.lookup(abspath) i, exact := fs.list.lookup(abspath)
if i < 0 { if i < 0 {
return -1, zipFI{}, fmt.Errorf("file not found: %s", abspath) return -1, zipFI{}, fmt.Errorf("file not found: %s", abspath)
} }
_, name := path.Split(abspath)
var file *zip.File var file *zip.File
if abspath == fs.list[i].Name { if exact {
file = fs.list[i] // exact match found - must be a file file = fs.list[i] // exact match found - must be a file
} }
_, name := path.Split(abspath)
return i, zipFI{name, file}, nil return i, zipFI{name, file}, nil
} }
@ -173,17 +174,29 @@ func (z zipList) Len() int { return len(z) }
func (z zipList) Less(i, j int) bool { return z[i].Name < z[j].Name } func (z zipList) Less(i, j int) bool { return z[i].Name < z[j].Name }
func (z zipList) Swap(i, j int) { z[i], z[j] = z[j], z[i] } func (z zipList) Swap(i, j int) { z[i], z[j] = z[j], z[i] }
// lookup returns the first index in the zipList // lookup returns the smallest index of an entry with an exact match
// of a path equal to name or beginning with name/. // for name, or an inexact match starting with name/. If there is no
func (z zipList) lookup(name string) int { // such entry, the result is -1, false.
func (z zipList) lookup(name string) (index int, exact bool) {
// look for exact match first (name comes before name/ in z)
i := sort.Search(len(z), func(i int) bool { i := sort.Search(len(z), func(i int) bool {
return name <= z[i].Name return name <= z[i].Name
}) })
if i >= 0 { if i < 0 {
iname := z[i].Name return -1, false
if strings.HasPrefix(iname, name) && (len(name) == len(iname) || iname[len(name)] == '/') {
return i
} }
if z[i].Name == name {
return i, true
} }
return -1 // no match
// look for inexact match (must be in z[i:], if present)
z = z[i:]
name += "/"
j := sort.Search(len(z), func(i int) bool {
return name <= z[i].Name
})
if j < 0 {
return -1, false
}
return i + j, false
} }