GoPLS Viewer

Home|gopls/internal/gcimporter/exportdata.go
1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
6
7// This file implements FindExportData.
8
9package gcimporter
10
11import (
12    "bufio"
13    "fmt"
14    "io"
15    "strconv"
16    "strings"
17)
18
19func readGopackHeader(r *bufio.Reader) (name stringsize int64err error) {
20    // See $GOROOT/include/ar.h.
21    hdr := make([]byte16+12+6+6+8+10+2)
22    _err = io.ReadFull(rhdr)
23    if err != nil {
24        return
25    }
26    // leave for debugging
27    if false {
28        fmt.Printf("header: %s"hdr)
29    }
30    s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
31    lengtherr := 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// FindExportData positions the reader r at the beginning of the
42// export data section of an underlying GC-created object/archive
43// file by reading from it. The reader must be positioned at the
44// start of the file before calling this function. The hdr result
45// is the string before the export data, either "$$" or "$$B".
46// The size result is the length of the export data in bytes, or -1 if not known.
47func FindExportData(r *bufio.Reader) (hdr stringsize int64err error) {
48    // Read first line to make sure this is an object file.
49    lineerr := 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        // Archive file. Scan to __.PKGDEF.
57        var name string
58        if namesizeerr = readGopackHeader(r); err != nil {
59            return
60        }
61
62        // First entry should be __.PKGDEF.
63        if name != "__.PKGDEF" {
64            err = fmt.Errorf("go archive is missing __.PKGDEF")
65            return
66        }
67
68        // Read first line of __.PKGDEF data, so that line
69        // is once again the first line of the input.
70        if lineerr = 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    // Now at __.PKGDEF in archive or still at beginning of file.
78    // Either way, line should begin with "go object ".
79    if !strings.HasPrefix(string(line), "go object ") {
80        err = fmt.Errorf("not a Go object file")
81        return
82    }
83
84    // Skip over object header to export data.
85    // Begins after first line starting with $$.
86    for line[0] != '$' {
87        if lineerr = 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
MembersX
io
readGopackHeader.r
FindExportData.err
FindExportData.BlockStmt.name
bufio
readGopackHeader.s
FindExportData
FindExportData.hdr
FindExportData.line
readGopackHeader.hdr
readGopackHeader.size
readGopackHeader.err
readGopackHeader.length
readGopackHeader
FindExportData.r
FindExportData.size
readGopackHeader.name
Members
X