1package bare 2 3import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 "math" 8) 9 10// A Writer for BARE primitive types. 11type Writer struct { 12 base io.Writer 13 scratch [binary.MaxVarintLen64]byte 14} 15 16// Returns a new BARE primitive writer wrapping the given io.Writer. 17func NewWriter(base io.Writer) *Writer { 18 return &Writer{base: base} 19} 20 21func (w *Writer) WriteUint(i uint64) error { 22 n := binary.PutUvarint(w.scratch[:], i) 23 _, err := w.base.Write(w.scratch[:n]) 24 return err 25} 26 27func (w *Writer) WriteU8(i uint8) error { 28 return binary.Write(w.base, binary.LittleEndian, i) 29} 30 31func (w *Writer) WriteU16(i uint16) error { 32 return binary.Write(w.base, binary.LittleEndian, i) 33} 34 35func (w *Writer) WriteU32(i uint32) error { 36 return binary.Write(w.base, binary.LittleEndian, i) 37} 38 39func (w *Writer) WriteU64(i uint64) error { 40 return binary.Write(w.base, binary.LittleEndian, i) 41} 42 43func (w *Writer) WriteInt(i int64) error { 44 var buf [binary.MaxVarintLen64]byte 45 n := binary.PutVarint(buf[:], i) 46 _, err := w.base.Write(buf[:n]) 47 return err 48} 49 50func (w *Writer) WriteI8(i int8) error { 51 return binary.Write(w.base, binary.LittleEndian, i) 52} 53 54func (w *Writer) WriteI16(i int16) error { 55 return binary.Write(w.base, binary.LittleEndian, i) 56} 57 58func (w *Writer) WriteI32(i int32) error { 59 return binary.Write(w.base, binary.LittleEndian, i) 60} 61 62func (w *Writer) WriteI64(i int64) error { 63 return binary.Write(w.base, binary.LittleEndian, i) 64} 65 66func (w *Writer) WriteF32(f float32) error { 67 if math.IsNaN(float64(f)) { 68 return fmt.Errorf("NaN is not permitted in BARE floats") 69 } 70 return binary.Write(w.base, binary.LittleEndian, f) 71} 72 73func (w *Writer) WriteF64(f float64) error { 74 if math.IsNaN(f) { 75 return fmt.Errorf("NaN is not permitted in BARE floats") 76 } 77 return binary.Write(w.base, binary.LittleEndian, f) 78} 79 80func (w *Writer) WriteBool(b bool) error { 81 return binary.Write(w.base, binary.LittleEndian, b) 82} 83 84func (w *Writer) WriteString(str string) error { 85 return w.WriteData([]byte(str)) 86} 87 88// Writes a fixed amount of arbitrary data, defined by the length of the slice. 89func (w *Writer) WriteDataFixed(data []byte) error { 90 var amt int = 0 91 for amt < len(data) { 92 n, err := w.base.Write(data[amt:]) 93 if err != nil { 94 return err 95 } 96 amt += n 97 } 98 return nil 99} 100 101// Writes arbitrary data whose length is encoded into the message. 102func (w *Writer) WriteData(data []byte) error { 103 err := w.WriteUint(uint64(len(data))) 104 if err != nil { 105 return err 106 } 107 var amt int = 0 108 for amt < len(data) { 109 n, err := w.base.Write(data[amt:]) 110 if err != nil { 111 return err 112 } 113 amt += n 114 } 115 return nil 116} 117