github.com/v2fly/v2ray-core/v4@v4.45.2/common/buf/buffer.go (about) 1 package buf 2 3 import ( 4 "io" 5 6 "github.com/v2fly/v2ray-core/v4/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 // Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles 17 // the buffer into an internal buffer pool, in order to recreate a buffer more 18 // quickly. 19 type Buffer struct { 20 v []byte 21 start int32 22 end int32 23 } 24 25 // New creates a Buffer with 0 length and 2K capacity. 26 func New() *Buffer { 27 return &Buffer{ 28 v: pool.Get().([]byte), 29 } 30 } 31 32 // StackNew creates a new Buffer object on stack. 33 // This method is for buffers that is released in the same function. 34 func StackNew() Buffer { 35 return Buffer{ 36 v: pool.Get().([]byte), 37 } 38 } 39 40 // Release recycles the buffer into an internal buffer pool. 41 func (b *Buffer) Release() { 42 if b == nil || b.v == nil { 43 return 44 } 45 46 p := b.v 47 b.v = nil 48 b.Clear() 49 pool.Put(p) // nolint: staticcheck 50 } 51 52 // Clear clears the content of the buffer, results an empty buffer with 53 // Len() = 0. 54 func (b *Buffer) Clear() { 55 b.start = 0 56 b.end = 0 57 } 58 59 // Byte returns the bytes at index. 60 func (b *Buffer) Byte(index int32) byte { 61 return b.v[b.start+index] 62 } 63 64 // SetByte sets the byte value at index. 65 func (b *Buffer) SetByte(index int32, value byte) { 66 b.v[b.start+index] = value 67 } 68 69 // Bytes returns the content bytes of this Buffer. 70 func (b *Buffer) Bytes() []byte { 71 return b.v[b.start:b.end] 72 } 73 74 // Extend increases the buffer size by n bytes, and returns the extended part. 75 // It panics if result size is larger than buf.Size. 76 func (b *Buffer) Extend(n int32) []byte { 77 end := b.end + n 78 if end > int32(len(b.v)) { 79 panic("extending out of bound") 80 } 81 ext := b.v[b.end:end] 82 b.end = end 83 return ext 84 } 85 86 // BytesRange returns a slice of this buffer with given from and to boundary. 87 func (b *Buffer) BytesRange(from, to int32) []byte { 88 if from < 0 { 89 from += b.Len() 90 } 91 if to < 0 { 92 to += b.Len() 93 } 94 return b.v[b.start+from : b.start+to] 95 } 96 97 // BytesFrom returns a slice of this Buffer starting from the given position. 98 func (b *Buffer) BytesFrom(from int32) []byte { 99 if from < 0 { 100 from += b.Len() 101 } 102 return b.v[b.start+from : b.end] 103 } 104 105 // BytesTo returns a slice of this Buffer from start to the given position. 106 func (b *Buffer) BytesTo(to int32) []byte { 107 if to < 0 { 108 to += b.Len() 109 } 110 return b.v[b.start : b.start+to] 111 } 112 113 // Resize cuts the buffer at the given position. 114 func (b *Buffer) Resize(from, to int32) { 115 if from < 0 { 116 from += b.Len() 117 } 118 if to < 0 { 119 to += b.Len() 120 } 121 if to < from { 122 panic("Invalid slice") 123 } 124 b.end = b.start + to 125 b.start += from 126 } 127 128 // Advance cuts the buffer at the given position. 129 func (b *Buffer) Advance(from int32) { 130 if from < 0 { 131 from += b.Len() 132 } 133 b.start += from 134 } 135 136 // Len returns the length of the buffer content. 137 func (b *Buffer) Len() int32 { 138 if b == nil { 139 return 0 140 } 141 return b.end - b.start 142 } 143 144 // IsEmpty returns true if the buffer is empty. 145 func (b *Buffer) IsEmpty() bool { 146 return b.Len() == 0 147 } 148 149 // IsFull returns true if the buffer has no more room to grow. 150 func (b *Buffer) IsFull() bool { 151 return b != nil && b.end == int32(len(b.v)) 152 } 153 154 // Write implements Write method in io.Writer. 155 func (b *Buffer) Write(data []byte) (int, error) { 156 nBytes := copy(b.v[b.end:], data) 157 b.end += int32(nBytes) 158 return nBytes, nil 159 } 160 161 // WriteByte writes a single byte into the buffer. 162 func (b *Buffer) WriteByte(v byte) error { 163 if b.IsFull() { 164 return newError("buffer full") 165 } 166 b.v[b.end] = v 167 b.end++ 168 return nil 169 } 170 171 // WriteString implements io.StringWriter. 172 func (b *Buffer) WriteString(s string) (int, error) { 173 return b.Write([]byte(s)) 174 } 175 176 // Read implements io.Reader.Read(). 177 func (b *Buffer) Read(data []byte) (int, error) { 178 if b.Len() == 0 { 179 return 0, io.EOF 180 } 181 nBytes := copy(data, b.v[b.start:b.end]) 182 if int32(nBytes) == b.Len() { 183 b.Clear() 184 } else { 185 b.start += int32(nBytes) 186 } 187 return nBytes, nil 188 } 189 190 // ReadFrom implements io.ReaderFrom. 191 func (b *Buffer) ReadFrom(reader io.Reader) (int64, error) { 192 n, err := reader.Read(b.v[b.end:]) 193 b.end += int32(n) 194 return int64(n), err 195 } 196 197 // ReadFullFrom reads exact size of bytes from given reader, or until error occurs. 198 func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) { 199 end := b.end + size 200 if end > int32(len(b.v)) { 201 v := end 202 return 0, newError("out of bound: ", v) 203 } 204 n, err := io.ReadFull(reader, b.v[b.end:end]) 205 b.end += int32(n) 206 return int64(n), err 207 } 208 209 // String returns the string form of this Buffer. 210 func (b *Buffer) String() string { 211 return string(b.Bytes()) 212 }