1 package battlemap 2 3 import ( 4 "io" 5 "net/http" 6 "strconv" 7 "unsafe" 8 ) 9 10 type fileType uint8 11 12 const ( 13 fileTypeUnknown fileType = iota 14 fileTypeImage 15 fileTypeAudio 16 fileTypeCharacter 17 fileTypeMap 18 ) 19 20 type getFileType struct { 21 Buffer [512]byte 22 Type fileType 23 } 24 25 func (g *getFileType) ReadFrom(r io.Reader) (int64, error) { 26 n, err := io.ReadFull(r, g.Buffer[:]) 27 if err != nil { 28 return int64(n), err 29 } 30 switch http.DetectContentType(g.Buffer[:n]) { 31 case "image/gif", "image/png", "image/jpeg", "image/webp", "video/apng": 32 g.Type = fileTypeImage 33 case "application/ogg", "audio/mpeg": 34 g.Type = fileTypeAudio 35 case "application/x-gzip": 36 g.Type = fileTypeCharacter 37 case "text/plain; charset=utf-8": 38 g.Type = fileTypeMap 39 default: 40 g.Type = fileTypeUnknown 41 } 42 return int64(n), nil 43 } 44 45 func isRoot(path string) bool { 46 return path == "/" || path == "" 47 } 48 49 func uniqueName(name string, checker func(string) bool) string { 50 if checker(name) { 51 return name 52 } 53 n := make([]byte, len(name)+32) 54 m := n[len(name)+1 : len(name)+1] 55 copy(n, name) 56 n[len(name)] = '.' 57 for i := uint64(0); ; i++ { 58 p := n[:len(name)+1+len(strconv.AppendUint(m, i, 10))] 59 newName := *(*string)(unsafe.Pointer(&p)) 60 if checker(newName) { 61 return newName 62 } 63 } 64 } 65