Source file
src/debug/elf/reader.go
1
2
3
4
5 package elf
6
7 import (
8 "io"
9 "os"
10 )
11
12
13 type errorReader struct {
14 error
15 }
16
17 func (r errorReader) Read(p []byte) (n int, err error) {
18 return 0, r.error
19 }
20
21 func (r errorReader) ReadAt(p []byte, off int64) (n int, err error) {
22 return 0, r.error
23 }
24
25 func (r errorReader) Seek(offset int64, whence int) (int64, error) {
26 return 0, r.error
27 }
28
29 func (r errorReader) Close() error {
30 return r.error
31 }
32
33
34
35
36
37 type readSeekerFromReader struct {
38 reset func() (io.Reader, error)
39 r io.Reader
40 size int64
41 offset int64
42 }
43
44 func (r *readSeekerFromReader) start() {
45 x, err := r.reset()
46 if err != nil {
47 r.r = errorReader{err}
48 } else {
49 r.r = x
50 }
51 r.offset = 0
52 }
53
54 func (r *readSeekerFromReader) Read(p []byte) (n int, err error) {
55 if r.r == nil {
56 r.start()
57 }
58 n, err = r.r.Read(p)
59 r.offset += int64(n)
60 return n, err
61 }
62
63 func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) {
64 var newOffset int64
65 switch whence {
66 case seekStart:
67 newOffset = offset
68 case seekCurrent:
69 newOffset = r.offset + offset
70 case seekEnd:
71 newOffset = r.size + offset
72 default:
73 return 0, os.ErrInvalid
74 }
75
76 switch {
77 case newOffset == r.offset:
78 return newOffset, nil
79
80 case newOffset < 0, newOffset > r.size:
81 return 0, os.ErrInvalid
82
83 case newOffset == 0:
84 r.r = nil
85
86 case newOffset == r.size:
87 r.r = errorReader{io.EOF}
88
89 default:
90 if newOffset < r.offset {
91
92 r.start()
93 }
94
95 var buf [512]byte
96 for r.offset < newOffset {
97 b := buf[:]
98 if newOffset-r.offset < int64(len(buf)) {
99 b = buf[:newOffset-r.offset]
100 }
101 if _, err := r.Read(b); err != nil {
102 return 0, err
103 }
104 }
105 }
106 r.offset = newOffset
107 return r.offset, nil
108 }
109
View as plain text