Commit f3fc5958 authored by Masih H. Derkani's avatar Masih H. Derkani Committed by Daniel Martí

Refactor utility io conversions into one internal package

Improve reader type conversion by checking if type satisfies
ReaderAt to avoid unnecessary wrapping.

Move io converters into one place.

Fixes:
- https://github.com/ipld/go-car/issues/145
parent 6434cd83
......@@ -4,7 +4,6 @@ import (
"fmt"
"io"
"os"
"sync"
internalio "github.com/ipld/go-car/v2/internal/io"
......@@ -97,22 +96,6 @@ func GenerateIndexFromFile(path string) (index.Index, error) {
return GenerateIndex(f)
}
var _ io.ReaderAt = (*readSeekerAt)(nil)
type readSeekerAt struct {
rs io.ReadSeeker
mu sync.Mutex
}
func (rsa *readSeekerAt) ReadAt(p []byte, off int64) (n int, err error) {
rsa.mu.Lock()
defer rsa.mu.Unlock()
if _, err := rsa.rs.Seek(off, io.SeekStart); err != nil {
return 0, err
}
return rsa.rs.Read(p)
}
// ReadOrGenerateIndex accepts both CAR v1 and v2 format, and reads or generates an index for it.
// When the given reader is in CAR v1 format an index is always generated.
// For a payload in CAR v2 format, an index is only generated if Header.HasIndex returns false.
......@@ -137,7 +120,7 @@ func ReadOrGenerateIndex(rs io.ReadSeeker) (index.Index, error) {
return GenerateIndex(rs)
case 2:
// Read CAR v2 format
v2r, err := NewReader(&readSeekerAt{rs: rs})
v2r, err := NewReader(internalio.ToReaderAt(rs))
if err != nil {
return nil, err
}
......
......@@ -3,6 +3,7 @@ package io
import (
"io"
"io/ioutil"
"sync"
)
var (
......@@ -10,6 +11,7 @@ var (
_ io.ByteReader = (*readSeekerPlusByte)(nil)
_ io.ByteReader = (*discardingReadSeekerPlusByte)(nil)
_ io.ReadSeeker = (*discardingReadSeekerPlusByte)(nil)
_ io.ReaderAt = (*readSeekerAt)(nil)
)
type (
......@@ -30,6 +32,11 @@ type (
io.ReadSeeker
io.ByteReader
}
readSeekerAt struct {
rs io.ReadSeeker
mu sync.Mutex
}
)
func ToByteReader(r io.Reader) io.ByteReader {
......@@ -49,6 +56,13 @@ func ToByteReadSeeker(r io.Reader) ByteReadSeeker {
return &discardingReadSeekerPlusByte{Reader: r}
}
func ToReaderAt(rs io.ReadSeeker) io.ReaderAt {
if ra, ok := rs.(io.ReaderAt); ok {
return ra
}
return &readSeekerAt{rs: rs}
}
func (rb readerPlusByte) ReadByte() (byte, error) {
return readByte(rb)
}
......@@ -89,3 +103,12 @@ func readByte(r io.Reader) (byte, error) {
_, err := io.ReadFull(r, p[:])
return p[0], err
}
func (rsa *readSeekerAt) ReadAt(p []byte, off int64) (n int, err error) {
rsa.mu.Lock()
defer rsa.mu.Unlock()
if _, err := rsa.rs.Seek(off, io.SeekStart); err != nil {
return 0, err
}
return rsa.rs.Read(p)
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment