forked from toolshed/abra
85
vendor/github.com/mattn/go-localereader/localereader_windows.go
generated
vendored
Normal file
85
vendor/github.com/mattn/go-localereader/localereader_windows.go
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
// +build windows
|
||||
|
||||
package localereader
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
const (
|
||||
CP_ACP = 0
|
||||
MB_ERR_INVALID_CHARS = 8
|
||||
)
|
||||
|
||||
var (
|
||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar")
|
||||
procIsDBCSLeadByte = modkernel32.NewProc("IsDBCSLeadByte")
|
||||
)
|
||||
|
||||
type codepageDecoder struct {
|
||||
transform.NopResetter
|
||||
|
||||
cp int
|
||||
}
|
||||
|
||||
func (codepageDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||
r, size := rune(0), 0
|
||||
loop:
|
||||
for ; nSrc < len(src); nSrc += size {
|
||||
switch c0 := src[nSrc]; {
|
||||
case c0 < utf8.RuneSelf:
|
||||
r, size = rune(c0), 1
|
||||
|
||||
default:
|
||||
br, _, _ := procIsDBCSLeadByte.Call(uintptr(src[nSrc]))
|
||||
if br == 0 {
|
||||
r = rune(src[nSrc])
|
||||
size = 1
|
||||
break
|
||||
}
|
||||
if nSrc >= len(src)-1 {
|
||||
r = rune(src[nSrc])
|
||||
size = 1
|
||||
break
|
||||
}
|
||||
n, _, _ := procMultiByteToWideChar.Call(CP_ACP, 0, uintptr(unsafe.Pointer(&src[nSrc])), uintptr(2), uintptr(0), 0)
|
||||
if n <= 0 {
|
||||
err = syscall.GetLastError()
|
||||
break
|
||||
}
|
||||
var us [1]uint16
|
||||
rc, _, _ := procMultiByteToWideChar.Call(CP_ACP, 0, uintptr(unsafe.Pointer(&src[nSrc])), uintptr(2), uintptr(unsafe.Pointer(&us[0])), 1)
|
||||
if rc == 0 {
|
||||
size = 1
|
||||
break
|
||||
}
|
||||
r = rune(us[0])
|
||||
size = 2
|
||||
}
|
||||
if nDst+utf8.RuneLen(r) > len(dst) {
|
||||
err = transform.ErrShortDst
|
||||
break loop
|
||||
}
|
||||
nDst += utf8.EncodeRune(dst[nDst:], r)
|
||||
}
|
||||
return nDst, nSrc, err
|
||||
|
||||
}
|
||||
|
||||
func newReader(r io.Reader) io.Reader {
|
||||
return transform.NewReader(r, NewAcpDecoder())
|
||||
}
|
||||
|
||||
func NewCodePageDecoder(cp int) transform.Transformer {
|
||||
return &codepageDecoder{cp: cp}
|
||||
}
|
||||
|
||||
func NewAcpDecoder() transform.Transformer {
|
||||
return &codepageDecoder{cp: CP_ACP}
|
||||
}
|
Reference in New Issue
Block a user