Antonio Mika
·
2025-03-12
writer.go
1package sftp
2
3import (
4 "fmt"
5 "io"
6 "sync"
7
8 "github.com/picosh/pico/pkg/send/utils"
9)
10
11type buffer struct {
12 buf []byte
13 m sync.Mutex
14 off int
15}
16
17func (b *buffer) WriteAt(p []byte, pos int64) (n int, err error) {
18 pLen := len(p)
19 expLen := pos + int64(pLen)
20 b.m.Lock()
21 defer b.m.Unlock()
22 if int64(len(b.buf)) < expLen {
23 if int64(cap(b.buf)) < expLen {
24 newBuf := make([]byte, expLen)
25 copy(newBuf, b.buf)
26 b.buf = newBuf
27 }
28 b.buf = b.buf[:expLen]
29 }
30 copy(b.buf[pos:], p)
31 return pLen, nil
32}
33
34func (b *buffer) Read(p []byte) (n int, err error) {
35 b.m.Lock()
36 defer b.m.Unlock()
37 if len(b.buf) <= b.off {
38 if len(p) == 0 {
39 return 0, nil
40 }
41 return 0, io.EOF
42 }
43 n = copy(p, b.buf[b.off:])
44 b.off += n
45 return n, nil
46}
47
48func (b *buffer) Close() error {
49 b.buf = []byte{}
50 return nil
51}
52
53type fakeWrite struct {
54 fileEntry *utils.FileEntry
55 handler *handler
56 buf *buffer
57}
58
59func (f fakeWrite) WriteAt(p []byte, off int64) (int, error) {
60 return f.buf.WriteAt(p, off)
61}
62
63func (f fakeWrite) Close() error {
64 msg, err := f.handler.writeHandler.Write(f.handler.session, f.fileEntry)
65 if err != nil {
66 errMsg := fmt.Sprintf("%s\r\n", err.Error())
67 _, err = f.handler.session.Stderr().Write([]byte(errMsg))
68 }
69 if msg != "" {
70 nMsg := fmt.Sprintf("%s\r\n", msg)
71 _, err = f.handler.session.Stderr().Write([]byte(nMsg))
72 }
73 f.buf.Close()
74 return err
75}