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 }