| | |
| | |
| | |
| |
|
| | package elf |
| |
|
| | import ( |
| | "io" |
| | "os" |
| | ) |
| |
|
| | |
| | type errorReader struct { |
| | error |
| | } |
| |
|
| | func (r errorReader) Read(p []byte) (n int, err error) { |
| | return 0, r.error |
| | } |
| |
|
| | func (r errorReader) ReadAt(p []byte, off int64) (n int, err error) { |
| | return 0, r.error |
| | } |
| |
|
| | func (r errorReader) Seek(offset int64, whence int) (int64, error) { |
| | return 0, r.error |
| | } |
| |
|
| | func (r errorReader) Close() error { |
| | return r.error |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | type readSeekerFromReader struct { |
| | reset func() (io.Reader, error) |
| | r io.Reader |
| | size int64 |
| | offset int64 |
| | } |
| |
|
| | func (r *readSeekerFromReader) start() { |
| | x, err := r.reset() |
| | if err != nil { |
| | r.r = errorReader{err} |
| | } else { |
| | r.r = x |
| | } |
| | r.offset = 0 |
| | } |
| |
|
| | func (r *readSeekerFromReader) Read(p []byte) (n int, err error) { |
| | if r.r == nil { |
| | r.start() |
| | } |
| | n, err = r.r.Read(p) |
| | r.offset += int64(n) |
| | return n, err |
| | } |
| |
|
| | func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) { |
| | var newOffset int64 |
| | switch whence { |
| | case io.SeekStart: |
| | newOffset = offset |
| | case io.SeekCurrent: |
| | newOffset = r.offset + offset |
| | case io.SeekEnd: |
| | newOffset = r.size + offset |
| | default: |
| | return 0, os.ErrInvalid |
| | } |
| |
|
| | switch { |
| | case newOffset == r.offset: |
| | return newOffset, nil |
| |
|
| | case newOffset < 0, newOffset > r.size: |
| | return 0, os.ErrInvalid |
| |
|
| | case newOffset == 0: |
| | r.r = nil |
| |
|
| | case newOffset == r.size: |
| | r.r = errorReader{io.EOF} |
| |
|
| | default: |
| | if newOffset < r.offset { |
| | |
| | r.start() |
| | } |
| | |
| | var buf [512]byte |
| | for r.offset < newOffset { |
| | b := buf[:] |
| | if newOffset-r.offset < int64(len(buf)) { |
| | b = buf[:newOffset-r.offset] |
| | } |
| | if _, err := r.Read(b); err != nil { |
| | return 0, err |
| | } |
| | } |
| | } |
| | r.offset = newOffset |
| | return r.offset, nil |
| | } |
| |
|