Hunter0x7c7
2022-08-11 a82f9cb69f63aaeba40c024960deda7d75b9fece
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package json
 
import (
    "io"
 
    "github.com/v2fly/v2ray-core/v5/common/buf"
)
 
// State is the internal state of parser.
type State byte
 
const (
    StateContent State = iota
    StateEscape
    StateDoubleQuote
    StateDoubleQuoteEscape
    StateSingleQuote
    StateSingleQuoteEscape
    StateComment
    StateSlash
    StateMultilineComment
    StateMultilineCommentStar
)
 
// Reader is a reader for filtering comments.
// It supports Java style single and multi line comment syntax, and Python style single line comment syntax.
type Reader struct {
    io.Reader
 
    state State
    br    *buf.BufferedReader
}
 
// Read implements io.Reader.Read(). Buffer must be at least 3 bytes.
func (v *Reader) Read(b []byte) (int, error) {
    if v.br == nil {
        v.br = &buf.BufferedReader{Reader: buf.NewReader(v.Reader)}
    }
 
    p := b[:0]
    for len(p) < len(b)-2 {
        x, err := v.br.ReadByte()
        if err != nil {
            if len(p) == 0 {
                return 0, err
            }
            return len(p), nil
        }
        switch v.state {
        case StateContent:
            switch x {
            case '"':
                v.state = StateDoubleQuote
                p = append(p, x)
            case '\'':
                v.state = StateSingleQuote
                p = append(p, x)
            case '\\':
                v.state = StateEscape
            case '#':
                v.state = StateComment
            case '/':
                v.state = StateSlash
            default:
                p = append(p, x)
            }
        case StateEscape:
            p = append(p, '\\', x)
            v.state = StateContent
        case StateDoubleQuote:
            switch x {
            case '"':
                v.state = StateContent
                p = append(p, x)
            case '\\':
                v.state = StateDoubleQuoteEscape
            default:
                p = append(p, x)
            }
        case StateDoubleQuoteEscape:
            p = append(p, '\\', x)
            v.state = StateDoubleQuote
        case StateSingleQuote:
            switch x {
            case '\'':
                v.state = StateContent
                p = append(p, x)
            case '\\':
                v.state = StateSingleQuoteEscape
            default:
                p = append(p, x)
            }
        case StateSingleQuoteEscape:
            p = append(p, '\\', x)
            v.state = StateSingleQuote
        case StateComment:
            if x == '\n' {
                v.state = StateContent
                p = append(p, '\n')
            }
        case StateSlash:
            switch x {
            case '/':
                v.state = StateComment
            case '*':
                v.state = StateMultilineComment
            default:
                p = append(p, '/', x)
            }
        case StateMultilineComment:
            switch x {
            case '*':
                v.state = StateMultilineCommentStar
            case '\n':
                p = append(p, '\n')
            }
        case StateMultilineCommentStar:
            switch x {
            case '/':
                v.state = StateContent
            case '*':
                // Stay
            case '\n':
                p = append(p, '\n')
            default:
                v.state = StateMultilineComment
            }
        default:
            panic("Unknown state.")
        }
    }
    return len(p), nil
}