Writing cross platform code is easy nowadays. You use Qt, implement stuff, and it compiles and runs almost everywhere. I also enjoy that in my work on the ownCloud desktop client. But, as you know, there is the other part in the client called csync. Its the syncing engine underneath. And that does not build up on Qt, but is plain C. Adventure starts here.
This bug took me on an interesting (well…) journey into what cross platform really means.It is about a complex thing like filenames containing special characters, my favorite example is the directory “Übergröße”. Directories and files like this could not successfully be synced with the latest client.
Windows does not utf8 by default. As far as I understood it, it does a local encoding by default. If you use normal C functions to access the filesystem, something like readdir or so, you get the names in that encoding. But, because that caused problems in some point, there is another set of functions which often start with _w (for example _wreaddir) and that has an interface to deal with wide characters. This is the way to internationalization.
So what needs to be done is to use the wide character implementations everywhere where you deal with filenames (in my case). That, in turn, requires to use wchar_t instead of normal char. But that again requires a lot of #ifdef _WIN32, if its done the naive way at every place it needs to be done. I learned that typedef helps here and a meta type is defined called _TCHAR. And also for all the needed functions, meta functions are defined which are replaced by tricky defines depending on the platform. For example _treaddir becomes readdir on linux and _wreaddir on win32, while _TCHAR becomes wchar_t on Win and char on linux. The code is written using the meta types to not poison it too much with platform ifdefs.
But that is only the first step. Wide character is not utf8! And since utf8 should be used within the software all over, a conversion from wide character to utf8 and back is needed whenever the file system is accessed. Thankfully from csyncs nature, these places are quite nicely concentrated.
All that combines into a larger patch. And now the “Übergröße” folder can be synced correctly from Windows to Linux and back. Great.
What can we learn from that? Well, easy, and once again: If you have no Qt, you’re alone. Better don’t let that happen. If you have Qt, be happy and aware of what it does for you :-)