Example #1
0
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
}
Example #2
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]
}
Example #3
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")) }