84 lines
1.5 KiB
Go

package epub
import (
"archive/zip"
"fmt"
"os"
"time"
)
type epubZip struct {
w *os.File
wz *zip.Writer
}
func newEpubZip(path string) (*epubZip, error) {
w, err := os.Create(path)
if err != nil {
return nil, err
}
wz := zip.NewWriter(w)
return &epubZip{w, wz}, nil
}
func (e *epubZip) Close() error {
if err := e.wz.Close(); err != nil {
return err
}
return e.w.Close()
}
func (e *epubZip) WriteMagic() error {
t := time.Now()
fh := &zip.FileHeader{
Name: "mimetype",
Method: zip.Store,
Modified: t,
ModifiedTime: uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11),
ModifiedDate: uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9),
CompressedSize64: 20,
UncompressedSize64: 20,
CRC32: 0x2cab616f,
}
fh.SetMode(0600)
m, err := e.wz.CreateRaw(fh)
if err != nil {
return err
}
_, err = m.Write([]byte("application/epub+zip"))
return err
}
func (e *epubZip) WriteImage(image *ImageData) error {
m, err := e.wz.CreateRaw(image.Header)
if err != nil {
return err
}
_, err = m.Write(image.Data)
return err
}
func (e *epubZip) WriteFile(file string, data any) error {
var content []byte
switch b := data.(type) {
case string:
content = []byte(b)
case []byte:
content = b
default:
return fmt.Errorf("support string of []byte")
}
m, err := e.wz.CreateHeader(&zip.FileHeader{
Name: file,
Modified: time.Now(),
Method: zip.Deflate,
})
if err != nil {
return err
}
_, err = m.Write(content)
return err
}