Ticket #27169Open Date: 2012-01-19 08:39 Last Update: 2012-02-23 17:24 [ソースコード]mesg-jpn.h を読める形式にする
Attach FileTicket History - 3/13 Histories [Show all old Histories]2012-01-19 08:39 Update by: umorigu
2012-01-19 09:10 Update by: umorigu
Comment(a)は設定次第では自動化も可能です。 (b)は確かに修正したいと考えていました。 (c)はmbtoutf8を書き換えて"mesg-jpn.h"をUTF-8で保存すれば対応可能です。 u8マクロは今後の移植を考えると、C++11ではu8が予約語になるので、それらしい別の名前(例えば"_Tu8(x)"など)に変えた方が良いと思います。 この仕様だと恐らく実行時にUTF-16 LEやShift_JISからUTF-8に変換することになりますが、これには考慮するべき点がいくつかあります。
これは変換後に、確保したメモリをVirtualProtectExで変更すれば実現可能です。
MSGJPN001などの定数をconst char*型グローバル変数に置き換え、変換後の文字列を指すようにし、さらにそのグローバル変数をVirtualProtectExで変更不可にすれば実現可能です。 コードレビューは後で行います。 Commentコードを見てみましたが、参照するたびに検索し、しかも検索が単純な線形探索でしたので、testブランチでは一旦無効化しました。文字列の検索には二分探索などを用いると良いでしょう。 こちらでも改善策を考えてみます。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=1a0506a7fce0ca8d2d735bc6d5e1f79b73487b51 Comment#define U8MSG(text, u8) (u8)
#define MSGJPN001 U8MSG("テスト", "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88")
この方式はどうでしょうか。 Comment>s_kawamotoさん レビューありがとうございました。 ひとつずつコメントします。
C++11において'u8'は予約ではありません。現状でも L"文字列" はWide文字列を表しますが、Lが予約語で無いのと同じ理屈です。u8という変数も有効です。 (参考: http://d.hatena.ne.jp/melpon/20110826/1314343549 ) わかりやすさからいうとu8(x)はわりと適切ではないかと考えています。
VirtualProtectEx は知りませんでした。これを使うと文字列定数をエミュレートできますね。素晴らしいです。 今の実装は関数の戻り値をconst char* constにしてお茶を濁していましたが、char*にキャストした上で実際書き換えられてしまうと困るなぁと思っていたところでした。
はい。逐一検索を行っています。 ただし、今回の実装は「文字列検索」でなく、「文字列の先頭アドレス」検索を行っています。 「u8(x)の引数には文字列定数しか与えない」という制約を想定しての実装です。 文字列全体を比較するのではなく、単純な数値比較になるので、逐一検索であっても十分に高速な処理となっています。 #define U8MSG(text, u8) (u8)
#define MSGJPN001 U8MSG("テスト", "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88")
こうなると結局第一引数と第二引数の二重管理になってしまうので、個人的にはできれば避けたいところです。次のとおり、メンテナンスコストに比べて得られるパフォーマンスメリットは少ないと踏んでいます。
現状、文字列定数は高々350程度であり、また通常実行時に参照される文字列定数は2桁のオーダーに収まりそうです。さらに、『検索のキーは「文字列の先頭アドレス(数値)」であるために検索処理は高速である』『内部文字列フォーマットがUTF-8であるため、取得した文字列についてはほぼすべてWindows APIに渡すタイミングでUTF8→16変換を行っており、この変換にくらべて各々の逐一検索のための数値比較が十分小さい処理時間と考えられる』さらに言うと、他の処理に隠れてしまうほどの処理時間増加であり、無視できると考えています。 二分探索については、実現にするためのコードの複雑さとソート時間を嫌ったのですが、処理速度が文字列定数の増加に影響されないという意味でおっしゃるとおりメリットがありそうです。試してみます。ありがとうございます。 まとめ。 主張としては「参照のたびに検索したとしても十分高速であり、アプリ実行速度に影響を及ぼさない」ということなのですが、処理速度について現状では主観になってしまうので計測するのがよさそうですね。ベンチマークプログラムを書いてみます。
Comment解決不可能な欠点が見つかりましたので、こちらで考えた案で実装しようと思います。 u8マクロの欠点は以下の通りです。
代替案は以下の通りです。
2012-01-20 19:53 Update by: |
Comment
msg-utf8ブランチで実装してみました。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=shortlog;h=refs/heads/msg-utf8
メインの変更は http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commitdiff;h=166d7d7d10119b178e33e04b4bed01976887cd57 です。
mesg-jpn.h で使っている u8(x) は msgutil.h によって msgutil.c の MessageUtil_GetUTF8StaticBinaryBlock関数に展開されます。
ご検討お願いします。