"use strict"; var Controller = require("../controller"); var WVocabulary = require("../../wType/vocabulary"); var Uint64 = require("../../wType/uint64"); var Blob = require("../../wType/blob"); var File = Controller.inherit({ "className": "File", "constructor": function(addr) { Controller.fn.constructor.call(this, addr); this._hasData = false; this._hasAdditional = false; this.data = new Blob(); this._additional = null; this._waitingForSlice = false; this._need = 0; this.addHandler("get"); this.addHandler("getAdditional"); this.addHandler("getSlice"); }, "destructor": function() { this.data.destructor(); if (this._hasAdditional) { this._additional.destructor(); } Controller.fn.destructor.call(this); }, "dontNeedData": function() { --this._need; }, "hasData": function() { return this._hasData }, "_getAdditional": function(add) { var ac = !this._hasAdditional || !this._additional["=="](add); if (ac) { if (this._hasAdditional) { this._additional.destructor(); } this._additional = add.clone(); } this._hasAdditional = true; return ac; }, "getMimeType": function() { return this._additional.at("mimeType").toString(); }, "getSize": function() { return this._additional.at("size").valueOf(); }, "_h_get": function(ev) { var dt = ev.getData(); var ac = this._getAdditional(dt.at("additional")); if (ac) { this.trigger("additionalChange") } this._hasData = true; var oldData = this.data; this.data = dt.at("data").clone(); oldData.destructor(); this.trigger("data"); }, "_h_getAdditional": function(ev) { var ac = this._getAdditional(ev.getData()); if (ac) { this.trigger("additionalChange"); } if (!this.initialized) { this.initialized = true; this.trigger("ready"); } }, "_h_getSlice": function(ev) { if (this._waitingForSlice) { this._waitingForSlice = false; var vc = ev.getData(); if (vc.at("result").valueOf() == 0) { var slice = vc.at("slice"); this.data["+="](slice); this.trigger("slice", slice); if (this.getSize() === this.data.length()) { this._hasData = true; this.trigger("data"); } } else { this.trigger("serviceMessage", "Error receiving slice from " + this._pairAddress.toString(), 1); } } }, "needData": function() { if (this._need === 0) { var vc = new WVocabulary(); this.send(vc, "get"); } ++this._need; }, "requestSlice": function(size) { if (this._hasAdditional) { if (this._waitingForSlice) { throw new Error("An attempt to request a slice of data from " + this._pairAddress.toString() + " while another request is in progress"); } var begin = this.data.length(); var newSize = Math.min(size, this.getSize() - begin); if (newSize !== size) { //TODO may be inform the developer about that? } if (newSize === 0) { return; //TODO may be inform the developer about that? } var vc = new WVocabulary(); vc.insert("begin", new Uint64(begin)); vc.insert("size", new Uint64(newSize)); this.send(vc, "getSlice"); this._waitingForSlice = true; } else { throw new Error("An attempt to request a slice of data from " + this._pairAddress.toString() + " before controller got initialized"); } }, "subscribe": function() { Controller.fn.subscribe.call(this); if (this._need > 0) { var vc = new WVocabulary(); this.send(vc, "get"); } } }); module.exports = File;