zip.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package bundle_packager
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "errors"
  6. "io"
  7. "os"
  8. "strconv"
  9. "strings"
  10. )
  11. type ZipBundlePackager struct {
  12. *MemoryZipBundlePackager
  13. path string
  14. }
  15. func NewZipBundlePackager(path string) (BundlePackager, error) {
  16. zipFile, err := os.Open(path)
  17. if err != nil {
  18. return nil, err
  19. }
  20. defer zipFile.Close()
  21. zipBytes, err := io.ReadAll(zipFile)
  22. if err != nil {
  23. return nil, err
  24. }
  25. memoryPackager, err := NewMemoryZipBundlePackager(zipBytes)
  26. if err != nil {
  27. return nil, err
  28. }
  29. zipBundlePackager := &ZipBundlePackager{
  30. MemoryZipBundlePackager: memoryPackager,
  31. path: path,
  32. }
  33. return zipBundlePackager, nil
  34. }
  35. func NewZipBundlePackagerWithSizeLimit(path string, maxSize int64) (BundlePackager, error) {
  36. zipFile, err := os.Open(path)
  37. if err != nil {
  38. return nil, err
  39. }
  40. defer zipFile.Close()
  41. zipBytes, err := io.ReadAll(zipFile)
  42. if err != nil {
  43. return nil, err
  44. }
  45. reader, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
  46. if err != nil {
  47. return nil, errors.New(strings.ReplaceAll(err.Error(), "zip", "difypkg"))
  48. }
  49. totalSize := int64(0)
  50. for _, file := range reader.File {
  51. totalSize += int64(file.UncompressedSize64)
  52. if totalSize > maxSize {
  53. return nil, errors.New(
  54. "bundle package size is too large, please ensure the uncompressed size is less than " +
  55. strconv.FormatInt(maxSize, 10) + " bytes",
  56. )
  57. }
  58. }
  59. memoryPackager, err := NewMemoryZipBundlePackager(zipBytes)
  60. if err != nil {
  61. return nil, err
  62. }
  63. zipBundlePackager := &ZipBundlePackager{
  64. MemoryZipBundlePackager: memoryPackager,
  65. path: path,
  66. }
  67. return zipBundlePackager, nil
  68. }
  69. func (p *ZipBundlePackager) Save() error {
  70. // export the bundle to a zip file
  71. zipBytes, err := p.Export()
  72. if err != nil {
  73. return err
  74. }
  75. // save the zip file
  76. err = os.WriteFile(p.path, zipBytes, 0644)
  77. if err != nil {
  78. return err
  79. }
  80. // reload zip reader
  81. zipFile, err := os.Open(p.path)
  82. if err != nil {
  83. return err
  84. }
  85. defer zipFile.Close()
  86. zipFileInfo, err := zipFile.Stat()
  87. if err != nil {
  88. return err
  89. }
  90. p.zipReader, err = zip.NewReader(zipFile, zipFileInfo.Size())
  91. if err != nil {
  92. return err
  93. }
  94. return nil
  95. }