| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package json
- import (
- "io"
- "github.com/xtls/xray-core/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
- }
|