github.com/LagrangeDev/LagrangeGo@v0.0.0-20240512064304-ad4a85e10cb4/utils/binary/reader.go (about) 1 package binary 2 3 import ( 4 "encoding/binary" 5 "io" 6 "strconv" 7 "unsafe" 8 9 "github.com/LagrangeDev/LagrangeGo/utils" 10 ) 11 12 type Reader struct { 13 reader io.Reader 14 buffer []byte 15 pos int 16 } 17 18 func ParseReader(reader io.Reader) *Reader { 19 return &Reader{ 20 reader: reader, 21 } 22 } 23 24 func NewReader(buffer []byte) *Reader { 25 return &Reader{ 26 buffer: buffer, 27 } 28 } 29 30 func (r *Reader) Len() int { 31 if r.reader != nil { 32 return -1 33 } 34 return len(r.buffer) - r.pos 35 } 36 37 // String means read all available data and return them as a string 38 // 39 // if r.reader got error, it will returns as err.Error() 40 func (r *Reader) String() string { 41 if r.reader != nil { 42 data, err := io.ReadAll(r.reader) 43 if err != nil { 44 return err.Error() 45 } 46 return utils.B2S(data) 47 } 48 s := string(r.buffer[r.pos:]) 49 r.pos = 0 50 r.buffer = r.buffer[:0] 51 return s 52 } 53 54 // ReadAll means read all available data and return them 55 // 56 // if r.reader got error, it will return nil 57 func (r *Reader) ReadAll() []byte { 58 if r.reader != nil { 59 data, err := io.ReadAll(r.reader) 60 if err != nil { 61 return nil 62 } 63 return data 64 } 65 s := r.buffer[r.pos:] 66 r.pos = 0 67 r.buffer = r.buffer[:0] 68 buf := make([]byte, len(s)) 69 copy(buf, s) 70 return s 71 } 72 73 func (r *Reader) ReadU8() (v uint8) { 74 if r.reader != nil { 75 _, _ = r.reader.Read(unsafe.Slice(&v, 1)) 76 return 77 } 78 v = r.buffer[r.pos] 79 r.pos++ 80 return 81 } 82 83 func readint[T ~uint16 | ~uint32 | ~uint64](r *Reader) (v T) { 84 sz := unsafe.Sizeof(v) 85 buf := make([]byte, 8) 86 if r.reader != nil { 87 _, _ = r.reader.Read(buf[8-sz:]) 88 } else { 89 copy(buf[8-sz:], r.buffer[r.pos:r.pos+int(sz)]) 90 r.pos += int(sz) 91 } 92 v = (T)(binary.BigEndian.Uint64(buf)) 93 return 94 } 95 96 func (r *Reader) ReadU16() (v uint16) { 97 return readint[uint16](r) 98 } 99 100 func (r *Reader) ReadU32() (v uint32) { 101 return readint[uint32](r) 102 } 103 func (r *Reader) ReadU64() (v uint64) { 104 return readint[uint64](r) 105 } 106 107 func (r *Reader) SkipBytes(length int) { 108 if r.reader != nil { 109 _, _ = r.reader.Read(make([]byte, length)) 110 return 111 } 112 r.pos += length 113 } 114 115 // ReadBytesNoCopy 不拷贝读取的数据, 用于读取后立即使用, 慎用 116 // 117 // 如需使用, 请确保 Reader 未被回收 118 func (r *Reader) ReadBytesNoCopy(length int) (v []byte) { 119 if r.reader != nil { 120 return r.ReadBytes(length) 121 } 122 v = r.buffer[r.pos : r.pos+length] 123 r.pos += length 124 return 125 } 126 127 func (r *Reader) ReadBytes(length int) (v []byte) { 128 // 返回一个全新的数组罢 129 v = make([]byte, length) 130 if r.reader != nil { 131 _, _ = r.reader.Read(v) 132 } else { 133 copy(v, r.buffer[r.pos:r.pos+length]) 134 r.pos += length 135 } 136 return 137 } 138 139 func (r *Reader) ReadString(length int) string { 140 return utils.B2S(r.ReadBytes(length)) 141 } 142 143 func (r *Reader) SkipBytesWithLength(prefix string, withPerfix bool) { 144 var length int 145 switch prefix { 146 case "u8": 147 length = int(r.ReadU8()) 148 case "u16": 149 length = int(r.ReadU16()) 150 case "u32": 151 length = int(r.ReadU32()) 152 case "u64": 153 length = int(r.ReadU64()) 154 default: 155 panic("invaild prefix") 156 } 157 if withPerfix { 158 plus, err := strconv.Atoi(prefix[1:]) 159 if err != nil { 160 panic(err) 161 } 162 length -= plus / 8 163 } 164 r.SkipBytes(length) 165 } 166 167 func (r *Reader) ReadBytesWithLength(prefix string, withPerfix bool) []byte { 168 var length int 169 switch prefix { 170 case "u8": 171 length = int(r.ReadU8()) 172 case "u16": 173 length = int(r.ReadU16()) 174 case "u32": 175 length = int(r.ReadU32()) 176 case "u64": 177 length = int(r.ReadU64()) 178 default: 179 panic("invaild prefix") 180 } 181 if withPerfix { 182 plus, err := strconv.Atoi(prefix[1:]) 183 if err != nil { 184 panic(err) 185 } 186 length -= plus / 8 187 } 188 return r.ReadBytes(length) 189 } 190 191 func (r *Reader) ReadStringWithLength(prefix string, withPerfix bool) string { 192 return utils.B2S(r.ReadBytesWithLength(prefix, withPerfix)) 193 } 194 195 func (r *Reader) ReadTlv() (result map[uint16][]byte) { 196 result = map[uint16][]byte{} 197 count := r.ReadU16() 198 199 for i := 0; i < int(count); i++ { 200 tag := r.ReadU16() 201 result[tag] = r.ReadBytes(int(r.ReadU16())) 202 } 203 return 204 } 205 206 func (r *Reader) ReadI8() (v int8) { 207 return int8(r.ReadU8()) 208 } 209 210 func (r *Reader) ReadI16() (v int16) { 211 return int16(r.ReadU16()) 212 } 213 214 func (r *Reader) ReadI32() (v int32) { 215 return int32(r.ReadU32()) 216 } 217 218 func (r *Reader) ReadI64() (v int64) { 219 return int64(r.ReadU64()) 220 }