123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- 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
- }
|