github.com/LagrangeDev/LagrangeGo@v0.0.0-20240512064304-ad4a85e10cb4/utils/string.go (about)

     1  package utils
     2  
     3  // from https://github.com/Mrs4s/MiraiGo/blob/master/utils/string.go
     4  
     5  import (
     6  	"crypto/rand"
     7  	"encoding/hex"
     8  	"fmt"
     9  	"sync"
    10  	"unsafe"
    11  )
    12  
    13  // B2S converts byte slice to a string without memory allocation.
    14  func B2S(b []byte) string {
    15  	size := len(b)
    16  	if size == 0 {
    17  		return ""
    18  	}
    19  	return unsafe.String(&b[0], size)
    20  }
    21  
    22  // S2B converts string to a byte slice without memory allocation.
    23  //
    24  // Note it may break if string and/or slice header will change
    25  // in the future go versions.
    26  func S2B(s string) (b []byte) {
    27  	return unsafe.Slice(unsafe.StringData(s), len(s))
    28  }
    29  
    30  func MustParseHexStr(s string) []byte {
    31  	result, err := hex.DecodeString(s)
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  	return result
    36  }
    37  
    38  func NewTrace() string {
    39  	randomBytes := make([]byte, 16+8)
    40  
    41  	if _, err := rand.Read(randomBytes); err != nil {
    42  		return ""
    43  	}
    44  
    45  	trace := fmt.Sprintf("00-%x-%x-01", randomBytes[:16], randomBytes[16:])
    46  	return trace
    47  }
    48  
    49  // String Interning is a technique for reducing the memory footprint of large
    50  // strings. It can re-use strings that are already in memory.
    51  
    52  type StringInterner struct {
    53  	mu      sync.RWMutex
    54  	strings map[string]string
    55  }
    56  
    57  func NewStringInterner() *StringInterner {
    58  	return &StringInterner{
    59  		strings: make(map[string]string),
    60  	}
    61  }
    62  
    63  func (i *StringInterner) Intern(s string) string {
    64  	i.mu.RLock()
    65  	if v, ok := i.strings[s]; ok {
    66  		i.mu.RUnlock()
    67  		return v
    68  	}
    69  	i.mu.RUnlock()
    70  	i.mu.Lock()
    71  	i.strings[s] = s
    72  	i.mu.Unlock()
    73  	return s
    74  }