github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_encoder_iface.go (about) 1 package jzon 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type IfaceValEncoder interface { 9 Encode(o interface{}, s *Streamer, opts *EncOpts) 10 } 11 12 type IfaceValEncoderConfig struct { 13 Type reflect.Type 14 Encoder IfaceValEncoder 15 } 16 17 type ifaceValEncoder struct { 18 isEmpty isEmptyFunc 19 encoder IfaceValEncoder 20 rtype rtype 21 } 22 23 func (enc *ifaceValEncoder) IsEmpty(ptr unsafe.Pointer) bool { 24 return enc.isEmpty(ptr) 25 } 26 27 func (enc *ifaceValEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) { 28 if s.Error != nil { 29 return 30 } 31 if ptr == nil { 32 s.Null() 33 return 34 } 35 obj := packEFace(enc.rtype, ptr) 36 enc.encoder.Encode(obj, s, opts) 37 } 38 39 type pointerIfaceValEncoder struct { 40 encoder IfaceValEncoder 41 rtype rtype 42 } 43 44 func (pointerIfaceValEncoder) IsEmpty(ptr unsafe.Pointer) bool { 45 return *(*unsafe.Pointer)(ptr) == nil 46 } 47 48 func (enc *pointerIfaceValEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) { 49 if s.Error != nil { 50 return 51 } 52 if ptr == nil { 53 s.Null() 54 return 55 } 56 ptr = *(*unsafe.Pointer)(ptr) 57 if ptr == nil { 58 s.Null() 59 return 60 } 61 obj := packEFace(enc.rtype, ptr) 62 enc.encoder.Encode(obj, s, opts) 63 } 64 65 type directIfaceValEncoder struct { 66 isEmpty isEmptyFunc 67 encoder IfaceValEncoder 68 rtype rtype 69 } 70 71 func (enc *directIfaceValEncoder) IsEmpty(ptr unsafe.Pointer) bool { 72 return enc.isEmpty(ptr) 73 } 74 75 func (enc *directIfaceValEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) { 76 if s.Error != nil { 77 return 78 } 79 if ptr == nil { 80 s.Null() 81 return 82 } 83 obj := packEFace(enc.rtype, *(*unsafe.Pointer)(ptr)) 84 enc.encoder.Encode(obj, s, opts) 85 } 86 87 type dynamicIfaceValEncoder struct { 88 encoder IfaceValEncoder 89 rtype rtype 90 } 91 92 func (enc *dynamicIfaceValEncoder) IsEmpty(ptr unsafe.Pointer) bool { 93 if ptr == nil { 94 return true 95 } 96 obj := packIFace(ptr) 97 return obj == nil 98 } 99 100 func (enc *dynamicIfaceValEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) { 101 if s.Error != nil { 102 return 103 } 104 if ptr == nil { 105 s.Null() 106 return 107 } 108 // ptr is a pointer to the interface (*I) 109 obj := packIFace(ptr) 110 if obj == nil { 111 s.Null() 112 return 113 } 114 enc.encoder.Encode(obj, s, opts) 115 }