summaryrefslogtreecommitdiff
path: root/src/cmd/godoc/zip.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/godoc/zip.go')
-rw-r--r--src/cmd/godoc/zip.go236
1 files changed, 0 insertions, 236 deletions
diff --git a/src/cmd/godoc/zip.go b/src/cmd/godoc/zip.go
deleted file mode 100644
index 620eb4f3c..000000000
--- a/src/cmd/godoc/zip.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file provides an implementation of the FileSystem
-// interface based on the contents of a .zip file.
-//
-// Assumptions:
-//
-// - The file paths stored in the zip file must use a slash ('/') as path
-// separator; and they must be relative (i.e., they must not start with
-// a '/' - this is usually the case if the file was created w/o special
-// options).
-// - The zip file system treats the file paths found in the zip internally
-// like absolute paths w/o a leading '/'; i.e., the paths are considered
-// relative to the root of the file system.
-// - All path arguments to file system methods must be absolute paths.
-
-package main
-
-import (
- "archive/zip"
- "fmt"
- "io"
- "os"
- "path"
- "sort"
- "strings"
- "time"
-)
-
-// zipFI is the zip-file based implementation of FileInfo
-type zipFI struct {
- name string // directory-local name
- file *zip.File // nil for a directory
-}
-
-func (fi zipFI) Name() string {
- return fi.name
-}
-
-func (fi zipFI) Size() int64 {
- if f := fi.file; f != nil {
- return int64(f.UncompressedSize)
- }
- return 0 // directory
-}
-
-func (fi zipFI) ModTime() time.Time {
- if f := fi.file; f != nil {
- return f.ModTime()
- }
- return time.Time{} // directory has no modified time entry
-}
-
-func (fi zipFI) Mode() os.FileMode {
- if fi.file == nil {
- // Unix directories typically are executable, hence 555.
- return os.ModeDir | 0555
- }
- return 0444
-}
-
-func (fi zipFI) IsDir() bool {
- return fi.file == nil
-}
-
-func (fi zipFI) Sys() interface{} {
- return nil
-}
-
-// zipFS is the zip-file based implementation of FileSystem
-type zipFS struct {
- *zip.ReadCloser
- list zipList
- name string
-}
-
-func (fs *zipFS) String() string {
- return "zip(" + fs.name + ")"
-}
-
-func (fs *zipFS) Close() error {
- fs.list = nil
- return fs.ReadCloser.Close()
-}
-
-func zipPath(name string) string {
- name = path.Clean(name)
- if !path.IsAbs(name) {
- panic(fmt.Sprintf("stat: not an absolute path: %s", name))
- }
- return name[1:] // strip leading '/'
-}
-
-func (fs *zipFS) stat(abspath string) (int, zipFI, error) {
- i, exact := fs.list.lookup(abspath)
- if i < 0 {
- // abspath has leading '/' stripped - print it explicitly
- return -1, zipFI{}, fmt.Errorf("file not found: /%s", abspath)
- }
- _, name := path.Split(abspath)
- var file *zip.File
- if exact {
- file = fs.list[i] // exact match found - must be a file
- }
- return i, zipFI{name, file}, nil
-}
-
-func (fs *zipFS) Open(abspath string) (readSeekCloser, error) {
- _, fi, err := fs.stat(zipPath(abspath))
- if err != nil {
- return nil, err
- }
- if fi.IsDir() {
- return nil, fmt.Errorf("Open: %s is a directory", abspath)
- }
- r, err := fi.file.Open()
- if err != nil {
- return nil, err
- }
- return &zipSeek{fi.file, r}, nil
-}
-
-type zipSeek struct {
- file *zip.File
- io.ReadCloser
-}
-
-func (f *zipSeek) Seek(offset int64, whence int) (int64, error) {
- if whence == 0 && offset == 0 {
- r, err := f.file.Open()
- if err != nil {
- return 0, err
- }
- f.Close()
- f.ReadCloser = r
- return 0, nil
- }
- return 0, fmt.Errorf("unsupported Seek in %s", f.file.Name)
-}
-
-func (fs *zipFS) Lstat(abspath string) (os.FileInfo, error) {
- _, fi, err := fs.stat(zipPath(abspath))
- return fi, err
-}
-
-func (fs *zipFS) Stat(abspath string) (os.FileInfo, error) {
- _, fi, err := fs.stat(zipPath(abspath))
- return fi, err
-}
-
-func (fs *zipFS) ReadDir(abspath string) ([]os.FileInfo, error) {
- path := zipPath(abspath)
- i, fi, err := fs.stat(path)
- if err != nil {
- return nil, err
- }
- if !fi.IsDir() {
- return nil, fmt.Errorf("ReadDir: %s is not a directory", abspath)
- }
-
- var list []os.FileInfo
- dirname := path + "/"
- prevname := ""
- for _, e := range fs.list[i:] {
- if !strings.HasPrefix(e.Name, dirname) {
- break // not in the same directory anymore
- }
- name := e.Name[len(dirname):] // local name
- file := e
- if i := strings.IndexRune(name, '/'); i >= 0 {
- // We infer directories from files in subdirectories.
- // If we have x/y, return a directory entry for x.
- name = name[0:i] // keep local directory name only
- file = nil
- }
- // If we have x/y and x/z, don't return two directory entries for x.
- // TODO(gri): It should be possible to do this more efficiently
- // by determining the (fs.list) range of local directory entries
- // (via two binary searches).
- if name != prevname {
- list = append(list, zipFI{name, file})
- prevname = name
- }
- }
-
- return list, nil
-}
-
-func NewZipFS(rc *zip.ReadCloser, name string) FileSystem {
- list := make(zipList, len(rc.File))
- copy(list, rc.File) // sort a copy of rc.File
- sort.Sort(list)
- return &zipFS{rc, list, name}
-}
-
-type zipList []*zip.File
-
-// zipList implements sort.Interface
-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) Swap(i, j int) { z[i], z[j] = z[j], z[i] }
-
-// lookup returns the smallest index of an entry with an exact match
-// for name, or an inexact match starting with name/. If there is no
-// 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 {
- return name <= z[i].Name
- })
- if i >= len(z) {
- return -1, false
- }
- // 0 <= i < len(z)
- if z[i].Name == name {
- return i, true
- }
-
- // 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 >= len(z) {
- return -1, false
- }
- // 0 <= j < len(z)
- if strings.HasPrefix(z[j].Name, name) {
- return i + j, false
- }
-
- return -1, false
-}