UNPKG

slimerjs-firefox

Version:

This repo includes slimerjs as well as downloads a local copy of Firefox.

146 lines (120 loc) 3.68 kB
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim:set ts=2 sw=2 sts=2 et filetype=javascript * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; module.metadata = { "stability": "experimental" }; exports.ByteReader = ByteReader; exports.ByteWriter = ByteWriter; const {Cc, Ci} = require("chrome"); // This just controls the maximum number of bytes we read in at one time. const BUFFER_BYTE_LEN = 0x8000; function ByteReader(inputStream) { const self = this; let stream = Cc["@mozilla.org/binaryinputstream;1"]. createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); let manager = new StreamManager(this, stream); let eof = false; let readSpecialFile = function (data, stream, read, numBytes) { try { while (read < numBytes) { data += stream.readBytes(1); read ++; } } catch(e) { eof = true; } return data; } this.read = function ByteReader_read(numBytes) { manager.ensureOpened(); if (typeof(numBytes) !== "number") numBytes = Infinity; let data = ""; let read = 0; try { while (true) { let avail = 0; try { avail = stream.available(); } catch(e) { // on special file, like /dev/stdin, available() fails. // let's use an other method (which may be lower) data = readSpecialFile(data, stream, read, numBytes); break; } let toRead = Math.min(numBytes - read, avail, BUFFER_BYTE_LEN); if (toRead <= 0) { eof = true; break; } data += stream.readBytes(toRead); read += toRead; } } catch (err) { throw new Error("Error reading from stream: " + err); } return data; }; this.atEnd = function() { return eof; } } function ByteWriter(outputStream, nobuffer) { const self = this; let stream = Cc["@mozilla.org/binaryoutputstream;1"]. createInstance(Ci.nsIBinaryOutputStream); stream.setOutputStream(outputStream); let manager = new StreamManager(this, stream); this.write = function ByteWriter_write(str) { manager.ensureOpened(); try { stream.writeBytes(str, str.length); if (nobuffer) { stream.flush(); } } catch (err) { throw new Error("Error writing to stream: " + err); } }; /** * Flushes the backing stream's buffer. */ this.flush = function ByteWriter_flush() { manager.ensureOpened(); stream.flush(); }; } // This manages the lifetime of stream, a ByteReader or ByteWriter. It defines // closed and close() on stream and registers an unload listener that closes // rawStream if it's still opened. It also provides ensureOpened(), which // throws an exception if the stream is closed. function StreamManager(stream, rawStream) { const self = this; this.rawStream = rawStream; this.opened = true; stream.__defineGetter__("closed", function stream_closed() { return !self.opened; }); stream.close = function stream_close() { self.ensureOpened(); self.unload(); }; //require("../system/unload").ensure(this); } StreamManager.prototype = { ensureOpened: function StreamManager_ensureOpened() { if (!this.opened) throw new Error("The stream is closed and cannot be used."); }, unload: function StreamManager_unload() { this.rawStream.close(); this.opened = false; } };