github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/fichier/replace.go (about)

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