github.com/gramework/runtimer@v0.0.0-20211014201118-d25b6e2ccefd/string.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtimer
     6  
     7  import "unsafe" // #nosec
     8  
     9  type StringStruct struct {
    10  	Str unsafe.Pointer
    11  	Len int
    12  }
    13  
    14  // Variant with *byte pointer type for DWARF debugging.
    15  type StringStructDWARF struct {
    16  	Str *byte
    17  	Len int
    18  }
    19  
    20  func StringStructOf(sp *string) *StringStruct {
    21  	return (*StringStruct)(unsafe.Pointer(sp))
    22  }
    23  
    24  func Contains(s, t string) bool {
    25  	return Index(s, t) >= 0
    26  }
    27  
    28  func Index(s, t string) int {
    29  	if len(t) == 0 {
    30  		return 0
    31  	}
    32  	for i := 0; i < len(s); i++ {
    33  		if s[i] == t[0] && HasPrefix(s[i:], t) {
    34  			return i
    35  		}
    36  	}
    37  	return -1
    38  }
    39  
    40  func HasPrefix(s, t string) bool {
    41  	return len(s) >= len(t) && s[:len(t)] == t
    42  }
    43  
    44  const (
    45  	maxUint = ^uint(0)
    46  	maxInt  = int(maxUint >> 1)
    47  )
    48  
    49  // Atoi parses an int from a string s.
    50  // The bool result reports whether s is a number
    51  // representable by a value of type int.
    52  func Atoi(s string) (int, bool) {
    53  	if s == "" {
    54  		return 0, false
    55  	}
    56  
    57  	neg := false
    58  	if s[0] == '-' {
    59  		neg = true
    60  		s = s[1:]
    61  	}
    62  
    63  	un := uint(0)
    64  	for i := 0; i < len(s); i++ {
    65  		c := s[i]
    66  		if c < '0' || c > '9' {
    67  			return 0, false
    68  		}
    69  		if un > maxUint/10 {
    70  			// overflow
    71  			return 0, false
    72  		}
    73  		un *= 10
    74  		un1 := un + uint(c) - '0'
    75  		if un1 < un {
    76  			// overflow
    77  			return 0, false
    78  		}
    79  		un = un1
    80  	}
    81  
    82  	if !neg && un > uint(maxInt) {
    83  		return 0, false
    84  	}
    85  	if neg && un > uint(maxInt)+1 {
    86  		return 0, false
    87  	}
    88  
    89  	n := int(un)
    90  	if neg {
    91  		n = -n
    92  	}
    93  
    94  	return n, true
    95  }
    96  
    97  // Atoi32 is like Atoi but for integers
    98  // that fit into an int32.
    99  func Atoi32(s string) (int32, bool) {
   100  	if n, ok := Atoi(s); n == int(int32(n)) {
   101  		return int32(n), ok
   102  	}
   103  	return 0, false
   104  }
   105  
   106  func Findnull(s *byte) int {
   107  	return findnull(s)
   108  }
   109  
   110  //go:nosplit
   111  //go:linkname findnull runtime.findnull
   112  func findnull(s *byte) int
   113  
   114  func Findnullw(s *uint16) int {
   115  	return findnullw(s)
   116  }
   117  
   118  //go:linkname findnullw runtime.findnullw
   119  func findnullw(s *uint16) int
   120  
   121  func Gostringnocopy(str *byte) string {
   122  	return gostringnocopy(str)
   123  }
   124  
   125  //go:nosplit
   126  //go:linkname gostringnocopy runtime.gostringnocopy
   127  func gostringnocopy(str *byte) string
   128  
   129  const (
   130  	PageShift uint = 13
   131  
   132  	// Public64bit = 1 on 64-bit systems, 0 on 32-bit systems
   133  	Public64bit uint = 1 << (^uintptr(0) >> 63) / 2
   134  
   135  	MHeapMapTotalBits = (Public64bit*GoosWindows)*35 + (Public64bit*(1-GoosWindows)*(1-GoosDarwin*GoarchArm64))*39 + GoosDarwin*GoarchArm64*31 + (1-Public64bit)*(32-(GoarchMips+GoarchMipsle))
   136  	MHeapMapBits      = MHeapMapTotalBits - PageShift
   137  
   138  	// MaxMem is the maximum heap arena size minus 1.
   139  	//
   140  	// On 32-bit, this is also the maximum heap pointer value,
   141  	// since the arena starts at address 0.
   142  	MaxMem = 1<<MHeapMapTotalBits - 1
   143  )
   144  
   145  func gostringw(strw *uint16) string {
   146  	var buf [8]byte
   147  	str := (*[MaxMem/2/2 - 1]uint16)(unsafe.Pointer(strw))
   148  	n1 := 0
   149  	for i := 0; str[i] != 0; i++ {
   150  		n1 += Encoderune(buf[:], rune(str[i]))
   151  	}
   152  	s, b := Rawstring(n1 + 4)
   153  	n2 := 0
   154  	for i := 0; str[i] != 0; i++ {
   155  		// check for race
   156  		if n2 >= n1 {
   157  			break
   158  		}
   159  		n2 += Encoderune(b[n2:], rune(str[i]))
   160  	}
   161  	b[n2] = 0 // for luck
   162  	return s[:n2]
   163  }