2019-05-22 23:16:55 +02:00
|
|
|
package bytesutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2022-01-25 14:16:24 +01:00
|
|
|
// ResizeWithCopy resizes b to 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 ResizeWithCopy(b []byte, n int) []byte {
|
|
|
|
if n <= cap(b) {
|
|
|
|
return b[:n]
|
|
|
|
}
|
|
|
|
// Allocate the exact number of bytes instead of using `b = append(b[:cap(b)], make([]byte, nn)...)`,
|
|
|
|
// since `append()` may allocate more than the requested bytes for additional capacity.
|
|
|
|
// Using make() instead of append() should save RAM when the resized slice is cached somewhere.
|
|
|
|
bNew := make([]byte, n)
|
|
|
|
copy(bNew, b)
|
|
|
|
return bNew
|
|
|
|
}
|
|
|
|
|
|
|
|
// ResizeNoCopy resizes b to 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 ResizeNoCopy(b []byte, n int) []byte {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
return *(*string)(unsafe.Pointer(&b))
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToUnsafeBytes converts s to a byte slice without memory allocations.
|
|
|
|
//
|
|
|
|
// The returned byte slice is valid only until s is reachable and unmodified.
|
2020-08-05 10:53:41 +02:00
|
|
|
func ToUnsafeBytes(s string) (b []byte) {
|
2019-05-22 23:16:55 +02:00
|
|
|
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
2020-08-05 10:53:41 +02:00
|
|
|
slh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
2019-05-22 23:16:55 +02:00
|
|
|
slh.Data = sh.Data
|
|
|
|
slh.Len = sh.Len
|
|
|
|
slh.Cap = sh.Len
|
2020-06-02 23:23:20 +02:00
|
|
|
return b
|
2019-05-22 23:16:55 +02:00
|
|
|
}
|