github.com/primecitizens/pcz/std@v0.2.1/core/sys/os_windows.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  
     4  //go:build !noos && windows
     5  
     6  package sys
     7  
     8  import (
     9  	"unsafe"
    10  
    11  	stdconst "github.com/primecitizens/pcz/std/builtin/const"
    12  	stdptr "github.com/primecitizens/pcz/std/builtin/ptr"
    13  	stdslice "github.com/primecitizens/pcz/std/builtin/slice"
    14  	stdstring "github.com/primecitizens/pcz/std/builtin/string"
    15  	"github.com/primecitizens/pcz/std/core/arch"
    16  	"github.com/primecitizens/pcz/std/core/assert"
    17  	"github.com/primecitizens/pcz/std/text/unicode/wtf16"
    18  )
    19  
    20  func init() {
    21  	base := unsafe.SliceData(_args)
    22  	if base == nil { // no args
    23  		return
    24  	}
    25  
    26  	args = wtf16Decode(_args)
    27  
    28  	// base is the envv
    29  	base = stdptr.Add(base, arch.PtrSize*uintptr(len(_args)+1 /* NULL sep */))
    30  	n := 0
    31  	for p := base; *p != nil; p = stdptr.Add(p, arch.PtrSize) {
    32  		n++
    33  	}
    34  
    35  	envs = wtf16Decode(unsafe.Slice(base, n))
    36  }
    37  
    38  func wtf16Decode(slice []*uint16) []string {
    39  	strsliceBytes := stdconst.SizeStringType * uintptr(len(slice))
    40  	totalBytes := strsliceBytes
    41  	for _, p := range slice {
    42  		x := unsafe.Slice(p, stdstring.FindNull2(p))
    43  		wtf8bytes, canDecodeInPlace := wtf16.WTF8DecodedSize(x...)
    44  
    45  		if !canDecodeInPlace {
    46  			totalBytes += uintptr(wtf8bytes)
    47  		}
    48  	}
    49  
    50  	buf := make([]byte, totalBytes)
    51  	ret := unsafe.Slice((*string)(unsafe.Pointer(unsafe.SliceData(buf))), len(slice))
    52  
    53  	buf = unsafe.Slice((*byte)(unsafe.SliceData(buf[strsliceBytes:])), totalBytes-strsliceBytes)[:0]
    54  	for i, p := range slice {
    55  		x := unsafe.Slice(p, stdstring.FindNull2(p))
    56  		wtf8bytes, canDecodeInPlace := wtf16.WTF8DecodedSize(x...)
    57  
    58  		var decoded []byte
    59  		if canDecodeInPlace {
    60  			decoded, _ = wtf16.WTF8Decode(unsafe.Slice((*byte)(unsafe.Pointer(p)), wtf8bytes)[:0], x...)
    61  		} else {
    62  			decoded, _ = wtf16.WTF8Decode(buf, x...)
    63  			decoded, buf = stdslice.Cut(decoded)
    64  		}
    65  
    66  		if len(decoded) != wtf8bytes {
    67  			assert.Throw("bad", "wtf16", "decoding")
    68  		}
    69  
    70  		ret[i] = stdstring.FromBytes(decoded)
    71  	}
    72  
    73  	return ret
    74  }