github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/streamer.go (about) 1 package jzon 2 3 import ( 4 "io" 5 ) 6 7 // Streamer is a chained class for encoding object to json 8 type Streamer struct { 9 cfg *EncoderConfig 10 11 writer io.Writer 12 buffer []byte 13 14 Error error 15 poped bool 16 17 // TODO: 1. type of context? 18 // TODO: 2. should context be reset as well? 19 Context interface{} // custom stream context 20 21 // runtime 22 escapeHTML bool 23 safeSet []string 24 // prefix string 25 // indent string 26 } 27 28 // NewStreamer returns a new streamer 29 func NewStreamer() *Streamer { 30 return DefaultEncoderConfig.NewStreamer() 31 } 32 33 // Release the streamer, the streamer should not be used after call 34 func (s *Streamer) Release() { 35 s.cfg.returnStreamer(s) 36 } 37 38 func (s *Streamer) reset() { 39 s.writer = nil 40 s.Error = nil 41 s.poped = false 42 s.buffer = s.buffer[:0] 43 s.Context = nil 44 } 45 46 // Reset resets the streamer with a new writer 47 func (s *Streamer) Reset(w io.Writer) { 48 s.reset() 49 s.writer = w 50 } 51 52 // EscapeHTML set if the string should be html-escaped 53 func (s *Streamer) EscapeHTML(on bool) { 54 s.escapeHTML = on 55 if on { 56 s.safeSet = htmlSafeSet[:] 57 } else { 58 s.safeSet = safeSet[:] 59 } 60 } 61 62 // func (s *Streamer) SetIndent(prefix, indent string) { 63 // s.prefix = prefix 64 // s.indent = indent 65 // } 66 67 // Flush flushes from buffer to the writer 68 func (s *Streamer) Flush() error { 69 if s.Error != nil { 70 return s.Error 71 } 72 if s.writer == nil { 73 return ErrNoAttachedWriter 74 } 75 l := len(s.buffer) 76 // see comment of io.Writer 77 n, err := s.writer.Write(s.buffer) 78 if n < l { 79 copy(s.buffer, s.buffer[n:]) 80 s.buffer = s.buffer[:l-n] 81 } else { 82 s.buffer = s.buffer[:0] 83 } 84 return err 85 } 86 87 func (s *Streamer) onVal() { 88 if s.poped { 89 s.buffer = append(s.buffer, ',') 90 } else { 91 s.poped = true 92 } 93 } 94 95 // RawString writes a raw object (in string) 96 func (s *Streamer) RawString(raw string) *Streamer { 97 if s.Error != nil { 98 return s 99 } 100 s.onVal() 101 s.buffer = append(s.buffer, raw...) 102 return s 103 } 104 105 // Raw writes a raw object (in byte slice) 106 func (s *Streamer) Raw(raw []byte) *Streamer { 107 if s.Error != nil { 108 return s 109 } 110 s.onVal() 111 s.buffer = append(s.buffer, raw...) 112 return s 113 } 114 115 func (s *Streamer) null() { 116 s.onVal() 117 s.buffer = append(s.buffer, 'n', 'u', 'l', 'l') 118 } 119 120 // Null writes a `null` 121 func (s *Streamer) Null() *Streamer { 122 if s.Error != nil { 123 return s 124 } 125 s.null() 126 return s 127 } 128 129 // True writes a `true` 130 func (s *Streamer) True() *Streamer { 131 if s.Error != nil { 132 return s 133 } 134 s.onVal() 135 s.buffer = append(s.buffer, 't', 'r', 'u', 'e') 136 return s 137 } 138 139 // False writes a `false` 140 func (s *Streamer) False() *Streamer { 141 if s.Error != nil { 142 return s 143 } 144 s.onVal() 145 s.buffer = append(s.buffer, 'f', 'a', 'l', 's', 'e') 146 return s 147 } 148 149 // Bool writes a boolean value 150 func (s *Streamer) Bool(b bool) *Streamer { 151 if b { 152 return s.True() 153 } 154 return s.False() 155 } 156 157 // ObjectStart starts to write an object 158 func (s *Streamer) ObjectStart() *Streamer { 159 if s.Error != nil { 160 return s 161 } 162 s.onVal() 163 s.buffer = append(s.buffer, '{') 164 s.poped = false 165 return s 166 } 167 168 // Field writes an object field 169 func (s *Streamer) Field(field string) *Streamer { 170 if s.Error != nil { 171 return s 172 } 173 s.onVal() 174 s.buffer = encodeString(s.buffer, field, s.safeSet) 175 s.buffer = append(s.buffer, ':') 176 s.poped = false 177 return s 178 } 179 180 // RawField writes an object field (in raw byte slice) 181 func (s *Streamer) RawField(b []byte) *Streamer { 182 if s.Error != nil { 183 return s 184 } 185 s.onVal() 186 s.buffer = append(s.buffer, b...) 187 s.buffer = append(s.buffer, ':') 188 s.poped = false 189 return s 190 } 191 192 // ObjectEnd ends the object writing 193 func (s *Streamer) ObjectEnd() *Streamer { 194 if s.Error != nil { 195 return s 196 } 197 s.buffer = append(s.buffer, '}') 198 s.poped = true 199 return s 200 } 201 202 // ArrayStart starts to write an array 203 func (s *Streamer) ArrayStart() *Streamer { 204 if s.Error != nil { 205 return s 206 } 207 s.onVal() 208 s.buffer = append(s.buffer, '[') 209 s.poped = false 210 return s 211 } 212 213 // ArrayEnd ends the array writing 214 func (s *Streamer) ArrayEnd() *Streamer { 215 if s.Error != nil { 216 return s 217 } 218 s.buffer = append(s.buffer, ']') 219 s.poped = true 220 return s 221 }