github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/jottacloud/replace.go (about) 1 /* 2 Translate file names for JottaCloud adapted from OneDrive 3 4 5 The following characters are JottaCloud reserved characters, and can't 6 be used in JottaCloud folder and file names. 7 8 jottacloud = "/" / "\" / "*" / "<" / ">" / "?" / "!" / "&" / ":" / ";" / "|" / "#" / "%" / """ / "'" / "." / "~" 9 10 11 */ 12 13 package jottacloud 14 15 import ( 16 "regexp" 17 "strings" 18 ) 19 20 // charMap holds replacements for characters 21 // 22 // Onedrive has a restricted set of characters compared to other cloud 23 // storage systems, so we to map these to the FULLWIDTH unicode 24 // equivalents 25 // 26 // http://unicode-search.net/unicode-namesearch.pl?term=SOLIDUS 27 var ( 28 charMap = map[rune]rune{ 29 '\\': '\', // FULLWIDTH REVERSE SOLIDUS 30 '*': '*', // FULLWIDTH ASTERISK 31 '<': '<', // FULLWIDTH LESS-THAN SIGN 32 '>': '>', // FULLWIDTH GREATER-THAN SIGN 33 '?': '?', // FULLWIDTH QUESTION MARK 34 ':': ':', // FULLWIDTH COLON 35 ';': ';', // FULLWIDTH SEMICOLON 36 '|': '|', // FULLWIDTH VERTICAL LINE 37 '"': '"', // FULLWIDTH QUOTATION MARK - not on the list but seems to be reserved 38 ' ': '␠', // SYMBOL FOR SPACE 39 } 40 invCharMap map[rune]rune 41 fixStartingWithSpace = regexp.MustCompile(`(/|^) `) 42 fixEndingWithSpace = regexp.MustCompile(` (/|$)`) 43 ) 44 45 func init() { 46 // Create inverse charMap 47 invCharMap = make(map[rune]rune, len(charMap)) 48 for k, v := range charMap { 49 invCharMap[v] = k 50 } 51 } 52 53 // replaceReservedChars takes a path and substitutes any reserved 54 // characters in it 55 func replaceReservedChars(in string) string { 56 // Filenames can't start with space 57 in = fixStartingWithSpace.ReplaceAllString(in, "$1"+string(charMap[' '])) 58 // Filenames can't end with space 59 in = fixEndingWithSpace.ReplaceAllString(in, string(charMap[' '])+"$1") 60 return strings.Map(func(c rune) rune { 61 if replacement, ok := charMap[c]; ok && c != ' ' { 62 return replacement 63 } 64 return c 65 }, in) 66 } 67 68 // restoreReservedChars takes a path and undoes any substitutions 69 // made by replaceReservedChars 70 func restoreReservedChars(in string) string { 71 return strings.Map(func(c rune) rune { 72 if replacement, ok := invCharMap[c]; ok { 73 return replacement 74 } 75 return c 76 }, in) 77 }