Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

web.http でバイナリファイルを扱えるようにしてほしい #53

Closed
syngan opened this issue May 15, 2013 · 13 comments
Closed

Comments

@syngan
Copy link
Contributor

syngan commented May 15, 2013

私の勘違い/使用法間違いかもしれませんが,
curl/wget により得られた content を s:_readfile() 内で join しているため,
call writefile(filename, split(string_list, "\n"), "b")
としても \x00 を含むファイルの場合にデータが壊れてしまいます.
バイナリファイル用に join しないモードを追加していただきたいです.

@mattn
Copy link
Member

mattn commented May 16, 2013

vimはそもそもバイナリを扱えない言語なので、直しても \x00 は保存出来ないと思いますよ。
文字列にバッファのポインタと長さの両方を持っている様な他の言語と違い、ポインタしか保持していないので \x00 が来た時点で終端します。

@mattn
Copy link
Member

mattn commented May 16, 2013

中平さんがよくやる手として、数値(バイト値)の配列としてバイナリを扱う方法があり、それを使うと xxd (vimに付属のバイナリ操作ツール)と連携してバイナリの入出力は可能ではあります。
zencoding-vim の画像解析処理や、webapi-vim のバイナリアップロード機能なんかで使ってます。
もしこれをやるのが難しいのであれば if_python 等に任せた方がいいでしょう。

@thinca
Copy link
Member

thinca commented May 16, 2013

  1. ファイル名を指定するとそのファイルに結果を保存してVim内には持ち込まない
  2. 結果を配列で返す

どちらが良いでしょう? (もしくは両方あったほうが良い?)
ちなみに 2 の場合は readfile() の仕様上、そして mattn さんが説明している通り、\x00 は扱えないので NL 文字に置換されます。

@syngan
Copy link
Contributor Author

syngan commented May 16, 2013

やりたいことは web サーバにあるファイルをダウンロードしたい、なので 1 で十分です.
2 の結果を配列のまま返すでも(私の認識では)問題ありません.
無駄に読み書きするだけなので 1 のほうが better な気がしています.


上記の説明していただいた内容 についてはよくわからないのですが,
以下のファイルで \x00 を含むファイルを問題なくコピーできました。
これとは違うことをお話されているのでしょうか?

let b = readfile("/tmp/p1", "b")
call writefile(b, "/tmp/p2", "b")

@mattn
Copy link
Member

mattn commented May 16, 2013

以下のファイルで \x00 を含むファイルを問題なくコピーできました。

それはないと思いますよ。文字が0x00以外の時しか書き込み処理してないですから。もし書けてるとしたら、それは直さないといけないバグです。

https://code.google.com/p/vim/source/browse/src/eval.c#18873

@mattn
Copy link
Member

mattn commented May 16, 2013

あー、改行で置き換えてます?

@mattn
Copy link
Member

mattn commented May 16, 2013

であれば行けるかもです。

@syngan
Copy link
Contributor Author

syngan commented May 16, 2013

何もしていません。 read した結果をそのまま write しただけで、
od で見た結果、および diff により同じファイルが生成されることを確認しています。

eval.c 見てみましたが、
readfile 内で "\0" を "\n" に、
"\n" の場合には次のリストに、しているようです。

@thinca
Copy link
Member

thinca commented May 16, 2013

@mattn readfile() は行単位(\n 区切り)でファイルを読んで、行内の \0\n に変換しています。writefile() はその逆をしています。これのおかげでバイナリファイルのコピーも可能です。これは :help writefile() にも書いてあります。

@thinca
Copy link
Member

thinca commented May 17, 2013

とりあえず 1 で実装してみたいと思います。オプション名は深く考えずに outputFile とかにしようかと思ってます。
これを指定した場合は結果の content は常に空になります。(読む分のオーバーヘッドが余計になる+読もうと思えば後から読めるため)

@thinca
Copy link
Member

thinca commented May 20, 2013

outputFile 追加しました。
78ae567

@thinca
Copy link
Member

thinca commented May 20, 2013

最低限の動作テストはしたつもりですが、いかんせんテスト不足は否めないので、何か問題があったらいつでも報告待ってます。

@syngan
Copy link
Contributor Author

syngan commented May 21, 2013

対応ありがとうございます。 curl/wget ともに動作することを確認しました。


別件ですが、「バイナリファイルの送信」ができないことがわかりました。
そもそも wget が multipart/form-data に対応していないのが問題なんですが。。。
少し考えます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants