mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-12-01 19:06:43 +00:00
129 lines
2.8 KiB
Go
129 lines
2.8 KiB
Go
|
package json
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
// kanged from v2ray
|
||
|
|
||
|
type commentFilterState = byte
|
||
|
|
||
|
const (
|
||
|
commentFilterStateContent commentFilterState = iota
|
||
|
commentFilterStateEscape
|
||
|
commentFilterStateDoubleQuote
|
||
|
commentFilterStateDoubleQuoteEscape
|
||
|
commentFilterStateSingleQuote
|
||
|
commentFilterStateSingleQuoteEscape
|
||
|
commentFilterStateComment
|
||
|
commentFilterStateSlash
|
||
|
commentFilterStateMultilineComment
|
||
|
commentFilterStateMultilineCommentStar
|
||
|
)
|
||
|
|
||
|
type CommentFilter struct {
|
||
|
br *bufio.Reader
|
||
|
state commentFilterState
|
||
|
}
|
||
|
|
||
|
func NewCommentFilter(reader io.Reader) io.Reader {
|
||
|
return &CommentFilter{br: bufio.NewReader(reader)}
|
||
|
}
|
||
|
|
||
|
func (v *CommentFilter) Read(b []byte) (int, error) {
|
||
|
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 commentFilterStateContent:
|
||
|
switch x {
|
||
|
case '"':
|
||
|
v.state = commentFilterStateDoubleQuote
|
||
|
p = append(p, x)
|
||
|
case '\'':
|
||
|
v.state = commentFilterStateSingleQuote
|
||
|
p = append(p, x)
|
||
|
case '\\':
|
||
|
v.state = commentFilterStateEscape
|
||
|
case '#':
|
||
|
v.state = commentFilterStateComment
|
||
|
case '/':
|
||
|
v.state = commentFilterStateSlash
|
||
|
default:
|
||
|
p = append(p, x)
|
||
|
}
|
||
|
case commentFilterStateEscape:
|
||
|
p = append(p, '\\', x)
|
||
|
v.state = commentFilterStateContent
|
||
|
case commentFilterStateDoubleQuote:
|
||
|
switch x {
|
||
|
case '"':
|
||
|
v.state = commentFilterStateContent
|
||
|
p = append(p, x)
|
||
|
case '\\':
|
||
|
v.state = commentFilterStateDoubleQuoteEscape
|
||
|
default:
|
||
|
p = append(p, x)
|
||
|
}
|
||
|
case commentFilterStateDoubleQuoteEscape:
|
||
|
p = append(p, '\\', x)
|
||
|
v.state = commentFilterStateDoubleQuote
|
||
|
case commentFilterStateSingleQuote:
|
||
|
switch x {
|
||
|
case '\'':
|
||
|
v.state = commentFilterStateContent
|
||
|
p = append(p, x)
|
||
|
case '\\':
|
||
|
v.state = commentFilterStateSingleQuoteEscape
|
||
|
default:
|
||
|
p = append(p, x)
|
||
|
}
|
||
|
case commentFilterStateSingleQuoteEscape:
|
||
|
p = append(p, '\\', x)
|
||
|
v.state = commentFilterStateSingleQuote
|
||
|
case commentFilterStateComment:
|
||
|
if x == '\n' {
|
||
|
v.state = commentFilterStateContent
|
||
|
p = append(p, '\n')
|
||
|
}
|
||
|
case commentFilterStateSlash:
|
||
|
switch x {
|
||
|
case '/':
|
||
|
v.state = commentFilterStateComment
|
||
|
case '*':
|
||
|
v.state = commentFilterStateMultilineComment
|
||
|
default:
|
||
|
p = append(p, '/', x)
|
||
|
}
|
||
|
case commentFilterStateMultilineComment:
|
||
|
switch x {
|
||
|
case '*':
|
||
|
v.state = commentFilterStateMultilineCommentStar
|
||
|
case '\n':
|
||
|
p = append(p, '\n')
|
||
|
}
|
||
|
case commentFilterStateMultilineCommentStar:
|
||
|
switch x {
|
||
|
case '/':
|
||
|
v.state = commentFilterStateContent
|
||
|
case '*':
|
||
|
// Stay
|
||
|
case '\n':
|
||
|
p = append(p, '\n')
|
||
|
default:
|
||
|
v.state = commentFilterStateMultilineComment
|
||
|
}
|
||
|
default:
|
||
|
panic("Unknown state.")
|
||
|
}
|
||
|
}
|
||
|
return len(p), nil
|
||
|
}
|