mirror of
https://github.com/esiur/esiur-js.git
synced 2025-06-27 07:13:12 +00:00
IIP v3.3
This commit is contained in:
@ -23,6 +23,8 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class AsyncBag extends AsyncReply
|
||||
{
|
||||
constructor() {
|
||||
@ -42,13 +44,27 @@ class AsyncBag extends AsyncReply
|
||||
|
||||
var self = this;
|
||||
|
||||
var singleTaskCompleted = function(taskIndex)
|
||||
{
|
||||
return function(results, reply){
|
||||
self.results[taskIndex] = results;
|
||||
self.count++;
|
||||
if (self.count == self.results.length)
|
||||
self.trigger(self.results);
|
||||
};
|
||||
};
|
||||
|
||||
for(var i = 0; i < this.results.length; i++)
|
||||
this.replies[i].then(singleTaskCompleted(i));
|
||||
|
||||
/*
|
||||
this.replies[i].then(function(r, reply){
|
||||
self.results[self.replies.indexOf(reply)] = r;
|
||||
self.count++;
|
||||
if (self.count == self.results.length)
|
||||
self.trigger(self.results);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
add(reply)
|
||||
|
88
src/AsyncException.js
Normal file
88
src/AsyncException.js
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
* Created by Ahmed Zamil on 18/11/2017.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const ExceptionCode =
|
||||
{
|
||||
HostNotReachable: 0,
|
||||
AccessDenied: 1,
|
||||
ResourceNotFound: 2,
|
||||
AttachDenied: 3,
|
||||
InvalidMethod: 4,
|
||||
InvokeDenied: 5,
|
||||
CreateDenied: 6,
|
||||
AddParentDenied: 7,
|
||||
AddChildDenied: 8,
|
||||
ViewAttributeDenied: 9,
|
||||
UpdateAttributeDenied: 10,
|
||||
StoreNotFound: 11,
|
||||
ParentNotFound: 12,
|
||||
ChildNotFound: 13,
|
||||
ResourceIsNotStore: 14,
|
||||
DeleteDenied: 15,
|
||||
DeleteFailed: 16,
|
||||
UpdateAttributeFailed: 17,
|
||||
GetAttributesFailed: 18,
|
||||
ClearAttributesFailed: 19,
|
||||
TemplateNotFound: 20,
|
||||
RenameDenied: 21,
|
||||
ClassNotFound: 22,
|
||||
MethodNotFound: 23,
|
||||
PropertyNotFound: 24,
|
||||
SetPropertyDenied: 25,
|
||||
ReadOnlyProperty: 26
|
||||
};
|
||||
|
||||
class AsyncException extends Error
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.raised = false;
|
||||
}
|
||||
|
||||
raise(type, code, message)
|
||||
{
|
||||
this.type = (type == 0 ? "Management" : "Execusion");
|
||||
this.code = code;
|
||||
|
||||
if (type == 0)
|
||||
for(var i in ExceptionCode)
|
||||
if (ExceptionCode[i] == code)
|
||||
{
|
||||
this.message = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
this.message = message;
|
||||
|
||||
this.raised = true;
|
||||
}
|
||||
|
||||
toString()
|
||||
{
|
||||
return this.type + " " + this.code + " " + this.message;
|
||||
}
|
||||
}
|
@ -22,6 +22,9 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class AsyncQueue extends AsyncReply
|
||||
{
|
||||
|
||||
|
@ -23,13 +23,72 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ErrorType = {
|
||||
Management: 0,
|
||||
Exception: 1
|
||||
};
|
||||
|
||||
const ProgressType = {
|
||||
Execution: 0,
|
||||
Network: 1
|
||||
};
|
||||
|
||||
class AsyncReply
|
||||
{
|
||||
then(callback)
|
||||
{
|
||||
this.callbacks.push(callback);
|
||||
|
||||
if (this.ready)
|
||||
{
|
||||
callback(this.result, this);
|
||||
|
||||
if (!this.taskExpired)
|
||||
{
|
||||
this.taskExpired = true;
|
||||
this.resolveTask(this.result);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
catch(callback)
|
||||
{
|
||||
return error(callback);
|
||||
}
|
||||
|
||||
error(callback)
|
||||
{
|
||||
this.errorCallbacks.push(callback);
|
||||
|
||||
if (this.exception.raised)
|
||||
{
|
||||
callback(this.exception);
|
||||
|
||||
if (!this.taskExpired)
|
||||
{
|
||||
this.taskExpired = true;
|
||||
this.rejectTask(this.exception);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
progress(callback)
|
||||
{
|
||||
this.progressCallbacks.push(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
chunk(callback)
|
||||
{
|
||||
this.chunkCallbacks.push(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
trigger(result)
|
||||
@ -39,15 +98,79 @@ class AsyncReply
|
||||
|
||||
for(var i = 0; i < this.callbacks.length; i++)
|
||||
this.callbacks[i](result, this);
|
||||
|
||||
|
||||
if (!this.taskExpired)
|
||||
{
|
||||
this.taskExpired = true;
|
||||
this.resolveTask(this.result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
triggerError(type, code, message)//exception)
|
||||
{
|
||||
if (this.ready)
|
||||
return;
|
||||
|
||||
this.exception.raise(type, code, message);// = exception;
|
||||
|
||||
for(var i = 0; i < this.errorCallbacks.length; i++)
|
||||
this.errorCallbacks[i](this.exception, this);
|
||||
|
||||
|
||||
if (!this.taskExpired)
|
||||
{
|
||||
this.taskExpired = true;
|
||||
this.rejectTask(this.exception);
|
||||
}
|
||||
}
|
||||
|
||||
triggerProgress(type, value, max)
|
||||
{
|
||||
if (this.ready)
|
||||
return;
|
||||
|
||||
for(var i = 0; i < this.progressCallbacks.length; i++)
|
||||
this.progressCallbacks[i](type, value, max, this);
|
||||
}
|
||||
|
||||
triggerChunk(value)
|
||||
{
|
||||
if (this.ready)
|
||||
return;
|
||||
|
||||
for(var i = 0; i < this.chunkCallbacks.length; i++)
|
||||
this.chunkCallbacks[i](value, this);
|
||||
}
|
||||
|
||||
constructor(result)
|
||||
{
|
||||
this.callbacks = [];
|
||||
this.errorCallbacks = [];
|
||||
this.progressCallbacks = [];
|
||||
this.chunkCallbacks = [];
|
||||
this.exception = new AsyncException();// null;
|
||||
|
||||
if (result) {
|
||||
var self = this;
|
||||
|
||||
this.task = new Promise(function(resolve, reject){
|
||||
self.resolveTask = resolve;
|
||||
self.rejectTask = reject;
|
||||
});
|
||||
|
||||
|
||||
if (result !== undefined) {
|
||||
this.result = result;
|
||||
this.ready = true;
|
||||
this.taskExpired = true;
|
||||
this.resolveTask(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.taskExpired = false;
|
||||
this.ready = false;
|
||||
this.result = null;
|
||||
}
|
||||
}
|
||||
}
|
50
src/Authentication.js
Normal file
50
src/Authentication.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 16/11/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const AuthenticationType = {
|
||||
Host: 0,
|
||||
CoHost: 1,
|
||||
Client: 2,
|
||||
Alien: 3
|
||||
};
|
||||
|
||||
class Authentication
|
||||
{
|
||||
constructor(type)
|
||||
{
|
||||
this.type = type;
|
||||
this.state = 0;
|
||||
this.domain = null;
|
||||
this.username = null;
|
||||
}
|
||||
|
||||
get fullName()
|
||||
{
|
||||
return this.domain + "@" + this.username;
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 05/09/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class AutoList extends IEventHandler
|
||||
{
|
||||
constructor()
|
||||
@ -32,10 +34,15 @@ class AutoList extends IEventHandler
|
||||
this.list = [];
|
||||
}
|
||||
|
||||
get length()
|
||||
{
|
||||
return this.list.length;
|
||||
}
|
||||
|
||||
add(value)
|
||||
{
|
||||
if (value instanceof IDestructible)
|
||||
value.on("destroy", this._item_destroyed);
|
||||
value.on("destroy", this._item_destroyed, this);
|
||||
|
||||
this.list.push(value);
|
||||
|
||||
@ -48,7 +55,7 @@ class AutoList extends IEventHandler
|
||||
return;
|
||||
|
||||
if (value instanceof IDestructible)
|
||||
value.on("destroy", this._item_destroyed);
|
||||
value.on("destroy", this._item_destroyed, this);
|
||||
|
||||
if (this.list[index] instanceof IDestructible)
|
||||
this.list[index].off("destroy", this._item_destroyed);
|
||||
@ -56,6 +63,16 @@ class AutoList extends IEventHandler
|
||||
this.list[index] = value;
|
||||
}
|
||||
|
||||
at(index)
|
||||
{
|
||||
return this.list[index];
|
||||
}
|
||||
|
||||
item(index)
|
||||
{
|
||||
return this.list[index];
|
||||
}
|
||||
|
||||
remove(value)
|
||||
{
|
||||
this.removeAt(this.list.indexOf(value));
|
||||
@ -66,6 +83,11 @@ class AutoList extends IEventHandler
|
||||
return this.list.indexOf(value) > -1;
|
||||
}
|
||||
|
||||
toArray()
|
||||
{
|
||||
return this.list.slice(0);
|
||||
}
|
||||
|
||||
removeAt(index)
|
||||
{
|
||||
if (index >= this.list.length || index < 0)
|
||||
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 05/09/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class AutoMap extends IEventHandler
|
||||
{
|
||||
constructor()
|
||||
|
@ -24,7 +24,9 @@
|
||||
* Created by Ahmed Zamil on 25/08/2017.
|
||||
*/
|
||||
|
||||
var BL = function(){
|
||||
"use strict";
|
||||
|
||||
function BL(){
|
||||
return new BinaryList();
|
||||
};
|
||||
|
||||
@ -140,6 +142,16 @@ class BinaryList
|
||||
return rt;
|
||||
}
|
||||
|
||||
toDC()
|
||||
{
|
||||
return new DC(this.toArray());
|
||||
}
|
||||
|
||||
addDateTime(value, position)
|
||||
{
|
||||
return this.add({type: DataType.DateTime, value: value}, position);
|
||||
}
|
||||
|
||||
addUint8Array(value, position)
|
||||
{
|
||||
return this.add({type: DataType.UInt8Array, value: value}, position);
|
||||
|
426
src/Codec.js
426
src/Codec.js
@ -24,16 +24,17 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
var ResourceComparisonResult =
|
||||
"use strict";
|
||||
|
||||
const ResourceComparisonResult =
|
||||
{
|
||||
Null: 0,
|
||||
Distributed: 1,
|
||||
DistributedSameClass: 2,
|
||||
Local: 3,
|
||||
Same: 4
|
||||
Local: 2,
|
||||
Same: 3
|
||||
};
|
||||
|
||||
var StructureComparisonResult =
|
||||
const StructureComparisonResult =
|
||||
{
|
||||
Null: 0,
|
||||
Structure: 1,
|
||||
@ -44,6 +45,7 @@ var StructureComparisonResult =
|
||||
|
||||
class Codec {
|
||||
|
||||
|
||||
static parse(data, offset, sizeObject, connection, dataType = DataType.Unspecified) {
|
||||
|
||||
var size;
|
||||
@ -215,16 +217,251 @@ class Codec {
|
||||
return connection.fetch(iid);// Warehouse.Get(iid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an array of bytes into array of resources
|
||||
/// </summary>
|
||||
/// <param name="data">Array of bytes.</param>
|
||||
/// <param name="length">Number of bytes to parse.</param>
|
||||
/// <param name="offset">Zero-indexed offset.</param>
|
||||
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
|
||||
/// <returns>Array of resources.</returns>
|
||||
static parseResourceArray(data, offset, length, connection)
|
||||
{
|
||||
var reply = new AsyncBag();
|
||||
if (length == 0)
|
||||
{
|
||||
reply.seal();
|
||||
return reply;
|
||||
}
|
||||
|
||||
static parseStructure(data, offset, contentLength, connection, keylist = null, typelist = null, keys = null, types = null) {
|
||||
var reply = new AsyncReply();
|
||||
var bag = new AsyncBag();
|
||||
var end = offset + length;
|
||||
|
||||
//
|
||||
var result = data[offset++];
|
||||
|
||||
var previous = null;
|
||||
|
||||
if (result == ResourceComparisonResult.Null)
|
||||
previous = new AsyncReply(null);
|
||||
else if (result == ResourceComparisonResult.Local)
|
||||
{
|
||||
previous = Warehouse.get(data.getUint32(offset));
|
||||
offset += 4;
|
||||
}
|
||||
else if (result == ResourceComparisonResult.Distributed)
|
||||
{
|
||||
previous = connection.fetch(data.getUint32(offset));
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
reply.add(previous);
|
||||
|
||||
|
||||
if (keylist == null)
|
||||
keylist = [];
|
||||
if (typelist == null)
|
||||
typelist = [];
|
||||
while (offset < end)
|
||||
{
|
||||
result = data[offset++];
|
||||
|
||||
var current = null;
|
||||
|
||||
if (result == ResourceComparisonResult.Null)
|
||||
{
|
||||
current = new AsyncReply(null);
|
||||
}
|
||||
else if (result == ResourceComparisonResult.Same)
|
||||
{
|
||||
current = previous;
|
||||
}
|
||||
else if (result == ResourceComparisonResult.Local)
|
||||
{
|
||||
current = Warehouse.get(data.getUint32(offset));
|
||||
offset += 4;
|
||||
}
|
||||
else if (result == ResourceComparisonResult.Distributed)
|
||||
{
|
||||
current = connection.fetch(data.getUint32(offset));
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
reply.add(current);
|
||||
|
||||
previous = current;
|
||||
}
|
||||
|
||||
reply.seal();
|
||||
return reply;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compose an array of property values.
|
||||
/// </summary>
|
||||
/// <param name="array">PropertyValue array.</param>
|
||||
/// <param name="connection">DistributedConnection is required to check locality.</param>
|
||||
/// <param name="prependLength">If True, prepend the length as UInt32 at the beginning of the output.</param>
|
||||
/// <returns>Array of bytes in the network byte order.</returns>
|
||||
|
||||
static composePropertyValueArray(array, connection, prependLength = false)
|
||||
{
|
||||
var rt = BL();
|
||||
for (var i = 0; i < array.Length; i++)
|
||||
rt.addUint8Array(Codec.composePropertyValue(array[i], connection));
|
||||
if (prependLength)
|
||||
rt.addUint32(rt.length, 0);
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compose a property value.
|
||||
/// </summary>
|
||||
/// <param name="propertyValue">Property value</param>
|
||||
/// <param name="connection">DistributedConnection is required to check locality.</param>
|
||||
/// <returns>Array of bytes in the network byte order.</returns>
|
||||
static composePropertyValue(propertyValue, connection)
|
||||
{
|
||||
// age, date, value
|
||||
return BL().addUint64(propertyValue.age)
|
||||
.addDateTime(propertyValue.date)
|
||||
.addUint8Array(Codec.compose(propertyValue.value, connection))
|
||||
.toArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse property value.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of bytes.</param>
|
||||
/// <param name="offset">Zero-indexed offset.</param>
|
||||
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
|
||||
/// <param name="cs">Output content size.</param>
|
||||
/// <returns>PropertyValue.</returns>
|
||||
static parsePropertyValue(data, offset, sizeObject, connection)
|
||||
{
|
||||
var reply = new AsyncReply();
|
||||
|
||||
var age = data.getUint64(offset);
|
||||
offset += 8;
|
||||
|
||||
var date = data.getDateTime(offset);
|
||||
offset += 8;
|
||||
|
||||
var cs = {};
|
||||
|
||||
Codec.parse(data, offset, cs, connection).then(function(value)
|
||||
{
|
||||
reply.trigger(new PropertyValue(value, age, date));
|
||||
});
|
||||
|
||||
sizeObject.size = 16 + cs.size;
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse resource history
|
||||
/// </summary>
|
||||
/// <param name="data">Array of bytes.</param>
|
||||
/// <param name="offset">Zero-indexed offset.</param>
|
||||
/// <param name="length">Number of bytes to parse.</param>
|
||||
/// <param name="resource">Resource</param>
|
||||
/// <param name="fromAge">Starting age.</param>
|
||||
/// <param name="toAge">Ending age.</param>
|
||||
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
|
||||
/// <returns></returns>
|
||||
static parseHistory(data, offset, length, resource, connection)
|
||||
{
|
||||
var list = new KeyList();
|
||||
|
||||
var reply = new AsyncReply();
|
||||
|
||||
var bagOfBags = new AsyncBag();
|
||||
|
||||
var ends = offset + length;
|
||||
while (offset < ends)
|
||||
{
|
||||
var index = data[offset++];
|
||||
var pt = resource.instance.template.getPropertyTemplateByIndex(index);
|
||||
|
||||
list.add(pt, null);
|
||||
|
||||
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
bagOfBags.add(Codec.parsePropertyValueArray(data, offset, cs, connection));
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
bagOfBags.seal();
|
||||
|
||||
bagOfBags.then(x =>
|
||||
{
|
||||
for(var i = 0; i < list.length; i++)
|
||||
list.values[i] = x[i];
|
||||
|
||||
reply.trigger(list);
|
||||
});
|
||||
|
||||
return reply;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compose resource history
|
||||
/// </summary>
|
||||
/// <param name="history">History</param>
|
||||
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
|
||||
/// <returns></returns>
|
||||
static composeHistory(history, connection, prependLength = false)
|
||||
{
|
||||
var rt = new BinaryList();
|
||||
|
||||
for (var i = 0; i < history.length; i++)
|
||||
rt.addUint8(history.keys[i].index).addUint8Array(Codec.composePropertyValueArray(history.values[i], connection, true));
|
||||
|
||||
if (prependLength)
|
||||
rt.addUint32(rt.length, 0);
|
||||
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an array of ProperyValue.
|
||||
/// </summary>
|
||||
/// <param name="data">Array of bytes.</param>
|
||||
/// <param name="offset">Zero-indexed offset.</param>
|
||||
/// <param name="length">Number of bytes to parse.</param>
|
||||
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
|
||||
/// <returns></returns>
|
||||
static parsePropertyValueArray(data, offset, length, connection)
|
||||
{
|
||||
var rt = new AsyncBag();
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
var cs = {};
|
||||
|
||||
rt.add(Codec.parsePropertyValue(data, offset, cs, connection));
|
||||
|
||||
if (cs.size > 0)
|
||||
{
|
||||
offset += cs.size;
|
||||
length -= cs.size;
|
||||
}
|
||||
else
|
||||
throw new Exception("Error while parsing ValueInfo structured data");
|
||||
}
|
||||
|
||||
rt.seal();
|
||||
return rt;
|
||||
}
|
||||
|
||||
static parseStructure(data, offset, contentLength, connection, metadata = null, keys = null, types = null)
|
||||
{
|
||||
var reply = new AsyncReply();
|
||||
var bag = new AsyncBag();
|
||||
|
||||
|
||||
var keylist = [];
|
||||
var typelist = [];
|
||||
|
||||
|
||||
if (keys == null) {
|
||||
while (contentLength > 0) {
|
||||
@ -249,11 +486,12 @@ class Codec {
|
||||
|
||||
var rt = {};
|
||||
bag.add(Codec.parse(data, offset, rt, connection));
|
||||
contentLength -= rt.size + 1;
|
||||
offset += rt.size + 1;
|
||||
contentLength -= rt.size;
|
||||
offset += rt.size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
keylist.push(keys[i]);
|
||||
typelist.push(types[i]);
|
||||
@ -279,7 +517,12 @@ class Codec {
|
||||
reply.trigger(s);
|
||||
});
|
||||
|
||||
|
||||
if (metadata != null)
|
||||
{
|
||||
metadata.keys = keylist;
|
||||
metadata.types = typelist;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
@ -308,6 +551,11 @@ class Codec {
|
||||
|
||||
static compose(value, connection, prependType = true) {
|
||||
|
||||
if (value instanceof Function)
|
||||
value = value(connection);
|
||||
else if (value instanceof DistributedPropertyContext)
|
||||
value = value.method(this);
|
||||
|
||||
var type = Codec.getDataType(value, connection);
|
||||
var rt = new BinaryList();
|
||||
|
||||
@ -322,7 +570,7 @@ class Codec {
|
||||
break;
|
||||
|
||||
case DataType.Resource:
|
||||
rt.addUint32(value.instance.id);
|
||||
rt.addUint32(value._p.instanceId);
|
||||
break;
|
||||
|
||||
case DataType.DistributedResource:
|
||||
@ -462,7 +710,7 @@ class Codec {
|
||||
|
||||
static isLocalResource(resource, connection) {
|
||||
if (resource instanceof DistributedResource)
|
||||
if (resource.connection == connection)
|
||||
if (resource._p.connection == connection)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -477,58 +725,47 @@ static isLocalResource(resource, connection) {
|
||||
}
|
||||
|
||||
static compareResource(previous, next, connection) {
|
||||
|
||||
if (next == null)
|
||||
return ResourceComparisonResult.Null;
|
||||
|
||||
if (next == previous)
|
||||
else if (next == previous)
|
||||
return ResourceComparisonResult.Same;
|
||||
|
||||
if (Codec.isLocalResource(next, connection))
|
||||
else if (Codec.isLocalResource(next, connection))
|
||||
return ResourceComparisonResult.Local;
|
||||
|
||||
if (previous == null)
|
||||
else
|
||||
return ResourceComparisonResult.Distributed;
|
||||
|
||||
if (previous.instance.template.classId.valueOf() == next.instance.template.classId.valueOf())
|
||||
return ResourceComparisonResult.DistributedSameClass;
|
||||
|
||||
return ResourceComparisonResult.Distributed;
|
||||
}
|
||||
|
||||
static composeResourceArray(resources, connection, prependLength = false) {
|
||||
if (resources == null || resources.length == 0 || !(resources instanceof ResourceArray))
|
||||
return new DC(0);
|
||||
|
||||
var rt = new BinaryList();
|
||||
var comparsion = Codec.compareResource(null, resources[0], connection);
|
||||
if (resources == null || resources.length == 0)// || !(resources instanceof ResourceArray))
|
||||
return prependLength ? new DC(4) : new DC(0);
|
||||
|
||||
rt.addUint8(comparsion);
|
||||
var rt = new BinaryList();
|
||||
var comparsion = Codec.compareResource(null, resources[0], connection);
|
||||
|
||||
if (comparsion == ResourceComparisonResult.Local)
|
||||
rt.addUint32(resources[0].id);
|
||||
else if (comparsion == ResourceComparisonResult.Distributed) {
|
||||
rt.addUint8Array(resources[0].instance.template.classId.value);
|
||||
rt.addUint32(resources[0].instance.id);
|
||||
}
|
||||
rt.addUint8(comparsion);
|
||||
|
||||
for (var i = 1; i < resources.length; i++) {
|
||||
comparsion = Codec.compareResource(resources[i - 1], resources[i], connection);
|
||||
rt.addUint8(comparsion);
|
||||
if (comparsion == ResourceComparisonResult.Local)
|
||||
rt.addUint32(resources[0].id);
|
||||
else if (comparsion == ResourceComparisonResult.Distributed) {
|
||||
rt.addUint8Array(resources[0].instance.template.classId.value);
|
||||
rt.addUint32(resources[0].instance.id);
|
||||
}
|
||||
else if (comparsion == ResourceComparisonResult.DistributedSameClass) {
|
||||
rt.addUint32(resources[0].instance.id);
|
||||
}
|
||||
}
|
||||
if (comparsion == ResourceComparisonResult.Local)
|
||||
rt.addUint32(resources[0]._p.instanceId);
|
||||
else if (comparsion == ResourceComparisonResult.Distributed)
|
||||
rt.addUint32(resources[0].instance.id);
|
||||
|
||||
if (prependLength)
|
||||
rt.addUint32(0, rt.length);
|
||||
for (var i = 1; i < resources.Length; i++)
|
||||
{
|
||||
comparsion = Codec.compareResource(resources[i - 1], resources[i], connection);
|
||||
rt.addUint8(comparsion);
|
||||
if (comparsion == ResourceComparisonResult.Local)
|
||||
rt.addUint32(resources[i]._p.instanceId);
|
||||
else if (comparsion == ResourceComparisonResult.Distributed)
|
||||
rt.addUint32(resources[i].instance.id);
|
||||
}
|
||||
|
||||
return rt.toArray();
|
||||
if (prependLength)
|
||||
rt.addUint32(rt.length, 0);
|
||||
|
||||
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
|
||||
@ -619,4 +856,83 @@ static getDataType(value) {
|
||||
return DataType.Void;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse an array of structures
|
||||
/// </summary>
|
||||
/// <param name="data">Bytes array</param>
|
||||
/// <param name="offset">Zero-indexed offset</param>
|
||||
/// <param name="length">Number of bytes to parse</param>
|
||||
/// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end</param>
|
||||
/// <returns>Array of structures</returns>
|
||||
static parseStructureArray(data, offset, length, connection)
|
||||
{
|
||||
var reply = new AsyncBag();
|
||||
if (length == 0)
|
||||
{
|
||||
reply.seal();
|
||||
return reply;
|
||||
}
|
||||
|
||||
var end = offset + length;
|
||||
|
||||
var result = data[offset++];
|
||||
|
||||
var previous = null;
|
||||
//var previousKeys = [];
|
||||
//var previousTypes = [];
|
||||
|
||||
var metadata = {keys: null, types: null};
|
||||
|
||||
|
||||
if (result == StructureComparisonResult.Null)
|
||||
previous = new AsyncReply(null);
|
||||
else if (result == StructureComparisonResult.Structure)
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
previous = this.parseStructure(data, offset, cs, connection, metadata);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
reply.add(previous);
|
||||
|
||||
|
||||
while (offset < end)
|
||||
{
|
||||
result = data[offset++];
|
||||
|
||||
if (result == StructureComparisonResult.Null)
|
||||
previous = new AsyncReply(null);
|
||||
else if (result == StructureComparisonResult.Structure)
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
previous = this.parseStructure(data, offset, cs, connection, metadata);
|
||||
offset += cs;
|
||||
}
|
||||
else if (result == StructureComparisonResult.StructureSameKeys)
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
previous = this.parseStructure(data, offset, cs, connection, metadata, metadata.keys);
|
||||
offset += cs;
|
||||
}
|
||||
else if (result == StructureComparisonResult.StructureSameTypes)
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
previous = this.parseStructure(data, offset, cs, connection, metadata, metadata.keys, metadata.types);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
reply.add(previous);
|
||||
}
|
||||
|
||||
reply.seal();
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
}
|
37
src/CustomResourceEvent.js
Normal file
37
src/CustomResourceEvent.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 10/11/2018.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class CustomResourceEvent
|
||||
{
|
||||
constructor(issuer, receivers, params)
|
||||
{
|
||||
this.issuer = issuer;
|
||||
this.receivers = receivers;
|
||||
this.params = params;
|
||||
}
|
||||
}
|
@ -24,8 +24,10 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
var UNIX_EPOCH = 621355968000000000;
|
||||
var TWO_PWR_32 = (1 << 16) * (1 << 16);
|
||||
"use strict";
|
||||
|
||||
const UNIX_EPOCH = 621355968000000000;
|
||||
const TWO_PWR_32 = (1 << 16) * (1 << 16);
|
||||
|
||||
class DC extends Uint8Array// extends DataView // Data Converter
|
||||
{
|
||||
@ -155,7 +157,17 @@ class DC extends Uint8Array// extends DataView // Data Converter
|
||||
return new DC(rt);
|
||||
}
|
||||
|
||||
static stringArrayToBytes(values)
|
||||
{
|
||||
var list = new BinaryList();
|
||||
for(var i = 0; i < values.length; i++)
|
||||
{
|
||||
var s = DC.stringToBytes(values[i]);
|
||||
list.addUint32(s.length).addUint8Array(s);
|
||||
}
|
||||
|
||||
return list.toArray();
|
||||
}
|
||||
|
||||
append(src, offset, length)
|
||||
{
|
||||
@ -438,7 +450,7 @@ class DC extends Uint8Array// extends DataView // Data Converter
|
||||
getDateTime(offset)
|
||||
{
|
||||
var ticks = this.getUint64(offset);
|
||||
return new Date(Math.round((ticks-DCStatic.UNIX_EPOCH)/10000));
|
||||
return new Date(Math.round((ticks-UNIX_EPOCH)/10000));
|
||||
}
|
||||
|
||||
getDateTimeArray(offset)
|
||||
@ -451,7 +463,7 @@ class DC extends Uint8Array// extends DataView // Data Converter
|
||||
|
||||
getGuid(offset)
|
||||
{
|
||||
return new Guid(this.getUint8Array(offset, 16));
|
||||
return new Guid(this.clip(offset, 16));
|
||||
|
||||
/*
|
||||
var d = this.getUint8Array(offset, 16);
|
||||
|
@ -23,7 +23,11 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
DataType = {
|
||||
|
||||
"use strict";
|
||||
|
||||
const DataType =
|
||||
{
|
||||
Void: 0x0,
|
||||
//Variant,
|
||||
Bool: 1,
|
||||
|
File diff suppressed because it is too large
Load Diff
43
src/DistributedPropertyContext.js
Normal file
43
src/DistributedPropertyContext.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 27/10/2018.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class DistributedPropertyContext
|
||||
{
|
||||
constructor(p1, p2)
|
||||
{
|
||||
if(arguments.length == 1)
|
||||
{
|
||||
this.method = p1;
|
||||
}
|
||||
else if (arguments.length == 2)
|
||||
{
|
||||
this.connection = p1;
|
||||
this.value = p2;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,18 +24,17 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class DistributedResource extends IResource
|
||||
{
|
||||
destroy()
|
||||
{
|
||||
this.destroyed = true;
|
||||
this._emit("destroy");
|
||||
this._emit("destroy", this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
constructor(connection, template, instanceId, age)
|
||||
constructor(connection, instanceId, age, link)
|
||||
{
|
||||
super();
|
||||
|
||||
@ -44,20 +43,38 @@ class DistributedResource extends IResource
|
||||
connection: connection,
|
||||
instanceId: instanceId,
|
||||
age: age,
|
||||
template: template
|
||||
link: link,
|
||||
properties: []
|
||||
};
|
||||
}
|
||||
|
||||
_serialize()
|
||||
{
|
||||
var props = [];
|
||||
|
||||
for (var i = 0; i < this._p.properties.length; i++)
|
||||
props.push(new PropertyValue(this._p.properties[i],
|
||||
this.instance.getAge(i),
|
||||
this.instance.getModificationDate(i)));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
_attached(properties)
|
||||
{
|
||||
|
||||
if (this._isAttached)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
this._p.properties = properties;
|
||||
this._p.ages = new Uint32Array(properties.length);
|
||||
//this.events = [];//new [this.template.events.length];
|
||||
{
|
||||
for(var i = 0; i < properties.length; i++)
|
||||
{
|
||||
this.instance.setAge(i, properties[i].age);
|
||||
this.instance.setModificationDate(i, properties[i].date);
|
||||
this._p.properties.push(properties[i].value);
|
||||
}
|
||||
|
||||
|
||||
this._p.isAttached = true;
|
||||
|
||||
var self = this;
|
||||
@ -83,15 +100,15 @@ class DistributedResource extends IResource
|
||||
};
|
||||
};
|
||||
|
||||
for(var i = 0; i < this._p.template.functions.length; i++)
|
||||
for(var i = 0; i < this.instance.template.functions.length; i++)
|
||||
{
|
||||
var ft = this._p.template.functions[i];
|
||||
var ft = this.instance.template.functions[i];
|
||||
this[ft.name] = makeFunc(ft.index);
|
||||
}
|
||||
|
||||
for(var i = 0; i < this._p.template.properties.length; i++)
|
||||
for(var i = 0; i < this.instance.template.properties.length; i++)
|
||||
{
|
||||
var pt = this._p.template.properties[i];
|
||||
var pt = this.instance.template.properties[i];
|
||||
|
||||
Object.defineProperty(this, pt.name, {
|
||||
get: makeGetter(pt.index),
|
||||
@ -107,18 +124,21 @@ class DistributedResource extends IResource
|
||||
|
||||
_emitEventByIndex(index, args)
|
||||
{
|
||||
var et = this._p.template.getEventTemplateByIndex(index);
|
||||
this._emit(et.name, args);
|
||||
this.instance.emitResourceEvent(et.name, null, args);
|
||||
var et = this.instance.template.getEventTemplateByIndex(index);
|
||||
this._emitArgs(et.name, args);
|
||||
this.instance._emitResourceEvent(null, null, et.name, args);
|
||||
}
|
||||
|
||||
_invoke(index, args) {
|
||||
if (this.destroyed)
|
||||
throw new Exception("Trying to access destroyed object");
|
||||
|
||||
if (index >= this._p.template.functions.length)
|
||||
if (index >= this.instance.template.functions.length)
|
||||
throw new Exception("Function index is incorrect");
|
||||
|
||||
return this._p.connection.sendInvoke(this._p.instanceId, index, args);
|
||||
|
||||
/*
|
||||
var reply = new AsyncReply();
|
||||
|
||||
var parameters = Codec.composeVarArray(args, this._p.connection, true);
|
||||
@ -135,7 +155,7 @@ class DistributedResource extends IResource
|
||||
|
||||
|
||||
return reply;
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -147,12 +167,11 @@ class DistributedResource extends IResource
|
||||
}
|
||||
|
||||
|
||||
|
||||
_updatePropertyByIndex(index, value)
|
||||
{
|
||||
var pt = this._p.template.getPropertyTemplateByIndex(index);
|
||||
var pt = this.instance.template.getPropertyTemplateByIndex(index);
|
||||
this._p.properties[index] = value;
|
||||
this.instance.modified(pt.name, value);
|
||||
this.instance.emitModification(pt, value);
|
||||
}
|
||||
|
||||
_set(index, value)
|
||||
@ -165,15 +184,15 @@ class DistributedResource extends IResource
|
||||
var parameters = Codec.compose(value, this._p.connection);
|
||||
var self = this;
|
||||
|
||||
this._p.connection.sendRequest(IIPPacketAction.SetProperty,
|
||||
BL().addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters))
|
||||
this._p.connection.sendRequest(IIPPacketAction.SetProperty)
|
||||
.addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters)
|
||||
.done()
|
||||
.then(function(res)
|
||||
{
|
||||
// not really needed, server will always send property modified, this only happens if the programmer forgot to emit in property setter
|
||||
//Update(index, value);
|
||||
self._p.properties[index] = value;
|
||||
reply.trigger(null);
|
||||
// nothing to do here
|
||||
});
|
||||
});
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
@ -23,7 +23,10 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
var DistributedResourceQueueItemType =
|
||||
|
||||
"use strict";
|
||||
|
||||
const DistributedResourceQueueItemType =
|
||||
{
|
||||
Propery: 0,
|
||||
Event: 1
|
||||
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 24/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class EventTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 27/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class FunctionTemplate extends MemberTemplate {
|
||||
compose() {
|
||||
var name = super.compose();
|
||||
@ -32,12 +34,12 @@ class FunctionTemplate extends MemberTemplate {
|
||||
if (this.expansion != null) {
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
|
||||
return rt.addUint8(0x10 | (IsVoid ? 0x8 : 0x0))
|
||||
return rt.addUint8(0x10 | (this.isVoid ? 0x8 : 0x0))
|
||||
.addUint32(exp.length).addUint8Array(exp)
|
||||
.addUint8(name.length).addUint8Array(name).toArray();
|
||||
}
|
||||
else
|
||||
return rt.addUint8(IsVoid ? 0x8 : 0x0).addUint8(name.length).addUint8Array(name).toArray();
|
||||
return rt.addUint8(this.isVoid ? 0x8 : 0x0).addUint8(name.length).addUint8Array(name).toArray();
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,9 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 02/09/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class Guid
|
||||
{
|
||||
constructor(dc)
|
||||
|
@ -23,6 +23,9 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 31/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class IDestructible extends IEventHandler
|
||||
{
|
||||
destroy()
|
||||
|
@ -23,6 +23,7 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 30/08/2017.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
class IEventHandler
|
||||
{
|
||||
@ -42,19 +43,32 @@ class IEventHandler
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
if (this._events[event])
|
||||
for(var i = 0; i < this._events[event].length; i++)
|
||||
if (this._events[event][i].apply(this, args))
|
||||
if (this._events[event][i].f.apply(this._events[event][i].i, args))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
on(event, fn)
|
||||
_emitArgs(event, args)
|
||||
{
|
||||
event = event.toLowerCase();
|
||||
if (this._events[event])
|
||||
for(var i = 0; i < this._events[event].length; i++)
|
||||
if (this._events[event][i].f.apply(this._events[event][i].i, args))
|
||||
return true;
|
||||
return this;
|
||||
}
|
||||
|
||||
on(event, fn, issuer)
|
||||
{
|
||||
if (!(fn instanceof Function))
|
||||
return this;
|
||||
|
||||
event = event.toLowerCase();
|
||||
// add
|
||||
if (!this._events[event])
|
||||
this._events[event] = [];
|
||||
this._events[event].push(fn);
|
||||
this._events[event].push({f: fn, i: issuer == null ? this: issuer});
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -65,9 +79,13 @@ class IEventHandler
|
||||
{
|
||||
if (fn)
|
||||
{
|
||||
var index = this._events[event].indexOf(fn);
|
||||
if (index > -1)
|
||||
this._events[event].splice(index, 1);
|
||||
for(var i = 0; i < this._events[event].length; i++)
|
||||
if (this._events[event][i].f == fn)
|
||||
this._events[event].splice(i--, 1);
|
||||
|
||||
//var index = this._events[event].indexOf(fn);
|
||||
//if (index > -1)
|
||||
//this._events[event].splice(index, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -23,7 +23,10 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
var IIPAuthPacketCommand =
|
||||
|
||||
"use strict";
|
||||
|
||||
const IIPAuthPacketCommand =
|
||||
{
|
||||
Action: 0,
|
||||
Declare: 1,
|
||||
@ -31,7 +34,7 @@ var IIPAuthPacketCommand =
|
||||
Error: 3
|
||||
};
|
||||
|
||||
var IIPAuthPacketAction =
|
||||
const IIPAuthPacketAction =
|
||||
{
|
||||
// Authenticate
|
||||
AuthenticateHash: 0,
|
||||
@ -41,7 +44,7 @@ var IIPAuthPacketAction =
|
||||
};
|
||||
|
||||
|
||||
var IIPAuthPacketMethod =
|
||||
const IIPAuthPacketMethod =
|
||||
{
|
||||
None: 0,
|
||||
Certificate: 1,
|
||||
|
346
src/IIPPacket.js
346
src/IIPPacket.js
@ -24,27 +24,43 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var IIPPacketCommand =
|
||||
const IIPPacketCommand =
|
||||
{
|
||||
Event: 0,
|
||||
Request: 1,
|
||||
Reply: 2,
|
||||
Error: 3
|
||||
Report: 3
|
||||
};
|
||||
|
||||
var IIPPacketEvent =
|
||||
const IIPPacketReport =
|
||||
{
|
||||
ManagementError: 0,
|
||||
ExecutionError: 1,
|
||||
ProgressReport: 0x8,
|
||||
ChunkStream: 0x9
|
||||
};
|
||||
|
||||
const IIPPacketEvent =
|
||||
{
|
||||
// Event Manage
|
||||
ResourceReassigned : 0,
|
||||
ResourceDestroyed: 1,
|
||||
ChildAdded: 2,
|
||||
ChildRemoved: 3,
|
||||
Renamed: 4,
|
||||
|
||||
// Event Invoke
|
||||
PropertyUpdated : 0x10,
|
||||
EventOccured: 0x11
|
||||
EventOccurred: 0x11,
|
||||
|
||||
// Attribute
|
||||
AttributesUpdated: 0x18
|
||||
|
||||
};
|
||||
|
||||
var IIPPacketAction =
|
||||
const IIPPacketAction =
|
||||
{
|
||||
// Request Manage
|
||||
AttachResource: 0,
|
||||
@ -52,25 +68,35 @@ var IIPPacketAction =
|
||||
DetachResource: 2,
|
||||
CreateResource: 3,
|
||||
DeleteResource: 4,
|
||||
AddChild: 5,
|
||||
RemoveChild: 6,
|
||||
RenameResource: 7,
|
||||
|
||||
// Request Inquire
|
||||
TemplateFromClassName: 0x8,
|
||||
TemplateFromClassId: 0x9,
|
||||
TemplateFromResourceLink: 0xA,
|
||||
TemplateFromResourceId: 0xB,
|
||||
ResourceIdFromResourceLink: 0xC,
|
||||
TemplateFromClassName: 8,
|
||||
TemplateFromClassId: 9,
|
||||
TemplateFromResourceId: 10,
|
||||
QueryLink: 11,
|
||||
ResourceHistory: 12,
|
||||
ResourceChildren: 13,
|
||||
ResourceParents: 14,
|
||||
|
||||
// Request Invoke
|
||||
InvokeFunction: 0x10,
|
||||
GetProperty: 0x11,
|
||||
GetPropertyIfModified: 0x12,
|
||||
SetProperty: 0x13
|
||||
InvokeFunction: 16,
|
||||
GetProperty: 17,
|
||||
GetPropertyIfModified: 18,
|
||||
SetProperty: 19,
|
||||
|
||||
// Request Attribute
|
||||
GetAllAttributes: 24,
|
||||
UpdateAllAttributes: 25,
|
||||
ClearAllAttributes: 26,
|
||||
GetAttributes: 27,
|
||||
UpdateAttributes: 28,
|
||||
ClearAttributes: 29
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class IIPPacket
|
||||
{
|
||||
constructor()
|
||||
@ -91,13 +117,14 @@ class IIPPacket
|
||||
this.methodName = "";
|
||||
this.callbackId = 0;
|
||||
this.dataLengthNeeded = 0;
|
||||
this.originalOffset = 0;
|
||||
}
|
||||
|
||||
notEnough(offset, ends, needed)
|
||||
{
|
||||
if (offset + needed > ends)
|
||||
{
|
||||
this.dataLengthNeeded = needed - (ends - offset);
|
||||
this.dataLengthNeeded = needed - (ends - this.originalOffset);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -106,7 +133,7 @@ class IIPPacket
|
||||
|
||||
parse(data, offset, ends)
|
||||
{
|
||||
var oOffset = offset;
|
||||
this.originalOffset = offset;
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
@ -123,6 +150,16 @@ class IIPPacket
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Report)
|
||||
{
|
||||
this.report = (data.getUint8(offset++) & 0x3f);
|
||||
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.callbackId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.action = (data.getUint8(offset++) & 0x3f);
|
||||
@ -149,6 +186,30 @@ class IIPPacket
|
||||
{
|
||||
// nothing to parse
|
||||
}
|
||||
else if (this.event == IIPPacketEvent.ChildAdded
|
||||
|| this.event == IIPPacketEvent.ChildRemoved)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.childId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if(this.event == IIPPacketEvent.Renamed)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.content = data.clip(offset, cl);
|
||||
|
||||
offset += cl;
|
||||
}
|
||||
else if (this.event == IIPPacketEvent.PropertyUpdated)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
@ -182,7 +243,7 @@ class IIPPacket
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
else if (this.event == IIPPacketEvent.EventOccured)
|
||||
else if (this.event == IIPPacketEvent.EventOccurred)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 5))
|
||||
return -this.dataLengthNeeded;
|
||||
@ -195,6 +256,22 @@ class IIPPacket
|
||||
this.content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
// Attribute
|
||||
else if (this.event == IIPPacketEvent.AttributesUpdated)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.content = data.clip(offset, cl);
|
||||
|
||||
offset += cl;
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Request)
|
||||
{
|
||||
@ -208,14 +285,14 @@ class IIPPacket
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ReattachResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 8))
|
||||
if (this.notEnough(offset, ends, 12))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
this.resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
@ -228,16 +305,21 @@ class IIPPacket
|
||||
}
|
||||
else if (this.action == IIPPacketAction.CreateResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
if (this.notEnough(offset, ends, 12))
|
||||
return -dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint8(offset++);
|
||||
this.storeId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
return -dataLengthNeeded;
|
||||
|
||||
this.className = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
this.content = data.clip(offset, cl);
|
||||
}
|
||||
else if (this.action == IIPPacketAction.DeleteResource)
|
||||
{
|
||||
@ -247,6 +329,37 @@ class IIPPacket
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.AddChild
|
||||
|| this.action == IIPPacketAction.RemoveChild)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 8))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.childId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.RenameResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 6))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromClassName)
|
||||
{
|
||||
@ -270,20 +383,6 @@ class IIPPacket
|
||||
this.classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromResourceLink)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceLink = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromResourceId)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
@ -292,7 +391,7 @@ class IIPPacket
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ResourceIdFromResourceLink)
|
||||
else if (this.action == IIPPacketAction.QueryLink)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
@ -306,6 +405,30 @@ class IIPPacket
|
||||
this.resourceLink = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ResourceChildren
|
||||
|| this.action == IIPPacketAction.ResourceParents)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ResourceHistory)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 20))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.fromDate = data.getDateTime(offset);
|
||||
offset += 8;
|
||||
|
||||
this.toDate = data.getDateTime(offset);
|
||||
offset += 8;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.InvokeFunction)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 9))
|
||||
@ -347,8 +470,8 @@ class IIPPacket
|
||||
|
||||
this.methodIndex = data[offset++];
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
this.resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.SetProperty)
|
||||
@ -388,6 +511,28 @@ class IIPPacket
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
// Attribute
|
||||
else if (this.action == IIPPacketAction.UpdateAllAttributes
|
||||
|| this.action == IIPPacketAction.GetAttributes
|
||||
|| this.action == IIPPacketAction.UpdateAttributes
|
||||
|| this.action == IIPPacketAction.ClearAttributes)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 8))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Reply)
|
||||
{
|
||||
@ -400,8 +545,8 @@ class IIPPacket
|
||||
this.classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
this.resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset+=2;
|
||||
@ -433,9 +578,6 @@ class IIPPacket
|
||||
if (this.notEnough(offset, ends, 20))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.classId = data.GetGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
@ -446,8 +588,14 @@ class IIPPacket
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromClassName
|
||||
|| this.action == IIPPacketAction.TemplateFromClassId
|
||||
|| this.action == IIPPacketAction.TemplateFromResourceLink
|
||||
|| this.action == IIPPacketAction.TemplateFromResourceId)
|
||||
|| this.action == IIPPacketAction.TemplateFromResourceId
|
||||
|| this.action == IIPPacketAction.QueryLink
|
||||
|| this.action == IIPPacketAction.ResourceChildren
|
||||
|| this.action == IIPPacketAction.ResourceParents
|
||||
|| this.action == IIPPacketAction.ResourceHistory
|
||||
// Attribute
|
||||
|| this.action == IIPPacketAction.GetAllAttributes
|
||||
|| this.action == IIPPacketAction.GetAttributes)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
@ -461,20 +609,6 @@ class IIPPacket
|
||||
this.content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ResourceIdFromResourceLink)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 24))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.InvokeFunction
|
||||
|| this.action == IIPPacketAction.GetProperty
|
||||
|| this.action == IIPPacketAction.GetPropertyIfModified)
|
||||
@ -513,32 +647,76 @@ class IIPPacket
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Error)
|
||||
else if (this.command == IIPPacketCommand.Report)
|
||||
{
|
||||
// Error
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
if (this.report == IIPPacketReport.ManagementError)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.callbackId = data.getUint32(offset);
|
||||
this.errorCode = data.getUint16(offset);
|
||||
offset += 2;
|
||||
}
|
||||
else if (this.report == IIPPacketReport.ExecutionError)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
this.errorCode = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
this.errorCode = data.getUint8(offset++);
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
this.errorMessage = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (this.report == IIPPacketReport.ProgressReport)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 8))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.errorMessage = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
this.progressValue = data.getInt32(offset);
|
||||
offset += 4;
|
||||
this.progressMax = data.getInt32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.report == IIPPacketReport.ChunkStream)
|
||||
{
|
||||
var dt = data.getUint8(offset++);
|
||||
var size = DataType.sizeOf(dt);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.content = data.clip(offset - 5, cl + 5);
|
||||
offset += cl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.notEnough(offset, ends, size))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.content = data.clip(offset - 1, size + 1);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset - oOffset;
|
||||
return offset - this.originalOffset;
|
||||
}
|
||||
}
|
77
src/IPermissionsManager.js
Normal file
77
src/IPermissionsManager.js
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 16/11/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ActionType =
|
||||
{
|
||||
Attach: 0,
|
||||
Delete: 1,
|
||||
Execute: 2,
|
||||
GetProperty: 3,
|
||||
SetProperty: 4,
|
||||
CreateResource: 5,
|
||||
UpdateAttributes: 6,
|
||||
InquireAttributes: 7,
|
||||
AddParent: 8,
|
||||
RemoveParent: 9,
|
||||
AddChild: 10,
|
||||
RemoveChild: 11,
|
||||
Rename: 12,
|
||||
ReceiveEvent: 13
|
||||
};
|
||||
|
||||
const Ruling = {
|
||||
Denied: 0,
|
||||
Allowed: 1,
|
||||
DontCare: 2,
|
||||
};
|
||||
|
||||
class IPermissionsManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Check for permission.
|
||||
/// </summary>
|
||||
/// <param name="resource">IResource.</param>
|
||||
/// <param name="session">Caller sessions.</param>
|
||||
/// <param name="action">Action type</param>
|
||||
/// <param name="member">Function or property to check for permission.</param>
|
||||
/// <returns>Allowed or denined.</returns>
|
||||
applicable(resource, session, action, member, inquirer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
initialize(settings, resource)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
get settings()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -24,7 +24,9 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
var ResourceTrigger =
|
||||
"use strict";
|
||||
|
||||
const ResourceTrigger =
|
||||
{
|
||||
Loaded : 0,
|
||||
Initialize: 1,
|
||||
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class IStore extends IResource {
|
||||
get(path) {
|
||||
|
||||
@ -37,6 +39,21 @@ class IStore extends IResource {
|
||||
|
||||
}
|
||||
|
||||
record(resource, propertyName, value, age, dateTime)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
getRecord(resource, fromDate, toDate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
remove(resource)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
|
265
src/Instance.js
265
src/Instance.js
@ -23,22 +23,77 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 29/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class Instance extends IEventHandler
|
||||
{
|
||||
|
||||
getAge(index)
|
||||
{
|
||||
if (index < this.ages.Count)
|
||||
if (index < this.ages.length)
|
||||
return this.ages[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
setAge(index, value)
|
||||
{
|
||||
if (index < this.ages.length)
|
||||
{
|
||||
this.ages[index] = value;
|
||||
if (value > this.instanceAge)
|
||||
this.instanceAge = value;
|
||||
}
|
||||
}
|
||||
|
||||
getModificationDate(index)
|
||||
{
|
||||
if (index < this.modificationDates.length)
|
||||
return this.modificationDates[index];
|
||||
else
|
||||
return new Date(0);
|
||||
}
|
||||
|
||||
setModificationDate(index, value)
|
||||
{
|
||||
if (index < this.modificationDates.length)
|
||||
{
|
||||
this.modificationDates[index] = value;
|
||||
|
||||
if (value > this.instanceModificationDate)
|
||||
this.instanceModificationDate = value;
|
||||
}
|
||||
}
|
||||
|
||||
loadProperty(name, age, modificationDate, value)
|
||||
{
|
||||
var pt = this.template.getPropertyTemplateByName(name);
|
||||
|
||||
if (pt == null)
|
||||
return false;
|
||||
|
||||
this.resource[name] = value;
|
||||
|
||||
this.setAge(pt.index, age);
|
||||
this.setModificationDate(pt.index, modificationDate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
deserialize(properties)
|
||||
{
|
||||
for(var i = 0; i < this.template.properties.length; i++)
|
||||
this.resource[this.template.properties[i].name] = properties[i];
|
||||
|
||||
for (var i = 0; i < properties.length; i++)
|
||||
{
|
||||
var pt = this.template.GetPropertyTemplateByIndex(i);
|
||||
if (pt != null)
|
||||
{
|
||||
var pv = properties[i];
|
||||
this.loadProperty(pt.name, pv.age, pv.date, pv.value);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -47,8 +102,10 @@ class Instance extends IEventHandler
|
||||
var props = [];
|
||||
|
||||
for (var i = 0; i < this.template.properties.length; i++)
|
||||
props.push(this.resource[this.template.properties[i].name]);
|
||||
|
||||
props.push(new PropertyValue(this.resource[this.template.properties[i].name],
|
||||
this.ages[this.template.properties[i].index],
|
||||
this.modificationDates[this.template.properties[i].index]));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
@ -57,25 +114,38 @@ class Instance extends IEventHandler
|
||||
return resource instanceof Storable;
|
||||
}
|
||||
|
||||
emitModification(pt, value)
|
||||
{
|
||||
this.instanceAge++;
|
||||
|
||||
modified(propertyName = null, newValue = null, oldValue = null)
|
||||
var now = new Date();
|
||||
|
||||
this.ages[pt.index] = this.instanceAge;
|
||||
this.modificationDates[pt.index] = now;
|
||||
|
||||
if (pt.recordable)
|
||||
this.store.record(this.resource, pt.name, value, this.ages[pt.index], now);
|
||||
|
||||
super._emit("ResourceModified", this.resource, pt.name, value);
|
||||
this.resource._emit("modified", pt.name, value);
|
||||
}
|
||||
|
||||
modified(propertyName = null)
|
||||
{
|
||||
if (propertyName == null)
|
||||
propertyName = modified.caller.name;
|
||||
|
||||
if (newValue == null)
|
||||
var val = {};
|
||||
if (this.getPropertyValue(propertyName, val))
|
||||
{
|
||||
var val = {};
|
||||
if (this.getPropertyValue(propertyName, val))
|
||||
super._emit("ResourceModified", this.resource, propertyName, val.value, oldValue);
|
||||
var pt = this.template.getPropertyTemplateByName(propertyName);
|
||||
this.emitModification(pt, val.value)
|
||||
}
|
||||
else
|
||||
super._emit("ResourceModified", this.resource, propertyName, newValue, oldValue);
|
||||
}
|
||||
|
||||
emitResourceEvent(name, receivers, args)
|
||||
_emitResourceEvent(issuer, receivers, name, args)
|
||||
{
|
||||
super._emit("ResourceEventOccured", this.resource, name, receivers, args);
|
||||
super._emit("ResourceEventOccurred", this.resource, issuer, receivers, name, args);
|
||||
}
|
||||
|
||||
getPropertyValue(name, resultObject)
|
||||
@ -92,7 +162,7 @@ class Instance extends IEventHandler
|
||||
|
||||
|
||||
|
||||
constructor(id, name, resource, store)
|
||||
constructor(id, name, resource, store, customTemplate = null, age = 0)
|
||||
{
|
||||
super();
|
||||
|
||||
@ -101,8 +171,14 @@ class Instance extends IEventHandler
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
|
||||
this.instanceAge = age;
|
||||
this.instanceModificationDate = new Date(0);
|
||||
|
||||
this.children = new AutoList();
|
||||
this.parents = new AutoList();
|
||||
this.managers = new AutoList();
|
||||
|
||||
this.attributes = new KeyList();
|
||||
|
||||
var self = this;
|
||||
|
||||
@ -119,24 +195,157 @@ class Instance extends IEventHandler
|
||||
self._emit("ResourceDestroyed", sender);
|
||||
});
|
||||
|
||||
this.template = Warehouse.getTemplateByType(this.resource.constructor);
|
||||
if (customTemplate != null)
|
||||
this.template = customTemplate;
|
||||
else
|
||||
this.template = Warehouse.getTemplateByType(this.resource.constructor);
|
||||
|
||||
// set ages
|
||||
this.ages = new Uint32Array(this.template.properties.length);
|
||||
this.ages = [];
|
||||
this.modificationDates = [];
|
||||
|
||||
for(var i = 0; i < this.template.properties.length; i++)
|
||||
{
|
||||
this.ages.push(0);
|
||||
this.modificationDates.push(new Date(0));
|
||||
}
|
||||
|
||||
// connect events
|
||||
var makeHandler = function(name, receivers, args)
|
||||
{
|
||||
return new function(receivers, args)
|
||||
{
|
||||
self.emitResourceEvent(name, receivers, args);
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0; i < this.template.events.length; i++)
|
||||
this.resource.on(this.template.events[i].name, makeHandler(this.template.events[i].name));
|
||||
|
||||
this.resource.on(this.template.events[i].name, this._makeHandler(this.template.events[i].name));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
_makeHandler(name)
|
||||
{
|
||||
var self = this;
|
||||
return function(args)
|
||||
{
|
||||
if (args instanceof CustomResourceEvent)
|
||||
self._emitResourceEvent(args.issuer, args.receivers, name, args.params);
|
||||
else
|
||||
self._emitResourceEvent(null, null, name, args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check for permission.
|
||||
/// </summary>
|
||||
/// <param name="session">Caller sessions.</param>
|
||||
/// <param name="action">Action type</param>
|
||||
/// <param name="member">Function or property to check for permission.</param>
|
||||
/// <returns>Ruling.</returns>
|
||||
applicable(session, action, member, inquirer)
|
||||
{
|
||||
for (var i = 0; i < this.managers.length; i++)
|
||||
{
|
||||
var r = this.managers.item(i).applicable(this.resource, session, action, member, inquirer);
|
||||
if (r != Ruling.DontCare)
|
||||
return r;
|
||||
}
|
||||
|
||||
return Ruling.DontCare;
|
||||
}
|
||||
|
||||
|
||||
|
||||
removeAttributes(attributes = null)
|
||||
{
|
||||
if (attributes == null)
|
||||
this.attributes.clear();
|
||||
else
|
||||
{
|
||||
for(var i = 0; i < attributes.length; i++)
|
||||
this.attributes.remove(attributes[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getAttributes(attributes = null)
|
||||
{
|
||||
var st = new Structure();
|
||||
|
||||
if (attributes == null)
|
||||
{
|
||||
attributes = this.attributes.keys.slice(0);
|
||||
attributes.push("managers");
|
||||
}
|
||||
|
||||
for(var i = 0; i < attributes.length; i++)
|
||||
{
|
||||
var attr = attributes[i];
|
||||
|
||||
if (attr == "name")
|
||||
st["name"] = this.name;
|
||||
|
||||
else if (attr == "managers")
|
||||
{
|
||||
var mngrs = new StructureArray();
|
||||
|
||||
for(var j = 0; j < this.managers.length; j++)
|
||||
{
|
||||
var manager = this.managers.item(j);
|
||||
var sm = new Structure();
|
||||
sm["type"] = manager.constructor.name;
|
||||
sm["settings"] = manager.settings;
|
||||
|
||||
mngrs.push(sm);
|
||||
}
|
||||
|
||||
st["managers"] = mngrs;
|
||||
|
||||
}
|
||||
else
|
||||
st[attr] = this.attributes.item(attr);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
setAttributes(attributes, clearAttributes = false)
|
||||
{
|
||||
|
||||
if (clearAttributes)
|
||||
this.attributes.clear();
|
||||
|
||||
|
||||
for (var attr in attributes)
|
||||
if (attr == "name")
|
||||
this.name = attributes[attr];
|
||||
else if (attr == "managers")
|
||||
{
|
||||
this.managers.clear();
|
||||
|
||||
var mngrs = attributes[attr];
|
||||
|
||||
for (var i = 0; i < mngrs.length; i++)
|
||||
{
|
||||
var mngr = mngrs[i];
|
||||
|
||||
var type = window[mngr];
|
||||
|
||||
var settings = mngr["settings"];
|
||||
|
||||
var manager = new (Function.prototype.bind.apply(type));
|
||||
|
||||
if (manager instanceof IPermissionsManager)
|
||||
{
|
||||
manager.initialize(settings, this.resource);
|
||||
this.managers.add(manager);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.attributes.set(attr, attributes[attr]);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
115
src/KeyList.js
Normal file
115
src/KeyList.js
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 06/11/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class KeyList
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.keys = [];
|
||||
this.values = [];
|
||||
}
|
||||
|
||||
at(index)
|
||||
{
|
||||
return this.values[index];
|
||||
}
|
||||
|
||||
item(key)
|
||||
{
|
||||
for(var i = 0; i < this.keys.length; i++)
|
||||
if (this.keys[i] == key)
|
||||
return this.values[i];
|
||||
}
|
||||
|
||||
get(key)
|
||||
{
|
||||
for(var i = 0; i < this.keys.length; i++)
|
||||
if (this.keys[i] == key)
|
||||
return this.values[i];
|
||||
}
|
||||
|
||||
_item_destroyed(sender)
|
||||
{
|
||||
for(var i = 0; i < this.values.length; i++)
|
||||
if (sender == this.values[i])
|
||||
{
|
||||
this.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
add(key, value)
|
||||
{
|
||||
this.remove(key);
|
||||
|
||||
if (value instanceof IDestructible)
|
||||
value.on("destroy", this._item_destroyed, this);
|
||||
|
||||
this.keys.push(key);
|
||||
this.values.push(value);
|
||||
}
|
||||
|
||||
contains(key)
|
||||
{
|
||||
for(var i = 0; i < this.keys.length; i++)
|
||||
if (this.keys[i] == key)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
set(key, value)
|
||||
{
|
||||
this.remove(key);
|
||||
this.add(key, value);
|
||||
}
|
||||
|
||||
remove(key)
|
||||
{
|
||||
for(var i = 0; i < this.keys.length; i++)
|
||||
if (key == this.keys[i])
|
||||
{
|
||||
this.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
removeAt(index)
|
||||
{
|
||||
if (this.values[index] instanceof IDestructible)
|
||||
this.values[index].off("destroy", this._item_destroyed);
|
||||
|
||||
this.keys.splice(index, 1);
|
||||
this.values.splice(index, 1);
|
||||
}
|
||||
|
||||
get length()
|
||||
{
|
||||
return this.keys.length;
|
||||
}
|
||||
}
|
@ -24,8 +24,9 @@
|
||||
* Created by Ahmed Zamil on 24/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var MemberType = {
|
||||
const MemberType = {
|
||||
Function: 0,
|
||||
Property: 1,
|
||||
Event: 2
|
||||
|
75
src/MemoryStore.js
Normal file
75
src/MemoryStore.js
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 12/11/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class MemoryStore extends IStore
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.resources = [];
|
||||
}
|
||||
|
||||
put(resource)
|
||||
{
|
||||
this.resources[resource.instance.id] = resource;
|
||||
}
|
||||
|
||||
retrive(id)
|
||||
{
|
||||
if (this.resources[resource.instance.id])
|
||||
return new AsyncReply(this.resources[resource.instance.id]);
|
||||
else
|
||||
return new AsyncReply(null);
|
||||
}
|
||||
|
||||
get(resource)
|
||||
{
|
||||
return new AsyncReply(null);
|
||||
}
|
||||
|
||||
link(resource)
|
||||
{
|
||||
if (resource.instance.store == this)
|
||||
return this.instance.name + "/" + resource.instance.id;
|
||||
}
|
||||
|
||||
trigger(trigger)
|
||||
{
|
||||
return new AsyncReply(true);
|
||||
}
|
||||
|
||||
record(resource, propertyName, value, age, dateTime)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
getRecord(resource, fromDate, toDate)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 01/09/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class NetworkBuffer {
|
||||
constructor() {
|
||||
this.neededDataLength = 0;
|
||||
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 26/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class NotModified
|
||||
{
|
||||
|
||||
|
@ -24,13 +24,14 @@
|
||||
* Created by Ahmed Zamil on 27/08/2017.
|
||||
*/
|
||||
|
||||
var PropertyPermission = {
|
||||
"use strict";
|
||||
|
||||
const PropertyPermission = {
|
||||
Read: 1,
|
||||
Write: 2,
|
||||
ReadWrite: 3
|
||||
};
|
||||
|
||||
|
||||
class PropertyTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
@ -44,12 +45,13 @@ class PropertyTemplate extends MemberTemplate
|
||||
{
|
||||
var name = super.compose();
|
||||
var rt = new BinaryList();
|
||||
var pv = (this.permission >> 1) | (this.recordable ? 1 : 0);
|
||||
|
||||
if (this.writeExpansion != null && this.readExpansion != null)
|
||||
{
|
||||
var rexp = DC.stringToBytes(this.readExpansion);
|
||||
var wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return rt.addUint8(0x38 | this.permission)
|
||||
return rt.addUint8(0x38 | pv)
|
||||
.addUint32(wexp.length)
|
||||
.addUint8Array(wexp)
|
||||
.addUint32(rexp.length)
|
||||
@ -60,7 +62,7 @@ class PropertyTemplate extends MemberTemplate
|
||||
else if (this.writeExpansion != null)
|
||||
{
|
||||
var wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return rt.addUint8(0x30 | this.permission)
|
||||
return rt.addUint8(0x30 | pv)
|
||||
.addUint32(wexp.length)
|
||||
.addUint8Array(wexp)
|
||||
.addUint8(name.length)
|
||||
@ -69,14 +71,14 @@ class PropertyTemplate extends MemberTemplate
|
||||
else if (this.readExpansion != null)
|
||||
{
|
||||
var rexp = DC.stringToBytes(this.readExpansion);
|
||||
return rt.addUint8(0x28 | this.permission)
|
||||
return rt.addUint8(0x28 | pv)
|
||||
.addUint32(rexp.length)
|
||||
.addUint8Array(rexp)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name).toArray();
|
||||
}
|
||||
else
|
||||
return rt.addUint8(0x20 | this.permission)
|
||||
return rt.addUint8(0x20 | pv)
|
||||
.addUint32(name.length)
|
||||
.addUint8Array(name).toArray();
|
||||
}
|
||||
|
37
src/PropertyValue.js
Normal file
37
src/PropertyValue.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 06/11/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class PropertyValue
|
||||
{
|
||||
constructor(value, age, date)
|
||||
{
|
||||
this.value = value;
|
||||
this.age = age;
|
||||
this.date = date;
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 26/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class ResourceArray extends Array
|
||||
{
|
||||
push(value)
|
||||
|
@ -20,18 +20,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
class ResourceTemplate {
|
||||
"use strict";
|
||||
|
||||
getMemberTemplate(member) {
|
||||
if (member instanceof MethodInfo)
|
||||
return this.getFunctionTemplate(member.name);
|
||||
else if (member instanceof EventInfo)
|
||||
return this.getEventTemplate(member.name);
|
||||
else if (member instanceof PropertyInfo)
|
||||
return this.getPropertyTemplate(member.name);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
class ResourceTemplate {
|
||||
|
||||
getEventTemplateByName(eventName) {
|
||||
for (var i = 0; i < this.events.length; i++)
|
||||
@ -107,7 +98,7 @@ class ResourceTemplate {
|
||||
// set guid
|
||||
this.className = template.namespace + "." + type.prototype.constructor.name;
|
||||
|
||||
this.classId = (new DC(sha256.arrayBuffer(this.className))).getGuid(0);
|
||||
this.classId = SHA256.compute(DC.stringToBytes(this.className)).getGuid(0);
|
||||
|
||||
//byte currentIndex = 0;
|
||||
|
||||
@ -117,6 +108,7 @@ class ResourceTemplate {
|
||||
pt.index = i;
|
||||
pt.readExpansion = template.properties[i].read;
|
||||
pt.writeExpansion = template.properties[i].write;
|
||||
pt.recordable = template.properties[i].recordable;
|
||||
this.properties.push(pt);
|
||||
}
|
||||
|
||||
@ -224,6 +216,7 @@ class ResourceTemplate {
|
||||
pt.index = propertyIndex++;
|
||||
var readExpansion = ((data.getUint8(offset) & 0x8) == 0x8);
|
||||
var writeExpansion = ((data.getUint8(offset) & 0x10) == 0x10);
|
||||
pt.recordable = ((data.getUint8(offset) & 1) == 1);
|
||||
pt.permission = ((data.getUint8(offset++) >> 1) & 0x3);
|
||||
pt.name = data.getString(offset + 1, data.getUint8(offset));// Encoding.ASCII.getString(data, (int)offset + 1, data.getUint8(offset));
|
||||
offset += data.getUint8(offset) + 1;
|
||||
|
177
src/SHA256.js
Normal file
177
src/SHA256.js
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/12/2017.
|
||||
* Ref: https://en.wikipedia.org/wiki/SHA-2
|
||||
*/
|
||||
|
||||
class SHA256
|
||||
{
|
||||
|
||||
static RROT(n, d)
|
||||
{
|
||||
return (n >>> d)|(n << (32 - d));
|
||||
}
|
||||
|
||||
static compute(msg)
|
||||
{
|
||||
/*
|
||||
Note 1: All variables are 32 bit unsigned integers and addition is calculated modulo 2^32
|
||||
Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 ≤ i ≤ 63
|
||||
Note 3: The compression function uses 8 working variables, a through h
|
||||
Note 4: Big-endian convention is used when expressing the constants in this pseudocode,
|
||||
and when parsing message block data from bytes to words, for example,
|
||||
the first word of the input message "abc" after padding is 0x61626380
|
||||
*/
|
||||
|
||||
// Initialize hash values:
|
||||
// (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
|
||||
|
||||
const hash = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);
|
||||
|
||||
// Initialize array of round constants:
|
||||
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
|
||||
const k = new Uint32Array([
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]);
|
||||
|
||||
|
||||
|
||||
// Pre-processing:
|
||||
// begin with the original message of length L bits
|
||||
var L = msg.length * 8;
|
||||
|
||||
// append a single '1' bit
|
||||
// append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 64 is a multiple of 512
|
||||
|
||||
var K = 512 - ((L + 1 + 64) % 512);
|
||||
|
||||
if (K == 512)
|
||||
K = 0;
|
||||
|
||||
var paddingLength = (K + 1) / 8;
|
||||
var paddingBytes = new Uint8Array(paddingLength);
|
||||
paddingBytes[0] = 0x80;
|
||||
|
||||
var data = new DC(BL().addUint8Array(msg).addUint8Array(paddingBytes).addUint64(L).toArray());
|
||||
|
||||
|
||||
|
||||
// append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bits
|
||||
|
||||
// Process the message in successive 512-bit chunks:
|
||||
// break message into 512-bit chunks
|
||||
// for each chunk
|
||||
|
||||
for(var chunk = 0; chunk < data.length; chunk+=64)
|
||||
{
|
||||
// create a 64-entry message schedule array w[0..63] of 32-bit words
|
||||
// (The initial values in w[0..63] don't matter, so many implementations zero them here)
|
||||
// copy chunk into first 16 words w[0..15] of the message schedule array
|
||||
|
||||
var w = new Uint32Array(64);
|
||||
for(var i = 0; i < 16; i++)
|
||||
w[i] = data.getInt32(chunk + (i * 4));
|
||||
|
||||
//for(var i = 16; i < 64; i++)
|
||||
// w[i] = 0;
|
||||
|
||||
// Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array:
|
||||
// for i from 16 to 63
|
||||
// s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)
|
||||
// s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)
|
||||
// w[i] := w[i-16] + s0 + w[i-7] + s1
|
||||
|
||||
for (var i = 16; i < 64; i++)
|
||||
{
|
||||
var s0 = SHA256.RROT(w[i-15], 7) ^ SHA256.RROT(w[i-15], 18) ^ (w[i-15] >>> 3);
|
||||
var s1 = SHA256.RROT(w[i-2], 17) ^ SHA256.RROT(w[i-2], 19) ^ (w[i-2] >>> 10);
|
||||
w[i] = w[i-16] + s0 + w[i-7] + s1;
|
||||
}
|
||||
|
||||
// Initialize working variables to current hash value:
|
||||
var a = hash[0];
|
||||
var b = hash[1];
|
||||
var c = hash[2];
|
||||
var d = hash[3];
|
||||
var e = hash[4];
|
||||
var f = hash[5];
|
||||
var g = hash[6];
|
||||
var h = hash[7];
|
||||
|
||||
|
||||
// Compression function main loop:
|
||||
for (var i = 0; i < 64; i++)
|
||||
{
|
||||
var S1 = SHA256.RROT(e, 6) ^ SHA256.RROT(e, 11) ^ SHA256.RROT(e, 25);
|
||||
var ch = (e & f) ^ ((~e) & g);
|
||||
var temp1 = h + S1 + ch + k[i] + w[i];
|
||||
var S0 = SHA256.RROT(a, 2) ^ SHA256.RROT(a, 13) ^ SHA256.RROT(a, 22);
|
||||
var maj = (a & b) ^ (a & c) ^ (b & c);
|
||||
var temp2 = S0 + maj;
|
||||
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + temp1) >>> 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (temp1 + temp2) >>> 0;
|
||||
}
|
||||
|
||||
// Add the compressed chunk to the current hash value:
|
||||
|
||||
hash[0] = (hash[0] + a) >>> 0;
|
||||
hash[1] = (hash[1] + b) >>> 0;
|
||||
hash[2] = (hash[2] + c) >>> 0;
|
||||
hash[3] = (hash[3] + d) >>> 0;
|
||||
hash[4] = (hash[4] + e) >>> 0;
|
||||
hash[5] = (hash[5] + f) >>> 0;
|
||||
hash[6] = (hash[6] + g) >>> 0;
|
||||
hash[7] = (hash[7] + h) >>> 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Produce the final hash value (big-endian):
|
||||
//digest := hash := h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
|
||||
|
||||
var results = new BinaryList();
|
||||
for(var i = 0; i < 8; i++)
|
||||
results.addUint32(hash[i]);
|
||||
|
||||
|
||||
return results.toDC();
|
||||
}
|
||||
}
|
@ -24,16 +24,20 @@
|
||||
* Created by Ahmed Zamil on 02/09/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class SendList extends BinaryList
|
||||
{
|
||||
constructor(connection)
|
||||
constructor(connection, doneReply)
|
||||
{
|
||||
super();
|
||||
this.connection = connection;
|
||||
this.reply = doneReply;
|
||||
}
|
||||
|
||||
done()
|
||||
{
|
||||
this.connection.send(this.toArray());
|
||||
return this.reply;
|
||||
}
|
||||
}
|
41
src/Session.js
Normal file
41
src/Session.js
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Created by Ahmed Zamil on 16/11/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class Session
|
||||
{
|
||||
constructor(localAuthentication, remoteAuthentication)
|
||||
{
|
||||
|
||||
this.localAuthentication = localAuthentication;
|
||||
this.remoteAuthentication = remoteAuthentication;
|
||||
this.id = null;
|
||||
this.creation = null;
|
||||
this.modification = null;
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 26/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class Structure
|
||||
{
|
||||
getKeys() {
|
||||
|
@ -24,6 +24,8 @@
|
||||
* Created by Ahmed Zamil on 06/09/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
class StructureArray extends Array
|
||||
{
|
||||
push(value)
|
||||
|
217
src/Warehouse.js
217
src/Warehouse.js
@ -23,33 +23,112 @@
|
||||
/**
|
||||
* Created by Ahmed Zamil on 25/07/2017.
|
||||
*/
|
||||
var Warehouse = {
|
||||
|
||||
stores: [],
|
||||
resources: {},
|
||||
resourceCounter: 0,
|
||||
templates: {},
|
||||
"use strict";
|
||||
|
||||
new(type, name, store = null, parent = null)
|
||||
|
||||
class Warehouse
|
||||
{
|
||||
static new(type, name, store = null, parent = null, manager = null)
|
||||
{
|
||||
var res = type();
|
||||
Warehouse.put(res, name, store, parent);
|
||||
Warehouse.put(res, name, store, parent, null, 0, manager);
|
||||
return res;
|
||||
},
|
||||
}
|
||||
|
||||
get: function(id)
|
||||
static get(id)
|
||||
{
|
||||
if (Warehouse.resources[id])
|
||||
return new AsyncReply(Warehouse.resources[id]);
|
||||
if (Number.isInteger(id))
|
||||
{
|
||||
//if (Warehouse.resources.contains(id))
|
||||
return new AsyncReply(Warehouse.resources.item(id));
|
||||
//else
|
||||
// return null;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
},
|
||||
{
|
||||
var p = id.split('/');
|
||||
var res = null;
|
||||
|
||||
put: function(resource, name, store, parent){
|
||||
resource.instance = new Instance(Warehouse.resourceCounter++, name, resource, store);
|
||||
for(var s = 0; s < this.stores.length; s++)
|
||||
{
|
||||
var d = this.stores.at(s);
|
||||
if (p[0] == d.instance.name)
|
||||
{
|
||||
var i = 1;
|
||||
res = d;
|
||||
while(p.length > i)
|
||||
{
|
||||
var si = i;
|
||||
|
||||
for (var r = 0; r < res.instance.children.length; r++)
|
||||
if (res.instance.children.item(r).instance.name == p[i])
|
||||
{
|
||||
i++;
|
||||
res = res.instance.children.item(r);
|
||||
break;
|
||||
}
|
||||
|
||||
if (si == i)
|
||||
// not found, ask the store
|
||||
return d.get(id.substring(p[0].length + 1));
|
||||
}
|
||||
|
||||
return new AsyncReply(res);
|
||||
}
|
||||
}
|
||||
|
||||
return new AsyncReply(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static remove(resource)
|
||||
{
|
||||
|
||||
if (Warehouse.resources.contains(resource.instance.id))
|
||||
Warehouse.resources.remove(resource.instance.id);
|
||||
else
|
||||
return false;
|
||||
|
||||
if (resource instanceof IStore)
|
||||
{
|
||||
Warehouse.stores.remove(resource);
|
||||
|
||||
// remove all objects associated with the store
|
||||
var toBeRemoved = null;
|
||||
|
||||
for (var i = 0; i < Warehouse.resources.length; i++)
|
||||
{
|
||||
var o = Warehouse.resources.at(i);
|
||||
if (o.instance.store == resource)
|
||||
{
|
||||
if (toBeRemoved == null)
|
||||
toBeRemoved = [];
|
||||
toBeRemoved.push(o);
|
||||
}
|
||||
}
|
||||
|
||||
if (toBeRemoved != null)
|
||||
for(var i = 0; i < toBeRemoved.length; i++)
|
||||
Warehouse.remove(toBeRemoved[i]);
|
||||
}
|
||||
|
||||
if (resource.instance.store != null)
|
||||
resource.instance.store.remove(resource);
|
||||
resource.destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static put(resource, name, store, parent, customTemplate = null, age = 0, manager = null){
|
||||
resource.instance = new Instance(Warehouse.resourceCounter++, name, resource, store, customTemplate, age);
|
||||
//resource.instance.children.on("add", Warehouse._onChildrenAdd).on("remove", Warehouse._onChildrenRemove);
|
||||
//resource.instance.parents.on("add", Warehouse._onParentsAdd).on("remove", Warehouse._onParentsRemove);
|
||||
|
||||
if (manager != null)
|
||||
resource.instance.managers.add(manager);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
parent.instance.children.add(resource);
|
||||
@ -61,69 +140,101 @@ get: function(id)
|
||||
}
|
||||
|
||||
if (resource instanceof IStore)
|
||||
Warehouse.stores.push(resource);
|
||||
Warehouse.stores.add(resource);
|
||||
else
|
||||
store.put(resource);
|
||||
|
||||
Warehouse.resources[resource.instance.id] = resource;
|
||||
},
|
||||
Warehouse.resources.add(resource.instance.id, resource);
|
||||
}
|
||||
|
||||
_onParentsRemove: function(value)
|
||||
static _onParentsRemove(value)
|
||||
{
|
||||
if (value.instance.children.contains(value))
|
||||
value.instance.children.remove(value);
|
||||
},
|
||||
}
|
||||
|
||||
_onParentsAdd: function(value)
|
||||
static _onParentsAdd(value)
|
||||
{
|
||||
if (!value.instance.children.contains(value))
|
||||
value.instance.children.add(value);
|
||||
},
|
||||
}
|
||||
|
||||
_onChildrenRemove: function(value)
|
||||
static _onChildrenRemove(value)
|
||||
{
|
||||
if (value.instance.parents.contains(value))
|
||||
value.instance.parents.remove(value);
|
||||
},
|
||||
}
|
||||
|
||||
_onChildrenAdd: function(value)
|
||||
static _onChildrenAdd(value)
|
||||
{
|
||||
if (!value.instance.parents.contains(value))
|
||||
value.instance.parents.add(value);
|
||||
},
|
||||
}
|
||||
|
||||
putTemplate: function(template)
|
||||
static putTemplate(template)
|
||||
{
|
||||
if (Warehouse.templates[template.classId])
|
||||
Warehouse.templates[template.classId] = template;
|
||||
},
|
||||
Warehouse.templates.add(template.classId.valueOf(), template);
|
||||
}
|
||||
|
||||
getTemplateByType: function(type)
|
||||
static getTemplateByType(type)
|
||||
{
|
||||
// loaded ?
|
||||
for (var t in Warehouse.templates)
|
||||
if (Warehouse.templates[t].className == typeof(type))
|
||||
return t;
|
||||
for (var i = 0; i < Warehouse.templates.length; i++)
|
||||
if (Warehouse.templates.at(i).className == typeof(type))
|
||||
return Warehouse.templates.at(i);
|
||||
|
||||
var template = new ResourceTemplate(type);
|
||||
Warehouse.templates[template.classId] = template;
|
||||
|
||||
Warehouse.templates.add(template.classId.valueOf(), template);
|
||||
|
||||
return template;
|
||||
},
|
||||
|
||||
getTemplateByClassId: function(classId)
|
||||
{
|
||||
if (Warehouse.templates[classId])
|
||||
return new AsyncReply(Warehouse.templates[classId]);
|
||||
return null;
|
||||
},
|
||||
|
||||
getTemplateByClassName: function(className)
|
||||
{
|
||||
for(var t in Warehouse.templates)
|
||||
if (Warehouse.templates[t].className == className)
|
||||
return new AsyncReply(t);
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
static getTemplateByClassId(classId)
|
||||
{
|
||||
var template = Warehouse.templates.item(classId);
|
||||
return new AsyncReply(template);
|
||||
}
|
||||
|
||||
static getTemplateByClassName(className)
|
||||
{
|
||||
for(var i = 0; i < Warehouse.templates.length; i++)
|
||||
if (Warehouse.templates.at(i).className == className)
|
||||
return new AsyncReply(Warehouse.templates.at(i));
|
||||
|
||||
return new AsyncReply(null);
|
||||
}
|
||||
|
||||
static _qureyIn(path, index, resources)
|
||||
{
|
||||
var rt = [];
|
||||
|
||||
if (index == path.length - 1)
|
||||
{
|
||||
if (path[index] == "")
|
||||
for(var i = 0; i < resources.length; i++)
|
||||
rt.push(resources.at(i));
|
||||
else
|
||||
for(var i = 0; i < resources.length; i++)
|
||||
if (resources.at(i).instance.name == path[index])
|
||||
rt.push(resources.at(i));
|
||||
}
|
||||
else
|
||||
for(var i = 0; i < resources.length; i++)
|
||||
if (resources.at(i).instance.name == path[index])
|
||||
rt = rt.concat(Warehouse._qureyIn(path, index+1, resources.at(i).instance.children));
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
static query(path)
|
||||
{
|
||||
var p = path.split('/');
|
||||
return new AsyncReply(Warehouse._qureyIn(p, 0, Warehouse.stores));
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize
|
||||
Warehouse.stores = new AutoList();
|
||||
Warehouse.resources = new KeyList();
|
||||
Warehouse.resourceCounter = 0;
|
||||
Warehouse.templates = new KeyList();
|
||||
|
Reference in New Issue
Block a user