github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/_vendor/src/golang.org/x/tools/godoc/util/util.go (about) 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 } 63 64 // IsTextFile reports whether the file has a known extension indicating 65 // a text file, or if a significant chunk of the specified file looks like 66 // correct UTF-8; that is, if it is likely that the file contains human- 67 // readable text. 68 func IsTextFile(fs vfs.Opener, filename string) bool { 69 // if the extension is known, use it for decision making 70 if isText, found := textExt[pathpkg.Ext(filename)]; found { 71 return isText 72 } 73 74 // the extension is not known; read an initial chunk 75 // of the file and check if it looks like text 76 f, err := fs.Open(filename) 77 if err != nil { 78 return false 79 } 80 defer f.Close() 81 82 var buf [1024]byte 83 n, err := f.Read(buf[0:]) 84 if err != nil { 85 return false 86 } 87 88 return IsText(buf[0:n]) 89 }