ReadLast returns the last n bytes from the buffer. If n is greater than the available data, returns an error. If n is negative, returns an error.
(n int)
| 92 | // If n is greater than the available data, returns an error. |
| 93 | // If n is negative, returns an error. |
| 94 | func (rb *ringBuffer) ReadLast(n int) ([]byte, error) { |
| 95 | if n < 0 { |
| 96 | return nil, xerrors.New("cannot read negative number of bytes") |
| 97 | } |
| 98 | |
| 99 | if n == 0 { |
| 100 | return nil, nil |
| 101 | } |
| 102 | |
| 103 | size := rb.Size() |
| 104 | |
| 105 | // If requested more than available, return error |
| 106 | if n > size { |
| 107 | return nil, xerrors.Errorf("requested %d bytes but only %d available", n, size) |
| 108 | } |
| 109 | |
| 110 | result := make([]byte, n) |
| 111 | capacity := len(rb.buffer) |
| 112 | |
| 113 | // Calculate where to start reading from (n bytes before the end) |
| 114 | startOffset := size - n |
| 115 | actualStart := (rb.start + startOffset) % capacity |
| 116 | |
| 117 | // Copy the last n bytes |
| 118 | if actualStart+n <= capacity { |
| 119 | // No wrap needed |
| 120 | copy(result, rb.buffer[actualStart:actualStart+n]) |
| 121 | } else { |
| 122 | // Need to wrap around |
| 123 | firstChunk := capacity - actualStart |
| 124 | copy(result[0:firstChunk], rb.buffer[actualStart:capacity]) |
| 125 | copy(result[firstChunk:], rb.buffer[0:n-firstChunk]) |
| 126 | } |
| 127 | |
| 128 | return result, nil |
| 129 | } |