wstr

package
v0.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Rendered for windows/amd64

Overview

This package provides support to convert between Go strings and native, null-terminated Windows UTF-16 strings. It's mainly used within the library, but it's available if you need this kind of encoding/decoding.

Index

Examples

Constants

View Source
const BUF_MAX = 260

Size of the stack buffer, equal to MAX_PATH.

Variables

This section is empty.

Functions

func Capitalize added in v0.2.4

func Capitalize(s string) string

Returns a new string with the first character converted to uppercase.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	s := wstr.Capitalize("abc")
	fmt.Println(s)
}
Output:

Abc

func Cmp

func Cmp(a, b string) int

Compares two strings lexographically.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	compare1 := wstr.Cmp("aa", "bb")
	compare2 := wstr.Cmp("bb", "aa")
	compare3 := wstr.Cmp("aa", "aa")
	fmt.Println(compare1, compare2, compare3)
}
Output:

-1 1 0

func CmpI

func CmpI(a, b string) int

Compares two strings lexographically, case insensitive.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	compare1 := wstr.CmpI("aa", "BB")
	compare2 := wstr.CmpI("bb", "AA")
	compare3 := wstr.CmpI("aa", "AA")
	fmt.Println(compare1, compare2, compare3)
}
Output:

-1 1 0

func CountRunes

func CountRunes(s string) int

Counts the number of runes in the string, which can be less than the number of bytes returned by len(s).

Adapted from [utf8.RuneCountInString].

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	c1 := wstr.CountRunes("foo")
	c2 := wstr.CountRunes("🙂")
	fmt.Println(c1, c2)
}
Output:

3 1

func CountUtf16Len

func CountUtf16Len(s string) int

Counts the number of uint16 words in the string, when encoded to UTF-16. This can be greater than the number of runes, because surrogate pairs are also counted.

This function doesn't count a terminating null, an empty string will return zero.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	c1 := wstr.CountUtf16Len("foo")
	c2 := wstr.CountUtf16Len("🙂")
	fmt.Println(c1, c2)
}
Output:

3 2

func DecodeArrPtr

func DecodeArrPtr(p *uint16) []string

Converts a pointer to a multi null-terminated UTF-16 string into a Go []string.

Source string must have 2 terminating nulls.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	wideStr := []uint16{'a', 'b', 0, 'c', 'd', 0, 0}
	goStr := wstr.DecodeArrPtr(&wideStr[0])
	fmt.Println(goStr)
}
Output:

[ab cd]

func DecodePtr

func DecodePtr(p *uint16) string

Converts a pointer to a null-terminated UTF-16 string into a Go string.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	wideStr := []uint16{'a', 'b', 0}
	goStr := wstr.DecodePtr(&wideStr[0])
	fmt.Println(goStr)
}
Output:

ab

func DecodeSlice

func DecodeSlice(str []uint16) string

Converts a []uint16 with an UTF-16 string, null-terminated or not, into a Go string.

Wraps utf16.Decode.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	wideStr := []uint16{'a', 'b', 0}
	goStr := wstr.DecodeSlice(wideStr)
	fmt.Println(goStr)
}
Output:

ab

func EncodeArrToBuf

func EncodeArrToBuf(dest []uint16, strs ...string) int

Converts multiple Go strings into multiple null-terminated UTF-16 strings, with a double null terminator. Writes to a previously allocated buffer. If the buffer isn't long enough, the output strings will be truncated.

Returns the number of uint16 words written, including the double terminating null.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	destBuf := make([]uint16, 7)
	goStrs := []string{"ab", "cd"}
	wstr.EncodeArrToBuf(destBuf, goStrs...)
	fmt.Println(destBuf)
}
Output:

[97 98 0 99 100 0 0]

func EncodeArrToPtr

func EncodeArrToPtr(strs ...string) *uint16

Converts multiple Go strings into multiple null-terminated UTF-16 strings, with a double null terminator. Returns a new heap-allocated *uint16.

Example
package main

import (
	"fmt"
	"unsafe"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	goStrs := []string{"ab", "cd"}
	pBuf := wstr.EncodeArrToPtr(goStrs...)
	sliceBuf := unsafe.Slice(pBuf, 7)
	fmt.Println(sliceBuf)
}
Output:

[97 98 0 99 100 0 0]

func EncodeArrToSlice

func EncodeArrToSlice(strs ...string) []uint16

Converts multiple Go strings into multiple null-terminated UTF-16 strings, with a double null terminator. Returns a new heap-allocated []uint16.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	goStrs := []string{"ab", "cd"}
	buf := wstr.EncodeArrToSlice(goStrs...)
	fmt.Println(buf)
}
Output:

[97 98 0 99 100 0 0]

func EncodeToBuf

func EncodeToBuf(dest []uint16, s string) int

Converts a Go string into a null-terminated UTF-16 string, writing to a previously allocated buffer. If the buffer isn't long enough, the output string will be truncated.

Returns the number of uint16 words written, including the terminating null.

Adapted from utf16.Encode; performs no allocations.

Example:

buf := make([]uint16, 10)
wstr.EncodeToBuf(buf, "abc")
Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	destBuf := make([]uint16, 3)
	goStr := "ab"
	wstr.EncodeToBuf(destBuf, goStr)
	fmt.Println(destBuf)
}
Output:

[97 98 0]

func EncodeToPtr

func EncodeToPtr(s string) *uint16

Converts a Go string into a null-terminated UTF-16 string. Returns a new heap-allocated *uint16.

Example
package main

import (
	"fmt"
	"unsafe"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	goStr := "ab"
	pBuf := wstr.EncodeArrToPtr(goStr)
	sliceBuf := unsafe.Slice(pBuf, 3)
	fmt.Println(sliceBuf)
}
Output:

[97 98 0]

func EncodeToSlice

func EncodeToSlice(s string) []uint16

Converts a Go string into a null-terminated UTF-16 string. Returns a new heap-allocated []uint16.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	goStr := "ab"
	buf := wstr.EncodeToSlice(goStr)
	fmt.Println(buf)
}
Output:

[97 98 0]

func FmtBytes

func FmtBytes(numBytes int) string

Formats a number of bytes into KB, MB, GB, TB, PB or EB, rounding to 2 decimal places.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	s := wstr.FmtBytes(2 * 1024 * 1024)
	fmt.Println(s)
}
Output:

2.00 MB

func FmtThousands

func FmtThousands(n int) string

Converts the number to a string with thousand separators.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	s := wstr.FmtThousands(2000)
	fmt.Println(s)
}
Output:

2,000

func RemoveDiacritics

func RemoveDiacritics(s string) string

Returns a new string with all diacritics removed.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	s := wstr.RemoveDiacritics("Éçãos")
	fmt.Println(s)
}
Output:

Ecaos

func SplitLines

func SplitLines(s string) []string

Splits the string into lines, considering LF or CR+LF.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	lines := wstr.SplitLines("ab\ncd")
	fmt.Println(lines)
}
Output:

[ab cd]

func SubstrRunes

func SubstrRunes(s string, start, length int) string

Returns a slice over the string, starting at the given index, and with the given length. Counts runes, not bytes.

This function is useful if your string contains multi-byte UTF-8 chars.

Panics if start or length is negative.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	s := wstr.SubstrRunes("ab🙂cd", 1, 3)
	fmt.Println(s)
}
Output:

b🙂c

Types

type BufDecoder

type BufDecoder struct {
	// contains filtered or unexported fields
}

A buffer to receive UTF-16 strings and convert them to Go strings.

This buffer is used internally to speed up syscalls that return strings, and it's prone to buffer overruns if used incorrectly. Be sure to allocate the needed space.

This struct contains a buffer intended to be stack-allocated, so don't move it.

Example:

var wBuf wstr.BufDecoder
wBuf.Alloc(20)
ptr := wBuf.Ptr()
Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	var wBuf wstr.BufDecoder
	wBuf.Alloc(20)

	wBuf.HotSlice()[0] = 'a'
	wBuf.HotSlice()[1] = 'b'

	goStr := wBuf.String()
	fmt.Println(goStr)
}
Output:

ab

func (*BufDecoder) Alloc

func (me *BufDecoder) Alloc(numChars int)

Makes sure there is enough room for the given number of chars. If an allocation is necessary, any previous content will be lost.

Panics if numChars is negative.

func (*BufDecoder) AllocAndZero

func (me *BufDecoder) AllocAndZero(numChars int)

Makes sure there is enough room for the given number of chars. If an allocation is necessary, any previous content will be lost.

In addition, zeroes the whole buffer.

Panics if numChars is negative.

func (*BufDecoder) HotSlice

func (me *BufDecoder) HotSlice() []uint16

Returns a slice over the internal memory block, up to latest BufDecoder.Alloc call.

func (*BufDecoder) Len

func (me *BufDecoder) Len() int

Returns the size of the last call to BufDecoder.Alloc.

func (*BufDecoder) Ptr

func (me *BufDecoder) Ptr() unsafe.Pointer

Returns a pointer to the internal memory block, either stack or heap.

func (*BufDecoder) String

func (me *BufDecoder) String() string

Converts the contents to a Go string.

func (*BufDecoder) Zero

func (me *BufDecoder) Zero()

Zeroes the whole buffer.

type BufEncoder

type BufEncoder struct {
	// contains filtered or unexported fields
}

Encodes a Go string into a null-terminated UTF-16. If the string fits the stack buffer, no allocation is performed.

This buffer is used internally to speed up syscalls with string arguments, and it's prone to buffer overruns if used incorrectly.

This struct contains a buffer intended to be stack-allocated, so don't move it.

Example:

var wFoo, wBar wstr.BufEncoder

_, _, _ = syscall.SyscallN(
	pProc,
	uintptr(wFoo.AllowEmpty("foo")),
)

_, _, _ = syscall.SyscallN(
	pProc,
	uintptr(wFoo.EmptyIsNil("bar")),
)
Example
package main

import (
	"fmt"
	"unsafe"

	"github.com/rodrigocfd/windigo/wstr"
)

func main() {
	var wBuf wstr.BufEncoder
	p := wBuf.AllowEmpty("ab")

	wideStr := unsafe.Slice((*uint16)(p), 2)
	fmt.Println(string(rune(wideStr[0])), string(rune(wideStr[1])))
}
Output:

a b

func (*BufEncoder) AllowEmpty

func (me *BufEncoder) AllowEmpty(s string) unsafe.Pointer

Encodes a Go string into a null-terminated UTF-16, returning a pointer to it. If the string is empty, the buffer will contain just nulls.

If the number of UTF-16 words fits the internal stack buffer, the returned pointer will point to the internal stack buffer. Otherwise, the returned pointer will point to a new heap-allocated slice.

The returned pointer can be passed to syscalls.

Example:

var wFoo wstr.BufEncoder
_, _, _ = syscall.SyscallN(
	pProc,
	uintptr(wFoo.AllowEmpty("foo")),
)

func (*BufEncoder) EmptyIsNil

func (me *BufEncoder) EmptyIsNil(s string) unsafe.Pointer

Encodes a Go string into a null-terminated UTF-16, returning a pointer to it. If the string is empty, returns nil.

If the number of UTF-16 words fit the internal stack buffer, the returned pointer will point to the internal stack buffer. Otherwise, the returned pointer will point to a new heap-allocated slice.

The returned pointer can be passed to syscalls.

Example:

var wFoo wstr.BufEncoder
_, _, _ = syscall.SyscallN(
	pProc,
	uintptr(wFoo.EmptyIsNil("foo")),
)

func (*BufEncoder) Slice

func (me *BufEncoder) Slice(s string) []uint16

Encodes a Go string into a null-terminated UTF-16, returning a slice with it.

If the number of UTF-16 words fit the internal stack buffer, the returned slice will point to the internal stack buffer. Otherwise, the returned slice will point to a new heap-allocated slice.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL