/
reader.go
103 lines (81 loc) · 1.85 KB
/
reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright 2018 Zachary Schneider
*/
package zpkg
import (
"bufio"
"bytes"
"errors"
"io"
"os"
"github.com/dsnet/compress/bzip2"
"github.com/fezz-io/zps/action"
"github.com/fezz-io/zps/zpkg/payload"
"github.com/lunixbochs/struc"
)
type Reader struct {
path string
workPath string
Header *Header
Manifest *action.Manifest
Payload *payload.Reader
}
func NewReader(path string, workPath string) *Reader {
reader := &Reader{}
reader.path = path
reader.workPath = workPath
reader.Manifest = action.NewManifest()
return reader
}
func (r *Reader) Read() error {
file, err := os.Open(r.path)
if err != nil {
return err
}
wd, err := os.Getwd()
if err != nil {
return err
}
if r.workPath == "" {
r.workPath = wd
}
reader := bufio.NewReader(file)
r.Header = &Header{}
struc.Unpack(reader, r.Header)
// Check magic
if string(r.Header.Magic[:6]) != Magic {
return errors.New("does not appear to be a zpkg file")
}
var cManifestBytes bytes.Buffer
_, err = io.CopyN(&cManifestBytes, reader, int64(r.Header.ManifestLength))
if err != nil {
return err
}
bzreader, err := bzip2.NewReader(&cManifestBytes, &bzip2.ReaderConfig{})
if err != nil {
return err
}
var manifestBytes bytes.Buffer
writer := io.Writer(&manifestBytes)
_, err = io.Copy(writer, bzreader)
if err != nil {
return err
}
err = r.Manifest.Load(manifestBytes.String())
if err != nil {
return err
}
file.Close()
// TODO get byte size of header instead of just setting it
offset := int64(r.Header.ManifestLength + 12)
r.Payload = payload.NewReader(r.workPath, r.path, offset)
return err
}
func (r *Reader) Close() {
r.Payload.Close()
}