From: qydysky Date: Mon, 21 Apr 2025 16:23:30 +0000 (+0800) Subject: 1 (#47) X-Git-Tag: v0.28.20250421162339 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=52c78d74224c2990cbeeb251ecaf997cb9077ffc;p=part%2F.git 1 (#47) --- diff --git a/io/copyDealer.go b/io/copyDealer.go new file mode 100644 index 0000000..82337fe --- /dev/null +++ b/io/copyDealer.go @@ -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 index 0000000..e3fe757 --- /dev/null +++ b/io/copyDealer_test.go @@ -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() + } +}