summaryrefslogtreecommitdiff
path: root/server/src/ffi/unicode.lua
blob: 734b467967668b2673b6188e6a7af6a559d323aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
local ffi = require 'ffi'
ffi.cdef[[
    int MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);
    int WideCharToMultiByte(unsigned int CodePage, unsigned long dwFlags, const wchar_t* lpWideCharStr, int cchWideChar, char* lpMultiByteStr, int cchMultiByte, const char* lpDefaultChar, int* pfUsedDefaultChar);
]]

local CP_UTF8 = 65001
local CP_ACP = 0

local function u2w(input)
    local wlen = ffi.C.MultiByteToWideChar(CP_UTF8, 0, input, #input, nil, 0)
    local wstr = ffi.new('wchar_t[?]', wlen+1)
    ffi.C.MultiByteToWideChar(CP_UTF8, 0, input, #input, wstr, wlen)
    return wstr, wlen
end

local function a2w(input)
    local wlen = ffi.C.MultiByteToWideChar(CP_ACP, 0, input, #input, nil, 0)
    local wstr = ffi.new('wchar_t[?]', wlen+1)
    ffi.C.MultiByteToWideChar(CP_ACP, 0, input, #input, wstr, wlen)
    return wstr, wlen
end

local function w2u(wstr, wlen)
    local len = ffi.C.WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, nil, 0, nil, nil)
    local str = ffi.new('char[?]', len+1)
    ffi.C.WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, str, len, nil, nil)
    return ffi.string(str)
end

local function w2a(wstr, wlen)
    local len = ffi.C.WideCharToMultiByte(CP_ACP, 0, wstr, wlen, nil, 0, nil, nil)
    local str = ffi.new('char[?]', len)
    ffi.C.WideCharToMultiByte(CP_ACP, 0, wstr, wlen, str, len, nil, nil)
    return ffi.string(str)
end

return {
    u2w = u2w,
    a2w = a2w,
    w2u = w2u,
    w2a = w2a,
    u2a = function (input)
        return w2a(u2w(input))
    end,
    a2u = function (input)
        return w2u(a2w(input))
    end,
}