github.com/philpearl/plenc@v0.0.15/plenccodec/float.go (about)

     1  package plenccodec
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"math"
     7  	"unsafe"
     8  
     9  	"github.com/philpearl/plenc/plenccore"
    10  )
    11  
    12  // Float64Codec is a coddec for a float64
    13  type Float64Codec struct{}
    14  
    15  // append encodes a float64
    16  func (Float64Codec) append(data []byte, ptr unsafe.Pointer) []byte {
    17  	var b [8]byte
    18  	binary.LittleEndian.PutUint64(b[:], math.Float64bits(*(*float64)(ptr)))
    19  	return append(data, b[:]...)
    20  }
    21  
    22  // Read decodes a float64
    23  func (Float64Codec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) {
    24  	if l := len(data); l < 8 {
    25  		if l == 0 {
    26  			*(*float64)(ptr) = 0
    27  			return 0, nil
    28  		}
    29  		return 0, fmt.Errorf("not enough data to read a float64. Have %d bytes", len(data))
    30  	}
    31  	bits := binary.LittleEndian.Uint64(data)
    32  	*(*float64)(ptr) = math.Float64frombits(bits)
    33  	return 8, nil
    34  }
    35  
    36  // New creates a pointer to a new float64
    37  func (c Float64Codec) New() unsafe.Pointer {
    38  	return unsafe.Pointer(new(float64))
    39  }
    40  
    41  // WireType returns the wire type used to encode this type
    42  func (c Float64Codec) WireType() plenccore.WireType {
    43  	return plenccore.WT64
    44  }
    45  
    46  // Omit indicates whether this field should be omitted
    47  func (c Float64Codec) Omit(ptr unsafe.Pointer) bool {
    48  	return *(*float64)(ptr) == 0
    49  }
    50  
    51  func (c Float64Codec) Descriptor() Descriptor {
    52  	return Descriptor{Type: FieldTypeFloat64}
    53  }
    54  
    55  func (c Float64Codec) Size(ptr unsafe.Pointer, tag []byte) int {
    56  	return 8 + len(tag)
    57  }
    58  
    59  func (c Float64Codec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte {
    60  	data = append(data, tag...)
    61  	return c.append(data, ptr)
    62  }
    63  
    64  // Float32Codec is a coddec for a float32
    65  type Float32Codec struct{}
    66  
    67  // append encodes a float32
    68  func (Float32Codec) append(data []byte, ptr unsafe.Pointer) []byte {
    69  	var b [4]byte
    70  	binary.LittleEndian.PutUint32(b[:], math.Float32bits(*(*float32)(ptr)))
    71  	return append(data, b[:]...)
    72  }
    73  
    74  // Read decodes a float32
    75  func (Float32Codec) Read(data []byte, ptr unsafe.Pointer, wt plenccore.WireType) (n int, err error) {
    76  	if l := len(data); l < 4 {
    77  		if l == 0 {
    78  			*(*float32)(ptr) = 0
    79  			return 0, nil
    80  		}
    81  		return 0, fmt.Errorf("not enough data to read a float32. Have %d bytes", l)
    82  	}
    83  	bits := binary.LittleEndian.Uint32(data)
    84  	*(*float32)(ptr) = math.Float32frombits(bits)
    85  	return 4, nil
    86  }
    87  
    88  // New creates a pointer to a new float32
    89  func (c Float32Codec) New() unsafe.Pointer {
    90  	return unsafe.Pointer(new(float32))
    91  }
    92  
    93  // WireType returns the wire type used to encode this type
    94  func (c Float32Codec) WireType() plenccore.WireType {
    95  	return plenccore.WT32
    96  }
    97  
    98  // Omit indicates whether this field should be omitted
    99  func (c Float32Codec) Omit(ptr unsafe.Pointer) bool {
   100  	return *(*float32)(ptr) == 0
   101  }
   102  
   103  func (c Float32Codec) Descriptor() Descriptor {
   104  	return Descriptor{Type: FieldTypeFloat32}
   105  }
   106  
   107  func (c Float32Codec) Size(ptr unsafe.Pointer, tag []byte) int {
   108  	return 4 + len(tag)
   109  }
   110  
   111  func (c Float32Codec) Append(data []byte, ptr unsafe.Pointer, tag []byte) []byte {
   112  	data = append(data, tag...)
   113  	return c.append(data, ptr)
   114  }