github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/buf/buffer.go (about) 1 package buf 2 3 import ( 4 "crypto/rand" 5 "io" 6 "net" 7 8 "github.com/sagernet/sing/common" 9 "github.com/sagernet/sing/common/atomic" 10 "github.com/sagernet/sing/common/debug" 11 E "github.com/sagernet/sing/common/exceptions" 12 F "github.com/sagernet/sing/common/format" 13 ) 14 15 type Buffer struct { 16 data []byte 17 start int 18 end int 19 capacity int 20 refs atomic.Int32 21 managed bool 22 } 23 24 func New() *Buffer { 25 return &Buffer{ 26 data: Get(BufferSize), 27 capacity: BufferSize, 28 managed: true, 29 } 30 } 31 32 func NewPacket() *Buffer { 33 return &Buffer{ 34 data: Get(UDPBufferSize), 35 capacity: UDPBufferSize, 36 managed: true, 37 } 38 } 39 40 func NewSize(size int) *Buffer { 41 if size == 0 { 42 return &Buffer{} 43 } else if size > 65535 { 44 return &Buffer{ 45 data: make([]byte, size), 46 capacity: size, 47 } 48 } 49 return &Buffer{ 50 data: Get(size), 51 capacity: size, 52 managed: true, 53 } 54 } 55 56 func As(data []byte) *Buffer { 57 return &Buffer{ 58 data: data, 59 end: len(data), 60 capacity: len(data), 61 } 62 } 63 64 func With(data []byte) *Buffer { 65 return &Buffer{ 66 data: data, 67 capacity: len(data), 68 } 69 } 70 71 func (b *Buffer) Byte(index int) byte { 72 return b.data[b.start+index] 73 } 74 75 func (b *Buffer) SetByte(index int, value byte) { 76 b.data[b.start+index] = value 77 } 78 79 func (b *Buffer) Extend(n int) []byte { 80 end := b.end + n 81 if end > b.capacity { 82 panic(F.ToString("buffer overflow: capacity ", b.capacity, ",end ", b.end, ", need ", n)) 83 } 84 ext := b.data[b.end:end] 85 b.end = end 86 return ext 87 } 88 89 func (b *Buffer) Advance(from int) { 90 b.start += from 91 } 92 93 func (b *Buffer) Truncate(to int) { 94 b.end = b.start + to 95 } 96 97 func (b *Buffer) Write(data []byte) (n int, err error) { 98 if len(data) == 0 { 99 return 100 } 101 if b.IsFull() { 102 return 0, io.ErrShortBuffer 103 } 104 n = copy(b.data[b.end:b.capacity], data) 105 b.end += n 106 return 107 } 108 109 func (b *Buffer) ExtendHeader(n int) []byte { 110 if b.start < n { 111 panic(F.ToString("buffer overflow: capacity ", b.capacity, ",start ", b.start, ", need ", n)) 112 } 113 b.start -= n 114 return b.data[b.start : b.start+n] 115 } 116 117 func (b *Buffer) WriteRandom(size int) []byte { 118 buffer := b.Extend(size) 119 common.Must1(io.ReadFull(rand.Reader, buffer)) 120 return buffer 121 } 122 123 func (b *Buffer) WriteByte(d byte) error { 124 if b.IsFull() { 125 return io.ErrShortBuffer 126 } 127 b.data[b.end] = d 128 b.end++ 129 return nil 130 } 131 132 func (b *Buffer) ReadOnceFrom(r io.Reader) (int, error) { 133 if b.IsFull() { 134 return 0, io.ErrShortBuffer 135 } 136 n, err := r.Read(b.FreeBytes()) 137 b.end += n 138 return n, err 139 } 140 141 func (b *Buffer) ReadPacketFrom(r net.PacketConn) (int64, net.Addr, error) { 142 if b.IsFull() { 143 return 0, nil, io.ErrShortBuffer 144 } 145 n, addr, err := r.ReadFrom(b.FreeBytes()) 146 b.end += n 147 return int64(n), addr, err 148 } 149 150 func (b *Buffer) ReadAtLeastFrom(r io.Reader, min int) (int64, error) { 151 if min <= 0 { 152 n, err := b.ReadOnceFrom(r) 153 return int64(n), err 154 } 155 if b.IsFull() { 156 return 0, io.ErrShortBuffer 157 } 158 n, err := io.ReadAtLeast(r, b.FreeBytes(), min) 159 b.end += n 160 return int64(n), err 161 } 162 163 func (b *Buffer) ReadFullFrom(r io.Reader, size int) (n int, err error) { 164 if b.end+size > b.capacity { 165 return 0, io.ErrShortBuffer 166 } 167 n, err = io.ReadFull(r, b.data[b.end:b.end+size]) 168 b.end += n 169 return 170 } 171 172 func (b *Buffer) ReadFrom(reader io.Reader) (n int64, err error) { 173 for { 174 if b.IsFull() { 175 return 0, io.ErrShortBuffer 176 } 177 var readN int 178 readN, err = reader.Read(b.FreeBytes()) 179 b.end += readN 180 n += int64(readN) 181 if err != nil { 182 if E.IsMulti(err, io.EOF) { 183 err = nil 184 } 185 return 186 } 187 } 188 } 189 190 func (b *Buffer) WriteRune(s rune) (int, error) { 191 return b.Write([]byte{byte(s)}) 192 } 193 194 func (b *Buffer) WriteString(s string) (n int, err error) { 195 if len(s) == 0 { 196 return 197 } 198 if b.IsFull() { 199 return 0, io.ErrShortBuffer 200 } 201 n = copy(b.data[b.end:b.capacity], s) 202 b.end += n 203 return 204 } 205 206 func (b *Buffer) WriteZero() error { 207 if b.IsFull() { 208 return io.ErrShortBuffer 209 } 210 b.data[b.end] = 0 211 b.end++ 212 return nil 213 } 214 215 func (b *Buffer) WriteZeroN(n int) error { 216 if b.end+n > b.capacity { 217 return io.ErrShortBuffer 218 } 219 common.ClearArray(b.Extend(n)) 220 return nil 221 } 222 223 func (b *Buffer) ReadByte() (byte, error) { 224 if b.IsEmpty() { 225 return 0, io.EOF 226 } 227 228 nb := b.data[b.start] 229 b.start++ 230 return nb, nil 231 } 232 233 func (b *Buffer) ReadBytes(n int) ([]byte, error) { 234 if b.end-b.start < n { 235 return nil, io.EOF 236 } 237 238 nb := b.data[b.start : b.start+n] 239 b.start += n 240 return nb, nil 241 } 242 243 func (b *Buffer) Read(data []byte) (n int, err error) { 244 if b.IsEmpty() { 245 return 0, io.EOF 246 } 247 n = copy(data, b.data[b.start:b.end]) 248 b.start += n 249 return 250 } 251 252 func (b *Buffer) WriteTo(w io.Writer) (int64, error) { 253 n, err := w.Write(b.Bytes()) 254 return int64(n), err 255 } 256 257 func (b *Buffer) Resize(start, end int) { 258 b.start = start 259 b.end = b.start + end 260 } 261 262 func (b *Buffer) Reserve(n int) { 263 if n > b.capacity { 264 panic(F.ToString("buffer overflow: capacity ", b.capacity, ", need ", n)) 265 } 266 b.capacity -= n 267 } 268 269 func (b *Buffer) OverCap(n int) { 270 if b.capacity+n > len(b.data) { 271 panic(F.ToString("buffer overflow: capacity ", len(b.data), ", need ", b.capacity+n)) 272 } 273 b.capacity += n 274 } 275 276 func (b *Buffer) Reset() { 277 b.start = 0 278 b.end = 0 279 b.capacity = len(b.data) 280 } 281 282 // Deprecated: use Reset instead. 283 func (b *Buffer) FullReset() { 284 b.Reset() 285 } 286 287 func (b *Buffer) IncRef() { 288 b.refs.Add(1) 289 } 290 291 func (b *Buffer) DecRef() { 292 b.refs.Add(-1) 293 } 294 295 func (b *Buffer) Release() { 296 if b == nil || !b.managed { 297 return 298 } 299 if b.refs.Load() > 0 { 300 return 301 } 302 common.Must(Put(b.data)) 303 *b = Buffer{} 304 } 305 306 func (b *Buffer) Leak() { 307 if debug.Enabled { 308 if b == nil || !b.managed { 309 return 310 } 311 refs := b.refs.Load() 312 if refs == 0 { 313 panic("leaking buffer") 314 } else { 315 panic(F.ToString("leaking buffer with ", refs, " references")) 316 } 317 } else { 318 b.Release() 319 } 320 } 321 322 func (b *Buffer) Start() int { 323 return b.start 324 } 325 326 func (b *Buffer) Len() int { 327 return b.end - b.start 328 } 329 330 func (b *Buffer) Cap() int { 331 return b.capacity 332 } 333 334 func (b *Buffer) RawCap() int { 335 return len(b.data) 336 } 337 338 func (b *Buffer) Bytes() []byte { 339 return b.data[b.start:b.end] 340 } 341 342 func (b *Buffer) From(n int) []byte { 343 return b.data[b.start+n : b.end] 344 } 345 346 func (b *Buffer) To(n int) []byte { 347 return b.data[b.start : b.start+n] 348 } 349 350 func (b *Buffer) Range(start, end int) []byte { 351 return b.data[b.start+start : b.start+end] 352 } 353 354 func (b *Buffer) Index(start int) []byte { 355 return b.data[b.start+start : b.start+start] 356 } 357 358 func (b *Buffer) FreeLen() int { 359 return b.capacity - b.end 360 } 361 362 func (b *Buffer) FreeBytes() []byte { 363 return b.data[b.end:b.capacity] 364 } 365 366 func (b *Buffer) IsEmpty() bool { 367 return b.end-b.start == 0 368 } 369 370 func (b *Buffer) IsFull() bool { 371 return b.end == b.capacity 372 } 373 374 func (b *Buffer) ToOwned() *Buffer { 375 n := NewSize(len(b.data)) 376 copy(n.data[b.start:b.end], b.data[b.start:b.end]) 377 n.start = b.start 378 n.end = b.end 379 n.capacity = b.capacity 380 return n 381 }