c gettext libintl : .mo load from memory
カテゴリー: General
2022-10-03
タイトル
c gettext libintl : .mo load from memory
gettext
リソースとして
メモリからロードしたいです。
どこのサンプルを見ても
ファイルのフォルダ指定(bindtextdomain)、ファイル名指定(textdomain)からの
gettextコールしかないので
みんな使っていないだけ?
ストリームロード機能ないの?
アホなの?
ということで、
ソースコートをみてみる
https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=tree;f=gettext-runtime/intl;h=0681bbc21d71b840111577c08a937c125d77f4ab;hb=HEAD
ごみがうようよしてますね
では、gettext.cをみると dcgettext.cへ
dcgettext.cへ dcigettext.cへ
怒りがこみ上げてきました。なんでしょう このクソ実装は・・・。
dcigettext.cでやっとコードが記載されていました。
struct known_translation_t
これで必要な設定を保持しているようですね。
ファイル名の保持しかないようですね。
dcigettextを検索します
455 char *
456 DCIGETTEXT
で処理されているようですね
ぐぐぐっと下がって
553 if (plural)
554 retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation,
555 (*foundp)->translation_length);
556 else
557 retval = (char *) (*foundp)->translation;
が翻訳の実態のようです
plural_lookupを検索します
1470 static char *
1471 internal_function
1472 plural_lookup
はい、見つかりました。
domain->data
を参照して値を決めているだけですね。
domain->dataに翻訳データを流し込んで、plural_lookup呼べばメモリから翻訳する関数が作れそうな気がします。
簡単に実装できそうな予感です。
このライブラリ開発者がいなくて単なる些細なバグをはぎ取るメンテナしかないのかな?
domain->dataを決定している関数を探すと解決しそうですね。
domain_file->dataが実態のようです。
domain = (struct loaded_domain *) domain_file->data;
_nl_load_domain (domain_file, domainbinding);
gettext-runtime/intl/loadmsgcat.c
715 _nl_load_domain (struct loaded_l10nfile *domain_file,
838:までに、moの内容を mallocして dataに放り込めばいいようです。
839:以降はそのまま使えそうですね
data = (struct mo_file_header *) malloc (size);
確保後にリソースからmemcpyでコピーするといいでしょう。
解放をどう処理するか?
直接リソースのアドレスを投げ込んで解放なしにする?
手順
Step1: _nl_load_domainを改造し、domain->dataにメモリから流し込む
Step2: plural_lookupにdomainを渡し翻訳をもらう
Step3: 確保メモリの解放 ( 本体は解放どこで処理しているのだろう? )
plural_lookupも内部関数なので、再実装が必要。
もしくはコード改造して _nl_load_domain_exとかにしてパラメーター増やして、
分岐させるほうが手間がなくて簡単かも
課題
言語の自動判定
言語の判定 → メモリからロード
言語の指定 → メモリからロード
執筆:2022.10.03
編集:2022.10.03
編集:2022.10.03
c gettext libintl : .mo load from memory
gettext
リソースとして
メモリからロードしたいです。
どこのサンプルを見ても
ファイルのフォルダ指定(bindtextdomain)、ファイル名指定(textdomain)からの
gettextコールしかないので
みんな使っていないだけ?
ストリームロード機能ないの?
アホなの?
ということで、
ソースコートをみてみる
https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=tree;f=gettext-runtime/intl;h=0681bbc21d71b840111577c08a937c125d77f4ab;hb=HEAD
ごみがうようよしてますね
では、gettext.cをみると dcgettext.cへ
dcgettext.cへ dcigettext.cへ
怒りがこみ上げてきました。なんでしょう このクソ実装は・・・。
dcigettext.cでやっとコードが記載されていました。
struct known_translation_t
これで必要な設定を保持しているようですね。
ファイル名の保持しかないようですね。
dcigettextを検索します
455 char *
456 DCIGETTEXT
で処理されているようですね
ぐぐぐっと下がって
553 if (plural)
554 retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation,
555 (*foundp)->translation_length);
556 else
557 retval = (char *) (*foundp)->translation;
が翻訳の実態のようです
plural_lookupを検索します
1470 static char *
1471 internal_function
1472 plural_lookup
はい、見つかりました。
domain->data
を参照して値を決めているだけですね。
domain->dataに翻訳データを流し込んで、plural_lookup呼べばメモリから翻訳する関数が作れそうな気がします。
簡単に実装できそうな予感です。
このライブラリ開発者がいなくて単なる些細なバグをはぎ取るメンテナしかないのかな?
domain->dataを決定している関数を探すと解決しそうですね。
domain_file->dataが実態のようです。
domain = (struct loaded_domain *) domain_file->data;
_nl_load_domain (domain_file, domainbinding);
gettext-runtime/intl/loadmsgcat.c
715 _nl_load_domain (struct loaded_l10nfile *domain_file,
838:までに、moの内容を mallocして dataに放り込めばいいようです。
839:以降はそのまま使えそうですね
data = (struct mo_file_header *) malloc (size);
確保後にリソースからmemcpyでコピーするといいでしょう。
解放をどう処理するか?
直接リソースのアドレスを投げ込んで解放なしにする?
手順
Step1: _nl_load_domainを改造し、domain->dataにメモリから流し込む
Step2: plural_lookupにdomainを渡し翻訳をもらう
Step3: 確保メモリの解放 ( 本体は解放どこで処理しているのだろう? )
plural_lookupも内部関数なので、再実装が必要。
もしくはコード改造して _nl_load_domain_exとかにしてパラメーター増やして、
分岐させるほうが手間がなくて簡単かも
課題
言語の自動判定
言語の判定 → メモリからロード
言語の指定 → メモリからロード