1
2
3
4
5
6
7 package importer
8
9 import (
10 "bufio"
11 "fmt"
12 "io"
13 "strconv"
14 "strings"
15 )
16
17 func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
18
19 hdr := make([]byte, 16+12+6+6+8+10+2)
20 _, err = io.ReadFull(r, hdr)
21 if err != nil {
22 return
23 }
24
25 if false {
26 fmt.Printf("header: %s", hdr)
27 }
28 s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
29 size, err = strconv.Atoi(s)
30 if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
31 err = fmt.Errorf("invalid archive header")
32 return
33 }
34 name = strings.TrimSpace(string(hdr[:16]))
35 return
36 }
37
38
39
40
41
42
43
44
45
46 func FindExportData(r *bufio.Reader) (hdr string, size int, err error) {
47
48 line, err := r.ReadSlice('\n')
49 if err != nil {
50 err = fmt.Errorf("can't find export data (%v)", err)
51 return
52 }
53
54 if string(line) == "!<arch>\n" {
55
56 var name string
57 if name, size, err = readGopackHeader(r); err != nil {
58 return
59 }
60
61
62 if name != "__.PKGDEF" {
63 err = fmt.Errorf("go archive is missing __.PKGDEF")
64 return
65 }
66
67
68
69 if line, err = r.ReadSlice('\n'); err != nil {
70 err = fmt.Errorf("can't find export data (%v)", err)
71 return
72 }
73 }
74
75
76
77 if !strings.HasPrefix(string(line), "go object ") {
78 err = fmt.Errorf("not a Go object file")
79 return
80 }
81 size -= len(line)
82
83
84
85 for line[0] != '$' {
86 if line, err = r.ReadSlice('\n'); err != nil {
87 err = fmt.Errorf("can't find export data (%v)", err)
88 return
89 }
90 size -= len(line)
91 }
92 hdr = string(line)
93
94 return
95 }
96
View as plain text