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