reader.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package json
  2. import (
  3. "io"
  4. )
  5. // State is the internal state of parser.
  6. type State byte
  7. const (
  8. StateContent State = iota
  9. StateEscape
  10. StateDoubleQuote
  11. StateDoubleQuoteEscape
  12. StateSingleQuote
  13. StateSingleQuoteEscape
  14. StateComment
  15. StateSlash
  16. StateMultilineComment
  17. StateMultilineCommentStar
  18. )
  19. // Reader is a JSON reader which allows comments.
  20. type Reader struct {
  21. io.Reader
  22. state State
  23. }
  24. // Read implements io.Reader.Read().
  25. func (v *Reader) Read(b []byte) (int, error) {
  26. n, err := v.Reader.Read(b)
  27. if err != nil {
  28. return n, err
  29. }
  30. p := b[:0]
  31. for _, x := range b[:n] {
  32. switch v.state {
  33. case StateContent:
  34. switch x {
  35. case '"':
  36. v.state = StateDoubleQuote
  37. p = append(p, x)
  38. case '\'':
  39. v.state = StateSingleQuote
  40. p = append(p, x)
  41. case '\\':
  42. v.state = StateEscape
  43. case '#':
  44. v.state = StateComment
  45. case '/':
  46. v.state = StateSlash
  47. default:
  48. p = append(p, x)
  49. }
  50. case StateEscape:
  51. p = append(p, '\\', x)
  52. v.state = StateContent
  53. case StateDoubleQuote:
  54. switch x {
  55. case '"':
  56. v.state = StateContent
  57. p = append(p, x)
  58. case '\\':
  59. v.state = StateDoubleQuoteEscape
  60. default:
  61. p = append(p, x)
  62. }
  63. case StateDoubleQuoteEscape:
  64. p = append(p, '\\', x)
  65. v.state = StateDoubleQuote
  66. case StateSingleQuote:
  67. switch x {
  68. case '\'':
  69. v.state = StateContent
  70. p = append(p, x)
  71. case '\\':
  72. v.state = StateSingleQuoteEscape
  73. default:
  74. p = append(p, x)
  75. }
  76. case StateSingleQuoteEscape:
  77. p = append(p, '\\', x)
  78. v.state = StateSingleQuote
  79. case StateComment:
  80. if x == '\n' {
  81. v.state = StateContent
  82. }
  83. case StateSlash:
  84. switch x {
  85. case '/':
  86. v.state = StateComment
  87. case '*':
  88. v.state = StateMultilineComment
  89. default:
  90. p = append(p, '/', x)
  91. }
  92. case StateMultilineComment:
  93. if x == '*' {
  94. v.state = StateMultilineCommentStar
  95. }
  96. case StateMultilineCommentStar:
  97. switch x {
  98. case '/':
  99. v.state = StateContent
  100. case '*':
  101. // Stay
  102. default:
  103. v.state = StateMultilineComment
  104. }
  105. default:
  106. panic("Unknown state.")
  107. }
  108. }
  109. return len(p), nil
  110. }