diff options
Diffstat (limited to 'client.go')
| -rw-r--r-- | client.go | 104 |
1 files changed, 104 insertions, 0 deletions
@@ -154,6 +154,36 @@ func (c *Client) DeleteFile(ctx context.Context, logicalPath string) error { return nil } +func (c *Client) MoveFile( + ctx context.Context, + sourcePath string, + destinationPath string, +) error { + _, err := c.rpc.MoveFile(ctx, &zwdaemonv1.MoveFileRequest{ + SourcePath: sourcePath, + DestinationPath: destinationPath, + }) + if err != nil { + return convertRPCError(err) + } + return nil +} + +func (c *Client) CopyFile( + ctx context.Context, + sourcePath string, + destinationPath string, +) error { + _, err := c.rpc.CopyFile(ctx, &zwdaemonv1.CopyFileRequest{ + SourcePath: sourcePath, + DestinationPath: destinationPath, + }) + if err != nil { + return convertRPCError(err) + } + return nil +} + func (c *Client) Compact(ctx context.Context) error { _, err := c.rpc.Compact(ctx, &zwdaemonv1.CompactRequest{}) if err != nil { @@ -291,3 +321,77 @@ func (c *Client) AddFile( } } } + +func (c *Client) ReplaceFile( + ctx context.Context, + logicalPath string, + source io.Reader, + sourceLen uint64, +) error { + uploadCtx, cancel := context.WithCancel(ctx) + defer cancel() + + stream, err := c.rpc.ReplaceFile(uploadCtx) + if err != nil { + return convertRPCError(err) + } + + send := func(request *zwdaemonv1.ReplaceFileRequest) error { + err := stream.Send(request) + if err == nil { + return nil + } + + if errors.Is(err, io.EOF) { + _, receiveErr := stream.CloseAndRecv() + if receiveErr != nil { + return convertRPCError(receiveErr) + } + } + + return convertRPCError(err) + } + + err = send(&zwdaemonv1.ReplaceFileRequest{ + Payload: &zwdaemonv1.ReplaceFileRequest_Header{ + Header: &zwdaemonv1.ReplaceFileHeader{ + LogicalPath: logicalPath, + SourceLen: sourceLen, + }, + }, + }) + if err != nil { + return err + } + + const chunkSize = 512 * 1024 + buffer := make([]byte, chunkSize) + + for { + n, readErr := source.Read(buffer) + + if n > 0 { + err := send(&zwdaemonv1.ReplaceFileRequest{ + Payload: &zwdaemonv1.ReplaceFileRequest_Chunk{ + Chunk: buffer[:n], + }, + }) + if err != nil { + return err + } + } + + switch { + case readErr == nil: + continue + case errors.Is(readErr, io.EOF): + _, err := stream.CloseAndRecv() + if err != nil { + return convertRPCError(err) + } + return nil + default: + return &UploadReadError{Err: readErr} + } + } +} |
