github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/ethutil/package.go (about) 1 package ethutil 2 3 import ( 4 "archive/zip" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "strings" 10 ) 11 12 // Manifest object 13 // 14 // The manifest object holds all the relevant information supplied with the 15 // the manifest specified in the package 16 type Manifest struct { 17 Entry string 18 Height, Width int 19 } 20 21 // External package 22 // 23 // External package contains the main html file and manifest 24 type ExtPackage struct { 25 EntryHtml string 26 Manifest *Manifest 27 } 28 29 // Read file 30 // 31 // Read a given compressed file and returns the read bytes. 32 // Returns an error otherwise 33 func ReadFile(f *zip.File) ([]byte, error) { 34 rc, err := f.Open() 35 if err != nil { 36 return nil, err 37 } 38 defer rc.Close() 39 40 content, err := ioutil.ReadAll(rc) 41 if err != nil { 42 return nil, err 43 } 44 45 return content, nil 46 } 47 48 // Reads manifest 49 // 50 // Reads and returns a manifest object. Returns error otherwise 51 func ReadManifest(m []byte) (*Manifest, error) { 52 var manifest Manifest 53 54 dec := json.NewDecoder(strings.NewReader(string(m))) 55 if err := dec.Decode(&manifest); err == io.EOF { 56 } else if err != nil { 57 return nil, err 58 } 59 60 return &manifest, nil 61 } 62 63 // Find file in archive 64 // 65 // Returns the index of the given file name if it exists. -1 if file not found 66 func FindFileInArchive(fn string, files []*zip.File) (index int) { 67 index = -1 68 // Find the manifest first 69 for i, f := range files { 70 if f.Name == fn { 71 index = i 72 } 73 } 74 75 return 76 } 77 78 // Open package 79 // 80 // Opens a prepared ethereum package 81 // Reads the manifest file and determines file contents and returns and 82 // the external package. 83 func OpenPackage(fn string) (*ExtPackage, error) { 84 r, err := zip.OpenReader(fn) 85 if err != nil { 86 return nil, err 87 } 88 defer r.Close() 89 90 manifestIndex := FindFileInArchive("manifest.json", r.File) 91 92 if manifestIndex < 0 { 93 return nil, fmt.Errorf("No manifest file found in archive") 94 } 95 96 f, err := ReadFile(r.File[manifestIndex]) 97 if err != nil { 98 return nil, err 99 } 100 101 manifest, err := ReadManifest(f) 102 if err != nil { 103 return nil, err 104 } 105 106 if manifest.Entry == "" { 107 return nil, fmt.Errorf("Entry file specified but appears to be empty: %s", manifest.Entry) 108 } 109 110 entryIndex := FindFileInArchive(manifest.Entry, r.File) 111 if entryIndex < 0 { 112 return nil, fmt.Errorf("Entry file not found: '%s'", manifest.Entry) 113 } 114 115 f, err = ReadFile(r.File[entryIndex]) 116 if err != nil { 117 return nil, err 118 } 119 120 extPackage := &ExtPackage{string(f), manifest} 121 122 return extPackage, nil 123 }