Pull request: replace agherr with golibs' errors
Merge in DNS/adguard-home from golibs-errors to master Squashed commit of the following: commit 5aba278a31c5a213bd9e08273ce7277c57713b22 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Mon May 24 17:05:18 2021 +0300 all: imp code commit f447eb875b81779fa9e391d98c31c1eeba7ef323 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Mon May 24 15:33:45 2021 +0300 replace agherr with golibs' errors
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
// Package aghio contains extensions for io package's types and methods
|
||||
package aghio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// LimitReachedError records the limit and the operation that caused it.
|
||||
type LimitReachedError struct {
|
||||
Limit int64
|
||||
}
|
||||
|
||||
// Error implements error interface for LimitReachedError.
|
||||
// TODO(a.garipov): Think about error string format.
|
||||
func (lre *LimitReachedError) Error() string {
|
||||
return fmt.Sprintf("attempted to read more than %d bytes", lre.Limit)
|
||||
}
|
||||
|
||||
// limitedReadCloser is a wrapper for io.ReadCloser with limited reader and
|
||||
// dealing with agherr package.
|
||||
type limitedReadCloser struct {
|
||||
limit int64
|
||||
n int64
|
||||
rc io.ReadCloser
|
||||
}
|
||||
|
||||
// Read implements Reader interface.
|
||||
func (lrc *limitedReadCloser) Read(p []byte) (n int, err error) {
|
||||
if lrc.n == 0 {
|
||||
return 0, &LimitReachedError{
|
||||
Limit: lrc.limit,
|
||||
}
|
||||
}
|
||||
if int64(len(p)) > lrc.n {
|
||||
p = p[0:lrc.n]
|
||||
}
|
||||
n, err = lrc.rc.Read(p)
|
||||
lrc.n -= int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Close implements Closer interface.
|
||||
func (lrc *limitedReadCloser) Close() error {
|
||||
return lrc.rc.Close()
|
||||
}
|
||||
|
||||
// LimitReadCloser wraps ReadCloser to make it's Reader stop with
|
||||
// ErrLimitReached after n bytes read.
|
||||
func LimitReadCloser(rc io.ReadCloser, n int64) (limited io.ReadCloser, err error) {
|
||||
if n < 0 {
|
||||
return nil, fmt.Errorf("aghio: invalid n in LimitReadCloser: %d", n)
|
||||
}
|
||||
return &limitedReadCloser{
|
||||
limit: n,
|
||||
n: n,
|
||||
rc: rc,
|
||||
}, nil
|
||||
}
|
||||
59
internal/aghio/limitedreader.go
Normal file
59
internal/aghio/limitedreader.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Package aghio contains extensions for io package's types and methods
|
||||
package aghio
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// LimitReachedError records the limit and the operation that caused it.
|
||||
type LimitReachedError struct {
|
||||
Limit int64
|
||||
}
|
||||
|
||||
// Error implements error interface for LimitReachedError.
|
||||
//
|
||||
// TODO(a.garipov): Think about error string format.
|
||||
func (lre *LimitReachedError) Error() string {
|
||||
return fmt.Sprintf("attempted to read more than %d bytes", lre.Limit)
|
||||
}
|
||||
|
||||
// limitedReader is a wrapper for io.Reader with limited reader and dealing with
|
||||
// errors package.
|
||||
type limitedReader struct {
|
||||
r io.Reader
|
||||
limit int64
|
||||
n int64
|
||||
}
|
||||
|
||||
// Read implements Reader interface.
|
||||
func (lr *limitedReader) Read(p []byte) (n int, err error) {
|
||||
if lr.n == 0 {
|
||||
return 0, &LimitReachedError{
|
||||
Limit: lr.limit,
|
||||
}
|
||||
}
|
||||
|
||||
if int64(len(p)) > lr.n {
|
||||
p = p[0:lr.n]
|
||||
}
|
||||
|
||||
n, err = lr.r.Read(p)
|
||||
lr.n -= int64(n)
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// LimitReader wraps Reader to make it's Reader stop with ErrLimitReached after
|
||||
// n bytes read.
|
||||
func LimitReader(r io.Reader, n int64) (limited io.Reader, err error) {
|
||||
if n < 0 {
|
||||
return nil, fmt.Errorf("aghio: invalid n in LimitReader: %d", n)
|
||||
}
|
||||
|
||||
return &limitedReader{
|
||||
r: r,
|
||||
limit: n,
|
||||
n: n,
|
||||
}, nil
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLimitReadCloser(t *testing.T) {
|
||||
func TestLimitReader(t *testing.T) {
|
||||
testCases := []struct {
|
||||
want error
|
||||
name string
|
||||
@@ -24,20 +24,20 @@ func TestLimitReadCloser(t *testing.T) {
|
||||
name: "zero",
|
||||
n: 0,
|
||||
}, {
|
||||
want: fmt.Errorf("aghio: invalid n in LimitReadCloser: -1"),
|
||||
want: fmt.Errorf("aghio: invalid n in LimitReader: -1"),
|
||||
name: "negative",
|
||||
n: -1,
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, err := LimitReadCloser(nil, tc.n)
|
||||
_, err := LimitReader(nil, tc.n)
|
||||
assert.Equal(t, tc.want, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLimitedReadCloser_Read(t *testing.T) {
|
||||
func TestLimitedReader_Read(t *testing.T) {
|
||||
testCases := []struct {
|
||||
err error
|
||||
name string
|
||||
@@ -77,7 +77,7 @@ func TestLimitedReadCloser_Read(t *testing.T) {
|
||||
readCloser := io.NopCloser(strings.NewReader(tc.rStr))
|
||||
buf := make([]byte, tc.limit+1)
|
||||
|
||||
lreader, err := LimitReadCloser(readCloser, tc.limit)
|
||||
lreader, err := LimitReader(readCloser, tc.limit)
|
||||
require.NoError(t, err)
|
||||
|
||||
n, err := lreader.Read(buf)
|
||||
@@ -87,7 +87,7 @@ func TestLimitedReadCloser_Read(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLimitedReadCloser_LimitReachedError(t *testing.T) {
|
||||
func TestLimitedReader_LimitReachedError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
err error
|
||||
name string
|
||||
Reference in New Issue
Block a user