generated from OtusGolang/home_work
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunpack.go
58 lines (52 loc) · 1.24 KB
/
unpack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package hw02unpackstring
import (
"errors"
"strings"
)
var ErrInvalidString = errors.New("invalid string")
func isASCIIDigit(r rune) bool {
return r >= '0' && r <= '9'
}
func Unpack(input string) (string, error) {
var sb strings.Builder
var currentSymbol rune // Last symbol read from input.
currentSymbolOk := false // If the last_symbol ready to copy to output.
escape := false // True if escape is active for the current symbol.
for _, r := range input {
switch {
case escape && isASCIIDigit(r):
currentSymbol = r
currentSymbolOk = true
escape = false
case isASCIIDigit(r):
if !currentSymbolOk {
return "", ErrInvalidString
}
// Do repeat.
for count := int(r - '0'); count > 0; count-- {
sb.WriteRune(currentSymbol)
}
currentSymbolOk = false
case escape && r == '\\':
escape = false
currentSymbol, currentSymbolOk = r, true
case r == '\\':
sb.WriteRune(currentSymbol)
escape = true
currentSymbolOk = false
default:
if escape {
return "", ErrInvalidString
}
if currentSymbolOk {
sb.WriteRune(currentSymbol)
}
currentSymbol, currentSymbolOk = r, true
escape = false
}
}
if currentSymbolOk {
sb.WriteRune(currentSymbol)
}
return sb.String(), nil
}