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  }