2013/09/25

文字列のバイト数を数える

(消えてしまった1年前の記事の焼き直しです^^)
(写真に出ている名前はでたらめです^^)

フリーのレーダーのもうひとつの不満は、HUDの上の表示が長いと勝手に切れてしまうことでした。
遠くの人から表示するので、肝心のチャット範囲の人が表示されないこともあります。
そこでこのレーダーでは、近い人優先で文字数制限内に納まるようにしました。
文字数制限といってますが、実際にはバイト数で254バイトまでです。
英数字だけの名前なら文字数=バイト数なのですが、日本語などは1文字=3バイトだったりします。
「文字数」を数える llStringLength() 関数はありますが、「バイト数」を数える関数は?…
…ありましたね~^^
integer strlenB(string str){
  string esc = llEscapeURL(str);
  string wk = (string)llParseString2List(esc,["%"],[]);
  return llStringLength(wk) * 2 - llStringLength(esc);
}
…参考:「jinkoさんSL日記」
http://jinko.slmame.com/e602732.html
(ちょっと改造しています)

llEscapeURL() という関数がありまして、これは英数字以外の記号や日本語のような複数バイト文字の各バイトを「%xx」(xは0~9またはA~F)の形の文字列で置き換えます。
これで作った新しい文字列(上のスクリプトでesc)は
・英数字はそのまま(バイト数も変わらず)
・英数字以外のバイトは置き換わって、バイト数は2づつ増える(1バイト→3バイト)
・置き換わると「%xx」の形になるので、「%」の数=もとの英数字以外のバイト数
ここで「%」を数えるのですが、一気に llParseString2List() で「%」を区切り文字として捨てながらリストに分解、すぐつなぎ直して文字列(上のスクリプトでwk)にするという荒業を使います^^
これはescから「%」を抜くためで、もとの英数字以外のバイト数=escの長さ-wkの長さ、になります。
escの長さ=もとのバイト数+もとの英数字以外のバイト数×2(増えた分)、ですから、
もとのバイト数=escの長さ-(escの長さ-wkの長さ)×2=wkの長さ×2-escの長さ、というわけです。

これでバイト数を計算しながら、制限いっぱいまで表示する人を増やします。