-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package rifs | ||
|
||
import ( | ||
"io" | ||
|
||
"github.com/dsoprea/go-logging" | ||
) | ||
|
||
// BoundedReadWriteSeekCloser wraps a RWS that is also a closer with boundaries. | ||
// This proxies the RWS methods to the inner BRWS inside. | ||
type BoundedReadWriteSeekCloser struct { | ||
io.Closer | ||
*BoundedReadWriteSeeker | ||
} | ||
|
||
// NewBoundedReadWriteSeekCloser returns a new BoundedReadWriteSeekCloser. | ||
func NewBoundedReadWriteSeekCloser(rwsc ReadWriteSeekCloser, minimumOffset int64, staticFileSize int) (brwsc *BoundedReadWriteSeekCloser, err error) { | ||
defer func() { | ||
if state := recover(); state != nil { | ||
err = log.Wrap(state.(error)) | ||
} | ||
}() | ||
|
||
bs, err := NewBoundedReadWriteSeeker(rwsc, minimumOffset, staticFileSize) | ||
log.PanicIf(err) | ||
|
||
brwsc = &BoundedReadWriteSeekCloser{ | ||
Closer: rwsc, | ||
BoundedReadWriteSeeker: bs, | ||
} | ||
|
||
return brwsc, nil | ||
} | ||
|
||
// Seek forwards calls to the inner RWS. | ||
func (rwsc *BoundedReadWriteSeekCloser) Seek(offset int64, whence int) (newOffset int64, err error) { | ||
defer func() { | ||
if state := recover(); state != nil { | ||
err = log.Wrap(state.(error)) | ||
} | ||
}() | ||
|
||
newOffset, err = rwsc.BoundedReadWriteSeeker.Seek(offset, whence) | ||
log.PanicIf(err) | ||
|
||
return newOffset, nil | ||
} | ||
|
||
// Read forwards calls to the inner RWS. | ||
func (rwsc *BoundedReadWriteSeekCloser) Read(buffer []byte) (readCount int, err error) { | ||
defer func() { | ||
if state := recover(); state != nil { | ||
err = log.Wrap(state.(error)) | ||
} | ||
}() | ||
|
||
readCount, err = rwsc.BoundedReadWriteSeeker.Read(buffer) | ||
if err != nil { | ||
if err == io.EOF { | ||
return 0, err | ||
} | ||
|
||
log.Panic(err) | ||
} | ||
|
||
return readCount, nil | ||
} | ||
|
||
// Write forwards calls to the inner RWS. | ||
func (rwsc *BoundedReadWriteSeekCloser) Write(buffer []byte) (writtenCount int, err error) { | ||
defer func() { | ||
if state := recover(); state != nil { | ||
err = log.Wrap(state.(error)) | ||
} | ||
}() | ||
|
||
writtenCount, err = rwsc.BoundedReadWriteSeeker.Write(buffer) | ||
log.PanicIf(err) | ||
|
||
return writtenCount, nil | ||
} | ||
|
||
// Close forwards calls to the inner RWS. | ||
func (rwsc *BoundedReadWriteSeekCloser) Close() (err error) { | ||
defer func() { | ||
if state := recover(); state != nil { | ||
err = log.Wrap(state.(error)) | ||
} | ||
}() | ||
|
||
err = rwsc.Closer.Close() | ||
log.PanicIf(err) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package rifs | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"io/ioutil" | ||
|
||
"github.com/dsoprea/go-logging" | ||
) | ||
|
||
func TestNewBoundedReadWriteSeekerCloser(t *testing.T) { | ||
sb := NewSeekableBuffer() | ||
rwsc := ReadWriteSeekNoopCloser(sb) | ||
|
||
brwsc, err := NewBoundedReadWriteSeekCloser(rwsc, 10, 0) | ||
log.PanicIf(err) | ||
|
||
err = brwsc.Close() | ||
log.PanicIf(err) | ||
} | ||
|
||
func TestNewBoundedReadWriteSeekerCloser_Read(t *testing.T) { | ||
data := []byte("this is a test; this is a test2") | ||
sb := NewSeekableBufferWithBytes(data) | ||
rwsc := ReadWriteSeekNoopCloser(sb) | ||
|
||
brwsc, err := NewBoundedReadWriteSeekCloser(rwsc, 10, 0) | ||
log.PanicIf(err) | ||
|
||
defer func() { | ||
err = brwsc.Close() | ||
log.PanicIf(err) | ||
}() | ||
|
||
recovered, err := ioutil.ReadAll(brwsc) | ||
log.PanicIf(err) | ||
|
||
if bytes.Equal(recovered, data[10:]) != true { | ||
t.Fatalf("Read bytes not correct.") | ||
} | ||
} | ||
|
||
func TestNewBoundedReadWriteSeekerCloser_Write(t *testing.T) { | ||
sb := NewSeekableBuffer() | ||
rwsc := ReadWriteSeekNoopCloser(sb) | ||
|
||
brwsc, err := NewBoundedReadWriteSeekCloser(rwsc, 10, 0) | ||
log.PanicIf(err) | ||
|
||
defer func() { | ||
err = brwsc.Close() | ||
log.PanicIf(err) | ||
}() | ||
|
||
data := []byte("this is a test; this is a test2") | ||
|
||
n, err := brwsc.Write(data) | ||
log.PanicIf(err) | ||
|
||
if n != len(data) { | ||
t.Fatalf("Written count not correct: (%d)", n) | ||
} | ||
|
||
_, err = sb.Seek(0, os.SEEK_SET) | ||
log.PanicIf(err) | ||
|
||
recovered, err := ioutil.ReadAll(sb) | ||
log.PanicIf(err) | ||
|
||
expectedRecovered := make([]byte, 10+len(data)) | ||
copy(expectedRecovered[10:], data) | ||
|
||
if bytes.Equal(recovered, expectedRecovered) != true { | ||
fmt.Printf("ACTUAL (%d):\n%v\n\nEXPECTED (%d):\n%v\n", len(recovered), recovered, len(expectedRecovered), expectedRecovered) | ||
|
||
t.Fatalf("Read bytes not correct.") | ||
} | ||
} | ||
|
||
func TestNewBoundedReadWriteSeekerCloser_Seek(t *testing.T) { | ||
sb := NewSeekableBuffer() | ||
rwsc := ReadWriteSeekNoopCloser(sb) | ||
|
||
brwsc, err := NewBoundedReadWriteSeekCloser(rwsc, 10, 0) | ||
log.PanicIf(err) | ||
|
||
defer func() { | ||
err = brwsc.Close() | ||
log.PanicIf(err) | ||
}() | ||
|
||
_, err = brwsc.Seek(10, os.SEEK_SET) | ||
log.PanicIf(err) | ||
|
||
data := []byte("this is a test; this is a test2") | ||
|
||
n, err := brwsc.Write(data) | ||
log.PanicIf(err) | ||
|
||
if n != len(data) { | ||
t.Fatalf("Written count not correct: (%d)", n) | ||
} | ||
|
||
_, err = sb.Seek(0, os.SEEK_SET) | ||
log.PanicIf(err) | ||
|
||
recovered, err := ioutil.ReadAll(sb) | ||
log.PanicIf(err) | ||
|
||
expectedRecovered := make([]byte, 20+len(data)) | ||
copy(expectedRecovered[20:], data) | ||
|
||
if bytes.Equal(recovered, expectedRecovered) != true { | ||
fmt.Printf("ACTUAL (%d):\n%v\n\nEXPECTED (%d):\n%v\n", len(recovered), recovered, len(expectedRecovered), expectedRecovered) | ||
|
||
t.Fatalf("Read bytes not correct.") | ||
} | ||
} | ||
|
||
func TestNewBoundedReadWriteSeekerCloser_Close(t *testing.T) { | ||
sb := NewSeekableBuffer() | ||
rwsc := ReadWriteSeekNoopCloser(sb) | ||
|
||
brwsc, err := NewBoundedReadWriteSeekCloser(rwsc, 10, 0) | ||
log.PanicIf(err) | ||
|
||
err = brwsc.Close() | ||
log.PanicIf(err) | ||
} |