reader.go 1.9 KB

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