github.com/philpearl/plenc@v0.0.15/null/null.go (about) 1 // Package null contains plenc codecs for the types in github.com/unravelin/null. 2 // Call RegisterCodecs to make these codecs available to plenc 3 package null 4 5 import ( 6 "reflect" 7 "time" 8 "unsafe" 9 10 "github.com/philpearl/plenc" 11 "github.com/philpearl/plenc/plenccodec" 12 "github.com/philpearl/plenc/plenccore" 13 "github.com/unravelin/null" 14 ) 15 16 // RegisterCodecs registers the codecs from this package and makes them 17 // available to plenc. 18 func RegisterCodecs() { 19 plenc.RegisterCodec(reflect.TypeOf(null.Int{}), nullIntCodec{}) 20 plenc.RegisterCodec(reflect.TypeOf(null.Bool{}), nullBoolCodec{}) 21 plenc.RegisterCodec(reflect.TypeOf(null.Float{}), nullFloatCodec{}) 22 plenc.RegisterCodec(reflect.TypeOf(null.String{}), nullStringCodec{}) 23 plenc.RegisterCodec(reflect.TypeOf(null.Time{}), &nullTimeCodec{}) 24 } 25 26 // AddCodecs registers the codecs from this package and makes them 27 // available to the given plenc instance 28 func AddCodecs(p *plenc.Plenc) { 29 p.RegisterCodec(reflect.TypeOf(null.Int{}), nullIntCodec{}) 30 p.RegisterCodec(reflect.TypeOf(null.Bool{}), nullBoolCodec{}) 31 p.RegisterCodec(reflect.TypeOf(null.Float{}), nullFloatCodec{}) 32 p.RegisterCodec(reflect.TypeOf(null.String{}), nullStringCodec{}) 33 p.RegisterCodec(reflect.TypeOf(null.Time{}), &nullTimeCodec{}) 34 } 35 36 type nullIntCodec struct { 37 plenccodec.IntCodec[int64] 38 } 39 40 func (c nullIntCodec) Omit(ptr unsafe.Pointer) bool { 41 n := *(*null.Int)(ptr) 42 return !n.Valid 43 } 44 45 func (c nullIntCodec) Size(ptr unsafe.Pointer, tag []byte) (size int) { 46 ni := (*null.Int)(ptr) 47 return c.IntCodec.Size(unsafe.Pointer(&ni.Int64), tag) 48 } 49 50 func (c nullIntCodec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 51 ni := (*null.Int)(ptr) 52 return c.IntCodec.Append(data, unsafe.Pointer(&ni.Int64), tag) 53 } 54 55 func (c nullIntCodec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 56 var i int64 57 n, err = c.IntCodec.Read(data, unsafe.Pointer(&i), wt) 58 if err != nil { 59 return n, err 60 } 61 ni := (*null.Int)(ptr) 62 ni.SetValid(i) 63 return n, err 64 } 65 66 func (c nullIntCodec) New() unsafe.Pointer { 67 return unsafe.Pointer(&null.Int{}) 68 } 69 70 func (c nullIntCodec) Descriptor() plenccodec.Descriptor { 71 d := c.IntCodec.Descriptor() 72 d.ExplicitPresence = true 73 return d 74 } 75 76 type nullBoolCodec struct { 77 plenccodec.BoolCodec 78 } 79 80 func (c nullBoolCodec) Omit(ptr unsafe.Pointer) bool { 81 n := *(*null.Bool)(ptr) 82 return !n.Valid 83 } 84 85 func (c nullBoolCodec) Size(ptr unsafe.Pointer, tag []byte) (size int) { 86 ni := (*null.Bool)(ptr) 87 return c.BoolCodec.Size(unsafe.Pointer(&ni.Bool), tag) 88 } 89 90 func (c nullBoolCodec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 91 ni := (*null.Bool)(ptr) 92 return c.BoolCodec.Append(data, unsafe.Pointer(&ni.Bool), tag) 93 } 94 95 func (c nullBoolCodec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 96 var b bool 97 n, err = c.BoolCodec.Read(data, unsafe.Pointer(&b), wt) 98 if err != nil { 99 return n, err 100 } 101 nb := (*null.Bool)(ptr) 102 nb.SetValid(b) 103 return n, err 104 } 105 106 func (c nullBoolCodec) New() unsafe.Pointer { 107 return unsafe.Pointer(&null.Bool{}) 108 } 109 110 func (c nullBoolCodec) Descriptor() plenccodec.Descriptor { 111 d := c.BoolCodec.Descriptor() 112 d.ExplicitPresence = true 113 return d 114 } 115 116 type nullFloatCodec struct { 117 plenccodec.Float64Codec 118 } 119 120 func (c nullFloatCodec) Omit(ptr unsafe.Pointer) bool { 121 n := *(*null.Float)(ptr) 122 return !n.Valid 123 } 124 125 func (c nullFloatCodec) Size(ptr unsafe.Pointer, tag []byte) (size int) { 126 nf := (*null.Float)(ptr) 127 return c.Float64Codec.Size(unsafe.Pointer(&nf.Float64), tag) 128 } 129 130 func (c nullFloatCodec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 131 nf := (*null.Float)(ptr) 132 return c.Float64Codec.Append(data, unsafe.Pointer(&nf.Float64), tag) 133 } 134 135 func (c nullFloatCodec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 136 var f float64 137 n, err = c.Float64Codec.Read(data, unsafe.Pointer(&f), wt) 138 if err != nil { 139 return n, err 140 } 141 nf := (*null.Float)(ptr) 142 nf.Valid = true 143 nf.Float64 = f 144 return n, err 145 } 146 147 func (c nullFloatCodec) New() unsafe.Pointer { 148 return unsafe.Pointer(&null.Float{}) 149 } 150 151 func (c nullFloatCodec) Descriptor() plenccodec.Descriptor { 152 d := c.Float64Codec.Descriptor() 153 d.ExplicitPresence = true 154 return d 155 } 156 157 type nullStringCodec struct { 158 plenccodec.StringCodec 159 } 160 161 func (c nullStringCodec) Omit(ptr unsafe.Pointer) bool { 162 n := *(*null.String)(ptr) 163 return !n.Valid 164 } 165 166 func (c nullStringCodec) Size(ptr unsafe.Pointer, tag []byte) (size int) { 167 ns := (*null.String)(ptr) 168 return c.StringCodec.Size(unsafe.Pointer(&ns.String), tag) 169 } 170 171 func (c nullStringCodec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 172 ns := (*null.String)(ptr) 173 return c.StringCodec.Append(data, unsafe.Pointer(&ns.String), tag) 174 } 175 176 func (c nullStringCodec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 177 ns := (*null.String)(ptr) 178 n, err = c.StringCodec.Read(data, unsafe.Pointer(&ns.String), wt) 179 if err != nil { 180 return n, err 181 } 182 ns.Valid = true 183 return n, err 184 } 185 186 func (c nullStringCodec) New() unsafe.Pointer { 187 return unsafe.Pointer(&null.String{}) 188 } 189 190 func (c nullStringCodec) Descriptor() plenccodec.Descriptor { 191 d := c.StringCodec.Descriptor() 192 d.ExplicitPresence = true 193 return d 194 } 195 196 func (nullStringCodec) WithInterning() plenccodec.Codec { 197 c, _ := plenccodec.StringCodec{}.WithInterning().(*plenccodec.InternedStringCodec) 198 return &internedNullStringCodec{ 199 stringCodec: c, 200 } 201 } 202 203 type internedNullStringCodec struct { 204 nullStringCodec 205 stringCodec *plenccodec.InternedStringCodec 206 } 207 208 func (c *internedNullStringCodec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 209 ns := (*null.String)(ptr) 210 n, err = c.stringCodec.Read(data, unsafe.Pointer(&ns.String), wt) 211 if err != nil { 212 return n, err 213 } 214 ns.Valid = true 215 return n, err 216 } 217 218 type nullTimeCodec struct { 219 plenccodec.TimeCodec 220 } 221 222 func (c *nullTimeCodec) Omit(ptr unsafe.Pointer) bool { 223 n := *(*null.Time)(ptr) 224 return !n.Valid 225 } 226 227 func (c *nullTimeCodec) Size(ptr unsafe.Pointer, tag []byte) (size int) { 228 nt := (*null.Time)(ptr) 229 return c.TimeCodec.Size(unsafe.Pointer(&nt.Time), tag) 230 } 231 232 func (c *nullTimeCodec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte { 233 nt := (*null.Time)(ptr) 234 return c.TimeCodec.Append(data, unsafe.Pointer(&nt.Time), tag) 235 } 236 237 func (c *nullTimeCodec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) { 238 var t time.Time 239 n, err = c.TimeCodec.Read(data, unsafe.Pointer(&t), wt) 240 if err != nil { 241 return n, err 242 } 243 nt := (*null.Time)(ptr) 244 nt.Valid = true 245 nt.Time = t 246 return n, err 247 } 248 249 func (c *nullTimeCodec) New() unsafe.Pointer { 250 return unsafe.Pointer(&null.Time{}) 251 } 252 253 func (c nullTimeCodec) Descriptor() plenccodec.Descriptor { 254 d := c.TimeCodec.Descriptor() 255 d.ExplicitPresence = true 256 return d 257 }