package.go 2.4 KB

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