141 lines
4.3 KiB
JavaScript
141 lines
4.3 KiB
JavaScript
"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;
|