HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0625
しまくろねこHSP3Dishでのhttpload, httpinfoによるWeb上のバイナリファイル取得について14解決


しまくろねこ

リンク

2017/6/25(Sun) 15:51:17|NO.80386

こんにちは。

HSP3DishにてWeb上に置いてあるバイナリファイルを読み込むプログラムを作っています。
Windows上だとWeb上に置いてあるバイナリファイルを取得して中身を正常に表示されるのですが、Android実機上だと正常に表示されません。


バイナリファイルは下記のようなABCDという内容です。

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00

またソースは以下のような内容です。

#include "hsp3dish.as" #const FALSE 0 #const TRUE 1 redraw 0 color 0, 0, 0 : boxf ; URLを指定 web_file = "test.bn" web_file_url = "http://www.geocities.jp/simakuroneko646/" + web_file web_res = 0 web_load_success = FALSE web_load_error = FALSE web_error_str = "" ; http通信の開始 httpload web_file_url if stat == 0 { ; 繋がった repeat httpinfo web_res, HTTPINFO_MODE if web_res == HTTPMODE_READY { web_load_success = TRUE break } if web_res <= HTTPMODE_NONE { web_load_error = TRUE break } await 16 loop } else { ; 繋がらなかった web_load_error = TRUE } if web_load_error { httpinfo web_error_str, HTTPINFO_ERROR dialog web_error_str,, "Error" end } if web_load_success { ; "DOWNLOAD 完了" get_web_size = 0 get_web_buff = "" httpinfo get_web_size, HTTPINFO_SIZE : sdim get_web_buff, get_web_size httpinfo get_web_buff, HTTPINFO_DATA : dim int_binary, get_web_size memcpy int_binary, get_web_buff, get_web_size data_cnt = get_web_size / 4 binary_buff = "" repeat data_cnt poke binary_buff, cnt, int_binary(cnt) loop color 255, 255, 255 mes binary_buff } redraw 1 wait 1 stop
実行結果は以下のようになります。
Windows:ABCD
Android:A???  (◇に?マークが入った文字が3つ)


httpload命令とhttpinfo命令にてWeb上のデータを取得しているのですが、どこかしら間違っているでしょうか?
もし分かる方がおりましたら教えてください。



この記事に返信する


窓月らら

リンク

2017/6/25(Sun) 23:37:34|NO.80387

試していないのですが
mes binary_buff
この部分を文字ではなく、バイナリデータの表示に変えてみて内容が正しいかですね。



窓月らら

リンク

2017/6/26(Mon) 00:54:18|NO.80388


repeat strlen(binary_buff) mes strf("%x",peek(binary_buff,cnt)) loop mes binary_buff
こうして実行すると、
41
80
c0
c0
80
80
c0
A????

あらやだ化けてる。



窓月らら

リンク

2017/6/26(Mon) 01:28:38|NO.80389

これでいちおうWindowsと同じ結果が得られます。
変換されちゃうんですねー。

if web_load_success { ; "DOWNLOAD 完了" get_web_size = 0 get_web_buff = "" httpinfo get_web_size, HTTPINFO_SIZE : sdim get_web_buff, get_web_size httpinfo get_web_buff, HTTPINFO_DATA : dim int_binary, get_web_size memcpy int_binary, get_web_buff, get_web_size data_cnt = get_web_size / 4 binary_buff = "" // Androidの場合 repeat data_cnt poke binary_buff, cnt, peek(int_binary,cnt*7) loop // Windowsの場合 ;repeat data_cnt ; poke binary_buff, cnt, int_binary(cnt) ;loop color 255, 255, 255 repeat 16 mes strf("%02x",peek(binary_buff,cnt))+" "+strf("%02x",peek(int_binary,cnt)) loop mes binary_buff }



窓月らら

リンク

2017/6/26(Mon) 02:01:50|NO.80390

41 01 01 01 42 01 01 01 43 01 01 01 44 01 01 01
これをバイナリモードでアップしたファイルだと普通に4バイト単位。
01が00だと7バイト。ふーん・・。

どうやら 00 は c0 80 に変換されるみたいですねー。

例えばファイルのデータが 41 00 01 01 なら 41 c0 80 01 01 となります。



しまくろねこ

リンク

2017/6/26(Mon) 06:56:26|NO.80391

>窓月ららさん

おはようございます。
コメントと色々試して頂いたみたいで本当にありがとうございます。

変換されてしまうのが不思議です。
バイナリファイルは無料のHPスペースの場所に置いてあるだけなので、Windows上でもAndroid上でも結果が同じになるはずだとおもうのです。
試しにWindowsから無料HPスペースにアップロードする前のバイナリファイルと、アップロードしたファイルをダウンロードしてバイナリエディタで比較してみましたが、全く同じバイナリデータというのが確認できました。
そう考えるとDish側の不具合なのでは?と思うのですが窓月ららさん的にどう感じますでしょうか?

実は、やりたいこと(実際にやっていること)はバイナリデータを表示するのではなく、bload命令で数値配列に一気に落とし込む処理をしています。
なぜかWindowsだと正常にバイナリデータを読み込むことができるのですが、Androidだと正しく読めないのが理解できません。
バイナリファイルの中身はマップチップのデータ(0とか1とか2とか10とか)しか入っていないファイルです。
マップファイルのバイナリファイルをローカルで持っている状態でAndroidで動かすと普通に読み込めています。



窓月らら

リンク

2017/6/26(Mon) 07:40:47|NO.80392

おはようございます。
Androidでの実行時は文字列扱いなんですかねー?

https://ja.wikipedia.org/wiki/UTF-8#.E3.82.B5.E3.83.AD.E3.82.B2.E3.83.BC.E3.83.88.E3.83.9A.E3.82.A2.E3.81.AE.E6.89.B1.E3.81.84
> また、Javaの一部の内部実装で用いられているModified UTF-8も、サロゲートペアをそのまま残す仕様となっている。
> ただし、NULL文字をC0 80とエンコードする(これもUTF-8規格外)点で、CESU-8とも異なる実装となっている。

これかなと。

とりあえず 00 が C0 80 になってしまうので、
bloadで読み込んだ後に C0 80 を 00 に変換する必要がありそうです。
データサイズによっては時間がかかりそうですよねぇ…。



窓月らら

リンク

2017/6/26(Mon) 07:55:54|NO.80393

うーん。マップデータなら00を使わないで回避する手もありますね。



しまくろねこ

リンク

2017/6/26(Mon) 21:56:36|NO.80415

こんにちは。

色々と調べてくださってありがとうございます。
マップデータそのものを見直すかどうするか等含めて検討してみたいと思います。
ありがとうございました。



zakki

リンク

2017/6/30(Fri) 12:16:56|NO.80442




BoNes

リンク

2017/11/11(Sat) 13:50:10|NO.81816

私も試してますが、00に限らずバイナリはそのまま取得できそうにないです。
色々変換されてしまうようで。



BoNes

リンク

2017/11/15(Wed) 10:31:42|NO.81845

zakkiさんのご指摘通りのようです。
恐らく文字列として取得してるので変換されてしまう。
バイナリのまま取得するにはbyte配列として結果を取得しないとダメそうな感じ。

参考:
http://dotnsf.blog.jp/archives/2017-03-17.html

OpenHSP眺めてみたんですが、httpinfoって
AndroidではHspActivity.java中でUTF-8で取得してますが、
Win版ではchar型(バイト)で取得してません?

理解不足だったらごめんなさい。



BoNes

リンク

2017/11/22(Wed) 11:19:23|NO.81887

「HspActivity.java」をあれこれいじくって試してみたりしたんですが
Javaでバイナリデータを文字型変数に入れて返すのって難しいんですのね。

できないよう(T▽T)



zakki

リンク

2017/12/4(Mon) 22:44:07|NO.81965

Javaだと任意のバイト列を文字として扱うことはしないので、HspActivity.javaではEntityUtils.toString()ではなくてEntityUtils.toByteArray()でbyte[]を返すようにして、
jni/javafunc.cppとjni/hsp3/ndk/webtask_ndk.cppもjstringとNULL終端文字列前提なのをjbyteArrayとcharポインタで扱うようにするという感じで
JavaだけじゃなくてC++側も修正するのが真っ当な対策かと思います。

あるいは、一旦 Base64.encodeToString(EntityUtils.toByteArray(httpResponse.getEntity()), Base64.DEFAULT); みたいなのでBase64文字列にして返して、as側でバイナリに戻すとか…



BoNes

リンク

2017/12/5(Tue) 16:55:22|NO.81969

zakkiさん、アドバイスありがとうございます。
私もアレコレ試して「HspActivity.java」側の修正だけではダメな気がしてました。

そこまで修正して頑張るものでもないかなと思い、これは仕様なんだと頭を切り替えて
Android版はバイナリのまま取得せず、回避手段で対応することにしました。

ファイルサイズは倍になっちゃいますが、とりあえずバイナリファイルを
16進数の文字列を並べたテキストファイルにしてWeb上に置き、
テキスト取得後に内部変換して対応することで一応の目的は果たせました。



ONION software Copyright 1997-2018(c) All rights reserved.