Boost logo

Boost Users :

Subject: Re: [Boost-users] wide-char version of boost::mapped_file?
From: Tan, Tom (Shanghai) (TTan_at_[hidden])
Date: 2009-05-26 03:54:43


By borrowing code from boost::filesystem V3, I re-implemented the
to_string function like this:
    std::string to_string(const wstring& ws)
    {
        const size_t BUFFER_SIZE = (ws.size() << 1) + 1;
        
        shared_array<char> p_mcb(new char[BUFFER_SIZE]);

        int count = ::WideCharToMultiByte( AreFileApisANSI() ?
CP_THREAD_ACP : CP_OEMCP,
            WC_NO_BEST_FIT_CHARS, ws.c_str(),
            ws.size(),
            p_mcb.get(),
            BUFFER_SIZE,
            0,
            0 );

        return (-1 == count) ? std::string() : std::string(p_mcb.get(),
count );
    }

This seems to have solved the conversion problem.

Is it possible to add an overloaded constructor based on this code to
take std::wstring or just take a boost::path when V3 comes out.? It
would ease the usage a lot in my opinion.

-----Original Message-----
From: Tan, Tom (Shanghai)
Sent: 2009-05-26 11:55
To: 'boost-users_at_[hidden]'
Subject: wide-char version of boost::mapped_file?

I am trying to use boost::mapped_file in the iostream library. While I
like the interface. The fact that it only supports the ANSI version of
windows API, thus dictating an ANSI version of file path, really drives
me crazy.

In my code I use std::wstring everywhere. Because boost::mapped_file
asked for a std::string to construct like this:
    explicit mapped_file( const std::string& path,
                          std::ios_base::openmode mode =
                              std::ios_base | std::ios_base,
                          size_type length = max_length,
                          boost::intmax_t offset = 0 );
I wrote a small routine to convert it like this:

    std::string to_string(const wstring& ws)
    {
        const size_t BUFFER_SIZE = (ws.size() << 1) + 1;
        
        shared_array<char> p_mcb(new char[BUFFER_SIZE]);

        setlocale( LC_ALL, ".2052");
        size_t count = wcstombs(p_mcb.get(), ws.c_str(), BUFFER_SIZE );
        
        return (-1 == count) ? std::string() : std::string(p_mcb.get());

    }

It does not really work well when I have Enlish and Chinese characters
mixed together in the path, while it does for pure Chinese paths.

So I traced down to the source code to find out why a std::string
instead of basic_string<Char> is needed, anyway, it's just a path, and
has nothing to do with mapping it does. There seems to be no clue except
for the ANSI version of Win32 APIs, which actually have wide-char
versions. Did I missing any design requirement that force it to be like
what it is today?

Another issue is, it throws exception from inside the constructor when
it tries to map a zero-length file. IMHO, it's not good to throw for a
legal file, be its length zero, and not good to throw from the
constructor either.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net