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 }