mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 01:57:12 -05:00
compact buffers
This commit is contained in:
parent
012a2d6f57
commit
fc92b6295a
@ -3,6 +3,7 @@ package buf
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/errors"
|
"v2ray.com/core/common/errors"
|
||||||
"v2ray.com/core/common/serial"
|
"v2ray.com/core/common/serial"
|
||||||
)
|
)
|
||||||
@ -121,6 +122,30 @@ func SplitBytes(mb MultiBuffer, b []byte) (MultiBuffer, int) {
|
|||||||
return mb, totalBytes
|
return mb, totalBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compact returns another MultiBuffer by merging all content of the given one together.
|
||||||
|
func Compact(mb MultiBuffer) MultiBuffer {
|
||||||
|
if len(mb) == 0 {
|
||||||
|
return mb
|
||||||
|
}
|
||||||
|
|
||||||
|
mb2 := make(MultiBuffer, 0, len(mb))
|
||||||
|
last := mb[0]
|
||||||
|
|
||||||
|
for i := 1; i < len(mb); i++ {
|
||||||
|
curr := mb[i]
|
||||||
|
if last.Len()+curr.Len() > Size {
|
||||||
|
mb2 = append(mb2, last)
|
||||||
|
last = curr
|
||||||
|
} else {
|
||||||
|
common.Must2(last.ReadFrom(curr))
|
||||||
|
curr.Release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mb2 = append(mb2, last)
|
||||||
|
return mb2
|
||||||
|
}
|
||||||
|
|
||||||
// SplitFirst splits the first Buffer from the beginning of the MultiBuffer.
|
// SplitFirst splits the first Buffer from the beginning of the MultiBuffer.
|
||||||
func SplitFirst(mb MultiBuffer) (MultiBuffer, *Buffer) {
|
func SplitFirst(mb MultiBuffer) (MultiBuffer, *Buffer) {
|
||||||
if len(mb) == 0 {
|
if len(mb) == 0 {
|
||||||
|
@ -171,33 +171,17 @@ func (c *interConn) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
if mb.IsEmpty() {
|
mb = buf.Compact(mb)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(mb) == 1 {
|
|
||||||
_, err := c.Write(mb[0].Bytes())
|
|
||||||
buf.ReleaseMulti(mb)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
b := getBuffer()
|
|
||||||
defer putBuffer(b)
|
|
||||||
|
|
||||||
reader := buf.MultiBufferContainer{
|
|
||||||
MultiBuffer: mb,
|
|
||||||
}
|
|
||||||
defer reader.Close()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
nBytes, err := reader.Read(b[:1200])
|
mb2, b := buf.SplitFirst(mb)
|
||||||
if err != nil {
|
mb = mb2
|
||||||
|
if b == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if nBytes == 0 {
|
|
||||||
continue
|
if err := buf.WriteAllBytes(c, b.Bytes()); err != nil {
|
||||||
}
|
buf.ReleaseMulti(mb)
|
||||||
if _, err := c.Write(b[:nBytes]); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ var (
|
|||||||
type connection struct {
|
type connection struct {
|
||||||
conn *websocket.Conn
|
conn *websocket.Conn
|
||||||
reader io.Reader
|
reader io.Reader
|
||||||
mergingWriter *buf.BufferedWriter
|
|
||||||
remoteAddr net.Addr
|
remoteAddr net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,13 +69,22 @@ func (c *connection) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *connection) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
func (c *connection) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
if c.mergingWriter == nil {
|
mb = buf.Compact(mb)
|
||||||
c.mergingWriter = buf.NewBufferedWriter(&buf.BufferToBytesWriter{Writer: c})
|
|
||||||
|
for {
|
||||||
|
mb2, b := buf.SplitFirst(mb)
|
||||||
|
mb = mb2
|
||||||
|
if b == nil {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
if err := c.mergingWriter.WriteMultiBuffer(mb); err != nil {
|
|
||||||
|
if err := buf.WriteAllBytes(c, b.Bytes()); err != nil {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.mergingWriter.Flush()
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *connection) Close() error {
|
func (c *connection) Close() error {
|
||||||
|
Loading…
Reference in New Issue
Block a user