class @Transfer
constructor: (options) ->
@session = options.session
@file = options.file
@to = options.to
@progress = options.progress
@complete = options.complete
@chunks = new Chunks @file
@opened = false
@closed = false
@sid = @session.uniqueId()
@seq = 0
@sent = 0
start: ->
node = $("""
""")
$('file', node).attr 'name', @file.name
@session.sendIQ node.get(0), (result) =>
methods = $('si feature x field[var="stream-method"] value', result)
ok = (true for m in methods when $(m).text() == 'http://jabber.org/protocol/ibb').length > 0
this.open() if ok
open: ->
node = $("""
""")
@session.sendIQ node.get(0), (result) =>
if this.ok result
@opened = true
this.sendChunk()
sendChunk: ->
return if @closed
@chunks.chunk (chunk) =>
unless chunk
this.close()
return
node = $("""
#{chunk}
""")
@seq = 0 if @seq > 65535
@session.sendIQ node.get(0), (result) =>
return unless this.ok result
pct = Math.ceil ++@sent / @chunks.total * 100
this.progress pct
this.sendChunk()
close: ->
return if @closed
@closed = true
node = $("""
""")
@session.sendIQ node.get(0), ->
this.complete()
stop: ->
if @opened
this.close()
else
this.complete()
ok: (result) -> $(result).attr('type') == 'result'
class Chunks
CHUNK_SIZE = 3 / 4 * 4096
constructor: (@file) ->
@total = Math.ceil @file.size / CHUNK_SIZE
@slice = @file.slice || @file.webkitSlice || @file.mozSlice
@pos = 0
chunk: (callback) ->
start = @pos
end = @pos + CHUNK_SIZE
@pos = end
if start > @file.size
callback null
else
chunk = @slice.call @file, start, end
reader = new FileReader()
reader.onload = (event) ->
callback btoa event.target.result
reader.readAsBinaryString chunk