Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/webtorrent/webtorrent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeross Aboukhadijeh <feross@feross.org>2014-09-21 05:41:24 +0400
committerFeross Aboukhadijeh <feross@feross.org>2014-09-21 05:41:24 +0400
commit93686505fbc90522c75b6c151ec7261aa76098de (patch)
tree5b474b920e79b7b39b6804fac5e6a641de6ae843 /lib/file-stream.js
parent2e14192c311f64c20496a72af7ffce36495be92b (diff)
merge `bittorrent-client` into this module
When I started the WebTorrent project I thought there were going to need to be two separate client implementations (bittorrent-client and webtorrent-client) that would get tied together in a higher-level module. Fortunately, this was not necessary because of the awesome “browser” field support in browserify. By substituting just a few modules, we can make the same module (webtorrent) work in node AND the browser, with the same codebase! So, from now on, you can just `require(‘webtorrent’)` in node or the browser, and it will just work. You can also `npm install webtorrent` if you want to use bittorrent in a node app or script. Lastly, you can `npm install webtorrent -g` if you want to use webtorrent as a command line app (it installs a `webtorrent` command).
Diffstat (limited to 'lib/file-stream.js')
-rw-r--r--lib/file-stream.js99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/file-stream.js b/lib/file-stream.js
new file mode 100644
index 0000000..6d86ea8
--- /dev/null
+++ b/lib/file-stream.js
@@ -0,0 +1,99 @@
+module.exports = FileStream
+
+var debug = require('debug')('webtorrent:file-stream')
+var inherits = require('inherits')
+var stream = require('stream')
+
+inherits(FileStream, stream.Readable)
+
+/**
+ * A readable stream of a torrent file.
+ *
+ * @param {Object} file
+ * @param {number} opts.start stream slice of file, starting from this byte (inclusive)
+ * @param {number} opts.end stream slice of file, ending with this byte (inclusive)
+ * @param {number} opts.pieceLength length of an individual piece
+ */
+function FileStream (file, opts) {
+ var self = this
+ if (!(self instanceof FileStream)) return new FileStream(file, opts)
+ stream.Readable.call(self, opts)
+ debug('new filestream %s', JSON.stringify(opts))
+
+ if (!opts) opts = {}
+ if (!opts.start) opts.start = 0
+ if (!opts.end) opts.end = file.length - 1
+
+ self.length = opts.end - opts.start + 1
+
+ var offset = opts.start + file.offset
+ var pieceLength = opts.pieceLength
+
+ self.startPiece = offset / pieceLength | 0
+ self.endPiece = (opts.end + file.offset) / pieceLength | 0
+
+ self._storage = file.storage
+ self._piece = self.startPiece
+ self._missing = self.length
+ self._reading = false
+ self._notifying = false
+ self._destroyed = false
+ self._criticalLength = Math.min((1024 * 1024 / pieceLength) | 0, 2)
+ self._offset = offset - (self.startPiece * pieceLength)
+}
+
+FileStream.prototype._read = function () {
+ debug('_read')
+ var self = this
+ if (self._reading) return
+ self._reading = true
+ self.notify()
+}
+
+FileStream.prototype.notify = function () {
+ debug('notify')
+ var self = this
+
+ if (!self._reading || self._missing === 0) return
+ if (!self._storage.bitfield.get(self._piece))
+ return self._storage.emit('critical', self._piece, self._piece + self._criticalLength)
+
+ if (self._notifying) return
+ self._notifying = true
+
+ var p = self._piece
+ debug('before read %s', p)
+ self._storage.read(self._piece++, function (err, buffer) {
+ debug('after read %s (buffer.length %s) (err %s)', p, buffer.length, (err && err.message) || err)
+ self._notifying = false
+
+ if (self._destroyed) return
+
+ if (err) {
+ self._storage.emit('error', err)
+ return self.destroy(err)
+ }
+
+ if (self._offset) {
+ buffer = buffer.slice(self._offset)
+ self._offset = 0
+ }
+
+ if (self._missing < buffer.length) {
+ buffer = buffer.slice(0, self._missing)
+ }
+ self._missing -= buffer.length
+
+ debug('pushing buffer of length %s', buffer.length)
+ self._reading = false
+ self.push(buffer)
+
+ if (self._missing === 0) self.push(null)
+ })
+}
+
+FileStream.prototype.destroy = function () {
+ var self = this
+ if (self._destroyed) return
+ self._destroyed = true
+}