Parcourir la source

vendor: github.com/philhofer/fwd v1.1.2

This is an (indirect) dependency of github.com/fluent/fluent-logger-golang,
which currently does not provide a go.mod, but tests against the latest
versions of its dependencies.

Updating this dependency to the latest version.

full diff: https://github.com/philhofer/fwd/compare/v1.0.0...v1.1.2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn il y a 2 ans
Parent
commit
24496fe097

+ 1 - 1
vendor.mod

@@ -134,7 +134,7 @@ require (
 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
 	github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
 	github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee // indirect
-	github.com/philhofer/fwd v1.0.0 // indirect
+	github.com/philhofer/fwd v1.1.2 // indirect
 	github.com/prometheus/client_model v0.3.0 // indirect
 	github.com/prometheus/common v0.37.0 // indirect
 	github.com/prometheus/procfs v0.8.0 // indirect

+ 2 - 2
vendor.sum

@@ -914,8 +914,8 @@ github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee h1:P6U24L02WMfj9ymZTxl7CxS73JC99x3ukk+DBkgQGQs=
 github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee/go.mod h1:3uODdxMgOaPYeWU7RzZLxVtJHZ/x1f/iHkBZuKJDzuY=
-github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
-github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
+github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
+github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

+ 82 - 38
vendor/github.com/philhofer/fwd/README.md

@@ -1,17 +1,25 @@
 
 # fwd
-    import "github.com/philhofer/fwd"
 
-The `fwd` package provides a buffered reader
+[![Go Reference](https://pkg.go.dev/badge/github.com/philhofer/fwd.svg)](https://pkg.go.dev/github.com/philhofer/fwd)
+
+
+`import "github.com/philhofer/fwd"`
+
+* [Overview](#pkg-overview)
+* [Index](#pkg-index)
+
+## <a name="pkg-overview">Overview</a>
+Package fwd provides a buffered reader
 and writer. Each has methods that help improve
 the encoding/decoding performance of some binary
 protocols.
 
-The `fwd.Writer` and `fwd.Reader` type provide similar
+The `Writer` and `Reader` type provide similar
 functionality to their counterparts in `bufio`, plus
 a few extra utility methods that simplify read-ahead
 and write-ahead. I wrote this package to improve serialization
-performance for <a href="http://github.com/tinylib/msgp">http://github.com/tinylib/msgp</a>,
+performance for [github.com/tinylib/msgp](https://github.com/tinylib/msgp),
 where it provided about a 2x speedup over `bufio` for certain
 workloads. However, care must be taken to understand the semantics of the
 extra methods provided by this package, as they allow
@@ -39,7 +47,37 @@ to write directly to the end of the buffer.
 
 
 
-## Constants
+## <a name="pkg-index">Index</a>
+* [Constants](#pkg-constants)
+* [type Reader](#Reader)
+  * [func NewReader(r io.Reader) *Reader](#NewReader)
+  * [func NewReaderBuf(r io.Reader, buf []byte) *Reader](#NewReaderBuf)
+  * [func NewReaderSize(r io.Reader, n int) *Reader](#NewReaderSize)
+  * [func (r *Reader) BufferSize() int](#Reader.BufferSize)
+  * [func (r *Reader) Buffered() int](#Reader.Buffered)
+  * [func (r *Reader) Next(n int) ([]byte, error)](#Reader.Next)
+  * [func (r *Reader) Peek(n int) ([]byte, error)](#Reader.Peek)
+  * [func (r *Reader) Read(b []byte) (int, error)](#Reader.Read)
+  * [func (r *Reader) ReadByte() (byte, error)](#Reader.ReadByte)
+  * [func (r *Reader) ReadFull(b []byte) (int, error)](#Reader.ReadFull)
+  * [func (r *Reader) Reset(rd io.Reader)](#Reader.Reset)
+  * [func (r *Reader) Skip(n int) (int, error)](#Reader.Skip)
+  * [func (r *Reader) WriteTo(w io.Writer) (int64, error)](#Reader.WriteTo)
+* [type Writer](#Writer)
+  * [func NewWriter(w io.Writer) *Writer](#NewWriter)
+  * [func NewWriterBuf(w io.Writer, buf []byte) *Writer](#NewWriterBuf)
+  * [func NewWriterSize(w io.Writer, n int) *Writer](#NewWriterSize)
+  * [func (w *Writer) BufferSize() int](#Writer.BufferSize)
+  * [func (w *Writer) Buffered() int](#Writer.Buffered)
+  * [func (w *Writer) Flush() error](#Writer.Flush)
+  * [func (w *Writer) Next(n int) ([]byte, error)](#Writer.Next)
+  * [func (w *Writer) ReadFrom(r io.Reader) (int64, error)](#Writer.ReadFrom)
+  * [func (w *Writer) Write(p []byte) (int, error)](#Writer.Write)
+  * [func (w *Writer) WriteByte(b byte) error](#Writer.WriteByte)
+  * [func (w *Writer) WriteString(s string) (int, error)](#Writer.WriteString)
+
+
+## <a name="pkg-constants">Constants</a>
 ``` go
 const (
     // DefaultReaderSize is the default size of the read buffer
@@ -121,7 +159,7 @@ and the reader position will not be incremented.
 
 
 
-### func (\*Reader) Peek
+### <a name="Reader.Peek">func</a> (\*Reader) Peek
 ``` go
 func (r *Reader) Peek(n int) ([]byte, error)
 ```
@@ -134,23 +172,23 @@ io.ErrUnexpectedEOF.
 
 
 
-### func (\*Reader) Read
+### <a name="Reader.Read">func</a> (\*Reader) Read
 ``` go
 func (r *Reader) Read(b []byte) (int, error)
 ```
-Read implements `io.Reader`
+Read implements `io.Reader`.
 
 
 
-### func (\*Reader) ReadByte
+### <a name="Reader.ReadByte">func</a> (\*Reader) ReadByte
 ``` go
 func (r *Reader) ReadByte() (byte, error)
 ```
-ReadByte implements `io.ByteReader`
+ReadByte implements `io.ByteReader`.
 
 
 
-### func (\*Reader) ReadFull
+### <a name="Reader.ReadFull">func</a> (\*Reader) ReadFull
 ``` go
 func (r *Reader) ReadFull(b []byte) (int, error)
 ```
@@ -161,7 +199,7 @@ EOF is considered an unexpected error.
 
 
 
-### func (\*Reader) Reset
+### <a name="Reader.Reset">func</a> (\*Reader) Reset
 ``` go
 func (r *Reader) Reset(rd io.Reader)
 ```
@@ -170,7 +208,7 @@ and the read buffer.
 
 
 
-### func (\*Reader) Skip
+### <a name="Reader.Skip">func</a> (\*Reader) Skip
 ``` go
 func (r *Reader) Skip(n int) (int, error)
 ```
@@ -182,27 +220,30 @@ that method will be used to skip forward.
 
 If the reader encounters
 an EOF before skipping 'n' bytes, it
-returns io.ErrUnexpectedEOF. If the
-underlying reader implements io.Seeker, then
+returns `io.ErrUnexpectedEOF`. If the
+underlying reader implements `io.Seeker`, then
 those rules apply instead. (Many implementations
 will not return `io.EOF` until the next call
-to Read.)
+to Read).
 
 
 
-### func (\*Reader) WriteTo
+
+### <a name="Reader.WriteTo">func</a> (\*Reader) WriteTo
 ``` go
 func (r *Reader) WriteTo(w io.Writer) (int64, error)
 ```
-WriteTo implements `io.WriterTo`
+WriteTo implements `io.WriterTo`.
+
 
 
 
-## type Writer
+## <a name="Writer">type</a> Writer
 ``` go
 type Writer struct {
     // contains filtered or unexported fields
 }
+
 ```
 Writer is a buffered writer
 
@@ -212,9 +253,7 @@ Writer is a buffered writer
 
 
 
-
-
-### func NewWriter
+### <a name="NewWriter">func</a> NewWriter
 ``` go
 func NewWriter(w io.Writer) *Writer
 ```
@@ -223,18 +262,24 @@ that writes to 'w' and has a buffer
 that is `DefaultWriterSize` bytes.
 
 
-### func NewWriterSize
+### <a name="NewWriterBuf">func</a> NewWriterBuf
 ``` go
-func NewWriterSize(w io.Writer, size int) *Writer
+func NewWriterBuf(w io.Writer, buf []byte) *Writer
 ```
-NewWriterSize returns a new writer
-that writes to 'w' and has a buffer
-that is 'size' bytes.
-
+NewWriterBuf returns a new writer
+that writes to 'w' and has 'buf' as a buffer.
+'buf' is not used when has smaller capacity than 18,
+custom buffer is allocated instead.
 
 
+### <a name="NewWriterSize">func</a> NewWriterSize
+``` go
+func NewWriterSize(w io.Writer, n int) *Writer
+```
+NewWriterSize returns a new writer that
+writes to 'w' and has a buffer size 'n'.
 
-### func (\*Writer) BufferSize
+### <a name="Writer.BufferSize">func</a> (\*Writer) BufferSize
 ``` go
 func (w *Writer) BufferSize() int
 ```
@@ -242,7 +287,7 @@ BufferSize returns the maximum size of the buffer.
 
 
 
-### func (\*Writer) Buffered
+### <a name="Writer.Buffered">func</a> (\*Writer) Buffered
 ``` go
 func (w *Writer) Buffered() int
 ```
@@ -251,7 +296,7 @@ in the reader.
 
 
 
-### func (\*Writer) Flush
+### <a name="Writer.Flush">func</a> (\*Writer) Flush
 ``` go
 func (w *Writer) Flush() error
 ```
@@ -260,7 +305,7 @@ to the underlying writer.
 
 
 
-### func (\*Writer) Next
+### <a name="Writer.Next">func</a> (\*Writer) Next
 ``` go
 func (w *Writer) Next(n int) ([]byte, error)
 ```
@@ -273,7 +318,7 @@ the size of the returned buffer.
 
 
 
-### func (\*Writer) ReadFrom
+### <a name="Writer.ReadFrom">func</a> (\*Writer) ReadFrom
 ``` go
 func (w *Writer) ReadFrom(r io.Reader) (int64, error)
 ```
@@ -281,7 +326,7 @@ ReadFrom implements `io.ReaderFrom`
 
 
 
-### func (\*Writer) Write
+### <a name="Writer.Write">func</a> (\*Writer) Write
 ``` go
 func (w *Writer) Write(p []byte) (int, error)
 ```
@@ -289,7 +334,7 @@ Write implements `io.Writer`
 
 
 
-### func (\*Writer) WriteByte
+### <a name="Writer.WriteByte">func</a> (\*Writer) WriteByte
 ``` go
 func (w *Writer) WriteByte(b byte) error
 ```
@@ -297,7 +342,7 @@ WriteByte implements `io.ByteWriter`
 
 
 
-### func (\*Writer) WriteString
+### <a name="Writer.WriteString">func</a> (\*Writer) WriteString
 ``` go
 func (w *Writer) WriteString(s string) (int, error)
 ```
@@ -310,6 +355,5 @@ WriteString is analogous to Write, but it takes a string.
 
 
 
-
 - - -
-Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
+Generated by [godoc2md](https://github.com/davecheney/godoc2md)

+ 66 - 66
vendor/github.com/philhofer/fwd/reader.go

@@ -1,10 +1,10 @@
-// The `fwd` package provides a buffered reader
+// Package fwd provides a buffered reader
 // and writer. Each has methods that help improve
 // the encoding/decoding performance of some binary
 // protocols.
 //
-// The `fwd.Writer` and `fwd.Reader` type provide similar
-// functionality to their counterparts in `bufio`, plus
+// The [Writer] and [Reader] type provide similar
+// functionality to their counterparts in [bufio], plus
 // a few extra utility methods that simplify read-ahead
 // and write-ahead. I wrote this package to improve serialization
 // performance for http://github.com/tinylib/msgp,
@@ -14,27 +14,29 @@
 // the user to access and manipulate the buffer memory
 // directly.
 //
-// The extra methods for `fwd.Reader` are `Peek`, `Skip`
-// and `Next`. `(*fwd.Reader).Peek`, unlike `(*bufio.Reader).Peek`,
+// The extra methods for [Reader] are [Reader.Peek], [Reader.Skip]
+// and [Reader.Next]. (*fwd.Reader).Peek, unlike (*bufio.Reader).Peek,
 // will re-allocate the read buffer in order to accommodate arbitrarily
-// large read-ahead. `(*fwd.Reader).Skip` skips the next `n` bytes
-// in the stream, and uses the `io.Seeker` interface if the underlying
-// stream implements it. `(*fwd.Reader).Next` returns a slice pointing
-// to the next `n` bytes in the read buffer (like `Peek`), but also
+// large read-ahead. (*fwd.Reader).Skip skips the next 'n' bytes
+// in the stream, and uses the [io.Seeker] interface if the underlying
+// stream implements it. (*fwd.Reader).Next returns a slice pointing
+// to the next 'n' bytes in the read buffer (like Reader.Peek), but also
 // increments the read position. This allows users to process streams
 // in arbitrary block sizes without having to manage appropriately-sized
 // slices. Additionally, obviating the need to copy the data from the
 // buffer to another location in memory can improve performance dramatically
 // in CPU-bound applications.
 //
-// `fwd.Writer` only has one extra method, which is `(*fwd.Writer).Next`, which
-// returns a slice pointing to the next `n` bytes of the writer, and increments
+// [Writer] only has one extra method, which is (*fwd.Writer).Next, which
+// returns a slice pointing to the next 'n' bytes of the writer, and increments
 // the write position by the length of the returned slice. This allows users
 // to write directly to the end of the buffer.
-//
 package fwd
 
-import "io"
+import (
+	"io"
+	"os"
+)
 
 const (
 	// DefaultReaderSize is the default size of the read buffer
@@ -50,11 +52,24 @@ func NewReader(r io.Reader) *Reader {
 }
 
 // NewReaderSize returns a new *Reader that
-// reads from 'r' and has a buffer size 'n'
+// reads from 'r' and has a buffer size 'n'.
 func NewReaderSize(r io.Reader, n int) *Reader {
+	buf := make([]byte, 0, max(n, minReaderSize))
+	return NewReaderBuf(r, buf)
+}
+
+// NewReaderBuf returns a new *Reader that
+// reads from 'r' and uses 'buf' as a buffer.
+// 'buf' is not used when has smaller capacity than 16,
+// custom buffer is allocated instead.
+func NewReaderBuf(r io.Reader, buf []byte) *Reader {
+	if cap(buf) < minReaderSize {
+		buf = make([]byte, 0, minReaderSize)
+	}
+	buf = buf[:0]
 	rd := &Reader{
 		r:    r,
-		data: make([]byte, 0, max(minReaderSize, n)),
+		data: buf,
 	}
 	if s, ok := r.(io.Seeker); ok {
 		rd.rs = s
@@ -113,6 +128,8 @@ func (r *Reader) more() {
 		// discard the io.EOF if we read more than 0 bytes.
 		// the next call to Read should return io.EOF again.
 		r.state = nil
+	} else if r.state != nil {
+		return
 	}
 	r.data = r.data[:len(r.data)+a]
 }
@@ -174,6 +191,19 @@ func (r *Reader) Peek(n int) ([]byte, error) {
 	return r.data[r.n : r.n+n], nil
 }
 
+// discard(n) discards up to 'n' buffered bytes, and
+// and returns the number of bytes discarded
+func (r *Reader) discard(n int) int {
+	inbuf := r.buffered()
+	if inbuf <= n {
+		r.n = 0
+		r.data = r.data[:0]
+		return inbuf
+	}
+	r.n += n
+	return n
+}
+
 // Skip moves the reader forward 'n' bytes.
 // Returns the number of bytes skipped and any
 // errors encountered. It is analogous to Seek(n, 1).
@@ -182,39 +212,31 @@ func (r *Reader) Peek(n int) ([]byte, error) {
 //
 // If the reader encounters
 // an EOF before skipping 'n' bytes, it
-// returns io.ErrUnexpectedEOF. If the
-// underlying reader implements io.Seeker, then
+// returns [io.ErrUnexpectedEOF]. If the
+// underlying reader implements [io.Seeker], then
 // those rules apply instead. (Many implementations
-// will not return `io.EOF` until the next call
-// to Read.)
+// will not return [io.EOF] until the next call
+// to Read).
 func (r *Reader) Skip(n int) (int, error) {
-
-	// fast path
-	if r.buffered() >= n {
-		r.n += n
-		return n, nil
+	if n < 0 {
+		return 0, os.ErrInvalid
 	}
 
-	// use seeker implementation
-	// if we can
-	if r.rs != nil {
-		return r.skipSeek(n)
-	}
+	// discard some or all of the current buffer
+	skipped := r.discard(n)
 
-	// loop on filling
-	// and then erasing
-	o := n
-	for r.buffered() < n && r.state == nil {
+	// if we can Seek() through the remaining bytes, do that
+	if n > skipped && r.rs != nil {
+		nn, err := r.rs.Seek(int64(n-skipped), 1)
+		return int(nn) + skipped, err
+	}
+	// otherwise, keep filling the buffer
+	// and discarding it up to 'n'
+	for skipped < n && r.state == nil {
 		r.more()
-		// we can skip forward
-		// up to r.buffered() bytes
-		step := min(r.buffered(), n)
-		r.n += step
-		n -= step
+		skipped += r.discard(n - skipped)
 	}
-	// at this point, n should be
-	// 0 if everything went smoothly
-	return o - n, r.noEOF()
+	return skipped, r.noEOF()
 }
 
 // Next returns the next 'n' bytes in the stream.
@@ -227,7 +249,6 @@ func (r *Reader) Skip(n int) (int, error) {
 // length asked for, an error will be returned,
 // and the reader position will not be incremented.
 func (r *Reader) Next(n int) ([]byte, error) {
-
 	// in case the buffer is too small
 	if cap(r.data) < n {
 		old := r.data[r.n:]
@@ -249,21 +270,7 @@ func (r *Reader) Next(n int) ([]byte, error) {
 	return out, nil
 }
 
-// skipSeek uses the io.Seeker to seek forward.
-// only call this function when n > r.buffered()
-func (r *Reader) skipSeek(n int) (int, error) {
-	o := r.buffered()
-	// first, clear buffer
-	n -= o
-	r.n = 0
-	r.data = r.data[:0]
-
-	// then seek forward remaning bytes
-	i, err := r.rs.Seek(int64(n), 1)
-	return int(i) + o, err
-}
-
-// Read implements `io.Reader`
+// Read implements [io.Reader].
 func (r *Reader) Read(b []byte) (int, error) {
 	// if we have data in the buffer, just
 	// return that.
@@ -318,7 +325,7 @@ func (r *Reader) ReadFull(b []byte) (int, error) {
 	return n, nil
 }
 
-// ReadByte implements `io.ByteReader`
+// ReadByte implements [io.ByteReader].
 func (r *Reader) ReadByte() (byte, error) {
 	for r.buffered() < 1 && r.state == nil {
 		r.more()
@@ -331,7 +338,7 @@ func (r *Reader) ReadByte() (byte, error) {
 	return b, nil
 }
 
-// WriteTo implements `io.WriterTo`
+// WriteTo implements [io.WriterTo].
 func (r *Reader) WriteTo(w io.Writer) (int64, error) {
 	var (
 		i   int64
@@ -368,13 +375,6 @@ func (r *Reader) WriteTo(w io.Writer) (int64, error) {
 	return i, nil
 }
 
-func min(a int, b int) int {
-	if a < b {
-		return a
-	}
-	return b
-}
-
 func max(a int, b int) int {
 	if a < b {
 		return b

+ 18 - 6
vendor/github.com/philhofer/fwd/writer.go

@@ -29,16 +29,28 @@ func NewWriter(w io.Writer) *Writer {
 	}
 }
 
-// NewWriterSize returns a new writer
-// that writes to 'w' and has a buffer
-// that is 'size' bytes.
-func NewWriterSize(w io.Writer, size int) *Writer {
-	if wr, ok := w.(*Writer); ok && cap(wr.buf) >= size {
+// NewWriterSize returns a new writer that
+// writes to 'w' and has a buffer size 'n'.
+func NewWriterSize(w io.Writer, n int) *Writer {
+	if wr, ok := w.(*Writer); ok && cap(wr.buf) >= n {
 		return wr
 	}
+	buf := make([]byte, 0, max(n, minWriterSize))
+	return NewWriterBuf(w, buf)
+}
+
+// NewWriterBuf returns a new writer
+// that writes to 'w' and has 'buf' as a buffer.
+// 'buf' is not used when has smaller capacity than 18,
+// custom buffer is allocated instead.
+func NewWriterBuf(w io.Writer, buf []byte) *Writer {
+	if cap(buf) < minWriterSize {
+		buf = make([]byte, 0, minWriterSize)
+	}
+	buf = buf[:0]
 	return &Writer{
 		w:   w,
-		buf: make([]byte, 0, max(size, minWriterSize)),
+		buf: buf,
 	}
 }
 

+ 1 - 0
vendor/github.com/philhofer/fwd/writer_appengine.go

@@ -1,3 +1,4 @@
+//go:build appengine
 // +build appengine
 
 package fwd

+ 19 - 0
vendor/github.com/philhofer/fwd/writer_tinygo.go

@@ -0,0 +1,19 @@
+//go:build tinygo
+// +build tinygo
+
+package fwd
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+// unsafe cast string as []byte
+func unsafestr(b string) []byte {
+	l := uintptr(len(b))
+	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
+		Len:  l,
+		Cap:  l,
+		Data: (*reflect.StringHeader)(unsafe.Pointer(&b)).Data,
+	}))
+}

+ 10 - 8
vendor/github.com/philhofer/fwd/writer_unsafe.go

@@ -1,4 +1,5 @@
-// +build !appengine
+//go:build !appengine && !tinygo
+// +build !appengine,!tinygo
 
 package fwd
 
@@ -8,11 +9,12 @@ import (
 )
 
 // unsafe cast string as []byte
-func unsafestr(b string) []byte {
-	l := len(b)
-	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
-		Len:  l,
-		Cap:  l,
-		Data: (*reflect.StringHeader)(unsafe.Pointer(&b)).Data,
-	}))
+func unsafestr(s string) []byte {
+	var b []byte
+	sHdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
+	bHdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
+	bHdr.Data = sHdr.Data
+	bHdr.Len = sHdr.Len
+	bHdr.Cap = sHdr.Len
+	return b
 }

+ 2 - 2
vendor/modules.txt

@@ -733,8 +733,8 @@ github.com/opencontainers/selinux/pkg/pwalkdir
 github.com/pelletier/go-toml
 # github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee
 ## explicit
-# github.com/philhofer/fwd v1.0.0
-## explicit
+# github.com/philhofer/fwd v1.1.2
+## explicit; go 1.15
 github.com/philhofer/fwd
 # github.com/pkg/errors v0.9.1
 ## explicit