func Write(fd int, p []byte) (n int, errno int) { var mode uint32 var done uint32 if isConsole, _ := GetConsoleMode(int32(fd), &mode); UnicodeConsoleOutput && isConsole { // TODO: The number of TCHARs to write. If the total size of the // specified number of characters exceeds 64 KB, the function fails with ERROR_NOT_ENOUGH_MEMORY. buf16 := utf16.Encode([]int(string(p))) //for _, c := range buf16 { print(c," ") } ; println() if ok, e := WriteConsole(int32(fd), buf16, &done); !ok { return 0, e } // convert length of utf16 characters to number of bytes written if done == uint32(len(buf16)) { done = uint32(len(p)) } else { done = 0 for _, rune := range utf16.Decode(buf16[:done]) { done += uint32(utf8.RuneLen(rune)) } } } else { // TODO: This might as well fail with large writes, only Microsoft doesn't say that, see // http://code.google.com/p/msysgit/issues/detail?id=409 for example if ok, e := syscall.WriteFile(int32(fd), p, &done, nil); !ok { return 0, e } } return int(done), 0 }
// createEnvBlock converts an array of environment strings into // the representation required by CreateProcess: a sequence of NUL // terminated strings followed by a nil. // Last bytes are two UCS-2 NULs, or four NUL bytes. func createEnvBlock(envv []string) *uint16 { if len(envv) == 0 { return &utf16.Encode([]int("\x00\x00"))[0] } length := 0 for _, s := range envv { length += len(s) + 1 } length += 1 b := make([]byte, length) i := 0 for _, s := range envv { l := len(s) copy(b[i:i+l], []byte(s)) copy(b[i+l:i+l+1], []byte{0}) i = i + l + 1 } copy(b[i:i+1], []byte{0}) return &utf16.Encode([]int(string(b)))[0] }
// StringToUTF16 returns the UTF-16 encoding of the UTF-8 string s, // with a terminating NUL added. func StringToUTF16(s string) []uint16 { return utf16.Encode([]int(s + "\x00")) }