mirror of
https://github.com/makeworld-the-better-one/amfora.git
synced 2024-09-11 14:55:51 +03:00
Move rr pkg to its own repo
This commit is contained in:
parent
a373aecfb7
commit
dc84332124
@ -14,12 +14,12 @@ import (
|
|||||||
"github.com/makeworld-the-better-one/amfora/client"
|
"github.com/makeworld-the-better-one/amfora/client"
|
||||||
"github.com/makeworld-the-better-one/amfora/config"
|
"github.com/makeworld-the-better-one/amfora/config"
|
||||||
"github.com/makeworld-the-better-one/amfora/renderer"
|
"github.com/makeworld-the-better-one/amfora/renderer"
|
||||||
"github.com/makeworld-the-better-one/amfora/rr"
|
|
||||||
"github.com/makeworld-the-better-one/amfora/structs"
|
"github.com/makeworld-the-better-one/amfora/structs"
|
||||||
"github.com/makeworld-the-better-one/amfora/subscriptions"
|
"github.com/makeworld-the-better-one/amfora/subscriptions"
|
||||||
"github.com/makeworld-the-better-one/amfora/sysopen"
|
"github.com/makeworld-the-better-one/amfora/sysopen"
|
||||||
"github.com/makeworld-the-better-one/amfora/webbrowser"
|
"github.com/makeworld-the-better-one/amfora/webbrowser"
|
||||||
"github.com/makeworld-the-better-one/go-gemini"
|
"github.com/makeworld-the-better-one/go-gemini"
|
||||||
|
"github.com/makeworld-the-better-one/rr"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@ -12,6 +12,7 @@ require (
|
|||||||
github.com/google/go-cmp v0.5.0 // indirect
|
github.com/google/go-cmp v0.5.0 // indirect
|
||||||
github.com/makeworld-the-better-one/go-gemini v0.13.0
|
github.com/makeworld-the-better-one/go-gemini v0.13.0
|
||||||
github.com/makeworld-the-better-one/go-gemini-socks5 v1.0.0
|
github.com/makeworld-the-better-one/go-gemini-socks5 v1.0.0
|
||||||
|
github.com/makeworld-the-better-one/rr v0.0.0-20220118144240-b31c79b0ff42
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/mitchellh/mapstructure v1.3.1 // indirect
|
github.com/mitchellh/mapstructure v1.3.1 // indirect
|
||||||
github.com/mmcdole/gofeed v1.1.2
|
github.com/mmcdole/gofeed v1.1.2
|
||||||
|
2
go.sum
2
go.sum
@ -146,6 +146,8 @@ github.com/makeworld-the-better-one/go-gemini v0.13.0 h1:CwUKLldUlZwWolG1/xKkYVg
|
|||||||
github.com/makeworld-the-better-one/go-gemini v0.13.0/go.mod h1:F+3x+R1xeYK90jMtBq+U+8Sh64r2dHleDZ/en3YgSmg=
|
github.com/makeworld-the-better-one/go-gemini v0.13.0/go.mod h1:F+3x+R1xeYK90jMtBq+U+8Sh64r2dHleDZ/en3YgSmg=
|
||||||
github.com/makeworld-the-better-one/go-gemini-socks5 v1.0.0 h1:D2o1rIfP/KOxcL3m3rzo4cfWNqfcGaMIhnU0keJc1+o=
|
github.com/makeworld-the-better-one/go-gemini-socks5 v1.0.0 h1:D2o1rIfP/KOxcL3m3rzo4cfWNqfcGaMIhnU0keJc1+o=
|
||||||
github.com/makeworld-the-better-one/go-gemini-socks5 v1.0.0/go.mod h1:mfPK9BfBAAyLKuxPEbZi8mgrGmVlzMKVTGElVspuVR8=
|
github.com/makeworld-the-better-one/go-gemini-socks5 v1.0.0/go.mod h1:mfPK9BfBAAyLKuxPEbZi8mgrGmVlzMKVTGElVspuVR8=
|
||||||
|
github.com/makeworld-the-better-one/rr v0.0.0-20220118144240-b31c79b0ff42 h1:s+0WxoBcnkZo1TX1jLRLF69k0G8Jgf7L8I+usThLbgg=
|
||||||
|
github.com/makeworld-the-better-one/rr v0.0.0-20220118144240-b31c79b0ff42/go.mod h1:sd3i5WAdkx/7ALu3V6AbVUyDw8uqmDQv55LgHta0f7g=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
37
rr/README.md
37
rr/README.md
@ -1,37 +0,0 @@
|
|||||||
# package `rr`, aka `RestartReader`
|
|
||||||
|
|
||||||
This package exists just to hold the `RestartReader` type. It wraps `io.ReadCloser` and implements it. It holds the data from every `Read` in a `[]byte` buffer, and allows you to call `.Restart()`, causing subsequent `Read` calls to start from the beginning again.
|
|
||||||
|
|
||||||
See [#140](https://github.com/makeworld-the-better-one/amfora/issues/140) for why this was needed.
|
|
||||||
|
|
||||||
Other projects are encouraged to copy this code if it's useful to them, and this package may move out of Amfora if I end up using it in multiple projects.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
If you prefer, you can consider the code in this package, and this package only, to be licensed under the MIT license instead. So the code in this package is dual-licensed. You can use the LICENSE file in the root of this repo, or the license text below.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Click to see MIT license terms</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
Copyright (c) 2020 makeworld
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
```
|
|
||||||
</details>
|
|
81
rr/rr.go
81
rr/rr.go
@ -1,81 +0,0 @@
|
|||||||
package rr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ErrClosed = errors.New("RestartReader: closed")
|
|
||||||
|
|
||||||
type RestartReader struct {
|
|
||||||
r io.ReadCloser
|
|
||||||
buf []byte
|
|
||||||
|
|
||||||
// Where in the buffer we are. If it's equal to len(buf) then the reader
|
|
||||||
// should be used.
|
|
||||||
i int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rr *RestartReader) Read(p []byte) (n int, err error) {
|
|
||||||
if rr.buf == nil {
|
|
||||||
return 0, ErrClosed
|
|
||||||
}
|
|
||||||
|
|
||||||
if rr.i >= int64(len(rr.buf)) {
|
|
||||||
// Read new data
|
|
||||||
tmp := make([]byte, len(p))
|
|
||||||
n, err = rr.r.Read(tmp)
|
|
||||||
if n > 0 {
|
|
||||||
rr.buf = append(rr.buf, tmp[:n]...)
|
|
||||||
copy(p, tmp[:n])
|
|
||||||
}
|
|
||||||
rr.i = int64(len(rr.buf))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reading from buffer
|
|
||||||
|
|
||||||
bufSize := len(rr.buf[rr.i:])
|
|
||||||
|
|
||||||
if len(p) > bufSize {
|
|
||||||
// It wants more data then what's in the buffer
|
|
||||||
tmp := make([]byte, len(p)-bufSize)
|
|
||||||
n, err = rr.r.Read(tmp)
|
|
||||||
if n > 0 {
|
|
||||||
rr.buf = append(rr.buf, tmp[:n]...)
|
|
||||||
}
|
|
||||||
copy(p, rr.buf[rr.i:])
|
|
||||||
n += bufSize
|
|
||||||
rr.i = int64(len(rr.buf))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// All the required data is in the buffer
|
|
||||||
end := rr.i + int64(len(p))
|
|
||||||
copy(p, rr.buf[rr.i:end])
|
|
||||||
rr.i = end
|
|
||||||
n = len(p)
|
|
||||||
err = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restart causes subsequent Read calls to read from the beginning, instead
|
|
||||||
// of where they left off.
|
|
||||||
func (rr *RestartReader) Restart() {
|
|
||||||
rr.i = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close clears the buffer and closes the underlying io.ReadCloser, returning
|
|
||||||
// its error.
|
|
||||||
func (rr *RestartReader) Close() error {
|
|
||||||
rr.buf = nil
|
|
||||||
return rr.r.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRestartReader creates and initializes a new RestartReader that reads from
|
|
||||||
// the provided io.ReadCloser.
|
|
||||||
func NewRestartReader(r io.ReadCloser) *RestartReader {
|
|
||||||
return &RestartReader{
|
|
||||||
r: r,
|
|
||||||
buf: make([]byte, 0),
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package rr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
var r1 *RestartReader
|
|
||||||
|
|
||||||
func reset() {
|
|
||||||
r1 = NewRestartReader(ioutil.NopCloser(strings.NewReader("1234567890")))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRead(t *testing.T) {
|
|
||||||
reset()
|
|
||||||
p := make([]byte, 1)
|
|
||||||
n, err := r1.Read(p)
|
|
||||||
assert.Equal(t, 1, n, "should read one byte")
|
|
||||||
assert.Equal(t, nil, err, "should be no error")
|
|
||||||
assert.Equal(t, []byte{'1'}, p, "should have read one byte, '1'")
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint
|
|
||||||
func TestRestart(t *testing.T) {
|
|
||||||
reset()
|
|
||||||
p := make([]byte, 4)
|
|
||||||
r1.Read(p)
|
|
||||||
|
|
||||||
r1.Restart()
|
|
||||||
p = make([]byte, 5)
|
|
||||||
n, err := r1.Read(p)
|
|
||||||
assert.Equal(t, []byte("12345"), p, "should read the first 5 bytes again")
|
|
||||||
assert.Equal(t, 5, n, "should have read 4 bytes")
|
|
||||||
assert.Equal(t, nil, err, "err should be nil")
|
|
||||||
|
|
||||||
r1.Restart()
|
|
||||||
p = make([]byte, 4)
|
|
||||||
n, err = r1.Read(p)
|
|
||||||
assert.Equal(t, []byte("1234"), p, "should read the first 4 bytes again")
|
|
||||||
assert.Equal(t, 4, n, "should have read 4 bytes")
|
|
||||||
assert.Equal(t, nil, err, "err should be nil")
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user