忍者ブログ
natsuの秘密基地です
はまり
はまり一件ごとのお話の流れです
カレンダー
03 2020/04 05
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
プロフィール
HN:
natsu
性別:
男性
趣味:
酒など
自己紹介:
ここに書かれていることはフィクションです。
ブログ内検索
アクセス解析
[23] [22] [21] [20] [19] [18] [17] [16] [15] [14] [12
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

UTF8。
マルチバイト文字ってねぇ。
難しいんですよ。
よくわかんないよ。わたしゃ。
 
 
鬼車にUTF8で渡していろいろ試したんだけども、
戻り値が案の定、何バイト目か。で、かえる。
 
そこまでの文字数を手に入れるにはどうすればいいんだろう。
UTF8は一個の文字を表現するためのバイト数が可変だ。
 
mblenでその文字何バイト?
を繰り返しやればいいのだろうか。
 
ええのんか。ええのんか。みたいな。(意味不明)
 
もう少し速そうな方法があればいいんだけども。
mblenが関数じゃなくてマクロだったらいいなあ。
とはおもった。
 
たぶん、こういうときにこそ、
関数呼び出しのオーバーヘッドを気にしなければいけない気がするから。
マクロだったらそのへんで繰り返し処理の効率がまだましになる。
それこそ、[lengthGetter length:str]
とかやっちゃうと大変なことになる気がする。
 
アセンブラで速くなんないかな、とか検討するにしてもね。
今それやっちゃうと、
iPhoneやiPadとか。柔軟性が無くなっちゃう。

それにマクロと同じくらいにしか速くならない気がする。
 
 
たぶんだけど、どの環境でもマクロが最も妥当。
勘だけど。
 
 
なんかGTKにそういう用途のコードがあるらしい。
ここでそのコードの引用を見つけた。
 
 
 
コードから察するに、
UTFの文字の先頭1byteと、
256の長さの配列で判定をするというものだと思う。
 
たぶんこういうことだと思う。
 
case1
その文字の1bit目が0の場合、
その1byteで一つの文字
 
case2
その文字の3bit目までが110の場合、
そのbyteと次のbyteの2byteで一つの文字
 
case3
その文字の4bit目までが1110の場合、
そのbyteと次の2つの3byteで一つの文字
 
case4
その文字の5bit目までが11110の場合、
そのbyteと次の3つの4byteで一つの文字
 
case5
その文字の6bit目までが111110の場合、
そのbyteと次の4つの5byteで一つの文字
 
case6
その文字の7bit目までが1111110の場合、
そのbyteと次の5つのbyteの6つで一つの文字
 
 
めんどい。要するに
 
0x000 <= 1byte目 <= 0x7F 1byte
0x80 <= 1byte目 <= 0xBF 得体の知れない何か
0xC0 <= 1byte目 <= 0xDF 2byte
0xE0 <= 1byte目 <= 0xEF 3byte
0xF0 <= 1byte目 <= 0xF7 4byte
0xF8 <= 1byte目 <= 0xFB 5byte
0xFC <= 1byte目 <= 0xFD 6byte
0xFEか0xFF == 1byte目 それらではない何か
 
ってことなので、
 
unsigned char charLength[256] = {
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 //ここまでで7F
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 //ここまででBF
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
 //ここまででDF
 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
 //ここまででEF
 4,4,4,4,4,4,4,4,
 //ここまででF7
 5,5,5,5,
 //ここまででFB
 6,6,
 //ここまででFD
 1,1
 //FEとFF
};
 
って配列を使って、
文字のバイト数 = charLength[1byte目];
って感じで文字のバイト数が得られる。
 
で、ここまでくると、
gtkのコードにあるようにマクロが組めるようになる
えっとbyte型って、あったっけ、なかったっけ。
 
#define UTF8STEP(p) ((p) + charLength[*(unsigned char *)(p)])
 
pがchar *でそのまさに指し示している文字の先頭1バイトを
配列に渡して文字数を返してもらい、
それをpに足せば次の文字の先頭のアドレスになる。
これを検索ヒットの位置まで繰り返していけば、
そこまでの文字数が手に入ると。
 
 
 
 
適当に文字列を思いついて、
最後の方にヒットするように正規表現を書いて、
なんとなく何バイト目かを出して、
その何バイト目か、から何文字目かを出すのに計測。
 
って感じで計測をすればいいと思ったので、
このエントリーの下書きのファイルを読み込んで、
最後の方にヒットするように条件を書く。
改行があると頭おかしくなりそうなので、
あらかじめ取り除いておく。
 
mblen_l
2010-05-17 16:28:26.956 onitest[23352:903] Elapsed time: 0.000142
 
マクロ
2010-05-17 19:32:32.280 onitest[24805:903] Elapsed time: 0.000048
 
あー。やっぱマクロでやった方が速いっすねー。
ほら計測結果みてごらんなさい。
もう全然違う。

何回かやったけど、
大体2倍から2.5倍は確実に速い。

 
っていっても、
一回だけやるんだったら、どちらも問題にならないくらい速い。
どちらでもいいと思った。
 
 
PR
この記事にコメントする
NAME:
TITLE:
color:
MAIL:
URL:
COMMENT:
PASS: Vodafone絵文字 i-mode絵文字 Ezweb絵文字
この記事へのトラックバック
この記事にトラックバックする:


Copyright (C) 2010 NEST,
All right Resieved.*Powered by ニンジャブログ *Designed by にこるん  / 忍者ブログ / [PR]