Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / godoc / util / util.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 util contains utility types and functions for godoc.
6 package util // import "golang.org/x/tools/godoc/util"
7
8 import (
9         pathpkg "path"
10         "sync"
11         "time"
12         "unicode/utf8"
13
14         "golang.org/x/tools/godoc/vfs"
15 )
16
17 // An RWValue wraps a value and permits mutually exclusive
18 // access to it and records the time the value was last set.
19 type RWValue struct {
20         mutex     sync.RWMutex
21         value     interface{}
22         timestamp time.Time // time of last set()
23 }
24
25 func (v *RWValue) Set(value interface{}) {
26         v.mutex.Lock()
27         v.value = value
28         v.timestamp = time.Now()
29         v.mutex.Unlock()
30 }
31
32 func (v *RWValue) Get() (interface{}, time.Time) {
33         v.mutex.RLock()
34         defer v.mutex.RUnlock()
35         return v.value, v.timestamp
36 }
37
38 // IsText reports whether a significant prefix of s looks like correct UTF-8;
39 // that is, if it is likely that s is human-readable text.
40 func IsText(s []byte) bool {
41         const max = 1024 // at least utf8.UTFMax
42         if len(s) > max {
43                 s = s[0:max]
44         }
45         for i, c := range string(s) {
46                 if i+utf8.UTFMax > len(s) {
47                         // last char may be incomplete - ignore
48                         break
49                 }
50                 if c == 0xFFFD || c < ' ' && c != '\n' && c != '\t' && c != '\f' {
51                         // decoding error or control character - not a text file
52                         return false
53                 }
54         }
55         return true
56 }
57
58 // textExt[x] is true if the extension x indicates a text file, and false otherwise.
59 var textExt = map[string]bool{
60         ".css": false, // must be served raw
61         ".js":  false, // must be served raw
62         ".svg": false, // must be served raw
63 }
64
65 // IsTextFile reports whether the file has a known extension indicating
66 // a text file, or if a significant chunk of the specified file looks like
67 // correct UTF-8; that is, if it is likely that the file contains human-
68 // readable text.
69 func IsTextFile(fs vfs.Opener, filename string) bool {
70         // if the extension is known, use it for decision making
71         if isText, found := textExt[pathpkg.Ext(filename)]; found {
72                 return isText
73         }
74
75         // the extension is not known; read an initial chunk
76         // of the file and check if it looks like text
77         f, err := fs.Open(filename)
78         if err != nil {
79                 return false
80         }
81         defer f.Close()
82
83         var buf [1024]byte
84         n, err := f.Read(buf[0:])
85         if err != nil {
86                 return false
87         }
88
89         return IsText(buf[0:n])
90 }