@@ -24,93 +24,112 @@ import (
24
24
"strings"
25
25
)
26
26
27
+ const (
28
+ Version = `v0.0.2`
29
+ )
30
+
27
31
var (
28
- stepOneEncoding = map [string ] string {
29
- " " : "^20" ,
30
- " \" " : "^22" ,
31
- "<" : "^3c" ,
32
- " \\ " : "^5c" ,
33
- "*" : "^2a" ,
34
- "=" : "^3d" ,
35
- "^" : "^5e" ,
36
- "+" : "^2b" ,
37
- ">" : "^3e" ,
38
- "|" : "^7c" ,
39
- "," : "^2c" ,
40
- "?" : "^3f" ,
32
+ stepOneEncoding = map [rune ][] rune {
33
+ ' ' : [] rune ( "^20" ) ,
34
+ '"' : [] rune ( "^22" ) ,
35
+ '<' : [] rune ( "^3c" ) ,
36
+ '\\' : [] rune ( "^5c" ) ,
37
+ '*' : [] rune ( "^2a" ) ,
38
+ '=' : [] rune ( "^3d" ) ,
39
+ '^' : [] rune ( "^5e" ) ,
40
+ '+' : [] rune ( "^2b" ) ,
41
+ '>' : [] rune ( "^3e" ) ,
42
+ '|' : [] rune ( "^7c" ) ,
43
+ ',' : [] rune ( "^2c" ) ,
44
+ '?' : [] rune ( "^3f" ) ,
41
45
}
42
- stepTwoEncoding = map [string ] string {
43
- "/" : "=" ,
44
- ":" : "+" ,
45
- "." : "," ,
46
+ stepTwoEncoding = map [rune ] rune {
47
+ '/' : '=' ,
48
+ ':' : '+' ,
49
+ '.' : ',' ,
46
50
}
47
51
)
48
52
49
- func charEncode (s string ) string {
50
- //NOTE: we need to replace ^ with ^5e and avoid collisions with other hex values
51
- // we split the string into an array of substrings then replace each one as as need to.
52
- p := strings .Split (s , "" )
53
- for i , target := range p {
54
- if val , ok := stepOneEncoding [target ]; ok == true {
55
- p [i ] = val
53
+ func charEncode (src []rune ) []rune {
54
+ // NOTE: We run through stepOneEncoding map first, then stepTwoEncoding...
55
+ results := []rune {}
56
+ for i := 0 ; i < len (src ); i ++ {
57
+ if val , ok := stepOneEncoding [src [i ]]; ok == true {
58
+ results = append (results , val ... )
59
+ } else {
60
+ results = append (results , src [i ])
56
61
}
57
62
}
58
- s = strings . Join ( p , "" )
59
- for target , replacement := range stepTwoEncoding {
60
- if strings . Contains ( s , target ) {
61
- s = strings . Replace ( s , target , replacement , - 1 )
63
+ for i := 0 ; i < len ( results ); i ++ {
64
+ key := results [ i ]
65
+ if val , ok := stepTwoEncoding [ key ]; ok == true {
66
+ results [ i ] = val
62
67
}
63
68
}
64
- return s
69
+ return results
65
70
}
66
71
67
72
func charDecode (s string ) string {
68
73
for replacement , target := range stepTwoEncoding {
69
- if strings .Contains (s , target ) {
70
- s = strings .Replace (s , target , replacement , - 1 )
74
+ t := string (target )
75
+ r := string (replacement )
76
+ if strings .Contains (s , t ) {
77
+ s = strings .Replace (s , t , r , - 1 )
71
78
}
72
79
}
73
80
for replacement , target := range stepOneEncoding {
74
- if strings .Contains (s , target ) {
75
- s = strings .Replace (s , target , replacement , - 1 )
81
+ t := string (target )
82
+ r := string (replacement )
83
+ if strings .Contains (s , t ) {
84
+ s = strings .Replace (s , t , r , - 1 )
76
85
}
77
86
}
78
87
return s
79
88
}
80
89
81
90
// Encode takes a string and encodes it as a pairtree path.
82
91
func Encode (src string ) string {
83
- s := charEncode (src )
84
- results := []string {}
92
+ //s := charEncode(src)
93
+ //s := []rune(src)
94
+ s := charEncode ([]rune (src ))
95
+ results := []rune {}
85
96
for i := 0 ; i < len (s ); i += 2 {
97
+ if len (results ) > 0 {
98
+ results = append (results , os .PathSeparator )
99
+ }
86
100
if (i + 2 ) < len (s ) {
101
+ //FIXME need to char encode here...
87
102
t := s [i : i + 2 ]
88
- results = append (results , t )
103
+ results = append (results , t ... )
89
104
} else {
105
+ //FIXME need to char encode here...
90
106
t := s [i :]
91
- results = append (results , t )
107
+ results = append (results , t ... )
92
108
}
93
109
}
94
- results = append (results , "" )
95
- return strings .Join (results , string (os .PathSeparator ))
110
+ if len (results ) > 0 {
111
+ return string (results ) + "/"
112
+ }
113
+ return string (results )
96
114
}
97
115
98
116
// Decode takes a pairtree path and returns the original string representation
99
117
func Decode (src string ) string {
100
- parts := strings . Split (src , string ( os . PathSeparator ) )
118
+ s := [] rune (src )
101
119
results := []string {}
102
- for _ , segment := range parts {
103
- if segment == "obj" {
104
- break
105
- }
106
- if len (segment ) > 2 {
107
- break
108
- }
109
- if len (segment ) == 1 {
110
- results = append (results , segment )
111
- break
120
+ prev , cur := 0 , 0
121
+ for ; cur < len (s ); cur ++ {
122
+ if s [cur ] == os .PathSeparator {
123
+ switch cur - prev {
124
+ case 2 :
125
+ results = append (results , string (s [prev :cur ]))
126
+ prev = cur + 1
127
+ case 1 :
128
+ results = append (results , string (s [prev :cur ]))
129
+ default :
130
+ break
131
+ }
112
132
}
113
- results = append (results , segment )
114
133
}
115
134
return charDecode (strings .Join (results , "" ))
116
135
}
0 commit comments