2019-05-22 23:16:55 +02:00
|
|
|
package bytesutil
|
|
|
|
|
|
|
|
import (
|
2022-01-31 23:18:39 +01:00
|
|
|
"math/bits"
|
2019-05-22 23:16:55 +02:00
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2022-01-31 23:18:39 +01:00
|
|
|
// ResizeWithCopyMayOverallocate resizes b to minimum n bytes and returns the resized buffer (which may be newly allocated).
|
2022-01-25 14:16:24 +01:00
|
|
|
//
|
|
|
|
// If newly allocated buffer is returned then b contents is copied to it.
|
2022-01-31 23:18:39 +01:00
|
|
|
func ResizeWithCopyMayOverallocate(b []byte, n int) []byte {
|
|
|
|
if n <= cap(b) {
|
|
|
|
return b[:n]
|
|
|
|
}
|
|
|
|
nNew := roundToNearestPow2(n)
|
|
|
|
bNew := make([]byte, nNew)
|
|
|
|
copy(bNew, b)
|
|
|
|
return bNew[:n]
|
|
|
|
}
|
|
|
|
|
|
|
|
// ResizeWithCopyNoOverallocate resizes b to exactly n bytes and returns the resized buffer (which may be newly allocated).
|
|
|
|
//
|
|
|
|
// If newly allocated buffer is returned then b contents is copied to it.
|
|
|
|
func ResizeWithCopyNoOverallocate(b []byte, n int) []byte {
|
2022-01-25 14:16:24 +01:00
|
|
|
if n <= cap(b) {
|
|
|
|
return b[:n]
|
|
|
|
}
|
|
|
|
bNew := make([]byte, n)
|
|
|
|
copy(bNew, b)
|
|
|
|
return bNew
|
|
|
|
}
|
|
|
|
|
2022-01-31 23:18:39 +01:00
|
|
|
// ResizeNoCopyMayOverallocate resizes b to minimum n bytes and returns the resized buffer (which may be newly allocated).
|
|
|
|
//
|
|
|
|
// If newly allocated buffer is returned then b contents isn't copied to it.
|
|
|
|
func ResizeNoCopyMayOverallocate(b []byte, n int) []byte {
|
|
|
|
if n <= cap(b) {
|
|
|
|
return b[:n]
|
|
|
|
}
|
|
|
|
nNew := roundToNearestPow2(n)
|
|
|
|
bNew := make([]byte, nNew)
|
|
|
|
return bNew[:n]
|
|
|
|
}
|
|
|
|
|
|
|
|
// ResizeNoCopyNoOverallocate resizes b to exactly n bytes and returns the resized buffer (which may be newly allocated).
|
2022-01-25 14:16:24 +01:00
|
|
|
//
|
|
|
|
// If newly allocated buffer is returned then b contents isn't copied to it.
|
2022-01-31 23:18:39 +01:00
|
|
|
func ResizeNoCopyNoOverallocate(b []byte, n int) []byte {
|
2022-01-25 14:16:24 +01:00
|
|
|
if n <= cap(b) {
|
|
|
|
return b[:n]
|
2019-05-22 23:16:55 +02:00
|
|
|
}
|
2022-01-25 14:16:24 +01:00
|
|
|
return make([]byte, n)
|
2019-05-22 23:16:55 +02:00
|
|
|
}
|
|
|
|
|
2022-01-31 23:18:39 +01:00
|
|
|
// roundToNearestPow2 rounds n to the nearest power of 2
|
|
|
|
//
|
|
|
|
// It is expected that n > 0
|
|
|
|
func roundToNearestPow2(n int) int {
|
|
|
|
pow2 := uint8(bits.Len(uint(n - 1)))
|
|
|
|
return 1 << pow2
|
|
|
|
}
|
|
|
|
|
2019-05-22 23:16:55 +02:00
|
|
|
// ToUnsafeString converts b to string without memory allocations.
|
|
|
|
//
|
|
|
|
// The returned string is valid only until b is reachable and unmodified.
|
|
|
|
func ToUnsafeString(b []byte) string {
|
2024-02-29 16:27:51 +01:00
|
|
|
return unsafe.String(unsafe.SliceData(b), len(b))
|
2019-05-22 23:16:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// ToUnsafeBytes converts s to a byte slice without memory allocations.
|
|
|
|
//
|
|
|
|
// The returned byte slice is valid only until s is reachable and unmodified.
|
2024-02-29 16:27:51 +01:00
|
|
|
func ToUnsafeBytes(s string) []byte {
|
2024-02-29 16:10:10 +01:00
|
|
|
return unsafe.Slice(unsafe.StringData(s), len(s))
|
2019-05-22 23:16:55 +02:00
|
|
|
}
|