go-pulse/common/package.go
2015-03-16 11:27:38 +01:00

124 lines
2.4 KiB
Go

package common
import (
"archive/zip"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"strings"
)
// Manifest object
//
// The manifest object holds all the relevant information supplied with the
// the manifest specified in the package
type Manifest struct {
Entry string
Height, Width int
}
// External package
//
// External package contains the main html file and manifest
type ExtPackage struct {
EntryHtml string
Manifest *Manifest
}
// Read file
//
// Read a given compressed file and returns the read bytes.
// Returns an error otherwise
func ReadFile(f *zip.File) ([]byte, error) {
rc, err := f.Open()
if err != nil {
return nil, err
}
defer rc.Close()
content, err := ioutil.ReadAll(rc)
if err != nil {
return nil, err
}
return content, nil
}
// Reads manifest
//
// Reads and returns a manifest object. Returns error otherwise
func ReadManifest(m []byte) (*Manifest, error) {
var manifest Manifest
dec := json.NewDecoder(strings.NewReader(string(m)))
if err := dec.Decode(&manifest); err == io.EOF {
} else if err != nil {
return nil, err
}
return &manifest, nil
}
// Find file in archive
//
// Returns the index of the given file name if it exists. -1 if file not found
func FindFileInArchive(fn string, files []*zip.File) (index int) {
index = -1
// Find the manifest first
for i, f := range files {
if f.Name == fn {
index = i
}
}
return
}
// Open package
//
// Opens a prepared ethereum package
// Reads the manifest file and determines file contents and returns and
// the external package.
func OpenPackage(fn string) (*ExtPackage, error) {
r, err := zip.OpenReader(fn)
if err != nil {
return nil, err
}
defer r.Close()
manifestIndex := FindFileInArchive("manifest.json", r.File)
if manifestIndex < 0 {
return nil, fmt.Errorf("No manifest file found in archive")
}
f, err := ReadFile(r.File[manifestIndex])
if err != nil {
return nil, err
}
manifest, err := ReadManifest(f)
if err != nil {
return nil, err
}
if manifest.Entry == "" {
return nil, fmt.Errorf("Entry file specified but appears to be empty: %s", manifest.Entry)
}
entryIndex := FindFileInArchive(manifest.Entry, r.File)
if entryIndex < 0 {
return nil, fmt.Errorf("Entry file not found: '%s'", manifest.Entry)
}
f, err = ReadFile(r.File[entryIndex])
if err != nil {
return nil, err
}
extPackage := &ExtPackage{string(f), manifest}
return extPackage, nil
}