github.com/aacfactory/avro@v1.2.12/internal/base/reader.go (about) 1 package base 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "strings" 8 "unsafe" 9 ) 10 11 const ( 12 maxIntBufSize = 5 13 maxLongBufSize = 10 14 ) 15 16 // ReaderFunc is a function used to customize the Reader. 17 type ReaderFunc func(r *Reader) 18 19 // WithReaderConfig specifies the configuration to use with a reader. 20 func WithReaderConfig(cfg API) ReaderFunc { 21 return func(r *Reader) { 22 r.cfg = cfg.(*frozenConfig) 23 } 24 } 25 26 // Reader is an Avro specific io.Reader. 27 type Reader struct { 28 cfg *frozenConfig 29 reader io.Reader 30 slab []byte 31 buf []byte 32 head int 33 tail int 34 Error error 35 } 36 37 // NewReader creates a new Reader. 38 func NewReader(r io.Reader, bufSize int, opts ...ReaderFunc) *Reader { 39 reader := &Reader{ 40 cfg: DefaultConfig.(*frozenConfig), 41 reader: r, 42 buf: make([]byte, bufSize), 43 head: 0, 44 tail: 0, 45 } 46 47 for _, opt := range opts { 48 opt(reader) 49 } 50 51 return reader 52 } 53 54 // Reset resets a Reader with a new byte array attached. 55 func (r *Reader) Reset(b []byte) *Reader { 56 r.reader = nil 57 r.buf = b 58 r.head = 0 59 r.tail = len(b) 60 return r 61 } 62 63 // ReportError record a error in iterator instance with current position. 64 func (r *Reader) ReportError(operation, msg string) { 65 if r.Error != nil && !errors.Is(r.Error, io.EOF) { 66 return 67 } 68 69 r.Error = fmt.Errorf("avro: %s: %s", operation, msg) 70 } 71 72 func (r *Reader) loadMore() bool { 73 if r.reader == nil { 74 if r.Error == nil { 75 r.head = r.tail 76 r.Error = io.EOF 77 } 78 return false 79 } 80 81 for { 82 n, err := r.reader.Read(r.buf) 83 if n == 0 { 84 if err != nil { 85 if r.Error == nil { 86 r.Error = err 87 } 88 return false 89 } 90 continue 91 } 92 93 r.head = 0 94 r.tail = n 95 return true 96 } 97 } 98 99 func (r *Reader) readByte() byte { 100 if r.head == r.tail { 101 if !r.loadMore() { 102 return 0 103 } 104 } 105 106 b := r.buf[r.head] 107 r.head++ 108 109 return b 110 } 111 112 // Read reads data into the given bytes. 113 func (r *Reader) Read(b []byte) { 114 size := len(b) 115 read := 0 116 117 for read < size { 118 if r.head == r.tail { 119 if !r.loadMore() { 120 return 121 } 122 } 123 124 n := copy(b[read:], r.buf[r.head:r.tail]) 125 r.head += n 126 read += n 127 } 128 } 129 130 // ReadBool reads a Bool from the Reader. 131 func (r *Reader) ReadBool() bool { 132 b := r.readByte() 133 134 if b != 0 && b != 1 { 135 r.ReportError("ReadBool", "invalid bool") 136 } 137 return b == 1 138 } 139 140 // ReadInt reads an Int from the Reader. 141 func (r *Reader) ReadInt() int32 { 142 var val uint32 143 var offset int8 144 145 for r.Error == nil { 146 if offset == maxIntBufSize { 147 r.ReportError("ReadInt", "int overflow") 148 return 0 149 } 150 151 b := r.readByte() 152 val |= uint32(b&0x7F) << uint(7*offset) 153 if b&0x80 == 0 { 154 break 155 } 156 offset++ 157 } 158 159 return int32((val >> 1) ^ -(val & 1)) 160 } 161 162 // ReadLong reads a Long from the Reader. 163 func (r *Reader) ReadLong() int64 { 164 var val uint64 165 var offset int8 166 167 for r.Error == nil { 168 if offset == maxLongBufSize { 169 r.ReportError("ReadLong", "long overflow") 170 return 0 171 } 172 173 b := r.readByte() 174 val |= uint64(b&0x7F) << uint(7*offset) 175 if b&0x80 == 0 { 176 break 177 } 178 offset++ 179 } 180 181 return int64((val >> 1) ^ -(val & 1)) 182 } 183 184 // ReadFloat reads a Float from the Reader. 185 func (r *Reader) ReadFloat() float32 { 186 var buf [4]byte 187 r.Read(buf[:]) 188 189 float := *(*float32)(unsafe.Pointer(&buf[0])) 190 return float 191 } 192 193 // ReadDouble reads a Double from the Reader. 194 func (r *Reader) ReadDouble() float64 { 195 var buf [8]byte 196 r.Read(buf[:]) 197 198 float := *(*float64)(unsafe.Pointer(&buf[0])) 199 return float 200 } 201 202 // ReadBytes reads Bytes from the Reader. 203 func (r *Reader) ReadBytes() []byte { 204 return r.readBytes("bytes") 205 } 206 207 // ReadString reads a String from the Reader. 208 func (r *Reader) ReadString() string { 209 b := r.readBytes("string") 210 if len(b) == 0 { 211 return "" 212 } 213 214 return *(*string)(unsafe.Pointer(&b)) 215 } 216 217 func (r *Reader) readBytes(op string) []byte { 218 size := int(r.ReadLong()) 219 if size < 0 { 220 fnName := "Read" + strings.ToTitle(op) 221 r.ReportError(fnName, "invalid "+op+" length") 222 return nil 223 } 224 if size == 0 { 225 return []byte{} 226 } 227 if max := r.cfg.getMaxByteSliceSize(); max > 0 && size > max { 228 fnName := "Read" + strings.ToTitle(op) 229 r.ReportError(fnName, "size is greater than `Config.MaxByteSliceSize`") 230 return nil 231 } 232 233 // The bytes are entirely in the buffer and of a reasonable size. 234 // Use the byte slab. 235 if r.head+size <= r.tail && size <= 1024 { 236 if cap(r.slab) < size { 237 r.slab = make([]byte, 1024) 238 } 239 dst := r.slab[:size] 240 r.slab = r.slab[size:] 241 copy(dst, r.buf[r.head:r.head+size]) 242 r.head += size 243 return dst 244 } 245 246 buf := make([]byte, size) 247 r.Read(buf) 248 return buf 249 } 250 251 // ReadBlockHeader reads a Block Header from the Reader. 252 func (r *Reader) ReadBlockHeader() (int64, int64) { 253 length := r.ReadLong() 254 if length < 0 { 255 size := r.ReadLong() 256 257 return -length, size 258 } 259 260 return length, 0 261 }