2
0
mirror of https://github.com/esiur/esiur-js.git synced 2025-05-07 12:52:58 +00:00
This commit is contained in:
Ahmed Zamil 2019-07-11 01:54:50 +03:00
parent c6c04b0212
commit 8cc5bd3777
9 changed files with 509 additions and 117 deletions

View File

@ -1193,6 +1193,13 @@ class Structure
return rt; return rt;
} }
constructor(data)
{
if (data instanceof Object)
for(var i in data)
this[i] = data[i];
}
} }
/* /*
* Copyright (c) 2017 Ahmed Kh. Zamil * Copyright (c) 2017 Ahmed Kh. Zamil
@ -2486,12 +2493,12 @@ class Codec {
if (includeKeys) { if (includeKeys) {
for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
var key = DC.stringToBytes(keys[i]); var key = DC.stringToBytes(keys[i]);
rt.addUint8(key.length).addString(key).addUint8Array(DC.compose(value[i], connection)); rt.addUint8(key.length).addUint8Array(key).addUint8Array(Codec.compose(value[keys[i]], connection));
} }
} }
else { else {
for (var i = 0; i < keys.length; i++) for (var i = 0; i < keys.length; i++)
rt.addUint8Array(DC.compose(value[keys[i]], connection, includeTypes)); rt.addUint8Array(Codec.compose(value[keys[i]], connection, includeTypes));
} }
if (prependLength) if (prependLength)
@ -3444,7 +3451,7 @@ const DataType =
class DistributedConnection extends IStore { class DistributedConnection extends IStore {
send(data) { send(data) {
console.log("Send", data.length); //console.log("Send", data.length);
this.socket.send(data.buffer); this.socket.send(data.buffer);
} }
@ -3534,7 +3541,7 @@ class DistributedConnection extends IStore {
this.socket.onmessage = function (msg) { this.socket.onmessage = function (msg) {
console.log("Rec", msg.data.byteLength); //console.log("Rec", msg.data.byteLength);
this.networkBuffer.writeAll(msg.data); this.networkBuffer.writeAll(msg.data);
@ -3658,9 +3665,12 @@ class DistributedConnection extends IStore {
break; break;
// Invoke // Invoke
case IIPPacketAction.InvokeFunction: case IIPPacketAction.InvokeFunctionArrayArguments:
this.IIPRequestInvokeFunction(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content); this.IIPRequestInvokeFunctionArrayArguments(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
break; break;
case IIPPacketAction.InvokeFunctionNamedArguments:
this.IIPRequestInvokeFunctionNamedArguments(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
break;
case IIPPacketAction.GetProperty: case IIPPacketAction.GetProperty:
this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex); this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex);
break; break;
@ -3732,9 +3742,11 @@ class DistributedConnection extends IStore {
this.IIPReply(packet.callbackId, packet.content); this.IIPReply(packet.callbackId, packet.content);
break; break;
case IIPPacketAction.InvokeFunction: case IIPPacketAction.InvokeFunctionArrayArguments:
case IIPPacketAction.InvokeFunctionNamedArguments:
this.IIPReplyInvoke(packet.callbackId, packet.content); this.IIPReplyInvoke(packet.callbackId, packet.content);
break; break;
case IIPPacketAction.GetProperty: case IIPPacketAction.GetProperty:
this.IIPReply(packet.callbackId, packet.content); this.IIPReply(packet.callbackId, packet.content);
break; break;
@ -3959,7 +3971,7 @@ class DistributedConnection extends IStore {
return this.sendParams(reply).addUint8(0x40 | action).addUint32(this.callbackCounter); return this.sendParams(reply).addUint8(0x40 | action).addUint32(this.callbackCounter);
} }
sendInvoke(instanceId, index, parameters) sendInvokeByArrayArguments(instanceId, index, parameters)
{ {
var reply = new AsyncReply(); var reply = new AsyncReply();
@ -3967,7 +3979,7 @@ class DistributedConnection extends IStore {
this.callbackCounter++; this.callbackCounter++;
this.sendParams() this.sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunction) .addUint8(0x40 | IIPPacketAction.InvokeFunctionArrayArguments)
.addUint32(this.callbackCounter) .addUint32(this.callbackCounter)
.addUint32(instanceId) .addUint32(instanceId)
.addUint8(index) .addUint8(index)
@ -3979,6 +3991,27 @@ class DistributedConnection extends IStore {
return reply; return reply;
} }
sendInvokeByNamedArguments(instanceId, index, parameters)
{
var reply = new AsyncReply();
var pb = Codec.composeStructure(parameters, this, true, true, true);
this.callbackCounter++;
this.sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunctionNamedArguments)
.addUint32(this.callbackCounter)
.addUint32(instanceId)
.addUint8(index)
.addUint8Array(pb)
.done();
this.requests[this.callbackCounter] = reply;
return reply;
}
sendError(type, callbackId, errorCode, errorMessage = "") sendError(type, callbackId, errorCode, errorMessage = "")
{ {
var msg = DC.stringToBytes(errorMessage); var msg = DC.stringToBytes(errorMessage);
@ -4423,7 +4456,7 @@ class DistributedConnection extends IStore {
}); });
} }
IIPRequestInvokeFunction(callback, resourceId, index, content) { IIPRequestInvokeFunctionArrayArguments(callback, resourceId, index, content) {
var self = this; var self = this;
@ -4433,10 +4466,10 @@ class DistributedConnection extends IStore {
var ft = r.instance.template.getFunctionTemplateByIndex(index); var ft = r.instance.template.getFunctionTemplateByIndex(index);
if (ft != null) { if (ft != null) {
if (r instanceof DistributedResource) { if (r instanceof DistributedResource) {
var rt = r._invoke(index, args); var rt = r._invokeByArrayArguments(index, args);
if (rt != null) { if (rt != null) {
rt.then(function (res) { rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(res, self)) .addUint8Array(Codec.compose(res, self))
.done(); .done();
}); });
@ -4463,13 +4496,93 @@ class DistributedConnection extends IStore {
if (rt instanceof AsyncReply) { if (rt instanceof AsyncReply) {
rt.then(function (res) { rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(res, self)) .addUint8Array(Codec.compose(res, self))
.done(); .done();
}); });
} }
else { else {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(rt, self))
.done();
}
}
else {
// ft found, fi not found, this should never happen
}
}
}
else {
// no function at this index
}
});
}
else {
// no resource with this id
}
});
}
IIPRequestInvokeFunctionNamedArguments(callback, resourceId, index, content) {
var self = this;
Warehouse.get(resourceId).then(function (r) {
if (r != null) {
Codec.parseStructure(content, 0, content.Length, self).then(function (namedArgs) {
var ft = r.instance.template.getFunctionTemplateByIndex(index);
if (ft != null) {
if (r instanceof DistributedResource) {
var rt = r._invokeByNamedArguments(index, namedArgs);
if (rt != null) {
rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(res, self))
.done();
});
}
else {
// function not found on a distributed object
}
}
else {
var fi = r[ft.name];
if (r.instance.applicable(self.session, ActionType.Execute, ft) == Ruling.Denied)
{
self.sendError(ErrorType.Management, callback, ExceptionCode.InvokeDenied);
return;
}
if (fi instanceof Function) {
var pi = ResourceTemplate.getFunctionParameters(fi);
var args = new Array(pi.length);
for (var i = 0; i < pi.Length; i++)
{
if (namedArgs[pi[i]] !== undefined)
args[i] = namedArgs[pi[i]];
}
// pass this to the last argument if it is undefined
if (args[args.length-1] === undefined)
args[args.length-1] = self;
var rt = fi.apply(r, args);
if (rt instanceof AsyncReply) {
rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(res, self))
.done();
});
}
else {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(rt, self)) .addUint8Array(Codec.compose(rt, self))
.done(); .done();
} }
@ -5319,7 +5432,18 @@ class DistributedResource extends IResource
var makeFunc = function(index) var makeFunc = function(index)
{ {
return function () { return function () {
return self._invoke(index, arguments);
if ( arguments.length = 1
&& arguments[0] instanceof Object
&& arguments[0].constructor.name == "Object")
{
var namedArgs = new Structure(arguments[0]);
return self._invokeByNamedArguments(index, namedArgs);
}
else
{
return self._invokeByArrayArguments(index, arguments);
}
}; };
}; };
@ -5366,35 +5490,25 @@ class DistributedResource extends IResource
this.instance._emitResourceEvent(null, null, et.name, args); this.instance._emitResourceEvent(null, null, et.name, args);
} }
_invoke(index, args) { _invokeByArrayArguments(index, args) {
if (this.destroyed) if (this.destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
if (index >= this.instance.template.functions.length) if (index >= this.instance.template.functions.length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
return this._p.connection.sendInvoke(this._p.instanceId, index, args); return this._p.connection.sendInvokeByArrayArguments(this._p.instanceId, index, args);
/*
var reply = new AsyncReply();
var parameters = Codec.composeVarArray(args, this._p.connection, true);
var self = this;
this._p.connection.sendRequest(IIPPacketAction.InvokeFunction,
BL().addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters))
.then(function (res) {
Codec.parse(res[0], 0, self._p.connection).then(function (rt) {
reply.trigger(rt);
});
});
return reply;
*/
} }
_invokeByNamedArguments(index, namedArgs) {
if (this.destroyed)
throw new Exception("Trying to access destroyed object");
if (index >= this.instance.template.functions.length)
throw new Exception("Function index is incorrect");
return this._p.connection.sendInvokeByNamedArguments(this._p.instanceId, index, namedArgs);
}
_get(index) _get(index)
{ {
@ -5973,10 +6087,11 @@ const IIPPacketAction =
ResourceParents: 14, ResourceParents: 14,
// Request Invoke // Request Invoke
InvokeFunction: 16, InvokeFunctionArrayArguments: 16,
GetProperty: 17, GetProperty: 17,
GetPropertyIfModified: 18, GetPropertyIfModified: 18,
SetProperty: 19, SetProperty: 19,
InvokeFunctionNamedArguments: 20,
// Request Attribute // Request Attribute
GetAllAttributes: 24, GetAllAttributes: 24,
@ -6320,7 +6435,8 @@ class IIPPacket
offset += 8; offset += 8;
} }
else if (this.action == IIPPacketAction.InvokeFunction) else if ( this.action == IIPPacket.InvokeFunctionArrayArguments
|| this.action == IIPPacketAction.InvokeFunctionNamedArguments)
{ {
if (this.notEnough(offset, ends, 9)) if (this.notEnough(offset, ends, 9))
return -this.dataLengthNeeded; return -this.dataLengthNeeded;
@ -6500,7 +6616,8 @@ class IIPPacket
this.content = data.clip(offset, cl); this.content = data.clip(offset, cl);
offset += cl; offset += cl;
} }
else if (this.action == IIPPacketAction.InvokeFunction else if (this.action == IIPPacketAction.InvokeFunctionArrayArguments
|| this.action == IIPPacketAction.InvokeFunctionNamedArguments
|| this.action == IIPPacketAction.GetProperty || this.action == IIPPacketAction.GetProperty
|| this.action == IIPPacketAction.GetPropertyIfModified) || this.action == IIPPacketAction.GetPropertyIfModified)
{ {
@ -7240,6 +7357,18 @@ class ResourceTemplate {
this.content = b.toArray(); this.content = b.toArray();
} }
static getFunctionParameters(func)
{
var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
static parse(data, offset = 0, contentLength = -1) { static parse(data, offset = 0, contentLength = -1) {
if (contentLength == -1) if (contentLength == -1)

View File

@ -1193,6 +1193,13 @@ class Structure
return rt; return rt;
} }
constructor(data)
{
if (data instanceof Object)
for(var i in data)
this[i] = data[i];
}
} }
/* /*
* Copyright (c) 2017 Ahmed Kh. Zamil * Copyright (c) 2017 Ahmed Kh. Zamil
@ -2486,12 +2493,12 @@ class Codec {
if (includeKeys) { if (includeKeys) {
for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
var key = DC.stringToBytes(keys[i]); var key = DC.stringToBytes(keys[i]);
rt.addUint8(key.length).addString(key).addUint8Array(DC.compose(value[i], connection)); rt.addUint8(key.length).addUint8Array(key).addUint8Array(Codec.compose(value[keys[i]], connection));
} }
} }
else { else {
for (var i = 0; i < keys.length; i++) for (var i = 0; i < keys.length; i++)
rt.addUint8Array(DC.compose(value[keys[i]], connection, includeTypes)); rt.addUint8Array(Codec.compose(value[keys[i]], connection, includeTypes));
} }
if (prependLength) if (prependLength)
@ -3444,7 +3451,7 @@ const DataType =
class DistributedConnection extends IStore { class DistributedConnection extends IStore {
send(data) { send(data) {
console.log("Send", data.length); //console.log("Send", data.length);
this.socket.send(data.buffer); this.socket.send(data.buffer);
} }
@ -3534,7 +3541,7 @@ class DistributedConnection extends IStore {
this.socket.onmessage = function (msg) { this.socket.onmessage = function (msg) {
console.log("Rec", msg.data.byteLength); //console.log("Rec", msg.data.byteLength);
this.networkBuffer.writeAll(msg.data); this.networkBuffer.writeAll(msg.data);
@ -3658,9 +3665,12 @@ class DistributedConnection extends IStore {
break; break;
// Invoke // Invoke
case IIPPacketAction.InvokeFunction: case IIPPacketAction.InvokeFunctionArrayArguments:
this.IIPRequestInvokeFunction(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content); this.IIPRequestInvokeFunctionArrayArguments(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
break; break;
case IIPPacketAction.InvokeFunctionNamedArguments:
this.IIPRequestInvokeFunctionNamedArguments(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
break;
case IIPPacketAction.GetProperty: case IIPPacketAction.GetProperty:
this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex); this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex);
break; break;
@ -3732,9 +3742,11 @@ class DistributedConnection extends IStore {
this.IIPReply(packet.callbackId, packet.content); this.IIPReply(packet.callbackId, packet.content);
break; break;
case IIPPacketAction.InvokeFunction: case IIPPacketAction.InvokeFunctionArrayArguments:
case IIPPacketAction.InvokeFunctionNamedArguments:
this.IIPReplyInvoke(packet.callbackId, packet.content); this.IIPReplyInvoke(packet.callbackId, packet.content);
break; break;
case IIPPacketAction.GetProperty: case IIPPacketAction.GetProperty:
this.IIPReply(packet.callbackId, packet.content); this.IIPReply(packet.callbackId, packet.content);
break; break;
@ -3959,7 +3971,7 @@ class DistributedConnection extends IStore {
return this.sendParams(reply).addUint8(0x40 | action).addUint32(this.callbackCounter); return this.sendParams(reply).addUint8(0x40 | action).addUint32(this.callbackCounter);
} }
sendInvoke(instanceId, index, parameters) sendInvokeByArrayArguments(instanceId, index, parameters)
{ {
var reply = new AsyncReply(); var reply = new AsyncReply();
@ -3967,7 +3979,7 @@ class DistributedConnection extends IStore {
this.callbackCounter++; this.callbackCounter++;
this.sendParams() this.sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunction) .addUint8(0x40 | IIPPacketAction.InvokeFunctionArrayArguments)
.addUint32(this.callbackCounter) .addUint32(this.callbackCounter)
.addUint32(instanceId) .addUint32(instanceId)
.addUint8(index) .addUint8(index)
@ -3979,6 +3991,27 @@ class DistributedConnection extends IStore {
return reply; return reply;
} }
sendInvokeByNamedArguments(instanceId, index, parameters)
{
var reply = new AsyncReply();
var pb = Codec.composeStructure(parameters, this, true, true, true);
this.callbackCounter++;
this.sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunctionNamedArguments)
.addUint32(this.callbackCounter)
.addUint32(instanceId)
.addUint8(index)
.addUint8Array(pb)
.done();
this.requests[this.callbackCounter] = reply;
return reply;
}
sendError(type, callbackId, errorCode, errorMessage = "") sendError(type, callbackId, errorCode, errorMessage = "")
{ {
var msg = DC.stringToBytes(errorMessage); var msg = DC.stringToBytes(errorMessage);
@ -4423,7 +4456,7 @@ class DistributedConnection extends IStore {
}); });
} }
IIPRequestInvokeFunction(callback, resourceId, index, content) { IIPRequestInvokeFunctionArrayArguments(callback, resourceId, index, content) {
var self = this; var self = this;
@ -4433,10 +4466,10 @@ class DistributedConnection extends IStore {
var ft = r.instance.template.getFunctionTemplateByIndex(index); var ft = r.instance.template.getFunctionTemplateByIndex(index);
if (ft != null) { if (ft != null) {
if (r instanceof DistributedResource) { if (r instanceof DistributedResource) {
var rt = r._invoke(index, args); var rt = r._invokeByArrayArguments(index, args);
if (rt != null) { if (rt != null) {
rt.then(function (res) { rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(res, self)) .addUint8Array(Codec.compose(res, self))
.done(); .done();
}); });
@ -4463,13 +4496,93 @@ class DistributedConnection extends IStore {
if (rt instanceof AsyncReply) { if (rt instanceof AsyncReply) {
rt.then(function (res) { rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(res, self)) .addUint8Array(Codec.compose(res, self))
.done(); .done();
}); });
} }
else { else {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(rt, self))
.done();
}
}
else {
// ft found, fi not found, this should never happen
}
}
}
else {
// no function at this index
}
});
}
else {
// no resource with this id
}
});
}
IIPRequestInvokeFunctionNamedArguments(callback, resourceId, index, content) {
var self = this;
Warehouse.get(resourceId).then(function (r) {
if (r != null) {
Codec.parseStructure(content, 0, content.Length, self).then(function (namedArgs) {
var ft = r.instance.template.getFunctionTemplateByIndex(index);
if (ft != null) {
if (r instanceof DistributedResource) {
var rt = r._invokeByNamedArguments(index, namedArgs);
if (rt != null) {
rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(res, self))
.done();
});
}
else {
// function not found on a distributed object
}
}
else {
var fi = r[ft.name];
if (r.instance.applicable(self.session, ActionType.Execute, ft) == Ruling.Denied)
{
self.sendError(ErrorType.Management, callback, ExceptionCode.InvokeDenied);
return;
}
if (fi instanceof Function) {
var pi = ResourceTemplate.getFunctionParameters(fi);
var args = new Array(pi.length);
for (var i = 0; i < pi.Length; i++)
{
if (namedArgs[pi[i]] !== undefined)
args[i] = namedArgs[pi[i]];
}
// pass this to the last argument if it is undefined
if (args[args.length-1] === undefined)
args[args.length-1] = self;
var rt = fi.apply(r, args);
if (rt instanceof AsyncReply) {
rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(res, self))
.done();
});
}
else {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(rt, self)) .addUint8Array(Codec.compose(rt, self))
.done(); .done();
} }
@ -5319,7 +5432,18 @@ class DistributedResource extends IResource
var makeFunc = function(index) var makeFunc = function(index)
{ {
return function () { return function () {
return self._invoke(index, arguments);
if ( arguments.length = 1
&& arguments[0] instanceof Object
&& arguments[0].constructor.name == "Object")
{
var namedArgs = new Structure(arguments[0]);
return self._invokeByNamedArguments(index, namedArgs);
}
else
{
return self._invokeByArrayArguments(index, arguments);
}
}; };
}; };
@ -5366,35 +5490,25 @@ class DistributedResource extends IResource
this.instance._emitResourceEvent(null, null, et.name, args); this.instance._emitResourceEvent(null, null, et.name, args);
} }
_invoke(index, args) { _invokeByArrayArguments(index, args) {
if (this.destroyed) if (this.destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
if (index >= this.instance.template.functions.length) if (index >= this.instance.template.functions.length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
return this._p.connection.sendInvoke(this._p.instanceId, index, args); return this._p.connection.sendInvokeByArrayArguments(this._p.instanceId, index, args);
/*
var reply = new AsyncReply();
var parameters = Codec.composeVarArray(args, this._p.connection, true);
var self = this;
this._p.connection.sendRequest(IIPPacketAction.InvokeFunction,
BL().addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters))
.then(function (res) {
Codec.parse(res[0], 0, self._p.connection).then(function (rt) {
reply.trigger(rt);
});
});
return reply;
*/
} }
_invokeByNamedArguments(index, namedArgs) {
if (this.destroyed)
throw new Exception("Trying to access destroyed object");
if (index >= this.instance.template.functions.length)
throw new Exception("Function index is incorrect");
return this._p.connection.sendInvokeByNamedArguments(this._p.instanceId, index, namedArgs);
}
_get(index) _get(index)
{ {
@ -5973,10 +6087,11 @@ const IIPPacketAction =
ResourceParents: 14, ResourceParents: 14,
// Request Invoke // Request Invoke
InvokeFunction: 16, InvokeFunctionArrayArguments: 16,
GetProperty: 17, GetProperty: 17,
GetPropertyIfModified: 18, GetPropertyIfModified: 18,
SetProperty: 19, SetProperty: 19,
InvokeFunctionNamedArguments: 20,
// Request Attribute // Request Attribute
GetAllAttributes: 24, GetAllAttributes: 24,
@ -6320,7 +6435,8 @@ class IIPPacket
offset += 8; offset += 8;
} }
else if (this.action == IIPPacketAction.InvokeFunction) else if ( this.action == IIPPacket.InvokeFunctionArrayArguments
|| this.action == IIPPacketAction.InvokeFunctionNamedArguments)
{ {
if (this.notEnough(offset, ends, 9)) if (this.notEnough(offset, ends, 9))
return -this.dataLengthNeeded; return -this.dataLengthNeeded;
@ -6500,7 +6616,8 @@ class IIPPacket
this.content = data.clip(offset, cl); this.content = data.clip(offset, cl);
offset += cl; offset += cl;
} }
else if (this.action == IIPPacketAction.InvokeFunction else if (this.action == IIPPacketAction.InvokeFunctionArrayArguments
|| this.action == IIPPacketAction.InvokeFunctionNamedArguments
|| this.action == IIPPacketAction.GetProperty || this.action == IIPPacketAction.GetProperty
|| this.action == IIPPacketAction.GetPropertyIfModified) || this.action == IIPPacketAction.GetPropertyIfModified)
{ {
@ -7240,6 +7357,18 @@ class ResourceTemplate {
this.content = b.toArray(); this.content = b.toArray();
} }
static getFunctionParameters(func)
{
var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
static parse(data, offset = 0, contentLength = -1) { static parse(data, offset = 0, contentLength = -1) {
if (contentLength == -1) if (contentLength == -1)

View File

@ -627,12 +627,12 @@ class Codec {
if (includeKeys) { if (includeKeys) {
for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
var key = DC.stringToBytes(keys[i]); var key = DC.stringToBytes(keys[i]);
rt.addUint8(key.length).addString(key).addUint8Array(DC.compose(value[i], connection)); rt.addUint8(key.length).addUint8Array(key).addUint8Array(Codec.compose(value[keys[i]], connection));
} }
} }
else { else {
for (var i = 0; i < keys.length; i++) for (var i = 0; i < keys.length; i++)
rt.addUint8Array(DC.compose(value[keys[i]], connection, includeTypes)); rt.addUint8Array(Codec.compose(value[keys[i]], connection, includeTypes));
} }
if (prependLength) if (prependLength)

View File

@ -243,9 +243,12 @@ class DistributedConnection extends IStore {
break; break;
// Invoke // Invoke
case IIPPacketAction.InvokeFunction: case IIPPacketAction.InvokeFunctionArrayArguments:
this.IIPRequestInvokeFunction(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content); this.IIPRequestInvokeFunctionArrayArguments(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
break; break;
case IIPPacketAction.InvokeFunctionNamedArguments:
this.IIPRequestInvokeFunctionNamedArguments(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
break;
case IIPPacketAction.GetProperty: case IIPPacketAction.GetProperty:
this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex); this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex);
break; break;
@ -317,9 +320,11 @@ class DistributedConnection extends IStore {
this.IIPReply(packet.callbackId, packet.content); this.IIPReply(packet.callbackId, packet.content);
break; break;
case IIPPacketAction.InvokeFunction: case IIPPacketAction.InvokeFunctionArrayArguments:
case IIPPacketAction.InvokeFunctionNamedArguments:
this.IIPReplyInvoke(packet.callbackId, packet.content); this.IIPReplyInvoke(packet.callbackId, packet.content);
break; break;
case IIPPacketAction.GetProperty: case IIPPacketAction.GetProperty:
this.IIPReply(packet.callbackId, packet.content); this.IIPReply(packet.callbackId, packet.content);
break; break;
@ -544,7 +549,7 @@ class DistributedConnection extends IStore {
return this.sendParams(reply).addUint8(0x40 | action).addUint32(this.callbackCounter); return this.sendParams(reply).addUint8(0x40 | action).addUint32(this.callbackCounter);
} }
sendInvoke(instanceId, index, parameters) sendInvokeByArrayArguments(instanceId, index, parameters)
{ {
var reply = new AsyncReply(); var reply = new AsyncReply();
@ -552,7 +557,7 @@ class DistributedConnection extends IStore {
this.callbackCounter++; this.callbackCounter++;
this.sendParams() this.sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunction) .addUint8(0x40 | IIPPacketAction.InvokeFunctionArrayArguments)
.addUint32(this.callbackCounter) .addUint32(this.callbackCounter)
.addUint32(instanceId) .addUint32(instanceId)
.addUint8(index) .addUint8(index)
@ -564,6 +569,27 @@ class DistributedConnection extends IStore {
return reply; return reply;
} }
sendInvokeByNamedArguments(instanceId, index, parameters)
{
var reply = new AsyncReply();
var pb = Codec.composeStructure(parameters, this, true, true, true);
this.callbackCounter++;
this.sendParams()
.addUint8(0x40 | IIPPacketAction.InvokeFunctionNamedArguments)
.addUint32(this.callbackCounter)
.addUint32(instanceId)
.addUint8(index)
.addUint8Array(pb)
.done();
this.requests[this.callbackCounter] = reply;
return reply;
}
sendError(type, callbackId, errorCode, errorMessage = "") sendError(type, callbackId, errorCode, errorMessage = "")
{ {
var msg = DC.stringToBytes(errorMessage); var msg = DC.stringToBytes(errorMessage);
@ -1008,7 +1034,7 @@ class DistributedConnection extends IStore {
}); });
} }
IIPRequestInvokeFunction(callback, resourceId, index, content) { IIPRequestInvokeFunctionArrayArguments(callback, resourceId, index, content) {
var self = this; var self = this;
@ -1018,10 +1044,10 @@ class DistributedConnection extends IStore {
var ft = r.instance.template.getFunctionTemplateByIndex(index); var ft = r.instance.template.getFunctionTemplateByIndex(index);
if (ft != null) { if (ft != null) {
if (r instanceof DistributedResource) { if (r instanceof DistributedResource) {
var rt = r._invoke(index, args); var rt = r._invokeByArrayArguments(index, args);
if (rt != null) { if (rt != null) {
rt.then(function (res) { rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(res, self)) .addUint8Array(Codec.compose(res, self))
.done(); .done();
}); });
@ -1048,13 +1074,93 @@ class DistributedConnection extends IStore {
if (rt instanceof AsyncReply) { if (rt instanceof AsyncReply) {
rt.then(function (res) { rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(res, self)) .addUint8Array(Codec.compose(res, self))
.done(); .done();
}); });
} }
else { else {
self.sendReply(IIPPacketAction.InvokeFunction, callback) self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback)
.addUint8Array(Codec.compose(rt, self))
.done();
}
}
else {
// ft found, fi not found, this should never happen
}
}
}
else {
// no function at this index
}
});
}
else {
// no resource with this id
}
});
}
IIPRequestInvokeFunctionNamedArguments(callback, resourceId, index, content) {
var self = this;
Warehouse.get(resourceId).then(function (r) {
if (r != null) {
Codec.parseStructure(content, 0, content.Length, self).then(function (namedArgs) {
var ft = r.instance.template.getFunctionTemplateByIndex(index);
if (ft != null) {
if (r instanceof DistributedResource) {
var rt = r._invokeByNamedArguments(index, namedArgs);
if (rt != null) {
rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(res, self))
.done();
});
}
else {
// function not found on a distributed object
}
}
else {
var fi = r[ft.name];
if (r.instance.applicable(self.session, ActionType.Execute, ft) == Ruling.Denied)
{
self.sendError(ErrorType.Management, callback, ExceptionCode.InvokeDenied);
return;
}
if (fi instanceof Function) {
var pi = ResourceTemplate.getFunctionParameters(fi);
var args = new Array(pi.length);
for (var i = 0; i < pi.Length; i++)
{
if (namedArgs[pi[i]] !== undefined)
args[i] = namedArgs[pi[i]];
}
// pass this to the last argument if it is undefined
if (args[args.length-1] === undefined)
args[args.length-1] = self;
var rt = fi.apply(r, args);
if (rt instanceof AsyncReply) {
rt.then(function (res) {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(res, self))
.done();
});
}
else {
self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback)
.addUint8Array(Codec.compose(rt, self)) .addUint8Array(Codec.compose(rt, self))
.done(); .done();
} }

View File

@ -82,7 +82,18 @@ class DistributedResource extends IResource
var makeFunc = function(index) var makeFunc = function(index)
{ {
return function () { return function () {
return self._invoke(index, arguments);
if ( arguments.length = 1
&& arguments[0] instanceof Object
&& arguments[0].constructor.name == "Object")
{
var namedArgs = new Structure(arguments[0]);
return self._invokeByNamedArguments(index, namedArgs);
}
else
{
return self._invokeByArrayArguments(index, arguments);
}
}; };
}; };
@ -129,35 +140,25 @@ class DistributedResource extends IResource
this.instance._emitResourceEvent(null, null, et.name, args); this.instance._emitResourceEvent(null, null, et.name, args);
} }
_invoke(index, args) { _invokeByArrayArguments(index, args) {
if (this.destroyed) if (this.destroyed)
throw new Exception("Trying to access destroyed object"); throw new Exception("Trying to access destroyed object");
if (index >= this.instance.template.functions.length) if (index >= this.instance.template.functions.length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
return this._p.connection.sendInvoke(this._p.instanceId, index, args); return this._p.connection.sendInvokeByArrayArguments(this._p.instanceId, index, args);
/*
var reply = new AsyncReply();
var parameters = Codec.composeVarArray(args, this._p.connection, true);
var self = this;
this._p.connection.sendRequest(IIPPacketAction.InvokeFunction,
BL().addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters))
.then(function (res) {
Codec.parse(res[0], 0, self._p.connection).then(function (rt) {
reply.trigger(rt);
});
});
return reply;
*/
} }
_invokeByNamedArguments(index, namedArgs) {
if (this.destroyed)
throw new Exception("Trying to access destroyed object");
if (index >= this.instance.template.functions.length)
throw new Exception("Function index is incorrect");
return this._p.connection.sendInvokeByNamedArguments(this._p.instanceId, index, namedArgs);
}
_get(index) _get(index)
{ {

View File

@ -82,10 +82,11 @@ const IIPPacketAction =
ResourceParents: 14, ResourceParents: 14,
// Request Invoke // Request Invoke
InvokeFunction: 16, InvokeFunctionArrayArguments: 16,
GetProperty: 17, GetProperty: 17,
GetPropertyIfModified: 18, GetPropertyIfModified: 18,
SetProperty: 19, SetProperty: 19,
InvokeFunctionNamedArguments: 20,
// Request Attribute // Request Attribute
GetAllAttributes: 24, GetAllAttributes: 24,
@ -429,7 +430,8 @@ class IIPPacket
offset += 8; offset += 8;
} }
else if (this.action == IIPPacketAction.InvokeFunction) else if ( this.action == IIPPacket.InvokeFunctionArrayArguments
|| this.action == IIPPacketAction.InvokeFunctionNamedArguments)
{ {
if (this.notEnough(offset, ends, 9)) if (this.notEnough(offset, ends, 9))
return -this.dataLengthNeeded; return -this.dataLengthNeeded;
@ -609,7 +611,8 @@ class IIPPacket
this.content = data.clip(offset, cl); this.content = data.clip(offset, cl);
offset += cl; offset += cl;
} }
else if (this.action == IIPPacketAction.InvokeFunction else if (this.action == IIPPacketAction.InvokeFunctionArrayArguments
|| this.action == IIPPacketAction.InvokeFunctionNamedArguments
|| this.action == IIPPacketAction.GetProperty || this.action == IIPPacketAction.GetProperty
|| this.action == IIPPacketAction.GetPropertyIfModified) || this.action == IIPPacketAction.GetPropertyIfModified)
{ {

View File

@ -158,6 +158,18 @@ class ResourceTemplate {
this.content = b.toArray(); this.content = b.toArray();
} }
static getFunctionParameters(func)
{
var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null)
result = [];
return result;
}
static parse(data, offset = 0, contentLength = -1) { static parse(data, offset = 0, contentLength = -1) {
if (contentLength == -1) if (contentLength == -1)

View File

@ -36,4 +36,11 @@ class Structure
return rt; return rt;
} }
constructor(data)
{
if (data instanceof Object)
for(var i in data)
this[i] = data[i];
}
} }

View File

@ -18,11 +18,16 @@
con.get("db/my").then(function(rt){ con.get("db/my").then(function(rt){
console.log("Object received."); console.log("Object received.");
demo = rt; demo = rt;
rt.on("LevelUp", function(v){ rt.on("LevelUp", function(a, b, c){
console.log("LevelUp", v); console.log("LevelUp", a, b, c);
}); });
rt.Add(3); rt.Add(3);
rt.Divide({nominator: 10, denominator: 50}).then(x=>{
console.log(x);
});
}); });
}).on("error", function(sender, code, msg){ }).on("error", function(sender, code, msg){
console.log(sender, code, msg); console.log(sender, code, msg);