UNPKG

@gmod/jbrowse

Version:

JBrowse - client-side genome browser

127 lines (111 loc) 3.88 kB
define([ 'dojo/_base/declare', 'dojo/_base/array', 'dojo/has', 'JBrowse/Util/TextIterator' ], function( declare, array, has, TextIterator ) { var FileBlob = declare( null, /** * @lends JBrowse.Model.FileBlob.prototype */ { /** * Blob of binary data fetched from a local file (with FileReader). * * Adapted by Robert Buels from the BlobFetchable object in the * Dalliance Genome Explorer, which is copyright Thomas Down * 2006-2011. * @constructs */ constructor: function(b) { this.blob = b; this.size = b.size; this.totalSize = b.size; }, slice: function(start, length) { var sliceFunc = this.blob.mozSlice || this.blob.slice || this.blob.webkitSlice; return new FileBlob( length ? sliceFunc.call( this.blob, start, start + length ) : sliceFunc.call( this.blob, start ) ); }, fetchLines: function( lineCallback, endCallback, failCallback ) { var thisB = this; this.fetch( function( data ) { data = new Uint8Array(data); var lineIterator = new TextIterator.FromBytes( { bytes: data, // only return a partial line at the end // if we are not operating on a slice of // the file returnPartialRecord: !this.end }); var line; while(( line = lineIterator.getline() )) { lineCallback( line ); } endCallback(); }, failCallback ); }, readLines: function( offset=0, length, lineCallback, endCallback, failCallback ) { var start = this.start + offset, end = start + length; var skipFirst = offset != 0; this.slice( offset, length ) .fetchLines( function() { // skip the first line if we have a // nonzero offset, because it is probably // incomplete if( ! skipFirst ) lineCallback(); skipFirst = false; }, endCallback, failCallback ); }, read: function( offset=0, length, callback, failCallback ) { var start = this.start + offset, end = start + length; // short-circuit a read of 0 bytes here, because browsers // actually sometimes crash if you try to read 0 bytes from // a local file! if (!length) { callback(new ArrayBuffer()) return } this.slice( offset, length ) .fetch( callback, failCallback ); }, readBufferPromise(offset,length) { return new Promise((resolve,reject) => { this.read(offset, length, data => { resolve(window.Buffer.from(data)) }, reject) }) }, fetch: function( callback, failCallback ) { try { const reader = new FileReader() reader.onloadend = ev => { callback( reader.result ) } reader.onerror = failCallback reader.readAsArrayBuffer(this.blob) } catch(e) { failCallback(e) } }, fetchBufferPromise() { return new Promise((resolve,reject) => { this.fetch(data => { resolve(window.Buffer.from(data)) }, reject) }) }, stat(callback,failCallback) { this.statPromise().then(callback, failCallback) }, async statPromise() { return { size: this.blob.size } } }); return FileBlob; });