]> git.r.bdr.sh - rbdr/mobius/commitdiff
Implement Scanner and Writer interface for FilePath
authorJeff Halter <redacted>
Wed, 29 Jun 2022 03:44:19 +0000 (20:44 -0700)
committerJeff Halter <redacted>
Wed, 29 Jun 2022 03:44:19 +0000 (20:44 -0700)
hotline/file_name_with_info_test.go
hotline/file_path.go
hotline/file_path_test.go
hotline/flattened_file_object_test.go
hotline/transaction_handlers.go
hotline/transaction_handlers_test.go

index 3ca2c3089131ba32fce2b8afca42b4d105a3b5d1..1637a64ce38c34a352ea0ee90dbad07e67cc506b 100644 (file)
@@ -72,7 +72,7 @@ func TestFileNameWithInfo_UnmarshalBinary(t *testing.T) {
                name    string
                fields  fields
                args    args
-               want *FileNameWithInfo
+               want    *FileNameWithInfo
                wantErr bool
        }{
                {
@@ -109,11 +109,11 @@ func TestFileNameWithInfo_UnmarshalBinary(t *testing.T) {
                                name:                   tt.fields.name,
                        }
                        if err := f.UnmarshalBinary(tt.args.data); (err != nil) != tt.wantErr {
-                               t.Errorf("UnmarshalBinary() error = %v, wantErr %v", err, tt.wantErr)
+                               t.Errorf("Write() error = %v, wantErr %v", err, tt.wantErr)
                        }
                        if !assert.Equal(t, tt.want, f) {
                                t.Errorf("Read() got = %v, want %v", f, tt.want)
                        }
                })
        }
-}
\ No newline at end of file
+}
index 460af03464cc2e5376769a30f2a1b5951cb4d785..46ef97c95915bd786917df4028b6883d2defbd4e 100644 (file)
@@ -1,6 +1,7 @@
 package hotline
 
 import (
+       "bufio"
        "bytes"
        "encoding/binary"
        "errors"
@@ -10,52 +11,66 @@ import (
 )
 
 // FilePathItem represents the file or directory portion of a delimited file path (e.g. foo and bar in "/foo/bar")
+// Example bytes:
 // 00 00
 // 09
-// 73 75 62 66 6f 6c 64 65 72 // "subfolder"
+// 73 75 62 66 6f 6c 64 65 72  "subfolder"
 type FilePathItem struct {
        Len  byte
        Name []byte
 }
 
+const fileItemMinLen = 3
+
+// fileItemScanner implements bufio.SplitFunc for parsing incoming byte slices into complete tokens
+func fileItemScanner(data []byte, _ bool) (advance int, token []byte, err error) {
+       if len(data) < fileItemMinLen {
+               return 0, nil, nil
+       }
+
+       advance = fileItemMinLen + int(data[2])
+       return advance, data[0:advance], nil
+}
+
+// Write implements the io.Writer interface for FilePathItem
+func (fpi *FilePathItem) Write(b []byte) (n int, err error) {
+       fpi.Len = b[2]
+       fpi.Name = b[fileItemMinLen : fpi.Len+fileItemMinLen]
+
+       return int(fpi.Len) + fileItemMinLen, nil
+}
+
 type FilePath struct {
        ItemCount [2]byte
        Items     []FilePathItem
 }
 
-func (fp *FilePath) UnmarshalBinary(b []byte) error {
+func (fp *FilePath) Write(b []byte) (n int, err error) {
        reader := bytes.NewReader(b)
-       err := binary.Read(reader, binary.BigEndian, &fp.ItemCount)
+       err = binary.Read(reader, binary.BigEndian, &fp.ItemCount)
        if err != nil && !errors.Is(err, io.EOF) {
-               return err
+               return n, err
        }
        if errors.Is(err, io.EOF) {
-               return nil
+               return n, nil
        }
 
-       for i := uint16(0); i < fp.Len(); i++ {
-               // skip two bytes for the file path delimiter
-               _, _ = reader.Seek(2, io.SeekCurrent)
-
-               // read the length of the next pathItem
-               segLen, err := reader.ReadByte()
-               if err != nil {
-                       return err
-               }
-
-               pBytes := make([]byte, segLen)
+       scanner := bufio.NewScanner(reader)
+       scanner.Split(fileItemScanner)
 
-               _, err = reader.Read(pBytes)
-               if err != nil && !errors.Is(err, io.EOF) {
-                       return err
+       for i := 0; i < int(binary.BigEndian.Uint16(fp.ItemCount[:])); i++ {
+               var fpi FilePathItem
+               scanner.Scan()
+               if _, err := fpi.Write(scanner.Bytes()); err != nil {
+                       return n, err
                }
-
-               fp.Items = append(fp.Items, FilePathItem{Len: segLen, Name: pBytes})
+               fp.Items = append(fp.Items, fpi)
        }
 
-       return nil
+       return n, nil
 }
 
+// IsDropbox checks if a FilePath matches the special drop box folder type
 func (fp *FilePath) IsDropbox() bool {
        if fp.Len() == 0 {
                return false
@@ -79,7 +94,7 @@ func (fp *FilePath) Len() uint16 {
 func readPath(fileRoot string, filePath, fileName []byte) (fullPath string, err error) {
        var fp FilePath
        if filePath != nil {
-               if err = fp.UnmarshalBinary(filePath); err != nil {
+               if _, err = fp.Write(filePath); err != nil {
                        return "", err
                }
        }
index f25941ebc55bc27ccd7a0e4eb01185a8b0a5deff..c2fa66687b02366320007df690db485b1fdfe038 100644 (file)
@@ -5,7 +5,7 @@ import (
        "testing"
 )
 
-func TestFilePath_UnmarshalBinary(t *testing.T) {
+func TestFilePath_Write(t *testing.T) {
        type args struct {
                b []byte
        }
@@ -56,8 +56,8 @@ func TestFilePath_UnmarshalBinary(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        var fp FilePath
-                       if err := fp.UnmarshalBinary(tt.args.b); (err != nil) != tt.wantErr {
-                               t.Errorf("UnmarshalBinary() error = %v, wantErr %v", err, tt.wantErr)
+                       if _, err := fp.Write(tt.args.b); (err != nil) != tt.wantErr {
+                               t.Errorf("Write() error = %v, wantErr %v", err, tt.wantErr)
                        }
                        if !assert.Equal(t, tt.want, fp) {
                                t.Errorf("Read() got = %v, want %v", fp, tt.want)
index 596ca2c2151ae9dd979da117000d57c83108cf5a..274ca2b1831ef5552f704d56739cc945d077c6f9 100644 (file)
@@ -37,7 +37,7 @@ func TestFlatFileInformationFork_UnmarshalBinary(t *testing.T) {
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        ffif := &FlatFileInformationFork{}
-                       tt.wantErr(t, ffif.UnmarshalBinary(tt.args.b), fmt.Sprintf("UnmarshalBinary(%v)", tt.args.b))
+                       tt.wantErr(t, ffif.UnmarshalBinary(tt.args.b), fmt.Sprintf("Write(%v)", tt.args.b))
                })
        }
 }
index 23ee0e6696035eea952e66ca2a75dcb0a14695e3..8ba363279f54512844edcc58ae1eb6f17edbdae4 100644 (file)
@@ -582,7 +582,7 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err
        // fieldFilePath is only present for nested paths
        if t.GetField(fieldFilePath).Data != nil {
                var newFp FilePath
-               err := newFp.UnmarshalBinary(t.GetField(fieldFilePath).Data)
+               _, err := newFp.Write(t.GetField(fieldFilePath).Data)
                if err != nil {
                        return nil, err
                }
@@ -1472,7 +1472,7 @@ func HandleDownloadFolder(cc *ClientConn, t *Transaction) (res []Transaction, er
        fileTransfer := cc.newFileTransfer(FolderDownload, t.GetField(fieldFileName).Data, t.GetField(fieldFilePath).Data, transferSize)
 
        var fp FilePath
-       err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data)
+       _, err = fp.Write(t.GetField(fieldFilePath).Data)
        if err != nil {
                return res, err
        }
@@ -1496,7 +1496,7 @@ func HandleDownloadFolder(cc *ClientConn, t *Transaction) (res []Transaction, er
 func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err error) {
        var fp FilePath
        if t.GetField(fieldFilePath).Data != nil {
-               if err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data); err != nil {
+               if _, err = fp.Write(t.GetField(fieldFilePath).Data); err != nil {
                        return res, err
                }
        }
@@ -1541,7 +1541,7 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er
 
        var fp FilePath
        if filePath != nil {
-               if err = fp.UnmarshalBinary(filePath); err != nil {
+               if _, err = fp.Write(filePath); err != nil {
                        return res, err
                }
        }
@@ -1658,7 +1658,7 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e
 
        var fp FilePath
        if t.GetField(fieldFilePath).Data != nil {
-               if err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data); err != nil {
+               if _, err = fp.Write(t.GetField(fieldFilePath).Data); err != nil {
                        return res, err
                }
        }
index 0d6b1dc3e7595345e1ba4583a58cd626f47e5e11..b5e0bacd773c6f818250a27764132319cb83d806 100644 (file)
@@ -814,7 +814,7 @@ func TestHandleNewFolder(t *testing.T) {
                        wantErr: false,
                },
                {
-                       name: "when UnmarshalBinary returns an err",
+                       name: "when Write returns an err",
                        args: args{
                                cc: &ClientConn{
                                        Account: &Account{