Skip to content

Instantly share code, notes, and snippets.

@rfl890
Last active December 13, 2023 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rfl890/d14d819797e1fc91f6092e57b484dcb6 to your computer and use it in GitHub Desktop.
Save rfl890/d14d819797e1fc91f6092e57b484dcb6 to your computer and use it in GitHub Desktop.
Hacky way of obtaining Unicode input as UTF-8 in Lua(JIT)
local ffi = require("ffi")
ffi.cdef[[
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
FILE *__cdecl __acrt_iob_func(unsigned int _Ix);
int __cdecl _setmode(int _FileHandle, int _Mode);
wchar_t *__cdecl fgetws(wchar_t *_Buffer, int _BufferCount, FILE *_Stream);
size_t __cdecl wcslen(const wchar_t *_String);
int __stdcall WideCharToMultiByte(unsigned int CodePage, unsigned long dwFlags, const wchar_t *lpWideCharStr, int cchWideChar, char *lpMultiByteStr, int cbMultiByte, const char *lpDefaultChar, int *lpUsedDefaultChar);
size_t __cdecl strlen(const char *_Str);
]]
local cstdin = ffi.C.__acrt_iob_func(0)
ffi.C._setmode(0, 0x20000)
local function readLine(max)
max = type(max) == "number" and max or 2000
max = math.floor(max)
max = math.abs(max)
if max > (0x7fffffff - 1) or max < 1 then error("maxmimum chars must be <= 2147483646 and >= 1") end
local utf16buf = ffi.new("wchar_t[?]", max + 1)
ffi.C.fgetws(utf16buf, max + 1, cstdin)
local charsRead = tonumber(ffi.C.wcslen(utf16buf))
local utfBufLen = (charsRead * 4) + 1;
local utfBuf = ffi.new("char[?]", utfBufLen)
ffi.C.WideCharToMultiByte(65001, 0, utf16buf, charsRead + 1, utfBuf, utfBufLen, nil, nil)
return ffi.string(utfBuf, ffi.C.strlen(utfBuf) - 1)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment