@@ -28,15 +28,32 @@ import (
28
28
"go/types"
29
29
"io"
30
30
"io/ioutil"
31
+ "os"
31
32
32
33
"honnef.co/go/tools/internal/go/gcimporter"
33
34
)
34
35
36
+ type bufferedReader struct {
37
+ r io.Reader
38
+ buf * bufio.Reader
39
+ }
40
+
41
+ func (r * bufferedReader ) Read (b []byte ) (int , error ) {
42
+ return r .buf .Read (b )
43
+ }
44
+
45
+ func (r * bufferedReader ) ReadSlice (delim byte ) (line []byte , err error ) {
46
+ return r .buf .ReadSlice (delim )
47
+ }
48
+
35
49
// NewReader returns a reader for the export data section of an object
36
50
// (.o) or archive (.a) file read from r. The new reader may provide
37
51
// additional trailing data beyond the end of the export data.
38
52
func NewReader (r io.Reader ) (io.Reader , error ) {
39
- buf := bufio .NewReader (r )
53
+ buf := & bufferedReader {
54
+ r : r ,
55
+ buf : bufio .NewReader (r ),
56
+ }
40
57
_ , err := gcimporter .FindExportData (buf )
41
58
// If we ever switch to a zip-like archive format with the ToC
42
59
// at the end, we can return the correct portion of export data,
@@ -57,9 +74,29 @@ func NewReader(r io.Reader) (io.Reader, error) {
57
74
//
58
75
// On return, the state of the reader is undefined.
59
76
func Read (in io.Reader , fset * token.FileSet , imports map [string ]* types.Package , path string ) (* types.Package , error ) {
60
- data , err := ioutil .ReadAll (in )
61
- if err != nil {
62
- return nil , fmt .Errorf ("reading export data for %q: %v" , path , err )
77
+ var data []byte
78
+ if br , ok := in .(* bufferedReader ); ok {
79
+ if f , ok := br .r .(* os.File ); ok {
80
+ fi , err := f .Stat ()
81
+ if err == nil {
82
+ // we expect to be close to the start of the file,
83
+ // which is why we don't bother checking with
84
+ // SEEK_CUR.
85
+ data = make ([]byte , fi .Size ())
86
+ n , err := io .ReadFull (in , data )
87
+ data = data [:n ]
88
+ if err != nil && err != io .ErrUnexpectedEOF {
89
+ data = nil
90
+ }
91
+ }
92
+ }
93
+ }
94
+ if data == nil {
95
+ var err error
96
+ data , err = ioutil .ReadAll (in )
97
+ if err != nil {
98
+ return nil , fmt .Errorf ("reading export data for %q: %v" , path , err )
99
+ }
63
100
}
64
101
65
102
if bytes .HasPrefix (data , []byte ("!<arch>" )) {
0 commit comments