97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
/// <reference path="../imports/imports_shared.d.ts" />
|
|
|
|
|
|
window["require_setup"](module);
|
|
import * as native from "teaclient_connection";
|
|
|
|
namespace _transfer {
|
|
class NativeFileDownload implements transfer.DownloadTransfer {
|
|
readonly key: transfer.DownloadKey;
|
|
private _handle: native.ft.NativeFileTransfer;
|
|
private _buffer: Uint8Array;
|
|
|
|
private _result: Promise<void>;
|
|
private _response: Response;
|
|
|
|
private _result_success: () => any;
|
|
private _result_error: (error: any) => any;
|
|
|
|
constructor(key: transfer.DownloadKey) {
|
|
this.key = key;
|
|
this._buffer = new Uint8Array(key.total_size);
|
|
this._handle = native.ft.spawn_connection({
|
|
client_transfer_id: key.client_transfer_id,
|
|
server_transfer_id: key.server_transfer_id,
|
|
|
|
remote_address: key.peer.hosts[0],
|
|
remote_port: key.peer.port,
|
|
|
|
transfer_key: key.key,
|
|
|
|
object: native.ft.download_transfer_object_from_buffer(this._buffer.buffer)
|
|
});
|
|
}
|
|
|
|
get_key(): transfer.DownloadKey {
|
|
return this.key;
|
|
}
|
|
|
|
async request_file(): Promise<Response> {
|
|
if(this._response)
|
|
return this._response;
|
|
|
|
try {
|
|
await (this._result || this._start_transfer());
|
|
} catch(error) {
|
|
throw error;
|
|
}
|
|
|
|
if(this._response)
|
|
return this._response;
|
|
|
|
const buffer = this._buffer.buffer.slice(this._buffer.byteOffset, this._buffer.byteOffset + Math.min(64, this._buffer.byteLength));
|
|
|
|
/* may another task has been stepped by and already set the response */
|
|
return this._response || (this._response = new Response(this._buffer, {
|
|
status: 200,
|
|
statusText: "success",
|
|
headers: {
|
|
"X-media-bytes": base64_encode_ab(buffer)
|
|
|
|
}
|
|
}));
|
|
}
|
|
|
|
_start_transfer() : Promise<void> {
|
|
return this._result = new Promise((resolve, reject) => {
|
|
this._result_error = (error) => {
|
|
this._result_error = undefined;
|
|
this._result_success = undefined;
|
|
reject(error);
|
|
};
|
|
this._result_success = () => {
|
|
this._result_error = undefined;
|
|
this._result_success = undefined;
|
|
resolve();
|
|
};
|
|
|
|
this._handle.callback_failed = this._result_error;
|
|
this._handle.callback_finished = aborted => {
|
|
if(aborted)
|
|
this._result_error("aborted");
|
|
else
|
|
this._result_success();
|
|
};
|
|
|
|
this._handle.start();
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
export function spawn_download_transfer(key: transfer.DownloadKey) : transfer.DownloadTransfer {
|
|
return new NativeFileDownload(key);
|
|
}
|
|
}
|
|
|
|
Object.assign(window["transfer"] || (window["transfer"] = {}), _transfer); |