...
1
2
3
4
5
6
7 package gcimporter
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 func FindExportData(r *bufio.Reader) (hdr string, size int, err error) {
44
45 line, err := r.ReadSlice('\n')
46 if err != nil {
47 err = fmt.Errorf("can't find export data (%v)", err)
48 return
49 }
50
51 if string(line) == "!<arch>\n" {
52
53 var name string
54 if name, size, err = readGopackHeader(r); err != nil {
55 return
56 }
57
58
59 if name != "__.PKGDEF" {
60 err = fmt.Errorf("go archive is missing __.PKGDEF")
61 return
62 }
63
64
65
66 if line, err = r.ReadSlice('\n'); err != nil {
67 err = fmt.Errorf("can't find export data (%v)", err)
68 return
69 }
70 }
71
72
73
74 if !strings.HasPrefix(string(line), "go object ") {
75 err = fmt.Errorf("not a Go object file")
76 return
77 }
78 size -= len(line)
79
80
81
82 for line[0] != '$' {
83 if line, err = r.ReadSlice('\n'); err != nil {
84 err = fmt.Errorf("can't find export data (%v)", err)
85 return
86 }
87 size -= len(line)
88 }
89 hdr = string(line)
90
91 return
92 }
93
View as plain text