youtubebeat/vendor/github.com/elastic/beats/libbeat/common/streambuf/io.go

204 lines
5 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. 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 streambuf
import (
"io"
"unicode/utf8"
)
func (b *Buffer) ioErr() error {
err := b.Err()
if err == ErrUnexpectedEOB || err == ErrNoMoreBytes {
return io.EOF
}
return err
}
func (b *Buffer) ioBufferEndError() error {
err := b.bufferEndError()
if err == ErrUnexpectedEOB || err == ErrNoMoreBytes {
return io.EOF
}
return err
}
// ReadByte reads and returns next byte from the buffer.
// If no byte is available returns either ErrNoMoreBytes (if buffer allows
// adding more bytes) or io.EOF
func (b *Buffer) ReadByte() (byte, error) {
if b.Failed() {
return 0, b.ioErr()
}
if !b.Avail(1) {
return 0, b.ioBufferEndError()
}
c := b.data[b.mark]
b.Advance(1)
return c, nil
}
// Unreads the last byte returned by most recent read operation.
func (b *Buffer) UnreadByte() error {
err := b.ioErr()
if err != nil && err != io.EOF {
return err
}
if b.mark == 0 {
return ErrOutOfRange
}
if b.mark == b.offset {
b.offset--
}
b.mark--
b.available++
return nil
}
// WriteByte appends the byte c to the buffer if buffer is not fixed.
func (b *Buffer) WriteByte(c byte) error {
p := [1]byte{c}
_, err := b.Write(p[:])
return err
}
// Read reads up to len(p) bytes into p if buffer is not in a failed state.
// Returns ErrNoMoreBytes or io.EOF (fixed buffer) if no bytes are available.
func (b *Buffer) Read(p []byte) (int, error) {
if b.Failed() {
return 0, b.ioErr()
}
if b.Len() == 0 {
return 0, b.ioBufferEndError()
}
tmp := b.Bytes()
n := copy(p, tmp)
b.Advance(n)
return n, nil
}
// Write writes p to the buffer if buffer is not fixed. Returns the number of
// bytes written or ErrOperationNotAllowed if buffer is fixed.
func (b *Buffer) Write(p []byte) (int, error) {
err := b.doAppend(p, false, -1)
if err != nil {
return 0, b.ioErr()
}
return len(p), nil
}
// ReadFrom reads data from r until error or io.EOF and appends it to the buffer.
// The amount of bytes read is returned plus any error except io.EOF.
func (b *Buffer) ReadFrom(r io.Reader) (int64, error) {
err := b.err
if err != nil && err != ErrNoMoreBytes {
return 0, b.ioErr()
}
if b.fixed {
return 0, ErrOperationNotAllowed
}
var buf [4096]byte
var total int64
for {
n, err := r.Read(buf[:])
if err != nil {
if err == io.EOF {
break
}
return total, err
}
_, err = b.Write(buf[:n])
if err != nil {
return total, err
}
total += int64(n)
}
return total, nil
}
// ReadRune reads and returns the next UTF-8-encoded Unicode code point from the
// buffer. If no bytes are available, the error returned is ErrNoMoreBytes (if
// buffer supports adding more bytes) or io.EOF. If the bytes are an erroneous
// UTF-8 encoding, it consumes one byte and returns U+FFFD, 1.
func (b *Buffer) ReadRune() (rune, int, error) {
if b.err != nil {
return 0, 0, b.ioErr()
}
if b.available == 0 {
return 0, 0, b.ioBufferEndError()
}
if c := b.data[b.mark]; c < utf8.RuneSelf {
b.Advance(1)
return rune(c), 1, nil
}
c, size := utf8.DecodeRune(b.data[b.mark:])
b.Advance(size)
return c, size, nil
}
// ReadAt reads bytes at off into p starting at the buffer its read marker.
// The read marker is not updated. If number of bytes returned is less len(p) or
// no bytes are available at off, io.EOF will be returned in err. If off is < 0,
// err is set to ErrOutOfRange.
func (b *Buffer) ReadAt(p []byte, off int64) (n int, err error) {
if b.err != nil {
return 0, b.ioErr()
}
if off < 0 {
return 0, ErrOutOfRange
}
off += int64(b.mark)
if off >= int64(len(b.data)) {
return 0, ErrOutOfRange
}
end := off + int64(len(p))
if end > int64(len(b.data)) {
err = io.EOF
end = int64(len(b.data))
}
copy(p, b.data[off:end])
return int(end - off), err
}
// WriteAt writes the content of p at off starting at recent read marker
// (already consumed bytes). Returns number of bytes written n = len(p) and err
// is nil if off and off+len(p) are within bounds, else n=0 and err is set to
// ErrOutOfRange.
func (b *Buffer) WriteAt(p []byte, off int64) (n int, err error) {
if b.err != nil {
return 0, b.ioErr()
}
end := off + int64(b.mark) + int64(len(p))
maxInt := int((^uint(0)) >> 1)
if off < 0 || end > int64(maxInt) {
return 0, ErrOutOfRange
}
// copy p into buffer
n = copy(b.sliceAt(int(off), len(p)), p)
return n, nil
}