Gio Streaming I/O @ Seed and PyGI

そういえば Seed で環境変数を使うにはどうすればいいのだろう?
Python のように便利な標準モジュールみたいなのは無いわけで。
多分 glib 等に頼るしかないのだろう。

Miscellaneous Utility Functions

glib に env 関連はあるね。

#!/usr/bin/env seed

GLib = imports.gi.GLib;

Seed.print(GLib.getenv("HOME"))

GLib.setenv("HOGE", "Madoka Magica")
Seed.print(GLib.getenv("HOGE"))

これでイケる、GLib.get_home_dir() でも $HOME は取れる。
でも日本語を getenv だと ? になって print されてしまった。

インタラクティブシェルなら問題なく日本語表示している。
? の文字数は合っているから UTF-8 だと認識はしているみたいだが何故だろう。
Python の coding:utf-8 指定のようなものが何か必要なのか?

そういえばファイルを読み書きする open() も無いよな。
gio で読み書きするしか方法が無いと思うけど。

Seed/Tutorial – GNOME Live!
Seed/Tutorial/Simple_file_io – GNOME Live!

GDataInputStream, GDataOutputStream を噛ます必要があるようです。
Streaming I/O
なんか面倒くさいけど以下で読み書きできた。
読み込みはよくある一行毎に処理する方法にしている。

#!/usr/bin/env seed

/*
    Streaming I/O File Read and Write Sample
    if the Seed
    ( null parameter is not needed )
*/

Gio = imports.gi.Gio;

var filename = "test_js.txt";
var lines = "madoka\nhomura\nmami\nsayaka\nkyoko";

// Write
var f = Gio.file_new_for_path(filename);
var fstream = f.replace();
var dstream = new Gio.DataOutputStream.c_new(fstream);
dstream.put_string(lines);
fstream.close();

// Read
f = Gio.file_new_for_path(filename);
fstream = f.read();
dstream = new Gio.DataInputStream.c_new(fstream);
while (1) {
    var text = dstream.read_line_utf8();
    if (text == null) break;
    Seed.printf("%s(%d)", text, text.length)
}
fstream.close();

日本語でも書き込みはできた、けれどアウトプットはやはり ? になる。
それと length を取得する方法が無いみたい、int では値渡しになるし…

コレで gi にて Streaming I/O を使う方法が解ったぞと。
ということは PyGI で同様にするには以下のように。
ほぼ同じだったけど微妙に違う。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

'''
    Streaming I/O File Read and Write Sample
    if the Python
    ( All None parameter @ GCancellable )
'''

from gi.repository import Gio

filename = "test_py.txt"
lines = "madoka\nhomura\nmami\nsayaka\nkyoko"

# Write
f = Gio.file_new_for_path(filename)
fstream = f.replace("", False, Gio.FileCreateFlags.NONE, None)
dstream = Gio.DataOutputStream.new(fstream)
dstream.put_string(lines, None)
fstream.close(None)

# Read
f = Gio.file_new_for_path(filename)
fstream = f.read(None)
dstream = Gio.DataInputStream.new(fstream)
while 1:
    text, length = dstream.read_line_utf8(None)
    if text == None:
        break
    print "{0}({1})".format(text, length)
fstream.close(None)

Seed は基本的に NULL でいい引数は書く必要は無い、書いても結果は同じ。
Python は GCancellable を強要する、None で通常なら問題ない。
つか Python はやっぱりタプルを戻す、つまり Python なら length も取れる。
慣れていないと困惑するよなこの仕様。

DataInputStream の c_new って何だろう?

#!/usr/bin/env seed

Gio = imports.gi.Gio;

for (var s in Gio.DataInputStream) {
    Seed.print(s);
}
/* output
type
c_new
prototype
*/

static 状態では prototype のメソッドを使えないということか。
そういうことなら new という名前でイイと思うが理由があるのだろう。

とりあえずこれだけ解れば小物スクリプト程度なら作れると思う。

どうでもいいけど。

var f = Gio.File.new_for_path(fn)
var f = Gio.file_new_for_path(fn)

PyGI でも同じである、gi ってどっちでもいいんだね。