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