unsafeslice

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2021 License: BSD-3-Clause Imports: 6 Imported by: 1

Documentation

Overview

Package unsafeslice implements common unsafe transformations involving slices.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AsString

func AsString(b []byte) string

AsString returns a string that refers to the data backing the slice s.

The caller must ensure that the contents of the slice are never again mutated, and that its memory either is managed by the Go garbage collector or remains valid for the remainder of this process's lifetime.

Programs that use AsString should be tested under the race detector to flag erroneous mutations.

Programs that have been adequately tested and shown to be safe may be recompiled with the "unsafe" tag to significantly reduce the overhead of this function, at the cost of reduced safety checks. Programs built under the race detector always have safety checks enabled, even when the "unsafe" tag is set.

Example
package main

import (
	"fmt"
	"hash/fnv"
	"io"

	"github.com/bcmills/unsafeslice"
)

func main() {
	const input = "Hello, world!"
	h := fnv.New64a()
	io.WriteString(h, input)

	// Save the computed checksum as an immutable string,
	// without incurring any additional allocations or copying
	// (beyond the slice for the Sum output).
	binaryChecksum := unsafeslice.AsString(h.Sum(nil))

	fmt.Printf("%x\n", binaryChecksum)

}
Output:

38d1334144987bf4

func ConvertAt

func ConvertAt(dst, src interface{})

ConvertAt sets dst, which must be a non-nil pointer to a variable of a slice type, to a slice that refers to the same memory region as the slice src, but possibly at a different type.

The caller must ensure that src meets the alignment requirements for dst, and that the length and capacity of src are integer multiples of the element size of dst.

This implements one possible API for https://golang.org/issue/38203.

Example
package main

import (
	"fmt"

	"github.com/bcmills/unsafeslice"
)

func main() {
	// For this example, we're going to do a transformation on some ASCII text.
	// That transformation is not endian-sensitive, so we can reinterpret the text
	// as a slice of uint32s to process it word-at-a-time instead of
	// byte-at-a-time.

	const input = "HELLO, WORLD!"

	// Allocate an aligned backing buffer.
	buf := make([]uint32, (len(input)+3)/4)

	// Reinterpret it as a byte slice so that we can copy in our text.
	var alias []byte
	unsafeslice.ConvertAt(&alias, buf)
	copy(alias, input)

	// Perform an endian-insensitive transformation word-by-word instead of
	// byte-by-byte.
	for i := range buf {
		buf[i] |= 0x20202020
	}

	// Read the result back out of the byte-slice view to interpret it as text.
	fmt.Printf("%s\n", alias[:len(input)])

}
Output:

hello, world!

func OfString

func OfString(s string) []byte

OfString returns a slice that refers to the data backing the string s.

The caller must ensure that the contents of the slice are never mutated.

Programs that use OfString should be tested under the race detector to flag erroneous mutations.

Programs that have been adequately tested and shown to be safe may be recompiled with the "unsafe" tag to significantly reduce the overhead of this function, at the cost of reduced safety checks. Programs built under the race detector always have safety checks enabled, even when the "unsafe" tag is set.

Example
package main

import (
	"fmt"
	"hash"
	"hash/fnv"

	"github.com/bcmills/unsafeslice"
)

func main() {
	s := "Hello, world!"

	// Temporarily view the string s as a slice,
	// so that we can compute its checksum with an arbitrary hash.Hash
	// implementation without needing to copy it.
	var h hash.Hash = fnv.New64a()
	b := unsafeslice.OfString(s)

	// This is safe because the contract for an io.Writer requires that
	// “Write must not modify the slice data, even temporarily.”
	h.Write(b)

	fmt.Printf("%x\n", h.Sum(nil))

}
Output:

38d1334144987bf4

func SetAt deprecated

func SetAt(dst interface{}, p unsafe.Pointer, n int)

SetAt sets dst, which must be a non-nil pointer to a variable of a slice type, to a slice of length and capacity n located at p.

The caller must ensure that p meets the alignment requirements for dst, and that the allocation to which p points contains at least n contiguous elements.

This implements one possible API for https://golang.org/issue/19367 and https://golang.org/issue/13656.

Deprecated: as of Go 1.17, use unsafe.Slice instead.

Example
package main

import (
	"fmt"
	"unsafe"

	"github.com/bcmills/unsafeslice"
)

// asCPointer returns b as a C-style pointer and length
func asCPointer(b []byte) (*byte, int) {
	if len(b) == 0 {
		return nil, 0
	}
	return &b[0], len(b)
}

func main() {
	original := []byte("Hello, world!")
	p, n := asCPointer(original)

	var alias []byte
	unsafeslice.SetAt(&alias, unsafe.Pointer(p), n)

	fmt.Printf("original: %s\n", original)
	fmt.Printf("alias: %s\n", alias)
	copy(alias, "Adios")
	fmt.Printf("original: %s\n", original)
	fmt.Printf("alias: %s\n", alias)

}
Output:

original: Hello, world!
alias: Hello, world!
original: Adios, world!
alias: Adios, world!

Types

This section is empty.

Directories

Path Synopsis
internal
eventually
Package eventually enables the use of finalizers whose registration can be blocked until an arbitrary point in the program.
Package eventually enables the use of finalizers whose registration can be blocked until an arbitrary point in the program.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL