If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
The command line program "xxd" can be used to easily turn a binary file into a sequence of hexadecimal byte values like this.
I realise that my application will consume an extra few hundred kilobytes of RAM if I do it this way (because all of my translations will be loaded into RAM when my program first loads up).
I think the best way to go about coding this is to look through the code for wxResourceTranslationsLoader, and to tweak it to read from an input iterator, e.g. from a simple pointer or from an "std::istream_iterator".
Before I start coding this, has anyone started it already?
wxMsgCatalog *wxResourceTranslationsLoader::LoadCatalog(const wxString& domain, const wxString& lang)
{
const void *mo_data = NULL;
size_t mo_size = 0;
const wxString resname = wxString::Format("%s_%s", domain, lang);
if ( !wxLoadUserResource(&mo_data, &mo_size, resname, GetResourceType().t_str(), GetModule()) )
return NULL;
wxLogTrace(TRACE_I18N, "Using catalog from Windows resource \"%s\".", resname);
wxMsgCatalog *cat = wxMsgCatalog::CreateFromData( wxCharBuffer::CreateNonOwned(static_cast<const char*>(mo_data), mo_size), domain);
if ( !cat )
{
wxLogWarning(_("Resource '%s' is not a valid message catalog."), resname);
}
return cat;
}
Sorry I copy-pasted this on my phone in a coffee shop so the line endings are all messed up.
It looks like all the functionality I need is already implemented in "wxMsgCatalog::CreateFromData( wxCharBuffer::CreateNonOwned(pointer,length), domain);"
Note that you can get this to read from any kind of input stream by using "std::istream_iterator". Here's how you'd get it to read from standard input:
wxTranslationsLoader *const p =
new wxInputIteratorTranslationsLoader<
std::istream_iterator<char unsigned>
>;
p->MakeCatalogueVisible(
wxT("de"),
istream_iterator<char unsigned>(std::cin),
istream_iterator<char unsigned>()
);
Similarly you can get it to read from a file by using "ifstream" along with "istream_iterator". It can also read from any kind of container (vector, set, stack) if you supply an input iterator.
I'm also working on a Makefile that will automatically process all your ".mo" files into char arrays before your application is compiled. So if you ever change a translation catalogue, you just need to hit "make" and it will automatically re-process all your ".mo" files into char arrays before your application is re-compiled.
It looks like I'll be making a template specialisation for wxInputIteratorTranslationsLoader<char> which passes the pointer directly to wxScopedCharBuffer::CreateNonOwned.
For any type other than char, I will use "std::copy" to copy into a char buffer, and then pass the char buffer to wxScopedCharBuffer::CreateNonOwned.
Another option would be to make another overload of CreateFromData which would take an input iterator (with the type as a template parameter).