HTTP POST GET 機能はあるのだけど、URLエンコード用の関数が無い。
もちろんデコードも無かった。なんだこれと思いフォーラムで探したら、まず有志が作ったスクリプトがあった。しかしソースコードが載っていたので見たら ASCII までにしか対応してない。英語以外全否定なの?
参考:This script only works on ASCII strings.
UTF-8 に対応したっぽいスクリプトは 2013 年に別のユーザから発表されていた。
参考:URL Encoding with UTF-8 support (GM8, GMS)
これで一安心?と思ったらこのスクリプトは URL エンコードしか対応してない。デコードはやはり見当たらない。
それにソースコードを見ると 3 byte までしか判定してないのだけど、UTF-8 は 4 byte もまれにあるんやで。ただし 4 byte は MySQL などデータベースがそのままだと対応できないのでサロゲートペアに対応する 3 byte 文字への変換処置が必要になったり処理にややこしさを増す。4 byte を無視する処置もゲーム用なら問題無いと思うけど、なんか不安は残る。UTF-8 に対応してると言いつつ、実は表現できない範囲があるということだから。
HTTP GET は標準機能で用意されているのに、URL Encode(別名%エンコード)機能が無いなんてそんなバカな。しかし無いものは無いので必要ならいざとなったら作らなければならない。
%エンコード機能は C 言語で CF25 用にエクステとして作った経験はあるので GM:Studio の機能でも作れるかわからないがやってみるしかない。方法をとりあえず考えてみた。
Unicode の数値実体参照コード
調べていたら GM:Studio には ord() という関数があり、文字列を Unicode の数値実体参照コードに変換する機能がある。
例えば「表現」という日本語の「表」を数値実体参照コードに直すと「34920」と返って来る。ちな上記ユーザが作った UTF-8 対応の URLEncode スクリプトも ord() を使って、文字列を Single Byte とそれ以外という判定を行っていた。
それよりこの場ではデコードの場合、%エンコードされた文字列を GM:Studio 内でどうやってまた元のユニコードに変換するんや。そっちのほうが問題だ。
chr() 関数あった
ord(); があるならその反対もあるだろ JK ということで、数値実体参照コードから文字列へ変換する関数を探してみた。chr(); を発見。ASCII 以外にも対応してるんだろなとギシアンしながら試してみる。
var test=ord("表");
var moji=chr(test);
draw_text(x,y,moji+moji);
結果「表表」と出た。やるじゃない。
っていうかこれならいけるわ
URL エンコードが GML のスクリプトで処理可能だということは、どっかで Bitwise を使っているはず。
例えば 3 byte の時の処理が
ここから引用
//3-byte characters
else if (o <= $FFFF) { escapes = 3; escape_bytes[0] = (o>>12)+224;
escape_bytes[1] = ((o>>6)&63)+128;
escape_bytes[2] = (o&63)+128;
}
ここまで引用
o>>6
の部分は Bitwise Operation の shift left。っていうか Bitwise 使えるんやなと確認。これを最終的に16進数化する。エンコードはこれでできてる。
デコードはこれと逆の処理をおこなえばいいんだっけ。これなら GML でデコード処理も作れるのだと思う。