| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- package json
- import (
- "io"
- )
- // 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 JSON reader which allows comments.
- type Reader struct {
- io.Reader
- state State
- }
- // Read implements io.Reader.Read().
- func (v *Reader) Read(b []byte) (int, error) {
- n, err := v.Reader.Read(b)
- if err != nil {
- return n, err
- }
- p := b[:0]
- for _, x := range b[:n] {
- 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
- }
- case StateSlash:
- switch x {
- case '/':
- v.state = StateComment
- case '*':
- v.state = StateMultilineComment
- default:
- p = append(p, '/', x)
- }
- case StateMultilineComment:
- if x == '*' {
- v.state = StateMultilineCommentStar
- }
- case StateMultilineCommentStar:
- switch x {
- case '/':
- v.state = StateContent
- case '*':
- // Stay
- default:
- v.state = StateMultilineComment
- }
- default:
- panic("Unknown state.")
- }
- }
- return len(p), nil
- }
|