mirror of https://github.com/v2ray/v2ray-core
Buffer.Prepend()
parent
2031c13a7f
commit
97a85f04ce
|
@ -5,6 +5,10 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultOffset = 16
|
||||||
|
)
|
||||||
|
|
||||||
func Release(buffer *Buffer) {
|
func Release(buffer *Buffer) {
|
||||||
if buffer != nil {
|
if buffer != nil {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
|
@ -22,9 +26,10 @@ func Len(buffer *Buffer) int {
|
||||||
// the buffer into an internal buffer pool, in order to recreate a buffer more
|
// the buffer into an internal buffer pool, in order to recreate a buffer more
|
||||||
// quickly.
|
// quickly.
|
||||||
type Buffer struct {
|
type Buffer struct {
|
||||||
head []byte
|
head []byte
|
||||||
pool *bufferPool
|
pool *bufferPool
|
||||||
Value []byte
|
Value []byte
|
||||||
|
offset int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release recycles the buffer into an internal buffer pool.
|
// Release recycles the buffer into an internal buffer pool.
|
||||||
|
@ -38,7 +43,8 @@ func (b *Buffer) Release() {
|
||||||
// Clear clears the content of the buffer, results an empty buffer with
|
// Clear clears the content of the buffer, results an empty buffer with
|
||||||
// Len() = 0.
|
// Len() = 0.
|
||||||
func (b *Buffer) Clear() *Buffer {
|
func (b *Buffer) Clear() *Buffer {
|
||||||
b.Value = b.head[:0]
|
b.offset = DefaultOffset
|
||||||
|
b.Value = b.head[b.offset:b.offset]
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +60,19 @@ func (b *Buffer) Append(data []byte) *Buffer {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepend prepends bytes in front of the buffer. Caller must ensure total bytes prepended is
|
||||||
|
// no more than 16 bytes.
|
||||||
|
func (b *Buffer) Prepend(data []byte) *Buffer {
|
||||||
|
newoffset := b.offset - len(data)
|
||||||
|
if newoffset < 0 {
|
||||||
|
newoffset = 0
|
||||||
|
}
|
||||||
|
copy(b.head[newoffset:], data)
|
||||||
|
b.Value = b.head[newoffset : b.offset+len(b.Value)]
|
||||||
|
b.offset = newoffset
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Buffer) Bytes() []byte {
|
func (b *Buffer) Bytes() []byte {
|
||||||
return b.Value
|
return b.Value
|
||||||
}
|
}
|
||||||
|
@ -125,9 +144,10 @@ func (p *bufferPool) allocate() *Buffer {
|
||||||
b = p.allocator.Get().([]byte)
|
b = p.allocator.Get().([]byte)
|
||||||
}
|
}
|
||||||
return &Buffer{
|
return &Buffer{
|
||||||
head: b,
|
head: b,
|
||||||
pool: p,
|
pool: p,
|
||||||
Value: b,
|
Value: b[DefaultOffset:],
|
||||||
|
offset: DefaultOffset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,3 +32,19 @@ func TestBufferIsFull(t *testing.T) {
|
||||||
buffer.Clear()
|
buffer.Clear()
|
||||||
assert.Bool(buffer.IsFull()).IsFalse()
|
assert.Bool(buffer.IsFull()).IsFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBufferPrepend(t *testing.T) {
|
||||||
|
v2testing.Current(t)
|
||||||
|
|
||||||
|
buffer := NewBuffer().Clear()
|
||||||
|
defer buffer.Release()
|
||||||
|
|
||||||
|
buffer.Append([]byte{'a', 'b', 'c'})
|
||||||
|
buffer.Prepend([]byte{'x', 'y', 'z'})
|
||||||
|
|
||||||
|
assert.Int(buffer.Len()).Equals(6)
|
||||||
|
assert.Bytes(buffer.Value).Equals([]byte("xyzabc"))
|
||||||
|
|
||||||
|
buffer.Prepend([]byte{'u', 'v', 'w'})
|
||||||
|
assert.Bytes(buffer.Value).Equals([]byte("uvwxyzabc"))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue