]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/file_wrapper.go
Adopt more fixed size array types for struct fields
[rbdr/mobius] / hotline / file_wrapper.go
index 997d6d94d64816d51667d327f03f52a437393aa0..bc6319b4f7db2db50ba1a102b91a4366c5421b33 100644 (file)
@@ -1,6 +1,7 @@
 package hotline
 
 import (
+       "bytes"
        "encoding/binary"
        "errors"
        "fmt"
@@ -26,8 +27,6 @@ type fileWrapper struct {
        rsrcPath       string // path to the file resource fork
        infoPath       string // path to the file information fork
        incompletePath string // path to partially transferred temp file
-       saveMetaData   bool   // if true, enables saving of info and resource forks in sidecar files
-       infoFork       *FlatFileInformationFork
        ffo            *flattenedFileObject
 }
 
@@ -105,21 +104,7 @@ func (f *fileWrapper) infoForkName() string {
        return fmt.Sprintf(infoForkNameTemplate, f.name)
 }
 
-func (f *fileWrapper) creatorCode() []byte {
-       if f.ffo.FlatFileInformationFork.CreatorSignature != nil {
-               return f.infoFork.CreatorSignature
-       }
-       return []byte(fileTypeFromFilename(f.name).CreatorCode)
-}
-
-func (f *fileWrapper) typeCode() []byte {
-       if f.infoFork != nil {
-               return f.infoFork.TypeSignature
-       }
-       return []byte(fileTypeFromFilename(f.name).TypeCode)
-}
-
-func (f *fileWrapper) rsrcForkWriter() (io.Writer, error) {
+func (f *fileWrapper) rsrcForkWriter() (io.WriteCloser, error) {
        file, err := os.OpenFile(f.rsrcPath, os.O_CREATE|os.O_WRONLY, 0644)
        if err != nil {
                return nil, err
@@ -128,8 +113,8 @@ func (f *fileWrapper) rsrcForkWriter() (io.Writer, error) {
        return file, nil
 }
 
-func (f *fileWrapper) infoForkWriter() (io.Writer, error) {
-       file, err := os.OpenFile(f.infoPath, os.O_CREATE|os.O_WRONLY, 0644)
+func (f *fileWrapper) infoForkWriter() (io.WriteCloser, error) {
+       file, err := os.OpenFile(f.infoPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
        if err != nil {
                return nil, err
        }
@@ -137,7 +122,7 @@ func (f *fileWrapper) infoForkWriter() (io.Writer, error) {
        return file, nil
 }
 
-func (f *fileWrapper) incFileWriter() (io.Writer, error) {
+func (f *fileWrapper) incFileWriter() (io.WriteCloser, error) {
        file, err := os.OpenFile(f.incompletePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
        if err != nil {
                return nil, err
@@ -165,26 +150,31 @@ func (f *fileWrapper) dataFile() (os.FileInfo, error) {
        return nil, errors.New("file or directory not found")
 }
 
-// move a fileWrapper and its associated metadata files to newPath
+// move a fileWrapper and its associated meta files to newPath.
+// Meta files include:
+// * Partially uploaded file ending with .incomplete
+// * Resource fork starting with .rsrc_
+// * Info fork starting with .info
+// During move of the meta files, os.ErrNotExist is ignored as these files may legitimately not exist.
 func (f *fileWrapper) move(newPath string) error {
        err := f.fs.Rename(f.dataPath, filepath.Join(newPath, f.name))
        if err != nil {
-               // TODO
+               return err
        }
 
        err = f.fs.Rename(f.incompletePath, filepath.Join(newPath, f.incompleteDataName()))
-       if err != nil {
-               // TODO
+       if err != nil && !errors.Is(err, os.ErrNotExist) {
+               return err
        }
 
        err = f.fs.Rename(f.rsrcPath, filepath.Join(newPath, f.rsrcForkName()))
-       if err != nil {
-               // TODO
+       if err != nil && !errors.Is(err, os.ErrNotExist) {
+               return err
        }
 
        err = f.fs.Rename(f.infoPath, filepath.Join(newPath, f.infoForkName()))
-       if err != nil {
-               // TODO
+       if err != nil && !errors.Is(err, os.ErrNotExist) {
+               return err
        }
 
        return nil
@@ -194,22 +184,22 @@ func (f *fileWrapper) move(newPath string) error {
 func (f *fileWrapper) delete() error {
        err := f.fs.RemoveAll(f.dataPath)
        if err != nil {
-               // TODO
+               return err
        }
 
        err = f.fs.Remove(f.incompletePath)
-       if err != nil {
-               // TODO
+       if err != nil && !errors.Is(err, os.ErrNotExist) {
+               return err
        }
 
        err = f.fs.Remove(f.rsrcPath)
-       if err != nil {
-               // TODO
+       if err != nil && !errors.Is(err, os.ErrNotExist) {
+               return err
        }
 
        err = f.fs.Remove(f.infoPath)
-       if err != nil {
-               // TODO
+       if err != nil && !errors.Is(err, os.ErrNotExist) {
+               return err
        }
 
        return nil
@@ -217,7 +207,7 @@ func (f *fileWrapper) delete() error {
 
 func (f *fileWrapper) flattenedFileObject() (*flattenedFileObject, error) {
        dataSize := make([]byte, 4)
-       mTime := make([]byte, 8)
+       mTime := [8]byte{}
 
        ft := defaultFileType
 
@@ -254,26 +244,25 @@ func (f *fileWrapper) flattenedFileObject() (*flattenedFileObject, error) {
 
                f.ffo.FlatFileHeader.ForkCount[1] = 3
 
-               if err := f.ffo.FlatFileInformationFork.UnmarshalBinary(b); err != nil {
-                       return nil, err
+               _, err = io.Copy(&f.ffo.FlatFileInformationFork, bytes.NewReader(b))
+               if err != nil {
+                       return nil, fmt.Errorf("error copying FlatFileInformationFork: %w", err)
                }
        } else {
                f.ffo.FlatFileInformationFork = FlatFileInformationFork{
-                       Platform:         []byte("AMAC"), // TODO: Remove hardcode to support "AWIN" Platform (maybe?)
-                       TypeSignature:    []byte(ft.TypeCode),
-                       CreatorSignature: []byte(ft.CreatorCode),
-                       Flags:            []byte{0, 0, 0, 0},
-                       PlatformFlags:    []byte{0, 0, 1, 0}, // TODO: What is this?
-                       RSVD:             make([]byte, 32),
-                       CreateDate:       mTime, // some filesystems don't support createTime
+                       Platform:         [4]byte{0x41, 0x4D, 0x41, 0x43}, // "AMAC" TODO: Remove hardcode to support "AWIN" Platform (maybe?)
+                       TypeSignature:    [4]byte([]byte(ft.TypeCode)),
+                       CreatorSignature: [4]byte([]byte(ft.CreatorCode)),
+                       PlatformFlags:    [4]byte{0, 0, 1, 0}, // TODO: What is this?
+                       CreateDate:       mTime,               // some filesystems don't support createTime
                        ModifyDate:       mTime,
-                       NameScript:       []byte{0, 0},
                        Name:             []byte(f.name),
-                       NameSize:         []byte{0, 0},
-                       CommentSize:      []byte{0, 0},
                        Comment:          []byte{},
                }
-               binary.BigEndian.PutUint16(f.ffo.FlatFileInformationFork.NameSize, uint16(len(f.name)))
+
+               ns := make([]byte, 2)
+               binary.BigEndian.PutUint16(ns, uint16(len(f.name)))
+               f.ffo.FlatFileInformationFork.NameSize = [2]byte(ns[:])
        }
 
        f.ffo.FlatFileInformationForkHeader = FlatFileForkHeader{