aboutsummaryrefslogblamecommitdiffstats
path: root/ethutil/package.go
blob: e5df989d234675f7b5d177a0714a61ce00381aee (plain) (tree)


























































































































                                                                                                          
package ethutil

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
}