Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIN: Unable to mmap a file having special characters in file name #56

Open
shivendra14 opened this issue Oct 19, 2019 · 4 comments
Open

Comments

@shivendra14
Copy link
Contributor

shivendra14 commented Oct 19, 2019

I was trying to mmap a file which has special characters in file name. アイコン
mmap = mio::make_mmap_source(file.GetFullPath().as_UTF8(), error);

But the mapping fails.. does mio accepts UTF8? or should I be doing something else to read such file correctly.

    typename String,
    typename = typename std::enable_if<
        std::is_same<typename char_type<String>::type, char>::value
    >::type
> file_handle_type open_file_helper(const String& path, const access_mode mode)
{
    return ::CreateFileA(c_str(path),
            mode == access_mode::read ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            0,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            0);
}

This returns an invalid handle.

@shivendra14
Copy link
Contributor Author

shivendra14 commented Oct 20, 2019

https://stackoverflow.com/questions/8831143/windows-api-ansi-functions-and-utf-8

Can somebody help to fix this CreateFileA and add support of UTF8

@shivendra14 shivendra14 changed the title Unable to mmap a file having special characters in file name WIN: Unable to mmap a file having special characters in file name Oct 20, 2019
@shivendra14
Copy link
Contributor Author

shivendra14 commented Oct 20, 2019

This is the code fix I have done locally to make this work:

std::wstring s2ws(const std::string& s)
{
	int slength = (int)s.length() + 1;
	int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, 0, 0);
	auto buf = std::make_unique<wchar_t[]>(len);
	MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, buf.get(), len);
	return buf.release();
}

template<
    typename String,
    typename = typename std::enable_if<
        std::is_same<typename char_type<String>::type, char>::value
    >::type
> file_handle_type open_file_helper(const String& path, const access_mode mode)
{
    return ::CreateFileW(s2ws(path).c_str(),
            mode == access_mode::read ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            0,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            0);
}

@vimpunk
Copy link
Owner

vimpunk commented Dec 27, 2019

Thanks for using mio! And apologies for the late reply. mio doesn't support utf8 out of the box, sorry about the inconvenience. I have very little time for open source these days, so I would be glad if someone took up the task of adding utf8 support.

@pps83
Copy link
Contributor

pps83 commented Mar 15, 2020

@jdarpinian,

std::wstring s2ws(const std::string& s)

you could simply have two overloads for toWideStr that accept std::string and std::wstring and always do:

::CreateFileW(toWideStr(path).c_str(), ...

without using all that template mumbo-jumbo.

return buf.release();

FYI, this obviously leaks memory. Change it to return buf.get();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants