github.com/richardwilkes/toolbox@v1.121.0/xio/fs/filename.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package fs 11 12 import ( 13 "path/filepath" 14 "strings" 15 ) 16 17 // SanitizeName sanitizes a file name by replacing invalid characters. 18 func SanitizeName(name string) string { 19 if name == "" { 20 return "@0" 21 } 22 if name == "." { 23 return "@1" 24 } 25 if name == ".." { 26 return "@2" 27 } 28 var buffer strings.Builder 29 for _, r := range name { 30 switch r { 31 case '@': 32 buffer.WriteString("@3") 33 case '/': 34 buffer.WriteString("@4") 35 case '\\': 36 buffer.WriteString("@5") 37 case ':': 38 buffer.WriteString("@6") 39 default: 40 buffer.WriteRune(r) 41 } 42 } 43 return buffer.String() 44 } 45 46 // UnsanitizeName reverses the effects of a call to SanitizeName. 47 func UnsanitizeName(name string) string { 48 if name == "@0" { 49 return "" 50 } 51 if name == "@1" { 52 return "." 53 } 54 if name == "@2" { 55 return ".." 56 } 57 var buffer strings.Builder 58 found := false 59 for _, r := range name { 60 switch { 61 case found: 62 switch r { 63 case '3': 64 buffer.WriteByte('@') 65 case '4': 66 buffer.WriteByte('/') 67 case '5': 68 buffer.WriteByte('\\') 69 case '6': 70 buffer.WriteByte(':') 71 default: 72 buffer.WriteByte('@') 73 buffer.WriteRune(r) 74 } 75 found = false 76 case r == '@': 77 found = true 78 default: 79 buffer.WriteRune(r) 80 } 81 } 82 if found { 83 buffer.WriteByte('@') 84 } 85 return buffer.String() 86 } 87 88 // BaseName returns the file name without the directory or extension. 89 func BaseName(path string) string { 90 return TrimExtension(filepath.Base(path)) 91 } 92 93 // TrimExtension trims any extension from the path. 94 func TrimExtension(path string) string { 95 return path[:len(path)-len(filepath.Ext(path))] 96 }