PlistCpp icon indicating copy to clipboard operation
PlistCpp copied to clipboard

Unicode String Support

Open DaZombieKiller opened this issue 8 years ago • 8 comments

So I'm using PlistCpp for a project, however I really need Unicode support (because there are various Japanese characters in the file that I need to read)

I noticed both in the README and by testing that Unicode is currently not supported. Is there any chance that this could be added soon(er)?

I tried giving it a shot myself, but my attempts failed.

DaZombieKiller avatar Apr 26 '16 06:04 DaZombieKiller

I am sorry to tell you that I did not use PlistCpp in my project.

I wrote a dedicated plist used to read the CPP file.

Because I am in Chinese, I can only give you a China SkyDrive share, I hope useful for you.

Url:http://pan.baidu.com/s/1nu9NVVr

Password: 6ymo

QiuShiHuang avatar Apr 27 '16 13:04 QiuShiHuang

PlistCpp should support unicode read, just not unicode write. I was hoping that someone would add that capability and issue a pull request. So Unicode read is failing for you?

animetrics avatar Apr 27 '16 14:04 animetrics

@animetrics The file would read without errors, but when attempting to access values within the file, any non-ANSI characters would appear as garbage. Reading/writing the file without any modifications would correctly save the file with the unicode intact however.

I ended up making a CMake version of libplist (based on a fork that supported MSVC2015) as a temporary solution, however I would prefer to use PlistCpp because it's a lot more convenient, due to being raw C++, rather than a C library with C++ bindings. https://github.com/DaZombieKiller/libplist-cmake

@QiuShiHuang I'm getting a 404 on that link

DaZombieKiller avatar Apr 27 '16 22:04 DaZombieKiller

Data is composed of bytes. ASIC conversion by Unicode or UTF-8 should be done according to the project.

QiuShiHuang avatar Apr 28 '16 01:04 QiuShiHuang

@QiuShiHuang can you clarify what you mean in your last comment?

animetrics avatar Apr 28 '16 04:04 animetrics

@animetrics I believe he meant that I had to manually widen the string to get it to work. I ended up using the nowide::widen() function from Boost.Nowide on the returned std::string: http://cppcms.com/files/nowide/html/ Worked like a charm.

As for Unicode writing mysteriously working for me, it might have something to do with this being at the beginning of my main() function:

// use a utf8 locale globally
std::locale utf8_locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>);
std::locale::global(utf8_locale);

Feel free to add that into PlistCpp, you'd just have to imbue that locale into the streams, rather than setting it as the global locale

DaZombieKiller avatar Apr 28 '16 07:04 DaZombieKiller

You can use c ++ or some other interface: ASCII, unicode, utf-8 three encoding conversion. This is my project in the use of a section of code.

int UniToUTF8(CStringW strUnicode,char *szUtf8)   
{   
    int ilen = WideCharToMultiByte(CP_UTF8, 0, (LPCTSTR)strUnicode, -1, NULL, 0, NULL, NULL);    
    char *szUtf8Temp=new char[ilen + 1];   
    memset(szUtf8Temp, 0, ilen +1);    
    WideCharToMultiByte (CP_UTF8, 0, (LPCTSTR)strUnicode, -1, szUtf8Temp, ilen, NULL,NULL);    
    sprintf(szUtf8, "%s", szUtf8Temp);//    
    delete[] szUtf8Temp;    
    return ilen;   
}  
CStringW UTF8ToUnicode(char* UTF8)
{
    DWORD dwUnicodeLen;        
    TCHAR *pwText;           
    CStringW strUnicode;        
    dwUnicodeLen = MultiByteToWideChar(CP_UTF8,0,UTF8,-1,NULL,0);
    pwText = new TCHAR[dwUnicodeLen];
    if (!pwText)
    {
        return strUnicode;
    }
    //To Unicode
    MultiByteToWideChar(CP_UTF8,0,UTF8,-1,pwText,dwUnicodeLen);
    // To CString
    strUnicode.Format(_T("%s"),pwText);
    delete []pwText;
    return strUnicode;
}

int UniToAscii(CStringW s_uin,char *c_ascii)
{
    if(s_uin.IsEmpty())
    {
        memset(c_asic,0,1);
        return FALSE;
    }
    else
    {
        int len = WideCharToMultiByte( CP_ACP , 0 , s_uin , s_uin.GetLength() , NULL , 0 , NULL , NULL );
        len = WideCharToMultiByte(  CP_ACP , 0 , s_uin , s_uin.GetLength() , c_asic , len +1 , NULL ,NULL );
        c_asic[len] = 0;
        return TRUE;
    }
}

QiuShiHuang avatar Apr 28 '16 09:04 QiuShiHuang

@QiuShiHuang I was using something similar earlier, but it's probably not a good idea to use that because it's not cross-platform friendly, that will only work on Windows.

Boost.Nowide does the same thing, but it's crossplatform.

DaZombieKiller avatar Apr 28 '16 10:04 DaZombieKiller