github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/buf/buffer.go (about) 1 package buf 2 3 import ( 4 "io" 5 6 "github.com/v2fly/v2ray-core/v5/common/bytespool" 7 ) 8 9 const ( 10 // Size of a regular buffer. 11 Size = 2048 12 ) 13 14 var pool = bytespool.GetPool(Size) 15 16 // ownership represents the data owner of the buffer. 17 type ownership uint8 18 19 const ( 20 managed ownership = 0 21 unmanaged ownership = 1 22 bytespools ownership = 2 23 ) 24 25 // Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles 26 // the buffer into an internal buffer pool, in order to recreate a buffer more 27 // quickly. 28 type Buffer struct { 29 v []byte 30 start int32 31 end int32 32 ownership ownership 33 } 34 35 // New creates a Buffer with 0 length and 2K capacity. 36 func New() *Buffer { 37 return &Buffer{ 38 v: pool.Get().([]byte), 39 } 40 } 41 42 // NewWithSize creates a Buffer with 0 length and capacity with at least the given size. 43 func NewWithSize(size int32) *Buffer { 44 return &Buffer{ 45 v: bytespool.Alloc(size), 46 ownership: bytespools, 47 } 48 } 49 50 // FromBytes creates a Buffer with an existed bytearray 51 func FromBytes(data []byte) *Buffer { 52 return &Buffer{ 53 v: data, 54 end: int32(len(data)), 55 ownership: unmanaged, 56 } 57 } 58 59 // StackNew creates a new Buffer object on stack. 60 // This method is for buffers that is released in the same function. 61 func StackNew() Buffer { 62 return Buffer{ 63 v: pool.Get().([]byte), 64 } 65 } 66 67 // Release recycles the buffer into an internal buffer pool. 68 func (b *Buffer) Release() { 69 if b == nil || b.v == nil || b.ownership == unmanaged { 70 return 71 } 72 73 p := b.v 74 b.v = nil 75 b.Clear() 76 switch b.ownership { 77 case managed: 78 pool.Put(p) // nolint: staticcheck 79 case bytespools: 80 bytespool.Free(p) // nolint: staticcheck 81 } 82 } 83 84 // Clear clears the content of the buffer, results an empty buffer with 85 // Len() = 0. 86 func (b *Buffer) Clear() { 87 b.start = 0 88 b.end = 0 89 } 90 91 // Byte returns the bytes at index. 92 func (b *Buffer) Byte(index int32) byte { 93 return b.v[b.start+index] 94 } 95 96 // SetByte sets the byte value at index. 97 func (b *Buffer) SetByte(index int32, value byte) { 98 b.v[b.start+index] = value 99 } 100 101 // Bytes returns the content bytes of this Buffer. 102 func (b *Buffer) Bytes() []byte { 103 return b.v[b.start:b.end] 104 } 105 106 // Extend increases the buffer size by n bytes, and returns the extended part. 107 // It panics if result size is larger than buf.Size. 108 func (b *Buffer) Extend(n int32) []byte { 109 end := b.end + n 110 if end > int32(len(b.v)) { 111 panic("extending out of bound") 112 } 113 ext := b.v[b.end:end] 114 b.end = end 115 return ext 116 } 117 118 // BytesRange returns a slice of this buffer with given from and to boundary. 119 func (b *Buffer) BytesRange(from, to int32) []byte { 120 if from < 0 { 121 from += b.Len() 122 } 123 if to < 0 { 124 to += b.Len() 125 } 126 return b.v[b.start+from : b.start+to] 127 } 128 129 // BytesFrom returns a slice of this Buffer starting from the given position. 130 func (b *Buffer) BytesFrom(from int32) []byte { 131 if from < 0 { 132 from += b.Len() 133 } 134 return b.v[b.start+from : b.end] 135 } 136 137 // BytesTo returns a slice of this Buffer from start to the given position. 138 func (b *Buffer) BytesTo(to int32) []byte { 139 if to < 0 { 140 to += b.Len() 141 } 142 return b.v[b.start : b.start+to] 143 } 144 145 // Resize cuts the buffer at the given position. 146 func (b *Buffer) Resize(from, to int32) { 147 if from < 0 { 148 from += b.Len() 149 } 150 if to < 0 { 151 to += b.Len() 152 } 153 if to < from { 154 panic("Invalid slice") 155 } 156 b.end = b.start + to 157 b.start += from 158 } 159 160 // Advance cuts the buffer at the given position. 161 func (b *Buffer) Advance(from int32) { 162 if from < 0 { 163 from += b.Len() 164 } 165 b.start += from 166 } 167 168 // Len returns the length of the buffer content. 169 func (b *Buffer) Len() int32 { 170 if b == nil { 171 return 0 172 } 173 return b.end - b.start 174 } 175 176 // Cap returns the capacity of the buffer content. 177 func (b *Buffer) Cap() int32 { 178 if b == nil { 179 return 0 180 } 181 return int32(len(b.v)) 182 } 183 184 // IsEmpty returns true if the buffer is empty. 185 func (b *Buffer) IsEmpty() bool { 186 return b.Len() == 0 187 } 188 189 // IsFull returns true if the buffer has no more room to grow. 190 func (b *Buffer) IsFull() bool { 191 return b != nil && b.end == int32(len(b.v)) 192 } 193 194 // Write implements Write method in io.Writer. 195 func (b *Buffer) Write(data []byte) (int, error) { 196 nBytes := copy(b.v[b.end:], data) 197 b.end += int32(nBytes) 198 return nBytes, nil 199 } 200 201 // WriteByte writes a single byte into the buffer. 202 func (b *Buffer) WriteByte(v byte) error { 203 if b.IsFull() { 204 return newError("buffer full") 205 } 206 b.v[b.end] = v 207 b.end++ 208 return nil 209 } 210 211 // WriteString implements io.StringWriter. 212 func (b *Buffer) WriteString(s string) (int, error) { 213 return b.Write([]byte(s)) 214 } 215 216 // ReadByte implements io.ByteReader 217 func (b *Buffer) ReadByte() (byte, error) { 218 if b.start == b.end { 219 return 0, io.EOF 220 } 221 222 nb := b.v[b.start] 223 b.start++ 224 return nb, nil 225 } 226 227 // ReadBytes implements bufio.Reader.ReadBytes 228 func (b *Buffer) ReadBytes(length int32) ([]byte, error) { 229 if b.end-b.start < length { 230 return nil, io.EOF 231 } 232 233 nb := b.v[b.start : b.start+length] 234 b.start += length 235 return nb, nil 236 } 237 238 // Read implements io.Reader.Read(). 239 func (b *Buffer) Read(data []byte) (int, error) { 240 if b.Len() == 0 { 241 return 0, io.EOF 242 } 243 nBytes := copy(data, b.v[b.start:b.end]) 244 if int32(nBytes) == b.Len() { 245 b.Clear() 246 } else { 247 b.start += int32(nBytes) 248 } 249 return nBytes, nil 250 } 251 252 // ReadFrom implements io.ReaderFrom. 253 func (b *Buffer) ReadFrom(reader io.Reader) (int64, error) { 254 n, err := reader.Read(b.v[b.end:]) 255 b.end += int32(n) 256 return int64(n), err 257 } 258 259 // ReadFullFrom reads exact size of bytes from given reader, or until error occurs. 260 func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) { 261 end := b.end + size 262 if end > int32(len(b.v)) { 263 v := end 264 return 0, newError("out of bound: ", v) 265 } 266 n, err := io.ReadFull(reader, b.v[b.end:end]) 267 b.end += int32(n) 268 return int64(n), err 269 } 270 271 // String returns the string form of this Buffer. 272 func (b *Buffer) String() string { 273 return string(b.Bytes()) 274 }