1
0
Fork 0
mirror of https://git.sr.ht/~adnano/go-gemini synced 2024-04-27 00:15:14 +02:00

Move I/O utilities to io.go

This commit is contained in:
Adnan Maolood 2021-02-23 20:49:42 -05:00
parent a65c3c3d4f
commit e8d98ef4ec
4 changed files with 105 additions and 103 deletions

View File

@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"crypto/x509"
"io"
"net"
"net/url"
"time"
@ -221,55 +220,3 @@ func punycodeHostname(hostname string) (string, error) {
}
return idna.Lookup.ToASCII(hostname)
}
type contextReader struct {
ctx context.Context
done <-chan struct{}
cancel func()
rc io.ReadCloser
}
func (r *contextReader) Read(p []byte) (int, error) {
select {
case <-r.done:
r.rc.Close()
return 0, r.ctx.Err()
default:
}
n, err := r.rc.Read(p)
if err != nil {
r.cancel()
}
return n, err
}
func (r *contextReader) Close() error {
r.cancel()
return r.rc.Close()
}
type contextWriter struct {
ctx context.Context
done <-chan struct{}
cancel func()
wc io.WriteCloser
}
func (w *contextWriter) Write(b []byte) (int, error) {
select {
case <-w.done:
w.wc.Close()
return 0, w.ctx.Err()
default:
}
n, err := w.wc.Write(b)
if err != nil {
w.cancel()
}
return n, err
}
func (w *contextWriter) Close() error {
w.cancel()
return w.wc.Close()
}

104
io.go Normal file
View File

@ -0,0 +1,104 @@
package gemini
import (
"bufio"
"context"
"io"
)
type contextReader struct {
ctx context.Context
done <-chan struct{}
cancel func()
rc io.ReadCloser
}
func (r *contextReader) Read(p []byte) (int, error) {
select {
case <-r.done:
r.rc.Close()
return 0, r.ctx.Err()
default:
}
n, err := r.rc.Read(p)
if err != nil {
r.cancel()
}
return n, err
}
func (r *contextReader) Close() error {
r.cancel()
return r.rc.Close()
}
type contextWriter struct {
ctx context.Context
done <-chan struct{}
cancel func()
wc io.WriteCloser
}
func (w *contextWriter) Write(b []byte) (int, error) {
select {
case <-w.done:
w.wc.Close()
return 0, w.ctx.Err()
default:
}
n, err := w.wc.Write(b)
if err != nil {
w.cancel()
}
return n, err
}
func (w *contextWriter) Close() error {
w.cancel()
return w.wc.Close()
}
type nopCloser struct {
io.Writer
}
func (nopCloser) Close() error {
return nil
}
type nopReadCloser struct{}
func (nopReadCloser) Read(p []byte) (int, error) {
return 0, io.EOF
}
func (nopReadCloser) Close() error {
return nil
}
type bufReadCloser struct {
br *bufio.Reader // used until empty
io.ReadCloser
}
func newBufReadCloser(br *bufio.Reader, rc io.ReadCloser) io.ReadCloser {
body := &bufReadCloser{ReadCloser: rc}
if br.Buffered() != 0 {
body.br = br
}
return body
}
func (b *bufReadCloser) Read(p []byte) (n int, err error) {
if b.br != nil {
if n := b.br.Buffered(); len(p) > n {
p = p[:n]
}
n, err = b.br.Read(p)
if b.br.Buffered() == 0 {
b.br = nil
}
return n, err
}
return b.ReadCloser.Read(p)
}

View File

@ -81,7 +81,7 @@ func ReadResponse(rc io.ReadCloser) (*Response, error) {
}
if resp.Status.Class() == StatusSuccess {
resp.body = newReadCloserBody(br, rc)
resp.body = newBufReadCloser(br, rc)
} else {
resp.body = nopReadCloser{}
rc.Close()
@ -89,43 +89,6 @@ func ReadResponse(rc io.ReadCloser) (*Response, error) {
return resp, nil
}
type nopReadCloser struct{}
func (nopReadCloser) Read(p []byte) (int, error) {
return 0, io.EOF
}
func (nopReadCloser) Close() error {
return nil
}
type readCloserBody struct {
br *bufio.Reader // used until empty
io.ReadCloser
}
func newReadCloserBody(br *bufio.Reader, rc io.ReadCloser) io.ReadCloser {
body := &readCloserBody{ReadCloser: rc}
if br.Buffered() != 0 {
body.br = br
}
return body
}
func (b *readCloserBody) Read(p []byte) (n int, err error) {
if b.br != nil {
if n := b.br.Buffered(); len(p) > n {
p = p[:n]
}
n, err = b.br.Read(p)
if b.br.Buffered() == 0 {
b.br = nil
}
return n, err
}
return b.ReadCloser.Read(p)
}
// Read reads data from the response body.
// The response body is streamed on demand as Read is called.
func (r *Response) Read(p []byte) (n int, err error) {

View File

@ -123,15 +123,3 @@ func TestReadWriteResponse(t *testing.T) {
}
}
}
type nopCloser struct {
io.Writer
}
func (w nopCloser) Write(b []byte) (int, error) {
return w.Writer.Write(b)
}
func (nopCloser) Close() error {
return nil
}