]> 127.0.0.1 Git - part/.git/commitdiff
1 (#47) v0.28.20250421162339
authorqydysky <qydysky@foxmail.com>
Mon, 21 Apr 2025 16:23:30 +0000 (00:23 +0800)
committerGitHub <noreply@github.com>
Mon, 21 Apr 2025 16:23:30 +0000 (00:23 +0800)
io/copyDealer.go [new file with mode: 0644]
io/copyDealer_test.go [new file with mode: 0644]

diff --git a/io/copyDealer.go b/io/copyDealer.go
new file mode 100644 (file)
index 0000000..82337fe
--- /dev/null
@@ -0,0 +1,52 @@
+package part
+
+import (
+       "errors"
+       "io"
+)
+
+var ErrCopyDealerStop = errors.New(`ErrCopyDealerStop`)
+var ErrCopyDealerBufOF = errors.New(`ErrCopyDealerBufOF`)
+
+// buf 最小需要匹配尺寸*1.5 才能有效
+func CopyDealer(w io.Writer, r io.Reader, buf []byte, dealers ...func(data []byte) (dealed []byte, stop bool)) (e error) {
+       n := 0
+       left := 0
+       si := len(buf) / 3
+       for {
+               n, e = r.Read(buf[left : si*2])
+               if n > 0 {
+                       n += left
+                       for i := 0; i < len(dealers); i++ {
+                               if dealed, stop := dealers[i](buf[:n]); stop {
+                                       return ErrCopyDealerStop
+                               } else if len(dealed) > len(buf) {
+                                       return ErrCopyDealerBufOF
+                               } else {
+                                       n = copy(buf, dealed)
+                               }
+                       }
+               } else if e != nil {
+                       if errors.Is(e, io.EOF) {
+                               e = nil
+                               if left > 0 {
+                                       if _, e := w.Write(buf[:left]); e != nil {
+                                               if errors.Is(e, io.EOF) {
+                                                       e = nil
+                                               }
+                                               return e
+                                       }
+                               }
+                       }
+                       return e
+               }
+               if wn, e := w.Write(buf[:min(si, n)]); wn > 0 {
+                       left = copy(buf, buf[wn:n])
+               } else if e != nil {
+                       if errors.Is(e, io.EOF) {
+                               e = nil
+                       }
+                       return e
+               }
+       }
+}
diff --git a/io/copyDealer_test.go b/io/copyDealer_test.go
new file mode 100644 (file)
index 0000000..e3fe757
--- /dev/null
@@ -0,0 +1,29 @@
+package part
+
+import (
+       "bytes"
+       "testing"
+)
+
+func Test_CopyDealer(t *testing.T) {
+       sbuf := []byte(`123456`)
+
+       mark := []byte(`23`)
+
+       if !bytes.Contains(sbuf, mark) {
+               t.Fatal()
+       }
+       tbuf1 := bytes.ReplaceAll(sbuf, mark, []byte(`11`))
+
+       tbuf := bytes.NewBuffer([]byte{})
+
+       if e := CopyDealer(tbuf, bytes.NewReader(sbuf), make([]byte, 3), func(data []byte) (dealed []byte, stop bool) {
+               return bytes.ReplaceAll(data, mark, []byte(`11`)), false
+       }); e != nil {
+               t.Fatal(e)
+       }
+
+       if !bytes.Equal(tbuf.Bytes(), tbuf1) {
+               t.Fatal()
+       }
+}