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  }