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 }