a geicko-2 based round robin ranking system designed to test c++ battleship submissions
battleship.dunkirk.sh
1// +build windows
2
3package localereader
4
5import (
6 "io"
7 "syscall"
8 "unicode/utf8"
9 "unsafe"
10
11 "golang.org/x/text/transform"
12)
13
14const (
15 CP_ACP = 0
16 MB_ERR_INVALID_CHARS = 8
17)
18
19var (
20 modkernel32 = syscall.NewLazyDLL("kernel32.dll")
21 procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar")
22 procIsDBCSLeadByte = modkernel32.NewProc("IsDBCSLeadByte")
23)
24
25type codepageDecoder struct {
26 transform.NopResetter
27
28 cp int
29}
30
31func (codepageDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
32 r, size := rune(0), 0
33loop:
34 for ; nSrc < len(src); nSrc += size {
35 switch c0 := src[nSrc]; {
36 case c0 < utf8.RuneSelf:
37 r, size = rune(c0), 1
38
39 default:
40 br, _, _ := procIsDBCSLeadByte.Call(uintptr(src[nSrc]))
41 if br == 0 {
42 r = rune(src[nSrc])
43 size = 1
44 break
45 }
46 if nSrc >= len(src)-1 {
47 r = rune(src[nSrc])
48 size = 1
49 break
50 }
51 n, _, _ := procMultiByteToWideChar.Call(CP_ACP, 0, uintptr(unsafe.Pointer(&src[nSrc])), uintptr(2), uintptr(0), 0)
52 if n <= 0 {
53 err = syscall.GetLastError()
54 break
55 }
56 var us [1]uint16
57 rc, _, _ := procMultiByteToWideChar.Call(CP_ACP, 0, uintptr(unsafe.Pointer(&src[nSrc])), uintptr(2), uintptr(unsafe.Pointer(&us[0])), 1)
58 if rc == 0 {
59 size = 1
60 break
61 }
62 r = rune(us[0])
63 size = 2
64 }
65 if nDst+utf8.RuneLen(r) > len(dst) {
66 err = transform.ErrShortDst
67 break loop
68 }
69 nDst += utf8.EncodeRune(dst[nDst:], r)
70 }
71 return nDst, nSrc, err
72
73}
74
75func newReader(r io.Reader) io.Reader {
76 return transform.NewReader(r, NewAcpDecoder())
77}
78
79func NewCodePageDecoder(cp int) transform.Transformer {
80 return &codepageDecoder{cp: cp}
81}
82
83func NewAcpDecoder() transform.Transformer {
84 return &codepageDecoder{cp: CP_ACP}
85}