blob: 1caae4dd5cef4b8fa81168f9db649faf6c0fb302 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* @fileoverview: The NaCl plugin leans on its host to provide some basic
* stream-like objects for /dev/random. The interface is likely to change
* in the near future, so documentation in this file is a bit sparse.
*/
/**
* Base class for streams required by the plugin.
*/
nassh.Stream = function(fd, path) {
this.fd_ = fd;
this.path = path;
this.open = false;
};
/**
* Errors we may raise.
*/
nassh.Stream.ERR_STREAM_CLOSED = 'Stream closed';
nassh.Stream.ERR_STREAM_OPENED = 'Stream opened';
nassh.Stream.ERR_FD_IN_USE = 'File descriptor in use';
nassh.Stream.ERR_NOT_IMPLEMENTED = 'Not implemented';
nassh.Stream.ERR_STREAM_CANT_READ = 'Stream has no read permission';
nassh.Stream.ERR_STREAM_CANT_WRITE = 'Stream has no write permission';
/**
* Convert binary byte array into base64 ascii.
*
* @param {!Array<!number>} b An array of bytes.
* @return {!string} The base64 encoding of the byte array.
*/
nassh.Stream.binaryToAscii = function(b) {
return btoa(b.map((byte) => String.fromCharCode(byte)).join(''));
};
/**
* Convert ascii base64 into binary byte array.
*
* @param {!string} a A base64-encoded string.
* @return {!Array<!number>} The array of byte values encoded in the string.
*/
nassh.Stream.asciiToBinary = function(a) {
return Array.prototype.map.call(atob(a), (char) => char.charCodeAt(0));
};
/**
* Open a stream, calling back when complete.
*/
nassh.Stream.prototype.asyncOpen_ = function(path, onOpen) {
setTimeout(function() { onOpen(false) }, 0);
};
/**
* Read from a stream, calling back with the result.
*
* The default implementation does not actually send data to the client, but
* assumes that it is instead pushed to the client using the
* onDataAvailable event.
*/
nassh.Stream.prototype.asyncRead = function(size, onRead) {
if (this.onDataAvailable === undefined)
throw nassh.Stream.ERR_NOT_IMPLEMENTED;
setTimeout(() => onRead(''), 0);
};
/**
* Write to a stream.
*/
nassh.Stream.prototype.asyncWrite = function(data, onSuccess) {
throw nassh.Stream.ERR_NOT_IMPLEMENTED;
};
/**
* Close a stream.
*/
nassh.Stream.prototype.close = function(reason) {
if (this.onClose)
this.onClose(reason || 'closed');
};
/**
* Set a new IO for the stream.
*/
nassh.Stream.prototype.setIo = function(io) {
this.io_ = io;
};
/**
* The /dev/random stream.
*
* This special case stream just returns random bytes when read.
*/
nassh.Stream.Random = function(fd) {
nassh.Stream.apply(this, [fd]);
};
nassh.Stream.Random.prototype = Object.create(nassh.Stream.prototype);
nassh.Stream.Random.constructor = nassh.Stream.Random;
nassh.Stream.Random.prototype.asyncOpen_ = function(path, onOpen) {
this.path = path;
setTimeout(function() { onOpen(true) }, 0);
};
nassh.Stream.Random.prototype.asyncRead = function(size, onRead) {
if (!this.open)
throw nassh.Stream.ERR_STREAM_CLOSED;
var bytes = new Uint8Array(size);
crypto.getRandomValues(bytes);
Array.prototype.map.apply(
bytes, [function(el) { return String.fromCharCode(el) }]);
var b64bytes = btoa(Array.prototype.join.apply(bytes, ['']));
setTimeout(function() { onRead(b64bytes) }, 0);
};