Hi Andrea, I've come up with something that... almost does what you're looking at here. Perhaps it's useful as a guide of what one can do with the Gio interface.
I think you may hit some awkward problems with modelling Node-style streams with GLib ones. But perhaps it is possible and this helps. I don't really know the Node stream semantics so I have assumed various things in my Readable implementation as you'll see... Note that MemoryInputStream really is just a byte stream; so there is no guarantee you'll receive the exact block of bytes that was written -- for example, when I run this I get a first chunk of "12", followed by "3", "4", etc. let Gio = imports.gi.Gio; let byteArray = imports.byteArray; let mainloop = imports.mainloop; class Readable { constructor() { this._mio = Gio.MemoryInputStream.new(); this._callbacks = {}; this._startNext(); } _startNext() { // Enqueue an async read; and re-enqueue when it finishes, so we're // always waiting for data... this._mio.read_bytes_async(4096, 1, null, (source, res) => { this._onData(this._mio.read_bytes_finish(res)); this._startNext(); }); } _onData(bytes) { if (this._callbacks['data']) { let ba = byteArray.fromGBytes(bytes); this._callbacks['data'](ba); this._read(); } } push(bytes) { if (bytes == null) { mainloop.quit('main'); return; } this._mio.add_bytes(bytes); } on(name, callback) { this._callbacks[name] = callback; if (name === 'data') { this._read(); } } } class Counter extends Readable { constructor(opt) { super(opt); this._max = 1000; this._index = 1; } _read() { const i = this._index++; if (i > this._max) this.push(null); else { const str = '' + i; const buf = byteArray.fromString(str); // Buffer.from(str, 'ascii'); this.push(buf); } } } (new Counter).on('data', (str) => { print("data", str.toString()); }); mainloop.run('main'); On 7 November 2017 at 10:08, Andrea Giammarchi <andrea.giammar...@gmail.com> wrote: > I am trying to implement a stream module and apparently I have everything > I need but practically I'm unable to use streams. > > If I instantiate a `new Gio.InputStream` I have the following error: > cannot create instance of abstract (non-instantiatable) type 'GInputStream' > > I cannot even extend it ... so I've though "ok, maybe it's like an > interface, I implement it and that's it" > > But then a JS class wouldn't work as base_stream for a > Gio.BufferedInputStream, and if I extend the JS class to be a > GObject.Object then: > Gjs-WARNING **: JS ERROR: TypeError: Object is of type GObject.Object - > cannot convert to GInputStream > > where GInputStream is the one I cannot use in the first place. > > I've reached full circle then so ... I wonder if anyone has any idea how > to use/create/extend streams in GJS (not talking about file streams but > streams in general) or if it's even possible. > > In node, as example, I could do this and it will work: > > ```js > > const { Readable } = require('stream'); > > class Counter extends Readable { > constructor(opt) { > super(opt); > this._max = 1000; > this._index = 1; > } > > _read() { > const i = this._index++; > if (i > this._max) > this.push(null); > else { > const str = '' + i; > const buf = Buffer.from(str, 'ascii'); > this.push(buf); > } > } > } > > (new Counter).on('data', console.log); > > ``` > > _______________________________________________ > javascript-list mailing list > javascript-list@gnome.org > https://mail.gnome.org/mailman/listinfo/javascript-list > >
_______________________________________________ javascript-list mailing list javascript-list@gnome.org https://mail.gnome.org/mailman/listinfo/javascript-list