github.com/iDigitalFlame/xmt@v0.5.4/data/data_writer.go (about) 1 // Copyright (C) 2020 - 2023 iDigitalFlame 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 // 16 17 package data 18 19 import "io" 20 21 type writer struct { 22 _ [0]func() 23 w io.Writer 24 } 25 type flusher interface { 26 Flush() error 27 } 28 29 func (w *writer) Flush() error { 30 if f, ok := w.w.(flusher); ok { 31 return f.Flush() 32 } 33 return nil 34 } 35 func (w *writer) Close() error { 36 if c, ok := w.w.(io.Closer); ok { 37 return c.Close() 38 } 39 return nil 40 } 41 42 // NewWriter creates a simple Writer struct from the base Writer provided. 43 func NewWriter(w io.Writer) Writer { 44 return &writer{w: w} 45 } 46 func (w *writer) WriteInt(n int) error { 47 return w.WriteUint64(uint64(n)) 48 } 49 func (w *writer) WriteUint(n uint) error { 50 return w.WriteUint64(uint64(n)) 51 } 52 func (w *writer) WriteInt8(n int8) error { 53 return w.WriteUint8(uint8(n)) 54 } 55 func (w *writer) WriteBool(b bool) error { 56 if b { 57 return w.WriteUint8(1) 58 } 59 return w.WriteUint8(0) 60 } 61 func (w *writer) WriteInt16(n int16) error { 62 return w.WriteUint16(uint16(n)) 63 } 64 func (w *writer) WriteInt32(n int32) error { 65 return w.WriteUint32(uint32(n)) 66 } 67 func (w *writer) WriteInt64(n int64) error { 68 return w.WriteUint64(uint64(n)) 69 } 70 func (w *writer) WriteUint8(n uint8) error { 71 v, err := w.w.Write([]byte{n}) 72 if err == nil && v != 1 { 73 return io.ErrShortWrite 74 } 75 return err 76 } 77 func (w *writer) WriteBytes(b []byte) error { 78 switch l := uint64(len(b)); { 79 case l == 0: 80 v, err := w.w.Write([]byte{0}) 81 if err == nil && v != 1 { 82 return io.ErrShortWrite 83 } 84 return err 85 case l < LimitSmall: 86 if v, err := w.w.Write([]byte{1, byte(l)}); err != nil { 87 return err 88 } else if v != 2 { 89 return io.ErrShortWrite 90 } 91 case l < LimitMedium: 92 if v, err := w.w.Write([]byte{3, byte(l >> 8), byte(l)}); err != nil { 93 return err 94 } else if v != 3 { 95 return io.ErrShortWrite 96 } 97 case l < LimitLarge: 98 if v, err := w.w.Write([]byte{5, byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l)}); err != nil { 99 return err 100 } else if v != 5 { 101 return io.ErrShortWrite 102 } 103 default: 104 if v, err := w.w.Write([]byte{ 105 7, byte(l >> 56), byte(l >> 48), byte(l >> 40), byte(l >> 32), 106 byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l), 107 }); err != nil { 108 return nil 109 } else if v != 9 { 110 return io.ErrShortWrite 111 } 112 } 113 _, err := w.w.Write(b) 114 return err 115 } 116 func (w *writer) WriteUint16(n uint16) error { 117 v, err := w.w.Write([]byte{byte(n >> 8), byte(n)}) 118 if err == nil && v != 2 { 119 return io.ErrShortWrite 120 } 121 return err 122 } 123 func (w *writer) WriteUint32(n uint32) error { 124 v, err := w.w.Write([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)}) 125 if err == nil && v != 4 { 126 return io.ErrShortWrite 127 } 128 return err 129 } 130 func (w *writer) WriteUint64(n uint64) error { 131 v, err := w.w.Write([]byte{ 132 byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32), 133 byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n), 134 }) 135 if err == nil && v != 8 { 136 return io.ErrShortWrite 137 } 138 return err 139 } 140 func (w *writer) WriteString(s string) error { 141 return w.WriteBytes([]byte(s)) 142 } 143 func (w *writer) Write(b []byte) (int, error) { 144 return w.w.Write(b) 145 } 146 func (w *writer) WriteFloat32(f float32) error { 147 return w.WriteUint32(float32ToInt(f)) 148 } 149 func (w *writer) WriteFloat64(f float64) error { 150 return w.WriteUint64(float64ToInt(f)) 151 }