github.com/lkarlslund/stringdedup@v0.6.2/common.go (about)

     1  package stringdedup
     2  
     3  import (
     4  	"reflect"
     5  	"runtime"
     6  	"sync"
     7  	"unsafe"
     8  )
     9  
    10  var lock sync.RWMutex
    11  
    12  type weakdata struct {
    13  	data   uintptr
    14  	length int
    15  }
    16  
    17  func (wd weakdata) Uintptr() uintptr {
    18  	return wd.data
    19  }
    20  
    21  func (wd weakdata) Pointer() *byte {
    22  	return (*byte)(unsafe.Pointer(wd.data))
    23  }
    24  
    25  func weakString(in string) weakdata {
    26  	header := (*reflect.StringHeader)(unsafe.Pointer(&in))
    27  	ws := weakdata{
    28  		data:   header.Data,
    29  		length: header.Len,
    30  	}
    31  	return ws
    32  }
    33  
    34  func weakBytes(in []byte) weakdata {
    35  	header := (*reflect.SliceHeader)(unsafe.Pointer(&in))
    36  	ws := weakdata{
    37  		data:   header.Data,
    38  		length: header.Len,
    39  	}
    40  	return ws
    41  }
    42  
    43  func (wd weakdata) String() string {
    44  	var returnstring string
    45  	synt := (*reflect.StringHeader)(unsafe.Pointer(&returnstring))
    46  	synt.Data = wd.data
    47  	synt.Len = wd.length
    48  	return returnstring
    49  }
    50  
    51  func (wd weakdata) Bytes() []byte {
    52  	var returnslice []byte
    53  	synt := (*reflect.SliceHeader)(unsafe.Pointer(&returnslice))
    54  	synt.Data = wd.data
    55  	synt.Len = wd.length
    56  	synt.Cap = wd.length
    57  	return returnslice
    58  }
    59  
    60  func castStringToBytes(in string) []byte {
    61  	var out []byte
    62  	inh := (*reflect.StringHeader)(unsafe.Pointer(&in))
    63  	outh := (*reflect.SliceHeader)(unsafe.Pointer(&out))
    64  	outh.Data = inh.Data
    65  	outh.Len = inh.Len
    66  	outh.Cap = inh.Len
    67  	return out
    68  }
    69  
    70  func castBytesToString(in []byte) string {
    71  	var out string
    72  	inh := (*reflect.SliceHeader)(unsafe.Pointer(&in))
    73  	outh := (*reflect.StringHeader)(unsafe.Pointer(&out))
    74  	outh.Data = inh.Data
    75  	outh.Len = inh.Len
    76  	runtime.KeepAlive(in)
    77  	return out
    78  }
    79  
    80  // ValidateResults ensures that no collisions in returned strings are possible. This is enabled default, but you can speed things up by setting this to false
    81  var ValidateResults = true
    82  
    83  // YesIKnowThisCouldGoHorriblyWrong requires you to read the source code to understand what it does. This is intentional, as usage is only for very specific an careful scenarios
    84  var YesIKnowThisCouldGoHorriblyWrong = false