-
Notifications
You must be signed in to change notification settings - Fork 808
/
bytebuf.go
133 lines (109 loc) · 3.94 KB
/
bytebuf.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* Copyright 2021 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package remote
import (
"io"
"net"
)
// ByteBufferFactory is used to create ByteBuffer.
type ByteBufferFactory interface {
NewByteBuffer(conn net.Conn) (ByteBuffer, error)
}
// NocopyWrite is to write []byte without copying, and splits the original buffer.
// It is used with linked buffer implement.
type NocopyWrite interface {
// the buf will be wrapped as a new data node no copy, then insert into the linked buffer.
// remainCap is the remain capacity of origin buff.
WriteDirect(buf []byte, remainCap int) error
}
// ByteBuffer is the core abstraction of buffer in Kitex.
type ByteBuffer interface {
io.ReadWriter
// Next reads the next n bytes sequentially and returns the original buffer.
Next(n int) (p []byte, err error)
// Peek returns the next n bytes without advancing the reader.
Peek(n int) (buf []byte, err error)
// Skip is used to skip the next few bytes quickly. It's faster than Next and doesn't cause release.
Skip(n int) (err error)
// Release will free the buffer. After release, buffer read by Next/Skip/Peek is invalid.
// Param e is used when the buffer release depend on error.
// For example, usually the write buffer will be released inside flush,
// but if flush error happen, write buffer may need to be released explicitly.
Release(e error) (err error)
// ReadableLen returns the total length of readable buffer.
// Return: -1 means unreadable.
ReadableLen() (n int)
// ReadLen returns the size already read.
ReadLen() (n int)
// ReadString is a more efficient way to read string than Next.
ReadString(n int) (s string, err error)
// ReadBinary like ReadString.
// Returns a copy of original buffer.
ReadBinary(n int) (p []byte, err error)
// Malloc n bytes sequentially in the writer buffer.
Malloc(n int) (buf []byte, err error)
// MallocLen returns the total length of the buffer malloced.
MallocLen() (length int)
// WriteString is a more efficient way to write string, using the unsafe method to convert the string to []byte.
WriteString(s string) (n int, err error)
// WriteBinary writes the []byte directly. Callers must guarantee that the []byte doesn't change.
WriteBinary(b []byte) (n int, err error)
// Flush writes any malloc data to the underlying io.Writer.
// The malloced buffer must be set correctly.
Flush() (err error)
// NewBuffer returns a new writable remote.ByteBuffer.
NewBuffer() ByteBuffer
// AppendBuffer appends buf to the original buffer.
AppendBuffer(buf ByteBuffer) (n int, err error)
// Bytes return the backing bytes slice of this buffer
Bytes() (buf []byte, err error)
}
// ByteBufferIO wrap ByteBuffer to implement io.ReadWriter
type ByteBufferIO struct {
buffer ByteBuffer
}
// NewByteBufferIO wraps ByBuffer to io.ReadWriter
func NewByteBufferIO(buffer ByteBuffer) io.ReadWriter {
return &ByteBufferIO{
buffer: buffer,
}
}
// Write implements the io.ReadWriter interface.
func (p *ByteBufferIO) Write(b []byte) (int, error) {
return p.buffer.WriteBinary(b)
}
// Read implements the io.ReadWriter interface.
func (p *ByteBufferIO) Read(b []byte) (n int, err error) {
var buf []byte
readable := p.buffer.ReadableLen()
if readable == 0 {
return 0, io.EOF
} else if len(b) <= readable {
buf, err = p.buffer.Next(len(b))
if err != nil {
return
}
n = len(b)
} else {
buf, err = p.buffer.Next(readable)
if err != nil {
return
}
n = readable
}
copy(b, buf)
return
}