mirror of https://github.com/XTLS/Xray-core
				
				
				
			
		
			
				
	
	
		
			134 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
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
 | 
						|
}
 |