github.com/primecitizens/pcz/std@v0.2.1/builtin/string/string.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2014 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  package stdstring
     9  
    10  import (
    11  	"unsafe"
    12  
    13  	"github.com/primecitizens/pcz/std/core/bytealg"
    14  	"github.com/primecitizens/pcz/std/core/os"
    15  )
    16  
    17  // FindNull returns the index of first \x00 byte, for UTF-8 encoding
    18  //
    19  //go:nosplit
    20  func FindNull(s *byte) int {
    21  	if s == nil {
    22  		return 0
    23  	}
    24  
    25  	// Avoid IndexByteString on Plan 9 because it uses SSE instructions
    26  	// on x86 machines, and those are classified as floating point instructions,
    27  	// which are illegal in a note handler.
    28  	if os.IsPlan9 != 0 {
    29  		p := (*[os.MaxAlloc/2 - 1]uint8)(unsafe.Pointer(s))
    30  		l := 0
    31  		for p[l] != 0 {
    32  			l++
    33  		}
    34  		return l
    35  	}
    36  
    37  	// pageSize is the unit we scan at a time looking for NULL.
    38  	// It must be the minimum page size for any architecture Go
    39  	// runs on. It's okay (just a minor performance loss) if the
    40  	// actual system page size is larger than this value.
    41  	const pageSize = 4096
    42  
    43  	offset := 0
    44  	ptr := unsafe.Pointer(s)
    45  	// IndexByteString uses wide reads, so we need to be careful
    46  	// with page boundaries. Call IndexByteString on
    47  	// [ptr, endOfPage) interval.
    48  	safeLen := int(pageSize - uintptr(ptr)%pageSize)
    49  
    50  	for {
    51  		t := unsafe.String((*byte)(ptr), safeLen)
    52  		// Check one page at a time.
    53  		if i := bytealg.IndexByte(t, 0); i != -1 {
    54  			return offset + i
    55  		}
    56  		// Move to next page
    57  		ptr = unsafe.Pointer(uintptr(ptr) + uintptr(safeLen))
    58  		offset += safeLen
    59  		safeLen = pageSize
    60  	}
    61  }
    62  
    63  // FindNull2 returns the first \x00 wide-char, intended for UTF-16 encoding
    64  //
    65  //go:nosplit
    66  func FindNull2(s *uint16) int {
    67  	if s == nil {
    68  		return 0
    69  	}
    70  	p := (*[os.MaxAlloc/2/2 - 1]uint16)(unsafe.Pointer(s))
    71  	l := 0
    72  	for p[l] != 0 {
    73  		l++
    74  	}
    75  	return l
    76  }