aboutsummaryrefslogtreecommitdiffstats
path: root/ethutil
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-04-23 17:50:17 +0800
committerobscuren <geffobscura@gmail.com>2014-04-23 17:50:17 +0800
commit11c26e32114dabc6524ad9fb1f868440f5d3fff3 (patch)
tree32bab7cf0040aa0f4ee4dabcd077b7134601af8e /ethutil
parent6930260962f4c6d1fe11d07a10300da96886ecd6 (diff)
downloaddexon-11c26e32114dabc6524ad9fb1f868440f5d3fff3.tar.gz
dexon-11c26e32114dabc6524ad9fb1f868440f5d3fff3.tar.zst
dexon-11c26e32114dabc6524ad9fb1f868440f5d3fff3.zip
Implemented ethereum package reader
Diffstat (limited to 'ethutil')
-rw-r--r--ethutil/package.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/ethutil/package.go b/ethutil/package.go
new file mode 100644
index 000000000..e5df989d2
--- /dev/null
+++ b/ethutil/package.go
@@ -0,0 +1,123 @@
+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
+}