github.com/urso/go-structform@v0.0.2/cborl/visitor.go (about) 1 package cborl 2 3 import ( 4 "encoding/binary" 5 "io" 6 "math" 7 8 structform "github.com/urso/go-structform" 9 ) 10 11 type Visitor struct { 12 w writer 13 scratch [16]byte 14 15 length lengthStack 16 } 17 18 type writer struct { 19 out io.Writer 20 } 21 22 func (w writer) write(b []byte) error { 23 _, err := w.out.Write(b) 24 return err 25 } 26 27 func NewVisitor(out io.Writer) *Visitor { 28 v := &Visitor{w: writer{out}} 29 v.length.stack = v.length.stack0[:0] 30 return v 31 } 32 33 func (vs *Visitor) writeByte(b byte) error { 34 vs.scratch[0] = b 35 return vs.w.write(vs.scratch[:1]) 36 } 37 38 func (vs *Visitor) OnObjectStart(len int, baseType structform.BaseType) error { 39 if err := vs.optLen(majorMap, len); err != nil { 40 return err 41 } 42 43 vs.length.push(int64(len)) 44 return nil 45 } 46 47 func (vs *Visitor) OnObjectFinished() error { 48 if vs.length.pop() < 0 { 49 return vs.writeByte(codeBreak) 50 } 51 return nil 52 } 53 54 func (vs *Visitor) OnKey(s string) error { 55 return vs.string(str2Bytes(s)) 56 } 57 58 func (vs *Visitor) OnKeyRef(s []byte) error { 59 return vs.string(s) 60 } 61 62 func (vs *Visitor) OnArrayStart(len int, baseType structform.BaseType) error { 63 if err := vs.optLen(majorArr, len); err != nil { 64 return err 65 } 66 67 vs.length.push(int64(len)) 68 return nil 69 } 70 71 func (vs *Visitor) OnArrayFinished() error { 72 if vs.length.pop() < 0 { 73 return vs.writeByte(codeBreak) 74 } 75 return nil 76 } 77 78 func (vs *Visitor) OnNil() error { 79 return vs.writeByte(codeNull) 80 } 81 82 func (vs *Visitor) OnBool(b bool) error { 83 if b { 84 return vs.writeByte(codeTrue) 85 } 86 return vs.writeByte(codeFalse) 87 } 88 89 func (vs *Visitor) OnString(s string) error { 90 return vs.string(str2Bytes(s)) 91 } 92 93 func (vs *Visitor) OnStringRef(s []byte) error { 94 return vs.string(s) 95 } 96 97 func (vs *Visitor) OnInt8(i int8) error { 98 return vs.int8(i) 99 } 100 101 func (vs *Visitor) OnInt16(i int16) error { 102 return vs.int16(i) 103 } 104 105 func (vs *Visitor) OnInt32(i int32) error { 106 return vs.int32(i) 107 } 108 109 func (vs *Visitor) OnInt64(i int64) error { 110 return vs.int64(i) 111 } 112 113 func (vs *Visitor) OnInt(i int) error { 114 return vs.int64(int64(i)) 115 } 116 117 func (vs *Visitor) OnByte(b byte) error { 118 return vs.uint8(majorUint, b) 119 } 120 121 func (vs *Visitor) OnUint8(u uint8) error { 122 return vs.uint8(majorUint, u) 123 } 124 125 func (vs *Visitor) OnUint16(u uint16) error { 126 return vs.uint16(majorUint, u) 127 } 128 129 func (vs *Visitor) OnUint32(u uint32) error { 130 return vs.uint32(majorUint, u) 131 } 132 133 func (vs *Visitor) OnUint64(u uint64) error { 134 return vs.uint64(majorUint, u) 135 } 136 137 func (vs *Visitor) OnUint(u uint) error { 138 return vs.uint64(majorUint, uint64(u)) 139 } 140 141 func (vs *Visitor) OnFloat32(f float32) error { 142 b := math.Float32bits(f) 143 vs.scratch[0] = codeSingleFloat 144 binary.BigEndian.PutUint32(vs.scratch[1:5], b) 145 return vs.w.write(vs.scratch[:5]) 146 } 147 148 func (vs *Visitor) OnFloat64(f float64) error { 149 b := math.Float64bits(f) 150 vs.scratch[0] = codeDoubleFloat 151 binary.BigEndian.PutUint64(vs.scratch[1:9], b) 152 return vs.w.write(vs.scratch[:9]) 153 } 154 155 func (vs *Visitor) OnBoolArray(a []bool) error { 156 if err := vs.arrLen(len(a)); err != nil { 157 return nil 158 } 159 for _, v := range a { 160 if err := vs.OnBool(v); err != nil { 161 return err 162 } 163 } 164 165 return nil 166 } 167 168 func (vs *Visitor) OnStringArray(a []string) error { 169 if err := vs.arrLen(len(a)); err != nil { 170 return nil 171 } 172 for _, v := range a { 173 if err := vs.OnString(v); err != nil { 174 return err 175 } 176 } 177 return nil 178 } 179 180 func (vs *Visitor) OnInt8Array(a []int8) error { 181 if err := vs.arrLen(len(a)); err != nil { 182 return nil 183 } 184 for _, v := range a { 185 if err := vs.OnInt8(v); err != nil { 186 return err 187 } 188 } 189 return nil 190 } 191 192 func (vs *Visitor) OnInt16Array(a []int16) error { 193 if err := vs.arrLen(len(a)); err != nil { 194 return nil 195 } 196 for _, v := range a { 197 if err := vs.OnInt16(v); err != nil { 198 return err 199 } 200 } 201 return nil 202 } 203 204 func (vs *Visitor) OnInt32Array(a []int32) error { 205 if err := vs.arrLen(len(a)); err != nil { 206 return nil 207 } 208 for _, v := range a { 209 if err := vs.OnInt32(v); err != nil { 210 return err 211 } 212 } 213 return nil 214 } 215 216 func (vs *Visitor) OnInt64Array(a []int64) error { 217 if err := vs.arrLen(len(a)); err != nil { 218 return nil 219 } 220 for _, v := range a { 221 if err := vs.OnInt64(v); err != nil { 222 return err 223 } 224 } 225 return nil 226 } 227 228 func (vs *Visitor) OnIntArray(a []int) error { 229 if err := vs.arrLen(len(a)); err != nil { 230 return nil 231 } 232 for _, v := range a { 233 if err := vs.OnInt(v); err != nil { 234 return err 235 } 236 } 237 return nil 238 } 239 240 func (vs *Visitor) OnBytes(a []byte) error { 241 return vs.bytes(majorBytes, a) 242 } 243 244 func (vs *Visitor) OnUint8Array(a []uint8) error { 245 return vs.bytes(majorBytes, a) 246 } 247 248 func (vs *Visitor) OnUint16Array(a []uint16) error { 249 if err := vs.arrLen(len(a)); err != nil { 250 return nil 251 } 252 for _, v := range a { 253 if err := vs.OnUint16(v); err != nil { 254 return err 255 } 256 } 257 return nil 258 } 259 260 func (vs *Visitor) OnUint32Array(a []uint32) error { 261 if err := vs.arrLen(len(a)); err != nil { 262 return nil 263 } 264 for _, v := range a { 265 if err := vs.OnUint32(v); err != nil { 266 return err 267 } 268 } 269 return nil 270 } 271 272 func (vs *Visitor) OnUint64Array(a []uint64) error { 273 if err := vs.arrLen(len(a)); err != nil { 274 return nil 275 } 276 for _, v := range a { 277 if err := vs.OnUint64(v); err != nil { 278 return err 279 } 280 } 281 return nil 282 } 283 284 func (vs *Visitor) OnUintArray(a []uint) error { 285 if err := vs.arrLen(len(a)); err != nil { 286 return nil 287 } 288 for _, v := range a { 289 if err := vs.OnUint(v); err != nil { 290 return err 291 } 292 } 293 return nil 294 } 295 296 func (vs *Visitor) OnFloat32Array(a []float32) error { 297 if err := vs.arrLen(len(a)); err != nil { 298 return nil 299 } 300 for _, v := range a { 301 if err := vs.OnFloat32(v); err != nil { 302 return err 303 } 304 } 305 return nil 306 } 307 308 func (vs *Visitor) OnFloat64Array(a []float64) error { 309 if err := vs.arrLen(len(a)); err != nil { 310 return nil 311 } 312 for _, v := range a { 313 if err := vs.OnFloat64(v); err != nil { 314 return err 315 } 316 } 317 return nil 318 } 319 320 func (vs *Visitor) string(s []byte) error { 321 return vs.bytes(majorText, s) 322 } 323 324 func (vs *Visitor) bytes(major uint8, buf []byte) error { 325 if err := vs.uint64(major, uint64(len(buf))); err != nil { 326 return err 327 } 328 return vs.w.write(buf) 329 } 330 331 func (vs *Visitor) arrLen(len int) error { 332 return vs.uint64(majorArr, uint64(len)) 333 } 334 335 func (vs *Visitor) optLen(major uint8, len int) error { 336 if len < 0 { 337 return vs.writeByte(major | lenIndef) 338 } 339 return vs.uint64(major, uint64(len)) 340 } 341 342 func (vs *Visitor) int8(v int8) error { 343 if v < 0 { 344 return vs.uint8(majorNeg, ^uint8(v)) 345 } 346 return vs.uint8(majorUint, uint8(v)) 347 } 348 349 func (vs *Visitor) int16(v int16) error { 350 if v < 0 { 351 return vs.uint16(majorNeg, ^uint16(v)) 352 } 353 return vs.uint16(majorUint, uint16(v)) 354 } 355 356 func (vs *Visitor) int32(v int32) error { 357 if v < 0 { 358 return vs.uint32(majorNeg, ^uint32(v)) 359 } 360 return vs.uint32(majorUint, uint32(v)) 361 } 362 363 func (vs *Visitor) int64(v int64) error { 364 if v < 0 { 365 return vs.uint64(majorNeg, ^uint64(v)) 366 } 367 return vs.uint64(majorUint, uint64(v)) 368 } 369 370 func (vs *Visitor) uint8(major uint8, v uint8) error { 371 if v < len8b { 372 return vs.writeByte(major | v) 373 } 374 375 vs.scratch[0], vs.scratch[1] = major|len8b, v 376 return vs.w.write(vs.scratch[:2]) 377 } 378 379 func (vs *Visitor) uint16(major uint8, v uint16) error { 380 switch { 381 case v < uint16(len8b): 382 return vs.writeByte(major | uint8(v)) 383 case v <= math.MaxUint8: 384 vs.scratch[0], vs.scratch[1] = major|len8b, uint8(v) 385 return vs.w.write(vs.scratch[:2]) 386 default: 387 vs.scratch[0] = major | len16b 388 binary.BigEndian.PutUint16(vs.scratch[1:3], v) 389 return vs.w.write(vs.scratch[:3]) 390 } 391 } 392 393 func (vs *Visitor) uint32(major uint8, v uint32) error { 394 switch { 395 case v < uint32(len8b): 396 return vs.writeByte(major | uint8(v)) 397 case v <= math.MaxUint8: 398 vs.scratch[0], vs.scratch[1] = major|len8b, uint8(v) 399 return vs.w.write(vs.scratch[:2]) 400 case v <= math.MaxUint16: 401 vs.scratch[0] = major | len16b 402 binary.BigEndian.PutUint16(vs.scratch[1:3], uint16(v)) 403 return vs.w.write(vs.scratch[:3]) 404 default: 405 vs.scratch[0] = major | len32b 406 binary.BigEndian.PutUint32(vs.scratch[1:5], v) 407 return vs.w.write(vs.scratch[:5]) 408 } 409 } 410 411 func (vs *Visitor) uint64(major uint8, v uint64) error { 412 switch { 413 case v < uint64(len8b): 414 return vs.writeByte(major | uint8(v)) 415 case v <= math.MaxUint8: 416 vs.scratch[0], vs.scratch[1] = major|len8b, uint8(v) 417 return vs.w.write(vs.scratch[:2]) 418 case v <= math.MaxUint16: 419 vs.scratch[0] = major | len16b 420 binary.BigEndian.PutUint16(vs.scratch[1:3], uint16(v)) 421 return vs.w.write(vs.scratch[:3]) 422 case v <= math.MaxUint32: 423 vs.scratch[0] = major | len32b 424 binary.BigEndian.PutUint32(vs.scratch[1:5], uint32(v)) 425 return vs.w.write(vs.scratch[:5]) 426 default: 427 vs.scratch[0] = major | len64b 428 binary.BigEndian.PutUint64(vs.scratch[1:9], uint64(v)) 429 return vs.w.write(vs.scratch[:9]) 430 } 431 }