2017-11-28 4 views
1

GJSのchrome/firefox拡張機能のためのnative messaging hostを書こうとしていますが(GJSですでに書かれたコードに依存しているため)、いくつかのハードルに遭遇しています。私はchrome-gnome-shellを粗いテンプレートとして使用しています。なぜならGLib/Gio instrospectionとGApplicationも使用しているからですが、私にはないPython structの利点があります。GJSでのネイティブメッセージングホストの作成

簡単に言えば、ネイティブメッセージングホストは、utf-8でエンコードされたJSONの文字列に続くInt32(4バイト)長のstdin/stdoutでメッセージを交換します。

chrome-gnome-shellは、GLib.IOChannelset_encoding('utf-8')structを使用してint32バイトを処理します。私はGJSでそのクラスを使用する際に問題がありました。structを持っていないので、をGio.DataInputStream(および出力する相手)に置き換えて試しています。put_int32()/read_int32()put_string()/read_string()です。

明らかに私は自分がしていることについて大いに混乱しています。私がGio.DataInputStream.read_int32()を呼び出すと、数値369098752が返されるので、int32は通常の数値に変換されていないと推測しています。私がGio.DataInputStream.read_bytes(4, null).unref_to_array()を呼び出してByteArrayを取得した場合、 ByteArray.toString()は '\ u0016'を返し、ByteArray [0]は実際の長さのように見える '22'を返します。

int32をデータストリームに読み書きするためのいくつかのポインタであり、非常に感謝しています。

クロムGNOMEシェルの参照:

答えて

0

これは、ここでこの問題を解決するための最良の方法ですが、場合、私は知らないが、私が思いついたものです。 ByteArrayのインポートを使用して

2つの関数(SO上のどこかから変更):

const ByteArray = imports.byteArray; 

function fromInt32 (byteArray) { 
    var value = 0; 

    for (var i = byteArray.length - 1; i >= 0; i--) { 
     value = (value * 256) + byteArray[i]; 
    } 

    return value; 
}; 

function toInt32 (num) { 
    var byteArray = [0, 0, 0, 0]; 

    for (var index_ = 0; index_ < byteArray.length; index_++) { 
     var byte = num & 0xff; 
     byteArray [index_] = byte; 
     num = (num - byte)/256 ; 
    } 

    return ByteArray.fromArray(byteArray); 
}; 

送信/受信の場合:もちろん

const Gio = imports.gi.Gio; 

// Receiving 
let stdin = new Gio.DataInputStream({ 
    base_stream: new Gio.UnixInputStream({ fd: 0 }) 
}); 

let int32 = stdin.read_bytes(4, null).toArray(); 
let length = fromInt32(int32); 
let data = stdin.read_bytes(length, null).toArray().toString(); 
let message = JSON.parse(data); 

// Sending 
let stdout = new Gio.DataOutputStream({ 
    base_stream: new Gio.UnixOutputStream({ fd: 1 }) 
}); 

let data = JSON.stringify(message); 
let int32 = toInt32(data.length); 
stdout.write(int32, null); 
stdout.put_string(data, null); 

を、あなたは、必要に応じてのtry-catchでこれらをラップする必要があります入力にソースを接続したいと思うかもしれません(Gio.UnixInputStreamを使うことができます)。

let source = stdin.base_stream.create_source(null); 
source.set_callback(onReceiveFunc); 
source.attach(null); 
0

Gio.DataOutputStream.put_int32()Gio.DataInputStream.read_int32()は、read_bytes()put_string()と同じ方法で使用できます。

+0

私は 'read_int32()'と 'put_int32()'を使ってみましたが、これらは標準のbase-10 javascript Numberとの間で変換されていないようですが、代わりに巨大な数値を返します。おそらくGJS/GIRのバグでしょうか? –

+1

はい、バグのようです。バグトラッカーは現在gitlab.gnome.org/GNOME/gjsにあります – ptomato

+0

きれいなコードハイライトともの;)ここでのバグ報告:https://gitlab.gnome.org/GNOME/gjs/issues/20 –

関連する問題