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 }