// Licensed to the Apache Software Foundation (ASF) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The ASF licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.package utilsimport ()typeReaderinterface {io.ReadSeekerio.ReaderAt}// byteReader is a wrapper for bytes.NewReadertype byteReader struct { r *bytes.Reader buf []byte pos int}// NewByteReader creates a new ByteReader instance from the given byte slice.// It wraps the bytes.NewReader function to implement BufferedReader interface.func ( []byte) *byteReader { := bytes.NewReader()return &byteReader{ , ,0, }}func ( *byteReader) ( []byte) ( int, error) { , = .r.Read() .pos += return}func ( *byteReader) ( int64, int) ( int64, error) { , = .r.Seek(, ) .pos = int()return}func ( *byteReader) ( []byte, int64) ( int, error) {return .r.ReadAt(, )}func ( *byteReader) ( int) ([]byte, error) {if < 0 {returnnil, fmt.Errorf("arrow/bytereader: %w", bufio.ErrNegativeCount) } := len(.buf) - .pos := min(, )varerrorif < { = io.EOF }return .buf[.pos : .pos+], }func ( *byteReader) ( int) (int, error) {if < 0 {return0, fmt.Errorf("arrow/bytereader: %w", bufio.ErrNegativeCount) }var (error = .pos + )if >= len(.buf) { = len(.buf) = - .pos = io.EOF } , := .Seek(int64(), io.SeekCurrent)if != nil {return , }return , }// Outer returns the byteReader itself, since it has already implemented Reader interface.func ( *byteReader) () Reader {return}func ( *byteReader) (Reader) {}func ( *byteReader) () int { returnlen(.buf) }// bufferedReader is similar to bufio.Reader except// it will expand the buffer if necessary when asked to Peek// more bytes than are in the buffertype bufferedReader struct { bufferSz int buf []byte r, w int rd Reader err error}// NewBufferedReader returns a buffered reader with similar semantics to bufio.Reader// except Peek will expand the internal buffer if needed rather than return// an error.func ( Reader, int) *bufferedReader { := &bufferedReader{rd: , } .resizeBuffer()return}func ( *bufferedReader) () Reader { return .rd }func ( *bufferedReader) ( Reader) { .resetBuffer() .rd = .r, .w = 0, 0}func ( *bufferedReader) () {if .buf == nil { .buf = make([]byte, .bufferSz) } elseif .bufferSz > cap(.buf) { := .buf .buf = make([]byte, .bufferSz)copy(.buf, ) } else { .buf = .buf[:.bufferSz] }}func ( *bufferedReader) ( int) { .bufferSz = .resetBuffer()}func ( *bufferedReader) () error {// slide existing data to the beginningif .r > 0 {copy(.buf, .buf[.r:.w]) .w -= .r .r = 0 }if .w >= len(.buf) {returnfmt.Errorf("arrow/bufferedreader: %w", bufio.ErrBufferFull) } , := io.ReadAtLeast(.rd, .buf[.w:], 1)if < 0 {returnfmt.Errorf("arrow/bufferedreader: filling buffer: %w", bufio.ErrNegativeCount) } .w += .err = returnnil}func ( *bufferedReader) () error { := .err .err = nilreturn}func ( *bufferedReader) () int { return .bufferSz }// Buffered returns the number of bytes currently bufferedfunc ( *bufferedReader) () int { return .w - .r }// SetBufferSize resets the size of the internal buffer to the desired size.// Will return an error if newSize is <= 0 or if newSize is less than the size// of the buffered data.func ( *bufferedReader) ( int) error {if <= 0 {returnerrors.New("buffer size should be positive") }if .w >= {returnerrors.New("cannot shrink read buffer if buffered data remains") } .resizeBuffer()returnnil}// Peek will buffer and return n bytes from the underlying reader without advancing// the reader itself. If n is larger than the current buffer size, the buffer will// be expanded to accommodate the extra bytes rather than error.func ( *bufferedReader) ( int) ([]byte, error) {if < 0 {returnnil, fmt.Errorf("arrow/bufferedreader: %w", bufio.ErrNegativeCount) }if > len(.buf) {if := .SetBufferSize(); != nil {returnnil, } }for .w-.r < && .w-.r < len(.buf) && .err == nil { .fill() // b.w-b.r < len(b.buf) => buffer is not full }return .buf[.r : .r+], .readErr()}// Discard skips the next n bytes either by advancing the internal buffer// or by reading that many bytes in and throwing them away.func ( *bufferedReader) ( int) ( int, error) {if < 0 {return0, fmt.Errorf("arrow/bufferedreader: %w", bufio.ErrNegativeCount) }if == 0 {return } := for { := .Buffered()if == 0 { .fill() = .Buffered() }if > { = } .r += -= if == 0 {return , nil }if .err != nil {return - , .readErr() } }}func ( *bufferedReader) ( []byte) ( int, error) { = len()if == 0 {if .Buffered() > 0 {return0, nil }return0, .readErr() }if .r == .w {if .err != nil {return0, .readErr() }iflen() >= len(.buf) {// large read, empty buffer // read directly into p to avoid extra copy , .err = .rd.Read()if < 0 {return , fmt.Errorf("arrow/bufferedreader: %w", bufio.ErrNegativeCount) }return , .readErr() }// one read // don't use b.fill .r, .w = 0, 0 , .err = .rd.Read(.buf)if < 0 {return , fmt.Errorf("arrow/bufferedreader: %w", bufio.ErrNegativeCount) }if == 0 {return0, .readErr() } .w += }// copy as much as we can = copy(, .buf[.r:.w]) .r += return , nil}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.