github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/unsafe/unsafe.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache-2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package unsafe
     6  
     7  import (
     8  	"reflect"
     9  	"unsafe"
    10  )
    11  
    12  // BytesToString casts src to a string without extra memory allocation. The
    13  // string returned by this function shares memory with "src".
    14  func BytesToString(src []byte) (d string) {
    15  	sh := (*reflect.SliceHeader)(unsafe.Pointer(&src))
    16  	dh := (*reflect.StringHeader)(unsafe.Pointer(&d))
    17  	dh.Data = sh.Data
    18  	dh.Len = sh.Len
    19  	return d
    20  }
    21  
    22  // StringToBytes casts src to []byte without extra memory allocation. The data
    23  // returned by this function shares memory with "src".
    24  func StringToBytes(src string) (d []byte) {
    25  	sh := (*reflect.StringHeader)(unsafe.Pointer(&src))
    26  	dh := (*reflect.SliceHeader)(unsafe.Pointer(&d))
    27  	dh.Data = sh.Data
    28  	dh.Len = sh.Len
    29  	dh.Cap = sh.Len
    30  	return d
    31  }
    32  
    33  // ExtendBytes extends the given byte slice, without zero-initializing the new
    34  // storage space.  The caller must guarantee that cap(d) >= newLen (using e.g.
    35  // a Grow() call on the parent buffer).
    36  func ExtendBytes(dptr *[]byte, newLen int) {
    37  	// An earlier version of this function returned a new byte slice.  However, I
    38  	// don't see a use case where you'd want to keep the old slice object, so
    39  	// I've changed the function to modify the slice object in-place.
    40  	if cap(*dptr) < newLen {
    41  		panic(newLen)
    42  	}
    43  	dh := (*reflect.SliceHeader)(unsafe.Pointer(dptr))
    44  	dh.Len = newLen
    45  }
    46