mirror of
https://github.com/esiur/esiur-js.git
synced 2025-05-06 04:22:58 +00:00
Publish
This commit is contained in:
parent
e6a9487797
commit
d92ce489e3
72
build.bat
Normal file
72
build.bat
Normal file
@ -0,0 +1,72 @@
|
||||
@echo off
|
||||
|
||||
del "build\esiur-debug.js"
|
||||
del "build\esiur.js"
|
||||
|
||||
type "src\IEventHandler.js" > build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "external\sha256.min.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\IDestructible.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\AutoList.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\IResource.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\IStore.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\Structure.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\StructureArray.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\ResourceArray.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\MemberTemplate.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\AsyncReply.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\AsyncBag.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\AsyncQueue.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\BinaryList.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\Codec.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\DataConverter.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\DataType.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\DistributedConnection.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\DistributedResource.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\DistributedResourceQueueItem.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\EventTemplate.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\FunctionTemplate.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\Guid.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\IIPAuthPacket.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\IIPPacket.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\Instance.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\NetworkBuffer.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\NotModified.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\PropertyTemplate.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\ResourceTemplate.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\SendList.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
type "src\Warehouse.js" >> build\esiur-debug.js
|
||||
echo. >> build\esiur-debug.js
|
||||
|
||||
REM minify build/esiur-debug.js -o build/esiur.js
|
||||
uglifyjs build/esiur-debug.js -c -o build/esiur.js
|
4935
build/esiur-debug.js
Normal file
4935
build/esiur-debug.js
Normal file
File diff suppressed because one or more lines are too long
1
build/esiur.js
Normal file
1
build/esiur.js
Normal file
File diff suppressed because one or more lines are too long
37
examples/test-debug.html
Normal file
37
examples/test-debug.html
Normal file
@ -0,0 +1,37 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../build/esiur-debug.js"></script>
|
||||
<script>
|
||||
var demo;
|
||||
|
||||
class MyStore extends IStore
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
var con = new DistributedConnection("ws://localhost:5001/iip/system/iip", "localhost", "ahmed", "password");
|
||||
Warehouse.put(con, "remote");
|
||||
|
||||
con.on("ready", function (d) {
|
||||
con.get("db/my").then(function(rt){
|
||||
console.log("Object received.");
|
||||
demo = rt;
|
||||
rt.on("LevelUp", function(v){
|
||||
console.log("LevelUp", v);
|
||||
});
|
||||
|
||||
rt.Add(3);
|
||||
});
|
||||
}).on("error", function(sender, code, msg){
|
||||
console.log(sender, code, msg);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
|
||||
</body>
|
||||
</html>
|
73
examples/test-plain.html
Normal file
73
examples/test-plain.html
Normal file
@ -0,0 +1,73 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../external/sha256.min.js"></script>
|
||||
<script src="../src/IEventHandler.js"></script>
|
||||
<script src="../src/IDestructible.js"></script>
|
||||
<script src="../src/AutoList.js"></script>
|
||||
|
||||
<script src="../src/IResource.js"></script>
|
||||
<script src="../src/IStore.js"></script>
|
||||
<script src="../src/Structure.js"></script>
|
||||
|
||||
<script src="../src/StructureArray.js"></script>
|
||||
<script src="../src/ResourceArray.js"></script>
|
||||
|
||||
<script src="../src/MemberTemplate.js"></script>
|
||||
<script src="../src/AsyncReply.js"></script>
|
||||
|
||||
<script src="../src/AsyncBag.js"></script>
|
||||
<script src="../src/AsyncQueue.js"></script>
|
||||
<script src="../src/BinaryList.js"></script>
|
||||
<script src="../src/Codec.js"></script>
|
||||
<script src="../src/DataConverter.js"></script>
|
||||
<script src="../src/DataType.js"></script>
|
||||
<script src="../src/DistributedConnection.js"></script>
|
||||
<script src="../src/DistributedResource.js"></script>
|
||||
<script src="../src/DistributedResourceQueueItem.js"></script>
|
||||
<script src="../src/EventTemplate.js"></script>
|
||||
<script src="../src/FunctionTemplate.js"></script>
|
||||
<script src="../src/Guid.js"></script>
|
||||
<script src="../src/IIPAuthPacket.js"></script>
|
||||
<script src="../src/IIPPacket.js"></script>
|
||||
<script src="../src/Instance.js"></script>
|
||||
<script src="../src/NetworkBuffer.js"></script>
|
||||
<script src="../src/NotModified.js"></script>
|
||||
<script src="../src/PropertyTemplate.js"></script>
|
||||
|
||||
<script src="../src/ResourceTemplate.js"></script>
|
||||
<script src="../src/SendList.js"></script>
|
||||
<script src="../src/Warehouse.js"></script>
|
||||
<script>
|
||||
var demo;
|
||||
|
||||
class MyStore extends IStore
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
var con = new DistributedConnection("ws://localhost:5001/iip/system/iip", "localhost", "ahmed", "password");
|
||||
Warehouse.put(con, "remote");
|
||||
|
||||
con.on("ready", function (d) {
|
||||
con.get("db/my").then(function(rt){
|
||||
console.log("Object received.");
|
||||
demo = rt;
|
||||
rt.on("LevelUp", function(v){
|
||||
console.log("LevelUp", v);
|
||||
});
|
||||
|
||||
rt.Add(3);
|
||||
});
|
||||
}).on("error", function(sender, code, msg){
|
||||
console.log(sender, code, msg);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
|
||||
</body>
|
||||
</html>
|
37
examples/test.html
Normal file
37
examples/test.html
Normal file
@ -0,0 +1,37 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../build/esiur.js"></script>
|
||||
<script>
|
||||
var demo;
|
||||
|
||||
class MyStore extends IStore
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
var con = new DistributedConnection("ws://localhost:5001/iip/system/iip", "localhost", "ahmed", "password");
|
||||
Warehouse.put(con, "remote");
|
||||
|
||||
con.on("ready", function (d) {
|
||||
con.get("db/my").then(function(rt){
|
||||
console.log("Object received.");
|
||||
demo = rt;
|
||||
rt.on("LevelUp", function(v){
|
||||
console.log("LevelUp", v);
|
||||
});
|
||||
|
||||
rt.Add(3);
|
||||
});
|
||||
}).on("error", function(sender, code, msg){
|
||||
console.log(sender, code, msg);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
|
||||
</body>
|
||||
</html>
|
9
external/sha256.min.js
vendored
Normal file
9
external/sha256.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
73
index.html
Normal file
73
index.html
Normal file
@ -0,0 +1,73 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="sha256.min.js"></script>
|
||||
<script src="IEventHandler.js"></script>
|
||||
<script src="IDestructible.js"></script>
|
||||
<script src="AutoList.js"></script>
|
||||
|
||||
<script src="IResource.js"></script>
|
||||
<script src="IStore.js"></script>
|
||||
<script src="Structure.js"></script>
|
||||
|
||||
<script src="StructureArray.js"></script>
|
||||
<script src="ResourceArray.js"></script>
|
||||
|
||||
<script src="MemberTemplate.js"></script>
|
||||
<script src="AsyncReply.js"></script>
|
||||
|
||||
<script src="AsyncBag.js"></script>
|
||||
<script src="AsyncQueue.js"></script>
|
||||
<script src="BinaryList.js"></script>
|
||||
<script src="Codec.js"></script>
|
||||
<script src="DataConverter.js"></script>
|
||||
<script src="DataType.js"></script>
|
||||
<script src="DistributedConnection.js"></script>
|
||||
<script src="DistributedResource.js"></script>
|
||||
<script src="DistributedResourceQueueItem.js"></script>
|
||||
<script src="EventTemplate.js"></script>
|
||||
<script src="FunctionTemplate.js"></script>
|
||||
<script src="Guid.js"></script>
|
||||
<script src="IIPAuthPacket.js"></script>
|
||||
<script src="IIPPacket.js"></script>
|
||||
<script src="Instance.js"></script>
|
||||
<script src="NetworkBuffer.js"></script>
|
||||
<script src="NotModified.js"></script>
|
||||
<script src="PropertyTemplate.js"></script>
|
||||
|
||||
<script src="ResourceTemplate.js"></script>
|
||||
<script src="SendList.js"></script>
|
||||
<script src="Warehouse.js"></script>
|
||||
<script>
|
||||
var demo;
|
||||
|
||||
class MyStore extends IStore
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
var con = new DistributedConnection("ws://localhost:5001/iip/root/main", "localhost", "ahmed", "password");
|
||||
Warehouse.put(con, "remote");
|
||||
|
||||
con.on("ready", function (d) {
|
||||
con.get("root/demo").then(function(rt){
|
||||
console.log("hiiii");
|
||||
demo = rt;
|
||||
rt.on("LevelUp", function(v){
|
||||
console.log("LevelUp", v);
|
||||
});
|
||||
|
||||
rt.Add(3);
|
||||
});
|
||||
}).on("error", function(sender, code, msg){
|
||||
console.log(sender, code, msg);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
|
||||
</body>
|
||||
</html>
|
61
src/AsyncBag.js
Normal file
61
src/AsyncBag.js
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
class AsyncBag extends AsyncReply
|
||||
{
|
||||
constructor() {
|
||||
super();
|
||||
this.replies = [];
|
||||
this.results = [];
|
||||
this.count = 0;
|
||||
this.sealedBag = false;
|
||||
}
|
||||
|
||||
seal()
|
||||
{
|
||||
this.sealedBag = true;
|
||||
|
||||
if (this.results.length == 0)
|
||||
this.trigger([]);
|
||||
|
||||
var self = this;
|
||||
|
||||
for(var i = 0; i < this.results.length; 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)
|
||||
{
|
||||
if (!this.sealedBag) {
|
||||
this.replies.push(reply);
|
||||
this.results.push(null);
|
||||
}
|
||||
}
|
||||
}
|
66
src/AsyncQueue.js
Normal file
66
src/AsyncQueue.js
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
class AsyncQueue extends AsyncReply
|
||||
{
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.list = [];
|
||||
|
||||
var self = this;
|
||||
|
||||
this.processQueue = function ()
|
||||
{
|
||||
for (var i = 0; i < self.list.length; i++)
|
||||
if (self.list[i].ready)
|
||||
{
|
||||
self.trigger(self.list[i].result);
|
||||
self.list.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
self.ready = (self.list.length == 0);
|
||||
}
|
||||
}
|
||||
|
||||
add(reply)
|
||||
{
|
||||
this.list.push(reply);
|
||||
this.ready = false;
|
||||
reply.then(this.processQueue);
|
||||
}
|
||||
|
||||
remove(reply)
|
||||
{
|
||||
this.list.splice(this.list.indexOf(reply), 1);
|
||||
this.processQueue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
53
src/AsyncReply.js
Normal file
53
src/AsyncReply.js
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
class AsyncReply
|
||||
{
|
||||
then(callback)
|
||||
{
|
||||
this.callbacks.push(callback);
|
||||
if (this.ready)
|
||||
callback(this.result, this);
|
||||
}
|
||||
|
||||
trigger(result)
|
||||
{
|
||||
this.result = result;
|
||||
this.ready = true;
|
||||
|
||||
for(var i = 0; i < this.callbacks.length; i++)
|
||||
this.callbacks[i](result, this);
|
||||
}
|
||||
|
||||
constructor(result)
|
||||
{
|
||||
this.callbacks = [];
|
||||
|
||||
if (result) {
|
||||
this.result = result;
|
||||
this.ready = true;
|
||||
}
|
||||
}
|
||||
}
|
88
src/AutoList.js
Normal file
88
src/AutoList.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 05/09/2017.
|
||||
*/
|
||||
|
||||
class AutoList extends IEventHandler
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.list = [];
|
||||
}
|
||||
|
||||
add(value)
|
||||
{
|
||||
if (value instanceof IDestructible)
|
||||
value.on("destroy", this._item_destroyed);
|
||||
|
||||
this.list.push(value);
|
||||
|
||||
this._emit("add", value);
|
||||
}
|
||||
|
||||
set(index, value)
|
||||
{
|
||||
if (index >= this.list.length || index < 0)
|
||||
return;
|
||||
|
||||
if (value instanceof IDestructible)
|
||||
value.on("destroy", this._item_destroyed);
|
||||
|
||||
if (this.list[index] instanceof IDestructible)
|
||||
this.list[index].off("destroy", this._item_destroyed);
|
||||
|
||||
this.list[index] = value;
|
||||
}
|
||||
|
||||
remove(value)
|
||||
{
|
||||
this.removeAt(this.list.indexOf(value));
|
||||
}
|
||||
|
||||
contains(value)
|
||||
{
|
||||
return this.list.indexOf(value) > -1;
|
||||
}
|
||||
|
||||
removeAt(index)
|
||||
{
|
||||
if (index >= this.list.length || index < 0)
|
||||
return;
|
||||
|
||||
var item = this.list[index];
|
||||
|
||||
if (item instanceof IDestructible)
|
||||
item.off("destroy", this._item_destroyed);
|
||||
|
||||
this.list.splice(index, 1);
|
||||
|
||||
this._emit("remove", item);
|
||||
}
|
||||
|
||||
_item_destroyed(sender)
|
||||
{
|
||||
this.remove(sender);
|
||||
}
|
||||
}
|
67
src/AutoMap.js
Normal file
67
src/AutoMap.js
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 05/09/2017.
|
||||
*/
|
||||
|
||||
class AutoMap extends IEventHandler
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.dic = {};
|
||||
}
|
||||
|
||||
add(key, value)
|
||||
{
|
||||
if (value instanceof IDestructible)
|
||||
value.on("destroy", this._item_destroyed);
|
||||
|
||||
this.dic[key] = value;
|
||||
|
||||
this._emit("add", key, value);
|
||||
}
|
||||
|
||||
set(key, value)
|
||||
{
|
||||
if (this.dic[key] !== undefined)
|
||||
this.remove(key);
|
||||
|
||||
this.add(key, value);
|
||||
}
|
||||
|
||||
remove(key)
|
||||
{
|
||||
if (this.dic[key] !== undefined) {
|
||||
if (this.dic[key] instanceof IDestructible)
|
||||
this.dic[key].off("destroy", this._item_destroyed);
|
||||
|
||||
delete this.dic[key];
|
||||
}
|
||||
}
|
||||
|
||||
_item_destroyed(sender)
|
||||
{
|
||||
this.remove(sender);
|
||||
}
|
||||
}
|
214
src/BinaryList.js
Normal file
214
src/BinaryList.js
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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/08/2017.
|
||||
*/
|
||||
|
||||
var BL = function(){
|
||||
return new BinaryList();
|
||||
};
|
||||
|
||||
class BinaryList
|
||||
{
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.list = [];
|
||||
}
|
||||
|
||||
|
||||
addRange(bl)
|
||||
{
|
||||
for(var i = 0; i < bl.list.length; i++)
|
||||
this.list.push(bl.list[i]);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
add(typedValue, position)
|
||||
{
|
||||
if (position !== undefined)
|
||||
this.list.splice(position, 0, typedValue);
|
||||
else
|
||||
this.list.push(typedValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
get length()
|
||||
{
|
||||
return this.toArray().length;
|
||||
}
|
||||
|
||||
toArray()
|
||||
{
|
||||
var ars = [];
|
||||
// calculate length
|
||||
for(var i = 0; i < this.list.length; i++)
|
||||
{
|
||||
switch (this.list[i].type)
|
||||
{
|
||||
case DataType.Bool:
|
||||
ars.push(DC.boolToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.UInt8:
|
||||
ars.push(DC.uint8ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Int8:
|
||||
ars.push(DC.int8ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Char:
|
||||
ars.push(DC.charToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.UInt16:
|
||||
ars.push(DC.uint16ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Int16:
|
||||
ars.push(DC.int16ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.UInt32:
|
||||
ars.push(DC.uint32ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Int32:
|
||||
ars.push(DC.int32ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.UInt64:
|
||||
ars.push(DC.uint64ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Int64:
|
||||
ars.push(DC.int64ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Float32:
|
||||
ars.push(DC.float32ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.Float64:
|
||||
ars.push(DC.float64ToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.String:
|
||||
ars.push(DC.stringToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.DateTime:
|
||||
ars.push(DC.dateTimeToBytes(this.list[i].value));
|
||||
break;
|
||||
case DataType.UInt8Array:
|
||||
ars.push(this.list[i].value);
|
||||
|
||||
//case DataType.Resource:
|
||||
// ars.push(DC.uint32ToBytes(this.list[i].value.instance.id));
|
||||
// break;
|
||||
//case DataType.DistributedResource:
|
||||
// ars.push(DC.int8ToBytes(this.list[i].value));
|
||||
// break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var length = 0;
|
||||
ars.forEach(function(a){
|
||||
length += a.length;
|
||||
});
|
||||
|
||||
var rt = new Uint8Array(length);
|
||||
|
||||
var offset = 0;
|
||||
for(var i = 0; i < ars.length; i++) {
|
||||
rt.set(ars[i], offset);
|
||||
offset+=ars[i].length;
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
addUint8Array(value, position)
|
||||
{
|
||||
return this.add({type: DataType.UInt8Array, value: value}, position);
|
||||
}
|
||||
|
||||
|
||||
addHex(value, position)
|
||||
{
|
||||
return this.addUint8Array(DC.hexToBytes(value), position);
|
||||
}
|
||||
|
||||
addString(value, position)
|
||||
{
|
||||
return this.add({type: DataType.String, value: value}, position);
|
||||
}
|
||||
|
||||
addUint8(value, position)
|
||||
{
|
||||
return this.add({type: DataType.UInt8, value: value}, position);
|
||||
}
|
||||
|
||||
addInt8(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Int8, value: value}, position);
|
||||
}
|
||||
|
||||
addChar(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Char, value: value}, position);
|
||||
}
|
||||
|
||||
addUint16(value, position)
|
||||
{
|
||||
return this.add({type: DataType.UInt16, value: value}, position);
|
||||
}
|
||||
|
||||
addInt16(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Int16, value: value}, position);
|
||||
}
|
||||
|
||||
addUint32(value, position)
|
||||
{
|
||||
return this.add({type: DataType.UInt32, value: value}, position);
|
||||
}
|
||||
|
||||
addInt32(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Int32, value: value}, position);
|
||||
}
|
||||
|
||||
addUint64(value, position)
|
||||
{
|
||||
return this.add({type: DataType.UInt64, value: value}, position);
|
||||
}
|
||||
|
||||
addInt64(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Int64, value: value}, position);
|
||||
}
|
||||
|
||||
addFloat32(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Float32, value: value}, position);
|
||||
}
|
||||
|
||||
addFloat64(value, position)
|
||||
{
|
||||
return this.add({type: DataType.Float64, value: value}, position);
|
||||
}
|
||||
|
||||
}
|
622
src/Codec.js
Normal file
622
src/Codec.js
Normal file
@ -0,0 +1,622 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
var ResourceComparisonResult =
|
||||
{
|
||||
Null: 0,
|
||||
Distributed: 1,
|
||||
DistributedSameClass: 2,
|
||||
Local: 3,
|
||||
Same: 4
|
||||
};
|
||||
|
||||
var StructureComparisonResult =
|
||||
{
|
||||
Null: 0,
|
||||
Structure: 1,
|
||||
StructureSameKeys: 2,
|
||||
StructureSameTypes: 3,
|
||||
Same: 4
|
||||
};
|
||||
|
||||
class Codec {
|
||||
|
||||
static parse(data, offset, sizeObject, connection, dataType = DataType.Unspecified) {
|
||||
|
||||
var size;
|
||||
|
||||
var reply = new AsyncReply();
|
||||
|
||||
var isArray;
|
||||
var t;
|
||||
|
||||
if (dataType == DataType.Unspecified) {
|
||||
size = 1;
|
||||
dataType = data[offset++];
|
||||
}
|
||||
else
|
||||
size = 0;
|
||||
|
||||
t = dataType & 0x7F;
|
||||
|
||||
isArray = (dataType & 0x80) == 0x80;
|
||||
|
||||
var payloadSize = DataType.sizeOf(dataType);
|
||||
|
||||
var contentLength = 0;
|
||||
|
||||
// check if we have the enough data
|
||||
if (payloadSize == -1) {
|
||||
contentLength = data.getUint32(offset);
|
||||
offset += 4;
|
||||
size += 4 + contentLength;
|
||||
}
|
||||
else
|
||||
size += payloadSize;
|
||||
|
||||
|
||||
sizeObject.size = size;
|
||||
|
||||
if (isArray) {
|
||||
switch (t) {
|
||||
// VarArray ?
|
||||
case DataType.Void:
|
||||
return Codec.parseVarArray(data, offset, contentLength, connection);
|
||||
|
||||
case DataType.Bool:
|
||||
return new AsyncReply(data.getBooleanArray(offset, contentLength));
|
||||
|
||||
case DataType.UInt8:
|
||||
return new AsyncReply(data.getUint8Array(offset, contentLength));
|
||||
|
||||
case DataType.Int8:
|
||||
return new AsyncReply(data.getInt8Array(offset, contentLength));
|
||||
|
||||
case DataType.Char:
|
||||
return new AsyncReply(data.getCharArray(offset, contentLength));
|
||||
|
||||
case DataType.Int16:
|
||||
return new AsyncReply(data.getInt16Array(offset, contentLength));
|
||||
|
||||
case DataType.UInt16:
|
||||
return new AsyncReply(data.getUint16Array(offset, contentLength));
|
||||
|
||||
case DataType.Int32:
|
||||
return new AsyncReply(data.getInt32Array(offset, contentLength));
|
||||
|
||||
case DataType.UInt32:
|
||||
return new AsyncReply(data.getUint32Array(offset, contentLength));
|
||||
|
||||
case DataType.Int64:
|
||||
return new AsyncReply(data.getInt64Array(offset, contentLength));
|
||||
|
||||
case DataType.UInt64:
|
||||
return new AsyncReply(data.getUint64Array(offset, contentLength));
|
||||
|
||||
case DataType.Float32:
|
||||
return new AsyncReply(data.getFloat32Array(offset, contentLength));
|
||||
|
||||
case DataType.Float64:
|
||||
return new AsyncReply(data.getFloat64Array(offset, contentLength));
|
||||
|
||||
case DataType.String:
|
||||
return new AsyncReply(data.getStringArray(offset, contentLength));
|
||||
|
||||
case DataType.Resource:
|
||||
case DataType.DistributedResource:
|
||||
return Codec.parseResourceArray(data, offset, contentLength, connection);
|
||||
|
||||
case DataType.DateTime:
|
||||
return new AsyncReply(data.getDateTimeArray(offset, contentLength));
|
||||
|
||||
case DataType.Structure:
|
||||
return Codec.parseStructureArray(data, offset, contentLength, connection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (t) {
|
||||
case DataType.NotModified:
|
||||
return new AsyncReply(new NotModified());
|
||||
|
||||
case DataType.Void:
|
||||
return new AsyncReply(null);
|
||||
|
||||
case DataType.Bool:
|
||||
return new AsyncReply(data.getBoolean(offset));
|
||||
|
||||
case DataType.UInt8:
|
||||
return new AsyncReply(data[offset]);
|
||||
|
||||
case DataType.Int8:
|
||||
return new AsyncReply(data.getInt8(offset));
|
||||
|
||||
case DataType.Char:
|
||||
return new AsyncReply(data.getChar(offset));
|
||||
|
||||
case DataType.Int16:
|
||||
return new AsyncReply(data.getInt16(offset));
|
||||
|
||||
case DataType.UInt16:
|
||||
return new AsyncReply(data.getUint16(offset));
|
||||
|
||||
case DataType.Int32:
|
||||
return new AsyncReply(data.getInt32(offset));
|
||||
|
||||
case DataType.UInt32:
|
||||
return new AsyncReply(data.getUint32(offset));
|
||||
|
||||
case DataType.Int64:
|
||||
return new AsyncReply(data.getInt64(offset));
|
||||
|
||||
case DataType.UInt64:
|
||||
return new AsyncReply(data.getUint64(offset));
|
||||
|
||||
case DataType.Float32:
|
||||
return new AsyncReply(data.getFloat32(offset));
|
||||
|
||||
case DataType.Float64:
|
||||
return new AsyncReply(data.getFloat64(offset));
|
||||
|
||||
case DataType.String:
|
||||
return new AsyncReply(data.getString(offset, contentLength));
|
||||
|
||||
case DataType.Resource:
|
||||
return Codec.parseResource(data, offset);
|
||||
|
||||
case DataType.DistributedResource:
|
||||
return Codec.parseDistributedResource(data, offset, connection);
|
||||
|
||||
case DataType.DateTime:
|
||||
return new AsyncReply(data.getDateTime(offset));
|
||||
|
||||
case DataType.Structure:
|
||||
return Codec.parseStructure(data, offset, contentLength, connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static parseResource(data, offset) {
|
||||
return Warehouse.get(data.getUint32(offset));
|
||||
}
|
||||
|
||||
static parseDistributedResource(data, offset, connection) {
|
||||
//var g = data.getGuid(offset);
|
||||
//offset += 16;
|
||||
|
||||
// find the object
|
||||
var iid = data.getUint32(offset);
|
||||
|
||||
return connection.fetch(iid);// Warehouse.Get(iid);
|
||||
}
|
||||
|
||||
|
||||
static parseStructure(data, offset, contentLength, connection, keylist = null, typelist = null, keys = null, types = null) {
|
||||
var reply = new AsyncReply();
|
||||
var bag = new AsyncBag();
|
||||
|
||||
|
||||
if (keylist == null)
|
||||
keylist = [];
|
||||
if (typelist == null)
|
||||
typelist = [];
|
||||
|
||||
if (keys == null) {
|
||||
while (contentLength > 0) {
|
||||
var len = data[offset++];
|
||||
keylist.push(data.getString(offset, len));
|
||||
offset += len;
|
||||
|
||||
typelist.push(data[offset]);
|
||||
|
||||
var rt = {};
|
||||
bag.add(Codec.parse(data, offset, rt, connection));
|
||||
contentLength -= rt.size + len + 1;
|
||||
offset += rt.size;
|
||||
}
|
||||
}
|
||||
else if (types == null) {
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
keylist.push(keys[i]);
|
||||
|
||||
while (contentLength > 0) {
|
||||
typelist.push(data[offset]);
|
||||
|
||||
var rt = {};
|
||||
bag.add(Codec.parse(data, offset, rt, connection));
|
||||
contentLength -= rt.size + 1;
|
||||
offset += rt.size + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
keylist.push(keys[i]);
|
||||
typelist.push(types[i]);
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
while (contentLength > 0) {
|
||||
var rt = {};
|
||||
bag.add(Codec.parse(data, offset, rt, connection, types[i]));
|
||||
contentLength -= rt.size;
|
||||
offset += rt.size;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bag.seal();
|
||||
|
||||
bag.then(function (res) {
|
||||
// compose the list
|
||||
var s = new Structure();
|
||||
for (var i = 0; i < keylist.length; i++)
|
||||
s[keylist[i]] = res[i];
|
||||
reply.trigger(s);
|
||||
});
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static parseVarArray(data, offset, contentLength, connection) {
|
||||
var rt = new AsyncBag();
|
||||
|
||||
while (contentLength > 0) {
|
||||
var cs = {};
|
||||
|
||||
rt.add(Codec.parse(data, offset, cs, connection));
|
||||
|
||||
if (cs.size > 0) {
|
||||
offset += cs.size;
|
||||
contentLength -= cs.size;
|
||||
}
|
||||
else
|
||||
throw new Exception("Error while parsing structured data");
|
||||
|
||||
}
|
||||
|
||||
rt.seal();
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
static compose(value, connection, prependType = true) {
|
||||
|
||||
var type = Codec.getDataType(value, connection);
|
||||
var rt = new BinaryList();
|
||||
|
||||
switch (type) {
|
||||
case DataType.Void:
|
||||
// nothing to do;
|
||||
break;
|
||||
|
||||
case DataType.String:
|
||||
var st = DC.stringToBytes(value);
|
||||
rt.addUint32(st.length).addUint8Array(st);
|
||||
break;
|
||||
|
||||
case DataType.Resource:
|
||||
rt.addUint32(value.instance.id);
|
||||
break;
|
||||
|
||||
case DataType.DistributedResource:
|
||||
// rt.addUint8Array(DC.stringToBytes(value.instance.template.classId)).addUint32(value.instance.id);
|
||||
rt.addUint32(value.instance.id);
|
||||
break;
|
||||
|
||||
case DataType.Structure:
|
||||
rt.addUint8Array(Codec.composeStructure(value, connection, true, true, true));
|
||||
break;
|
||||
|
||||
case DataType.VarArray:
|
||||
rt.addUint8Array(Codec.composeVarArray(value, connection, true));
|
||||
break;
|
||||
|
||||
case DataType.ResourceArray:
|
||||
rt.addUint8Array(Codec.composeResourceArray(value, connection, true));
|
||||
break;
|
||||
|
||||
case DataType.StructureArray:
|
||||
rt.addUint8Array(Codec.composeStructureArray(value, connection, true));
|
||||
break;
|
||||
|
||||
default:
|
||||
rt.add({type: type, value: value});
|
||||
if (DataType.isArray(type))
|
||||
rt.addUint32(rt.length, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (prependType)
|
||||
rt.addUint8(type, 0);
|
||||
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
static composeVarArray(array, connection, prependLength = false) {
|
||||
var rt = new BinaryList();
|
||||
|
||||
for (var i = 0; i < array.length; i++)
|
||||
rt.addUint8Array(Codec.compose(array[i], connection));
|
||||
|
||||
if (prependLength)
|
||||
rt.addUint32(rt.length, 0);
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
static composeStructure(value, connection, includeKeys = true, includeTypes = true, prependLength = false) {
|
||||
var rt = new BinaryList();
|
||||
|
||||
var keys = value.getKeys();
|
||||
|
||||
if (includeKeys) {
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = DC.stringToBytes(keys[i]);
|
||||
rt.addUint8(key.length).addString(key).addUint8Array(DC.compose(value[i], connection));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
rt.addUint8Array(DC.compose(value[keys[i]], connection, includeTypes));
|
||||
}
|
||||
|
||||
if (prependLength)
|
||||
rt.addUint32(rt.length, 0);
|
||||
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
static composeStructureArray(structures, connection, prependLength = false) {
|
||||
if (structures == null || structures.length == 0 || !(structures instanceof StructureArray))
|
||||
return new DC(0);
|
||||
|
||||
var rt = new BinaryList();
|
||||
var comparision = StructureComparisonResult.Structure;
|
||||
|
||||
rt.addUint8(comparision);
|
||||
rt.addUint8Array(Codec.composeStructure(structures[0], connection));
|
||||
|
||||
for (var i = 1; i < structures.Length; i++) {
|
||||
comparision = Codec.compareStructure(structures[i - 1], structures[i], connection);
|
||||
rt.addUint8(comparision);
|
||||
|
||||
if (comparision == StructureComparisonResult.Structure)
|
||||
rt.addUint8Array(Codec.composeStructure(structures[i], connection));
|
||||
else if (comparision == StructureComparisonResult.StructureSameKeys)
|
||||
rt.addUint8Array(Codec.composeStructure(structures[i], connection, false));
|
||||
else if (comparision == StructureComparisonResult.StructureSameTypes)
|
||||
rt.addUint8Array(Codec.composeStructure(structures[i], connection, false, false));
|
||||
}
|
||||
|
||||
if (prependLength)
|
||||
rt.addUint32(rt.length, 0);
|
||||
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
static compareStructure(previous, next, connection) {
|
||||
if (next == null)
|
||||
return StructureComparisonResult.Null;
|
||||
|
||||
if (previous == null)
|
||||
return StructureComparisonResult.Structure;
|
||||
|
||||
if (next == previous)
|
||||
return StructureComparisonResult.Same;
|
||||
|
||||
if (previous.length != next.length)
|
||||
return StructureComparisonResult.Structure;
|
||||
|
||||
var previousKeys = previous.getKeys();
|
||||
var nextKeys = next.getKeys();
|
||||
|
||||
for (var i = 0; i < previousKeys.length; i++)
|
||||
if (previousKeys[i] != nextKeys[i])
|
||||
return StructureComparisonResult.Structure;
|
||||
|
||||
var previousTypes = Codec.getStructureDateTypes(previous, connection);
|
||||
var nextTypes = Codec.getStructureDateTypes(next, connection);
|
||||
|
||||
for (var i = 0; i < previousTypes.length; i++)
|
||||
if (previousTypes[i] != nextTypes[i])
|
||||
return StructureComparisonResult.StructureSameKeys;
|
||||
|
||||
return StructureComparisonResult.StructureSameTypes;
|
||||
}
|
||||
|
||||
static getStructureDateTypes(structure, connection) {
|
||||
var keys = structure.getKeys();
|
||||
var types = [];
|
||||
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
types.push(Codec.getDataType(structure[keys[i]], connection));
|
||||
return types;
|
||||
}
|
||||
|
||||
static isLocalResource(resource, connection) {
|
||||
if (resource instanceof DistributedResource)
|
||||
if (resource.connection == connection)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static composeResource(resource, connection) {
|
||||
if (Codec.isLocalResource(resource, connection))
|
||||
return BL().addUint32(resource.id);
|
||||
else {
|
||||
return BL().addUint8Array(resource.instance.template.classId.value).addUint32(resource.instance.id);
|
||||
}
|
||||
}
|
||||
|
||||
static compareResource(previous, next, connection) {
|
||||
if (next == null)
|
||||
return ResourceComparisonResult.Null;
|
||||
|
||||
if (next == previous)
|
||||
return ResourceComparisonResult.Same;
|
||||
|
||||
if (Codec.isLocalResource(next, connection))
|
||||
return ResourceComparisonResult.Local;
|
||||
|
||||
if (previous == null)
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 (prependLength)
|
||||
rt.addUint32(0, rt.length);
|
||||
|
||||
return rt.toArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static getDataType(value) {
|
||||
switch (typeof value) {
|
||||
case "number":
|
||||
// float or ?
|
||||
if (Math.floor(value) == value) {
|
||||
if (value > 0) {
|
||||
// larger than byte ?
|
||||
if (value > 0xFF) {
|
||||
// larger than short ?
|
||||
if (value > 0xFFFF) {
|
||||
// larger than int ?
|
||||
if (value > 0xFFFFFFFF) {
|
||||
return DataType.UInt64;
|
||||
}
|
||||
else {
|
||||
return DataType.UInt32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return DataType.UInt16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return DataType.UInt8;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value < -128) {
|
||||
if (value < -32768) {
|
||||
if (value < -2147483648) {
|
||||
return DataType.Int64;
|
||||
}
|
||||
else {
|
||||
return DataType.Int32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return DataType.Int16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return DataType.Int8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// float or double
|
||||
return DataType.Float64;
|
||||
}
|
||||
break;
|
||||
|
||||
case "string":
|
||||
return DataType.String;
|
||||
case "boolean":
|
||||
return DataType.Bool;
|
||||
case "object":
|
||||
if (value instanceof Array) {
|
||||
return DataType.VarArray;
|
||||
}
|
||||
else if (value instanceof IResource) {
|
||||
return Codec.isLocalResource(value, connection) ? DataType.Resource : DataType.DistributedResource;
|
||||
}
|
||||
else if (value instanceof Date) {
|
||||
return DataType.DateTime;
|
||||
}
|
||||
else if (value instanceof Uint8Array
|
||||
|| value instanceof ArrayBuffer) {
|
||||
return DataType.UInt8Array;
|
||||
}
|
||||
else if (value instanceof Number) {
|
||||
// JS numbers are always 64-bit float
|
||||
return DataType.Float64;
|
||||
}
|
||||
else if (value instanceof Structure) {
|
||||
return DataType.Structure;
|
||||
}
|
||||
else {
|
||||
return DataType.Void
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return DataType.Void;
|
||||
}
|
||||
}
|
||||
}
|
490
src/DataConverter.js
Normal file
490
src/DataConverter.js
Normal file
@ -0,0 +1,490 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
var UNIX_EPOCH = 621355968000000000;
|
||||
var TWO_PWR_32 = (1 << 16) * (1 << 16);
|
||||
|
||||
class DC extends Uint8Array// extends DataView // Data Converter
|
||||
{
|
||||
constructor(bufferOrSize) {
|
||||
super(bufferOrSize);
|
||||
|
||||
//if (bufferOrSize instanceof ArrayBuffer) {
|
||||
// this.buffer = bufferOrSize;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// this.buffer = new Uint8Array(bufferOrSize);
|
||||
//}
|
||||
|
||||
this.dv = new DataView(this.buffer);
|
||||
}
|
||||
|
||||
|
||||
static boolToBytes(value)
|
||||
{
|
||||
var rt = new DC(1);
|
||||
rt.setBoolean(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static int8ToBytes(value)
|
||||
{
|
||||
var rt = new DC(1);
|
||||
rt.setInt8(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static hexToBytes(value)
|
||||
{
|
||||
// convert hex to Uint8Array
|
||||
var rt = new DC(value.length/2);
|
||||
for(var i = 0; i < ar.length; i++)
|
||||
rt[i] = parseInt(value.substr(i*2, 2), 16);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static uint8ToBytes(value)
|
||||
{
|
||||
var rt = new DC(1);
|
||||
rt.setUint8(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static charToBytes(value)
|
||||
{
|
||||
var rt = new DC(2);
|
||||
rt.setChar(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static int16ToBytes(value)
|
||||
{
|
||||
var rt = new DC(2);
|
||||
rt.setInt16(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static uint16ToBytes(value)
|
||||
{
|
||||
var rt = new DC(2);
|
||||
rt.setUint16(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static int32ToBytes(value)
|
||||
{
|
||||
var rt = new DC(4);
|
||||
rt.setInt32(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static uint32ToBytes(value)
|
||||
{
|
||||
var rt = new DC(4);
|
||||
rt.setUint32(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static float32ToBytes(value)
|
||||
{
|
||||
var rt = new DC(4);
|
||||
rt.setFloat32(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static int64ToBytes(value)
|
||||
{
|
||||
var rt = new DC(8);
|
||||
rt.setInt64(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static uint64ToBytes(value)
|
||||
{
|
||||
var rt = new DC(8);
|
||||
rt.setUint64(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static float64ToBytes(value)
|
||||
{
|
||||
var rt = new DC(8);
|
||||
rt.setFloat64(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static dateTimeToBytes(value)
|
||||
{
|
||||
var rt = new DC(8);
|
||||
rt.setDateTime(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static stringToBytes(value)
|
||||
{
|
||||
var utf8 = unescape(encodeURIComponent(value));
|
||||
var rt = [];
|
||||
|
||||
for (var i = 0; i < utf8.length; i++)
|
||||
rt.push(utf8.charCodeAt(i));
|
||||
|
||||
return new DC(rt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
append(src, offset, length)
|
||||
{
|
||||
if (!(src instanceof DC))
|
||||
src = new DC(src);
|
||||
|
||||
var appendix = src.clip(offset, length);
|
||||
var rt = new DC(this.length + appendix.length);
|
||||
rt.set(this, 0);
|
||||
rt.set(appendix, this.length);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static combine(a, aOffset, aLength, b, bOffset, bLength)
|
||||
{
|
||||
if (!(a instanceof DC))
|
||||
a = new DC(a);
|
||||
if (!(b instanceof DC))
|
||||
b = new DC(b);
|
||||
|
||||
a = a.clip(aOffset, aLength);
|
||||
b = b.clip(bOffset, bLength);
|
||||
|
||||
var rt = new DC(a.length + b.length);
|
||||
rt.set(a, 0);
|
||||
rt.set(b, a.length);
|
||||
return rt;
|
||||
}
|
||||
|
||||
clip(offset, length)
|
||||
{
|
||||
return this.slice(offset, offset+length);
|
||||
}
|
||||
|
||||
getInt8(offset)
|
||||
{
|
||||
return this.dv.getUint8(offset);
|
||||
}
|
||||
|
||||
getUint8(offset)
|
||||
{
|
||||
return this[offset];// this.dv.getUint8(offset);
|
||||
}
|
||||
|
||||
getInt16(offset)
|
||||
{
|
||||
return this.dv.getInt16(offset);
|
||||
}
|
||||
|
||||
getUint16(offset)
|
||||
{
|
||||
return this.dv.getUint16(offset);
|
||||
}
|
||||
|
||||
getInt32(offset)
|
||||
{
|
||||
return this.dv.getInt32(offset);
|
||||
}
|
||||
|
||||
getUint32(offset)
|
||||
{
|
||||
return this.dv.getUint32(offset);
|
||||
}
|
||||
|
||||
getFloat32(offset)
|
||||
{
|
||||
return this.dv.getFloat32(offset);
|
||||
}
|
||||
|
||||
getFloat64(offset)
|
||||
{
|
||||
return this.dv.getFloat64(offset);
|
||||
}
|
||||
|
||||
setInt8(offset, value)
|
||||
{
|
||||
return this.dv.setInt8(offset, value);
|
||||
}
|
||||
|
||||
setUint8(offset, value)
|
||||
{
|
||||
return this.dv.setUint8(offset, value);
|
||||
}
|
||||
|
||||
setInt16(offset, value)
|
||||
{
|
||||
return this.dv.setInt16(offset, value);
|
||||
}
|
||||
|
||||
setUint16(offset, value)
|
||||
{
|
||||
return this.dv.setUint16(offset, value);
|
||||
}
|
||||
|
||||
setInt32(offset, value)
|
||||
{
|
||||
return this.dv.setInt32(offset, value);
|
||||
}
|
||||
|
||||
setUint32(offset, value)
|
||||
{
|
||||
return this.dv.setUint32(offset, value);
|
||||
}
|
||||
|
||||
setFloat32(offset, value)
|
||||
{
|
||||
return this.dv.setFloat32(offset, value);
|
||||
}
|
||||
|
||||
setFloat64(offset, value)
|
||||
{
|
||||
return this.dv.setFloat64(offset, value);
|
||||
}
|
||||
|
||||
getInt8Array(offset, length)
|
||||
{
|
||||
return new Int8Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getUint8Array(offset, length)
|
||||
{
|
||||
return new Uint8Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getInt16Array(offset, length)
|
||||
{
|
||||
return new Int16Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getUint16Array(offset, length)
|
||||
{
|
||||
return new Uint16Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getInt32Array(offset, length)
|
||||
{
|
||||
return new Int32Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getUint32Array(offset, length)
|
||||
{
|
||||
return new Uint32Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getFloat32Array(offset, length)
|
||||
{
|
||||
return new Float32Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getFloat64Array(offset, length)
|
||||
{
|
||||
return new Float64Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getInt64Array(offset, length)
|
||||
{
|
||||
return new Int64Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
|
||||
getUint64Array(offset, length)
|
||||
{
|
||||
return new Uint64Array(this.buffer, offset, length);
|
||||
}
|
||||
|
||||
getBoolean(offset)
|
||||
{
|
||||
return this.getUint8(offset) > 0;
|
||||
}
|
||||
|
||||
setBoolean(offset, value)
|
||||
{
|
||||
this.setUint8(offset, value ? 1: 0);
|
||||
}
|
||||
|
||||
getBooleanArray(offset, length)
|
||||
{
|
||||
var rt = [];
|
||||
for(var i = 0; i < length; i++)
|
||||
rt.push(this.getBoolean(offset+i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
getChar(offset)
|
||||
{
|
||||
return String.fromCharCode(this.getUint16(offset));
|
||||
}
|
||||
|
||||
setChar(offset, value)
|
||||
{
|
||||
this.setUint16(offset, value.charCodeAt(0));
|
||||
}
|
||||
|
||||
getCharArray(offset, length)
|
||||
{
|
||||
var rt = [];
|
||||
for(var i = 0; i < length; i+=2)
|
||||
rt.push(this.getChar(offset+i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
getHex(offset, length)
|
||||
{
|
||||
var rt = "";
|
||||
for(var i = offset; i < offset + length; i++) {
|
||||
var h = this[i].toString(16);
|
||||
rt += h.length == 1 ? "0" + h : h;
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
getString(offset, length)
|
||||
{
|
||||
if (typeof StringView != "undefined")
|
||||
return new StringView(this.buffer, "UTF-8", offset, length);
|
||||
else
|
||||
{
|
||||
var bytes = this.getUint8Array(offset, length);
|
||||
var encodedString = String.fromCharCode.apply(null, bytes),
|
||||
decodedString = decodeURIComponent(escape(encodedString));
|
||||
return decodedString;
|
||||
}
|
||||
}
|
||||
|
||||
getStringArray(offset, length)
|
||||
{
|
||||
var rt = [];
|
||||
var i = 0;
|
||||
|
||||
while (i < length)
|
||||
{
|
||||
var cl = this.getUint32(offset + i);
|
||||
i += 4;
|
||||
rt.push(this.getString(offset + i, cl));
|
||||
i += cl;
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
getInt64(offset)
|
||||
{
|
||||
var h = this.getInt32(offset);
|
||||
var l = this.getInt32(offset + 4);
|
||||
|
||||
return h * TWO_PWR_32 + ((l >= 0) ? l : TWO_PWR_32 + l);
|
||||
}
|
||||
|
||||
getUint64(offset)
|
||||
{
|
||||
var h = this.getUint32(offset);
|
||||
var l = this.getUint32(offset + 4);
|
||||
return h * TWO_PWR_32 + ((l >= 0) ? l : TWO_PWR_32 + l);
|
||||
}
|
||||
|
||||
setInt64(offset, value)
|
||||
{
|
||||
var l = (value % TWO_PWR_32) | 0;
|
||||
var h = (value / TWO_PWR_32) | 0;
|
||||
this.setInt32(offset, h);
|
||||
this.setInt32(offset + 4, l);
|
||||
}
|
||||
|
||||
setUint64(offset, value)
|
||||
{
|
||||
var l = (value % TWO_PWR_32) | 0;
|
||||
var h = (value / TWO_PWR_32) | 0;
|
||||
this.setInt32(offset, h);
|
||||
this.setInt32(offset + 4, l);
|
||||
}
|
||||
|
||||
setDateTime(offset, value)
|
||||
{
|
||||
// Unix Epoch
|
||||
var ticks = 621355968000000000 + (value.getTime() * 10000);
|
||||
this.setUint64(offset, ticks);
|
||||
}
|
||||
|
||||
getDateTime(offset)
|
||||
{
|
||||
var ticks = this.getUint64(offset);
|
||||
return new Date(Math.round((ticks-DCStatic.UNIX_EPOCH)/10000));
|
||||
}
|
||||
|
||||
getDateTimeArray(offset)
|
||||
{
|
||||
var rt = [];
|
||||
for(var i = 0; i < length; i+=8)
|
||||
rt.push(this.getDateTime(offset+i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
getGuid(offset)
|
||||
{
|
||||
return new Guid(this.getUint8Array(offset, 16));
|
||||
|
||||
/*
|
||||
var d = this.getUint8Array(offset, 16);
|
||||
var rt = "";
|
||||
for (var i = 0; i < 16; i++) {
|
||||
rt += String.fromCharCode(d[i]);
|
||||
}
|
||||
|
||||
return btoa(rt);
|
||||
*/
|
||||
}
|
||||
|
||||
getGuidArray(offset, length)
|
||||
{
|
||||
var rt = [];
|
||||
for(var i = 0; i < length; i+=16)
|
||||
rt.push(this.getGuid(offset+i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
sequenceEqual(ar)
|
||||
{
|
||||
if (ar.length != this.length)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
for(var i = 0; i < this.length; i++)
|
||||
if (ar[i] != this[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
110
src/DataType.js
Normal file
110
src/DataType.js
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
DataType = {
|
||||
Void: 0x0,
|
||||
//Variant,
|
||||
Bool: 1,
|
||||
Int8: 2,
|
||||
UInt8: 3,
|
||||
Char: 4,
|
||||
Int16: 5,
|
||||
UInt16: 6,
|
||||
Int32: 7,
|
||||
UInt32: 8,
|
||||
Int64: 9,
|
||||
UInt64: 10,
|
||||
Float32: 11,
|
||||
Float64: 12,
|
||||
Decimal: 13,
|
||||
DateTime: 14,
|
||||
Resource: 15,
|
||||
DistributedResource: 16,
|
||||
ResourceLink: 17,
|
||||
String: 18,
|
||||
Structure: 19,
|
||||
//Stream,
|
||||
//Array = 0x80,
|
||||
VarArray: 0x80,
|
||||
BoolArray: 0x81,
|
||||
UInt8Array: 0x82,
|
||||
Int8Array: 0x83,
|
||||
CharArray: 0x84,
|
||||
Int16Array: 0x85,
|
||||
UInt16Array: 0x86,
|
||||
Int32Array: 0x87,
|
||||
UInt32Array: 0x88,
|
||||
Int64Array: 0x89,
|
||||
UInt64Array: 0x8A,
|
||||
Float32Array: 0x8B,
|
||||
Float64Array: 0x8C,
|
||||
DecimalArray: 0x8D,
|
||||
DateTimeArray: 0x8E,
|
||||
ResourceArray: 0x8F,
|
||||
DistributedResourceArray: 0x90,
|
||||
ResourceLinkArray: 0x91,
|
||||
StringArray: 0x92,
|
||||
StructureArray: 0x93,
|
||||
NotModified: 0x7f,
|
||||
Unspecified: 0xff,
|
||||
|
||||
isArray: function(type)
|
||||
{
|
||||
return ((type & 0x80) == 0x80) && (type != DataType.NotModified);
|
||||
},
|
||||
|
||||
sizeOf: function(type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataType.Void:
|
||||
case DataType.NotModified:
|
||||
return 0;
|
||||
case DataType.Bool:
|
||||
case DataType.Int8:
|
||||
case DataType.UInt8:
|
||||
return 1;
|
||||
case DataType.Char:
|
||||
case DataType.Int16:
|
||||
case DataType.UInt16:
|
||||
return 2;
|
||||
case DataType.Int32:
|
||||
case DataType.UInt32:
|
||||
case DataType.Float32:
|
||||
case DataType.Resource:
|
||||
return 4;
|
||||
case DataType.Int64:
|
||||
case DataType.UInt64:
|
||||
case DataType.Float64:
|
||||
case DataType.DateTime:
|
||||
return 8;
|
||||
case DataType.DistributedResource:
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
};
|
860
src/DistributedConnection.js
Normal file
860
src/DistributedConnection.js
Normal file
@ -0,0 +1,860 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
var AuthenticationType =
|
||||
{
|
||||
Host: 0,
|
||||
CoHost: 1,
|
||||
Client: 2,
|
||||
Alien: 3
|
||||
};
|
||||
|
||||
class DistributedConnection extends IStore {
|
||||
|
||||
send(data) {
|
||||
this.socket.send(data.buffer);
|
||||
}
|
||||
|
||||
sendParams() {
|
||||
return new SendList(this);
|
||||
}
|
||||
|
||||
constructor(url, domain, username, password, checkInterval = 30, connectionTimeout = 600, revivingTime = 120) {
|
||||
|
||||
super();
|
||||
|
||||
//Instance.Name = Global.GenerateCode(12);
|
||||
this.hostType = AuthenticationType.Client;
|
||||
this.domain = domain;
|
||||
this.localUsername = username;
|
||||
this.localPassword = DC.stringToBytes(password);
|
||||
|
||||
this.socket = new WebSocket(url, "iip");
|
||||
this.socket.binaryType = "arraybuffer";
|
||||
this.socket.connection = this;
|
||||
this.socket.networkBuffer = new NetworkBuffer();
|
||||
|
||||
this.debug = false;
|
||||
this.totalReceived = 0;
|
||||
this.totalSent = 0;
|
||||
|
||||
this.checkInterval = checkInterval * 1000; // check every 30 seconds
|
||||
this.connectionTimeout = connectionTimeout * 1000; // 10 minutes (4 pings failed)
|
||||
this.revivingTime = revivingTime * 1000; // 2 minutes
|
||||
this.lastAction = Date.now();
|
||||
|
||||
this.packet = new IIPPacket();
|
||||
this.authPacket = new IIPAuthPacket();
|
||||
|
||||
this.resources = {};
|
||||
this.templates = {};
|
||||
this.requests = {};
|
||||
this.pathRequests = {};
|
||||
this.templateRequests = {};
|
||||
this.resourceRequests = {};
|
||||
this.callbackCounter = 0;
|
||||
|
||||
this.queue = new AsyncQueue();
|
||||
|
||||
this.queue.then(function (x) {
|
||||
if (x.type == DistributedResourceQueueItemType.Event) {
|
||||
x.resource._emitEventByIndex(x.index, x.value);
|
||||
}
|
||||
else {
|
||||
x.resource._updatePropertyByIndex(x.index, x.value);
|
||||
}
|
||||
});
|
||||
|
||||
this.localNonce = new Uint8Array(32);
|
||||
window.crypto.getRandomValues(this.localNonce);
|
||||
|
||||
// declare (Credentials -> No Auth, No Enctypt)
|
||||
var un = DC.stringToBytes(username);
|
||||
var dmn = DC.stringToBytes(domain);
|
||||
var self = this;
|
||||
|
||||
this.socket.onopen = function () {
|
||||
var bl = new BinaryList();
|
||||
bl.addUint8(0x60).addUint8(dmn.length).addUint8Array(dmn).addUint8Array(self.localNonce).addUint8(un.length).addUint8Array(un);
|
||||
self.send(bl.toArray());
|
||||
};
|
||||
|
||||
this.socket.onmessage = function (msg) {
|
||||
|
||||
//console.log(msg);
|
||||
|
||||
this.networkBuffer.writeAll(msg.data);
|
||||
|
||||
self.lastAction = new Date();
|
||||
|
||||
while (this.networkBuffer.available > 0 && !this.networkBuffer.protected)
|
||||
self.receive(this.networkBuffer);
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
receive(data) {
|
||||
var msg = data.read();
|
||||
var offset = 0;
|
||||
var ends = msg.length;
|
||||
var packet = this.packet;
|
||||
var authPacket = this.authPacket;
|
||||
|
||||
//console.log("Data");
|
||||
|
||||
while (offset < ends) {
|
||||
|
||||
if (this.ready) {
|
||||
var rt = packet.parse(msg, offset, ends);
|
||||
if (rt <= 0) {
|
||||
data.holdFor(msg, offset, ends - offset, -rt);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
offset += rt;
|
||||
|
||||
if (packet.command == IIPPacketCommand.Event) {
|
||||
switch (packet.event) {
|
||||
case IIPPacketEvent.ResourceReassigned:
|
||||
this.IIPEventResourceReassigned(packet.resourceId, packet.newResourceId);
|
||||
break;
|
||||
case IIPPacketEvent.ResourceDestroyed:
|
||||
this.IIPEventResourceDestroyed(packet.resourceId);
|
||||
break;
|
||||
case IIPPacketEvent.PropertyUpdated:
|
||||
this.IIPEventPropertyUpdated(packet.resourceId, packet.methodIndex, packet.content);
|
||||
break;
|
||||
case IIPPacketEvent.EventOccured:
|
||||
this.IIPEventEventOccured(packet.resourceId, packet.methodIndex, packet.content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (packet.command == IIPPacketCommand.Request) {
|
||||
switch (packet.action) {
|
||||
case IIPPacketAction.AttachResource:
|
||||
this.IIPRequestAttachResource(packet.callbackId, packet.resourceId);
|
||||
break;
|
||||
case IIPPacketAction.ReattachResource:
|
||||
this.IIPRequestReattachResource(packet.callbackId, packet.resourceId, packet.resourceAge);
|
||||
break;
|
||||
case IIPPacketAction.DetachResource:
|
||||
this.IIPRequestDetachResource(packet.callbackId, packet.resourceId);
|
||||
break;
|
||||
case IIPPacketAction.CreateResource:
|
||||
this.IIPRequestCreateResource(packet.callbackId, packet.className);
|
||||
break;
|
||||
case IIPPacketAction.DeleteResource:
|
||||
this.IIPRequestDeleteResource(packet.callbackId, packet.resourceId);
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromClassName:
|
||||
this.IIPRequestTemplateFromClassName(packet.callbackId, packet.className);
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromClassId:
|
||||
this.IIPRequestTemplateFromClassId(packet.callbackId, packet.classId);
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromResourceLink:
|
||||
this.IIPRequestTemplateFromResourceLink(packet.callbackId, packet.resourceLink);
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromResourceId:
|
||||
this.IIPRequestTemplateFromResourceId(packet.callbackId, packet.resourceId);
|
||||
break;
|
||||
case IIPPacketAction.ResourceIdFromResourceLink:
|
||||
this.IIPRequestResourceIdFromResourceLink(packet.callbackId, packet.resourceLink);
|
||||
break;
|
||||
case IIPPacketAction.InvokeFunction:
|
||||
this.IIPRequestInvokeFunction(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
|
||||
break;
|
||||
case IIPPacketAction.GetProperty:
|
||||
this.IIPRequestGetProperty(packet.callbackId, packet.resourceId, packet.methodIndex);
|
||||
break;
|
||||
case IIPPacketAction.GetPropertyIfModified:
|
||||
this.IIPRequestGetPropertyIfModifiedSince(packet.callbackId, packet.resourceId, packet.methodIndex, packet.resourceAge);
|
||||
break;
|
||||
case IIPPacketAction.SetProperty:
|
||||
this.IIPRequestSetProperty(packet.callbackId, packet.resourceId, packet.methodIndex, packet.content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (packet.command == IIPPacketCommand.Reply) {
|
||||
switch (packet.action) {
|
||||
case IIPPacketAction.AttachResource:
|
||||
this.IIPReply(packet.callbackId, packet.classId, packet.resourceAge, packet.resourceLink, packet.content);
|
||||
break;
|
||||
case IIPPacketAction.ReattachResource:
|
||||
this.IIPReply(packet.callbackId, packet.resourceAge, packet.content);
|
||||
break;
|
||||
case IIPPacketAction.DetachResource:
|
||||
this.IIPReply(packet.callbackId);
|
||||
break;
|
||||
case IIPPacketAction.CreateResource:
|
||||
this.IIPReply(packet.callbackId, packet.classId, packet.resourceId);
|
||||
break;
|
||||
case IIPPacketAction.DeleteResource:
|
||||
this.IIPReply(packet.callbackId);
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromClassName:
|
||||
this.IIPReply(packet.callbackId, ResourceTemplate.parse(packet.content));
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromClassId:
|
||||
this.IIPReply(packet.callbackId, ResourceTemplate.parse(packet.content));
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromResourceLink:
|
||||
this.IIPReply(packet.callbackId, ResourceTemplate.parse(packet.content));
|
||||
break;
|
||||
case IIPPacketAction.TemplateFromResourceId:
|
||||
this.IIPReply(packet.callbackId, ResourceTemplate.parse(packet.content));
|
||||
break;
|
||||
case IIPPacketAction.ResourceIdFromResourceLink:
|
||||
this.IIPReply(packet.callbackId, packet.classId, packet.resourceId, packet.resourceAge);
|
||||
break;
|
||||
case IIPPacketAction.InvokeFunction:
|
||||
this.IIPReply(packet.callbackId, packet.content);
|
||||
break;
|
||||
case IIPPacketAction.GetProperty:
|
||||
this.IIPReply(packet.callbackId, packet.content);
|
||||
break;
|
||||
case IIPPacketAction.GetPropertyIfModified:
|
||||
this.IIPReply(packet.callbackId, packet.content);
|
||||
break;
|
||||
case IIPPacketAction.SetProperty:
|
||||
this.IIPReply(packet.callbackId);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
var rt = authPacket.parse(msg, offset, ends);
|
||||
|
||||
|
||||
if (rt <= 0) {
|
||||
data.holdAllFor(msg, ends - rt);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
offset += rt;
|
||||
|
||||
if (this.hostType == AuthenticationType.Host) {
|
||||
if (authPacket.command == IIPAuthPacketCommand.Declare) {
|
||||
if (authPacket.remoteMethod == IIPAuthPacketMethod.credentials
|
||||
&& authPacket.localMethod == IIPAuthPacketMethod.None) {
|
||||
this.remoteUsername = authPacket.remoteUsername;
|
||||
this.remoteNonce = authPacket.remoteNonce;
|
||||
this.domain = authPacket.domain;
|
||||
this.sendParams().addUint8(0xa0).addUint8Array(this.localNonce).done();
|
||||
}
|
||||
}
|
||||
else if (authPacket.command == IIPAuthPacketCommand.Action) {
|
||||
if (authPacket.action == IIPAuthPacketAction.AuthenticateHash) {
|
||||
var remoteHash = authPacket.hash;
|
||||
|
||||
this.server.membership.getPassword(this.remoteUsername, this.domain).then(function (pw) {
|
||||
if (pw != null) {
|
||||
|
||||
var hash = new DC(sha256.arrayBuffer(BL().addString(pw).addUint8Array(remoteNonce).addUint8Array(this.localNonce).toArray()));
|
||||
|
||||
|
||||
if (hash.sequenceEqual(remoteHash)) {
|
||||
// send our hash
|
||||
var localHash = new DC(sha256.arrayBuffer((new BinaryList()).addUint8Array(this.localNonce).addUint8Array(remoteNonce).addUint8Array(pw).toArray()));
|
||||
this.sendParams().addUint8(0).addUint8Array(localHash).done();
|
||||
|
||||
this.readyToEstablish = true;
|
||||
}
|
||||
else {
|
||||
// incorrect password
|
||||
this.sendParams().addUint8(0xc0).addInt32(1).addUint16(5).addString("Error").done();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (authPacket.action == IIPAuthPacketAction.NewConnection) {
|
||||
if (readyToEstablish) {
|
||||
this.sessionId = new DC(32);
|
||||
window.crypto.getRandomValues(this.sessionId);
|
||||
|
||||
this.sendParams().addUint8(0x28).addUint8Array(this.sessionId).done();
|
||||
this.ready = true;
|
||||
this._emit("ready", this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.hostType == AuthenticationType.Client) {
|
||||
if (authPacket.command == IIPAuthPacketCommand.Acknowledge) {
|
||||
this.remoteNonce = authPacket.remoteNonce;
|
||||
|
||||
// send our hash
|
||||
|
||||
var localHash = new DC(sha256.arrayBuffer(BL().addUint8Array(this.localPassword)
|
||||
.addUint8Array(this.localNonce)
|
||||
.addUint8Array(this.remoteNonce).toArray()));
|
||||
this.sendParams().addUint8(0).addUint8Array(localHash).done();
|
||||
}
|
||||
else if (authPacket.command == IIPAuthPacketCommand.Action) {
|
||||
if (authPacket.action == IIPAuthPacketAction.AuthenticateHash) {
|
||||
// check if the server knows my password
|
||||
var remoteHash = new DC(sha256.arrayBuffer(BL().addUint8Array(this.remoteNonce)
|
||||
.addUint8Array(this.localNonce)
|
||||
.addUint8Array(this.localPassword).toArray()
|
||||
));
|
||||
|
||||
if (remoteHash.sequenceEqual(authPacket.hash)) {
|
||||
// send establish request
|
||||
this.sendParams().addUint8(0x20).addUint16(0).done();
|
||||
}
|
||||
else {
|
||||
this.sendParams().addUint8(0xc0).addUint32(1).addUint16(5).addString("Error").done();
|
||||
}
|
||||
}
|
||||
else if (authPacket.action == IIPAuthPacketAction.ConnectionEstablished) {
|
||||
this.sessionId = authPacket.sessionId;
|
||||
this.ready = true;
|
||||
this._emit("ready", this);
|
||||
}
|
||||
}
|
||||
else if (authPacket.command == IIPAuthPacketCommand.Error)
|
||||
{
|
||||
this._emit("error", this, authPacket.errorCode, authPacket.errorMessage);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close()
|
||||
{
|
||||
this.socket.close();
|
||||
}
|
||||
|
||||
trigger(trigger) {
|
||||
return true;
|
||||
}
|
||||
|
||||
put(resource) {
|
||||
this.resources[parseInt(resource.instance.name)] = resource;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Protocol Implementation
|
||||
|
||||
sendRequest(action, binaryList) {
|
||||
var reply = new AsyncReply();
|
||||
this.callbackCounter++;
|
||||
this.sendParams().addUint8(0x40 | action).addUint32(this.callbackCounter).addRange(binaryList).done();
|
||||
this.requests[this.callbackCounter] = reply;
|
||||
return reply;
|
||||
}
|
||||
|
||||
IIPReply(callbackId) {
|
||||
var results = Array.prototype.slice.call(arguments, 1);
|
||||
var req = this.requests[callbackId];
|
||||
delete this.requests[callbackId];
|
||||
req.trigger(results);
|
||||
}
|
||||
|
||||
IIPEventResourceReassigned(resourceId, newResourceId) {
|
||||
|
||||
}
|
||||
|
||||
IIPEventResourceDestroyed(resourceId) {
|
||||
if (this.resources[resourceId]) {
|
||||
var r = this.resources[resourceId];
|
||||
delete this.resources[resourceId];
|
||||
r.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
IIPEventPropertyUpdated(resourceId, index, content) {
|
||||
if (this.resources[resourceId]) {
|
||||
// push to the queue to gaurantee serialization
|
||||
var reply = new AsyncReply();
|
||||
this.queue.add(reply);
|
||||
|
||||
var r = this.resources[resourceId];
|
||||
Codec.parse(content, 0, this).then(function (args) {
|
||||
var pt = r._p.template.getPropertyTemplateByIndex(index);
|
||||
if (pt != null) {
|
||||
reply.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Propery, args, index));
|
||||
}
|
||||
else { // ft found, fi not found, this should never happen
|
||||
this.queue.remove(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IIPEventEventOccured(resourceId, index, content) {
|
||||
if (this.resources[resourceId]) {
|
||||
// push to the queue to guarantee serialization
|
||||
var reply = new AsyncReply();
|
||||
var r = this.resources[resourceId];
|
||||
|
||||
this.queue.add(reply);
|
||||
|
||||
Codec.parseVarArray(content, 0, content.length, this).then(function (args) {
|
||||
var et = r._p.template.getEventTemplateByIndex(index);
|
||||
if (et != null) {
|
||||
reply.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Event, args, index));
|
||||
}
|
||||
else { // ft found, fi not found, this should never happen
|
||||
this.queue.remove(reply);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
IIPRequestAttachResource(callback, resourceId) {
|
||||
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null) {
|
||||
r.instance.on("ResourceEventOccured", this.instance_eventOccured);
|
||||
r.instance.on("ResourceModified", this.instance_propertyModified);
|
||||
r.instance.on("ResourceDestroyed", this.instance_resourceDestroyed);
|
||||
// reply ok
|
||||
|
||||
var link = DC.stringToBytes(r.instance.link);
|
||||
|
||||
sl.addUint8(0x80)
|
||||
.addUint32(callback)
|
||||
.addUint8Array(r.instance.template.classId.value)
|
||||
.addUint32(r.instance.age)
|
||||
.addUint16(link.length)
|
||||
.addUint8Array(link)
|
||||
.addUint8Array(Codec.composeVarArray(r.instance.serialize(), this, true))
|
||||
.done();
|
||||
}
|
||||
else {
|
||||
// reply failed
|
||||
//SendParams(0x80, r.Instance.Id, r.Instance.Age, r.Instance.Serialize(false, this));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestReattachResource(callback, resourceId, resourceAge) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (res != null) {
|
||||
r.instance.on("ResourceEventOccured", this.instance_eventOccured);
|
||||
r.instance.on("ResourceModified", this.instance_propertyModified);
|
||||
r.instance.on("ResourceDestroyed", this.instance_resourceDestroyed);
|
||||
// reply ok
|
||||
sl.addUint8(0x81)
|
||||
.addUint32(callback)
|
||||
.addUint32(r.instance.age)
|
||||
.addUint8Array(Codec.composeVarArray(r.instance.serialize(), this, true))
|
||||
.done();
|
||||
}
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestDetachResource(callback, resourceId) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null) {
|
||||
r.instance.off("ResourceEventOccured", this.instance_eventOccured);
|
||||
r.instance.off("ResourceModified", this.instance_propertyModified);
|
||||
r.instance.off("ResourceDestroyed", this.instance_resourceDestroyed);
|
||||
|
||||
// reply ok
|
||||
sl.addUint8(0x82).addUint32(callback).done();
|
||||
}
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestCreateResource(callback, className) {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
IIPRequestDeleteResource(callback, resourceId) {
|
||||
// not implemented
|
||||
}
|
||||
|
||||
IIPRequestTemplateFromClassName(callback, className) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.getTemplateByClassName(className).then(function (t) {
|
||||
if (t != null)
|
||||
sl.addUint8(0x88).addUint32(callback).addUint8Array(t.content).done();
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestTemplateFromClassId(callback, classId) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.getTemplateByClassId(classId).then(function (t) {
|
||||
if (t != null)
|
||||
sl.addUint8(0x89)
|
||||
.addUint32(callback)
|
||||
.addUint32(t.content.length)
|
||||
.addUint8Array(t.content)
|
||||
.done();
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestTemplateFromResourceLink(callback, resourceLink) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.getTemplate(resourceLink).then(function (t) {
|
||||
if (t != null)
|
||||
sl.addUint8(0x8a).addUint32(callback).addUint8Array(t.content).done();
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestTemplateFromResourceId(callback, resourceId) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null)
|
||||
sl.addUint8(0x8b).addUint32(callback).addUint8Array(r.instance.template.content).done();
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestResourceIdFromResourceLink(callback, resourceLink) {
|
||||
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceLink).then(function (r) {
|
||||
if (r != null)
|
||||
sl.addUint8(0x8c)
|
||||
.addUint32(callback)
|
||||
.addUint8Array(r.instance.template.classId.value)
|
||||
.addUint32(r.instance.id)
|
||||
.addUint32(r.instance.age).done();
|
||||
else {
|
||||
// reply failed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestInvokeFunction(callback, resourceId, index, content) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null) {
|
||||
Codec.parseVarArray(content, 0, content.length, sl.connection).then(function (args) {
|
||||
var ft = r.instance.template.getFunctionTemplateByIndex(index);
|
||||
if (ft != null) {
|
||||
if (r instanceof DistributedResource) {
|
||||
var rt = r._invoke(index, args);
|
||||
if (rt != null) {
|
||||
rt.then(function (res) {
|
||||
sl.addUint8(0x90).addUint32(callback).addUint8Array(Codec.compose(res, sl.connection)).done();
|
||||
});
|
||||
}
|
||||
else {
|
||||
// function not found on a distributed object
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
var fi = r[ft.name];
|
||||
if (fi instanceof Function) {
|
||||
args.push(sl.connection);
|
||||
|
||||
var rt = fi.apply(r, args);
|
||||
|
||||
|
||||
if (rt instanceof AsyncReply) {
|
||||
rt.then(function (res) {
|
||||
sl.addUint8(0x90).addUint32(callback).addUint8Array(Codec.compose(res, sl.connection)).done();
|
||||
});
|
||||
}
|
||||
else {
|
||||
sl.addUint8(0x90).addUint32(callback).addUint8Array(Codec.compose(rt, sl.connection)).done();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ft found, fi not found, this should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no function at this index
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
// no resource with this id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestGetProperty(callback, resourceId, index) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null) {
|
||||
var pt = r.instance.template.getFunctionTemplateByIndex(index);
|
||||
if (pt != null) {
|
||||
if (r instanceof DistributedResource) {
|
||||
sl.addUint8(0x91).addUint32(callback).addUint8Array(Codec.compose(r._get(pt.index), sl.connection)).done();
|
||||
}
|
||||
else {
|
||||
var pv = r[pt.name];
|
||||
sl.addUint8(0x91).addUint32(callback).addUint8Array(Codec.compose(pv, sl.connection)).done();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// pt not found
|
||||
}
|
||||
}
|
||||
else {
|
||||
// resource not found
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestGetPropertyIfModifiedSince(callback, resourceId, index, age) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null) {
|
||||
var pt = r.instance.template.getFunctionTemplateByIndex(index);
|
||||
if (pt != null) {
|
||||
if (r.instance.getAge(index) > age) {
|
||||
var pv = r[pt.name];
|
||||
sl.addUint8(0x92).addUint32(callback).addUint8Array(Codec.compose(pv, sl.connection)).done();
|
||||
}
|
||||
else {
|
||||
sl.addUint8(0x92).addUint32(callback).addUint8(DataType.NotModified).done();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// pt not found
|
||||
}
|
||||
}
|
||||
else {
|
||||
// resource not found
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
IIPRequestSetProperty(callback, resourceId, index, content) {
|
||||
var sl = this.sendParams();
|
||||
|
||||
Warehouse.get(resourceId).then(function (r) {
|
||||
if (r != null) {
|
||||
|
||||
|
||||
var pt = r.instance.template.getPropertyTemplateByIndex(index);
|
||||
if (pt != null) {
|
||||
Codec.parse(content, 0, this).then(function (value) {
|
||||
if (r instanceof DistributedResource) {
|
||||
// propagation
|
||||
r._set(index, value).then(function (x) {
|
||||
sl.addUint8(0x93).addUint32(callback).done();
|
||||
});
|
||||
}
|
||||
else {
|
||||
r[pt.name] = value;
|
||||
sl.addUint8(0x93).addUint32(callback).done();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else {
|
||||
// property not found
|
||||
}
|
||||
}
|
||||
else {
|
||||
// resource not found
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getTemplate(classId) {
|
||||
if (this.templates[classId])
|
||||
return new AsyncReply(this.templates[classId]);
|
||||
else if (this.templateRequests[classId])
|
||||
return this.templateRequests[classId];
|
||||
|
||||
var reply = new AsyncReply();
|
||||
this.templateRequests[classId] = reply;
|
||||
|
||||
var self = this;
|
||||
|
||||
this.sendRequest(IIPPacketAction.TemplateFromClassId, BL().addUint8Array(classId.value)).then(function (rt) {
|
||||
delete self.templateRequests[classId];
|
||||
self.templates[rt[0].classId] = rt[0];
|
||||
reply.trigger(rt[0]);
|
||||
});
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
// IStore interface
|
||||
get(path) {
|
||||
if (this.pathRequests[path])
|
||||
return this.pathRequests[path];
|
||||
|
||||
var reply = new AsyncReply();
|
||||
this.pathRequests[path] = reply;
|
||||
|
||||
var bl = new BinaryList();
|
||||
bl.addString(path);
|
||||
bl.addUint16(bl.length, 0);
|
||||
|
||||
var self = this;
|
||||
|
||||
this.sendRequest(IIPPacketAction.ResourceIdFromResourceLink, bl).then(function (rt) {
|
||||
delete self.pathRequests[path];
|
||||
|
||||
self.fetch(rt[1]).then(function (r) {
|
||||
reply.trigger(r);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
retrieve(iid) {
|
||||
for (var r in this.resources)
|
||||
if (this.resources[r].instance.id == iid)
|
||||
return new AsyncReply(r);
|
||||
return new AsyncReply(null);
|
||||
}
|
||||
|
||||
// Get a resource from the other end
|
||||
fetch(id) {
|
||||
if (this.resourceRequests[id] && this.resources[id]) {
|
||||
// dig for dead locks
|
||||
return this.resourceRequests[id];
|
||||
}
|
||||
else if (this.resourceRequests[id])
|
||||
return this.resourceRequests[id];
|
||||
else if (this.resources[id])
|
||||
return new AsyncReply(this.resources[id]);
|
||||
|
||||
var reply = new AsyncReply();
|
||||
|
||||
var self = this;
|
||||
|
||||
this.sendRequest(IIPPacketAction.AttachResource, BL().addUint32(id)).then(function (rt) {
|
||||
self.getTemplate(rt[0]).then(function (tmp) {
|
||||
|
||||
var dr = new DistributedResource(self, tmp, id, rt[1], rt[2]);
|
||||
Warehouse.put(dr, id.toString(), self);
|
||||
|
||||
Codec.parseVarArray(rt[3], 0, rt[3].length, self).then(function (ar) {
|
||||
dr._attached(ar);
|
||||
delete self.resourceRequests[id];
|
||||
reply.trigger(dr);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
instance_resourceDestroyed(resource) {
|
||||
// compose the packet
|
||||
this.sendParams().addUint8(0x1).addUint32(resource.instance.id).done();
|
||||
}
|
||||
|
||||
instance_propertyModified(resource, name, newValue, oldValue) {
|
||||
var pt = resource.instance.template.getPropertyTemplateByName(name);
|
||||
|
||||
if (pt == null)
|
||||
return;
|
||||
|
||||
// compose the packet
|
||||
if (newValue instanceof Function)
|
||||
sendParams().addUint8(0x10)
|
||||
.addUint32(resource.instance.id)
|
||||
.addUint8(pt.index)
|
||||
.addUint8Array(Codec.compose(newValue(this), this))
|
||||
.done();
|
||||
else
|
||||
sendParams().addUint8(0x10)
|
||||
.addUint32(resource.instance.id)
|
||||
.addUint8(pt.index)
|
||||
.addUint8Array(Codec.compose(newValue, this))
|
||||
.done();
|
||||
}
|
||||
|
||||
instance_eventOccured(resource, name, receivers, args) {
|
||||
var et = resource.instance.template.getEventTemplateByName(name);
|
||||
|
||||
if (et == null)
|
||||
return;
|
||||
|
||||
if (receivers != null)
|
||||
if (receivers.indexOf(this.remoteUsername) < 0)
|
||||
return;
|
||||
|
||||
var clientArgs = [];//new object[args.Length];
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
if (args[i] instanceof Function)
|
||||
clientArgs[i] = args[i](this);
|
||||
else
|
||||
clientArgs[i] = args[i];
|
||||
|
||||
|
||||
// compose the packet
|
||||
sendParams().addUint8(0x11)
|
||||
.addUint32(resource.instance.id)
|
||||
.addUint8(et.index)
|
||||
.addUint8Array(Codec.composeVarArray(args, this, true))
|
||||
.done();
|
||||
|
||||
}
|
||||
|
||||
}
|
180
src/DistributedResource.js
Normal file
180
src/DistributedResource.js
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
|
||||
class DistributedResource extends IResource
|
||||
{
|
||||
destroy()
|
||||
{
|
||||
this.destroyed = true;
|
||||
this._emit("destroy");
|
||||
}
|
||||
|
||||
|
||||
|
||||
constructor(connection, template, instanceId, age)
|
||||
{
|
||||
super();
|
||||
|
||||
this._p = {
|
||||
isAttached: false,
|
||||
connection: connection,
|
||||
instanceId: instanceId,
|
||||
age: age,
|
||||
template: template
|
||||
};
|
||||
}
|
||||
|
||||
_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];
|
||||
this._p.isAttached = true;
|
||||
|
||||
var self = this;
|
||||
|
||||
var makeFunc = function(index)
|
||||
{
|
||||
return function () {
|
||||
return self._invoke(index, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
var makeGetter = function(index)
|
||||
{
|
||||
return function () {
|
||||
return self._get(index);
|
||||
};
|
||||
};
|
||||
|
||||
var makeSetter = function(index)
|
||||
{
|
||||
return function (value) {
|
||||
self._set(index, value);
|
||||
};
|
||||
};
|
||||
|
||||
for(var i = 0; i < this._p.template.functions.length; i++)
|
||||
{
|
||||
var ft = this._p.template.functions[i];
|
||||
this[ft.name] = makeFunc(ft.index);
|
||||
}
|
||||
|
||||
for(var i = 0; i < this._p.template.properties.length; i++)
|
||||
{
|
||||
var pt = this._p.template.properties[i];
|
||||
|
||||
Object.defineProperty(this, pt.name, {
|
||||
get: makeGetter(pt.index),
|
||||
set: makeSetter(pt.index),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_emitEventByIndex(index, args)
|
||||
{
|
||||
var et = this._p.template.getEventTemplateByIndex(index);
|
||||
this._emit(et.name, args);
|
||||
this.instance.emitResourceEvent(et.name, null, args);
|
||||
}
|
||||
|
||||
_invoke(index, args) {
|
||||
if (this.destroyed)
|
||||
throw new Exception("Trying to access destroyed object");
|
||||
|
||||
if (index >= this._p.template.functions.length)
|
||||
throw new Exception("Function index is incorrect");
|
||||
|
||||
var reply = new AsyncReply();
|
||||
|
||||
var parameters = Codec.composeVarArray(args, this._p.connection, true);
|
||||
|
||||
var self = this;
|
||||
|
||||
this._p.connection.sendRequest(IIPPacketAction.InvokeFunction,
|
||||
BL().addUint32(self._p.instanceId).addUint8(index).addUint8Array(parameters))
|
||||
.then(function (res) {
|
||||
Codec.parse(res[0], 0, self._p.connection).then(function (rt) {
|
||||
reply.trigger(rt);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
return reply;
|
||||
|
||||
}
|
||||
|
||||
|
||||
_get(index)
|
||||
{
|
||||
if (index >= this._p.properties.length)
|
||||
return null;
|
||||
return this._p.properties[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
_updatePropertyByIndex(index, value)
|
||||
{
|
||||
var pt = this._p.template.getPropertyTemplateByIndex(index);
|
||||
this._p.properties[index] = value;
|
||||
this.instance.modified(pt.name, value);
|
||||
}
|
||||
|
||||
_set(index, value)
|
||||
{
|
||||
if (index >= this._p.properties.length)
|
||||
return null;
|
||||
|
||||
var reply = new AsyncReply();
|
||||
|
||||
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))
|
||||
.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);
|
||||
reply.trigger(null);
|
||||
// nothing to do here
|
||||
});
|
||||
|
||||
return reply;
|
||||
}
|
||||
}
|
40
src/DistributedResourceQueueItem.js
Normal file
40
src/DistributedResourceQueueItem.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
var DistributedResourceQueueItemType =
|
||||
{
|
||||
Propery: 0,
|
||||
Event: 1
|
||||
};
|
||||
|
||||
class DistributedResourceQueueItem {
|
||||
constructor(resource, type, value, index) {
|
||||
this.resource = resource;
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
49
src/EventTemplate.js
Normal file
49
src/EventTemplate.js
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 24/08/2017.
|
||||
*/
|
||||
|
||||
class EventTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.type = MemberType.Event;
|
||||
}
|
||||
|
||||
compose()
|
||||
{
|
||||
var rt = new BinaryList();
|
||||
|
||||
var name = super.compose();
|
||||
if (this.expansion != null) {
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
return rt.addUint8(0x50).addUint32(exp.length).addUint8Array(exp).addUint8(name.length).addUint8Array(name).toArray();
|
||||
}
|
||||
else
|
||||
return rt.addUint8(0x40).addUint32(name.length).addUint8Array(name).toArray();
|
||||
}
|
||||
|
||||
}
|
48
src/FunctionTemplate.js
Normal file
48
src/FunctionTemplate.js
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 27/08/2017.
|
||||
*/
|
||||
|
||||
class FunctionTemplate extends MemberTemplate {
|
||||
compose() {
|
||||
var name = super.compose();
|
||||
var rt = new BinaryList();
|
||||
|
||||
if (this.expansion != null) {
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
|
||||
return rt.addUint8(0x10 | (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();
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.type = MemberType.Function;
|
||||
}
|
||||
}
|
37
src/Guid.js
Normal file
37
src/Guid.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 02/09/2017.
|
||||
*/
|
||||
class Guid
|
||||
{
|
||||
constructor(dc)
|
||||
{
|
||||
this.value = dc;
|
||||
}
|
||||
|
||||
valueOf()
|
||||
{
|
||||
return this.value.getHex(0, 16);
|
||||
}
|
||||
}
|
37
src/IDestructible.js
Normal file
37
src/IDestructible.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 31/08/2017.
|
||||
*/
|
||||
class IDestructible extends IEventHandler
|
||||
{
|
||||
destroy()
|
||||
{
|
||||
this._emit("destroy", this);
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
78
src/IEventHandler.js
Normal file
78
src/IEventHandler.js
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 30/08/2017.
|
||||
*/
|
||||
|
||||
class IEventHandler
|
||||
{
|
||||
_register(event)
|
||||
{
|
||||
this._events[event] = [];
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
this._events = {};
|
||||
}
|
||||
|
||||
_emit(event)
|
||||
{
|
||||
event = event.toLowerCase();
|
||||
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))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
on(event, fn)
|
||||
{
|
||||
event = event.toLowerCase();
|
||||
// add
|
||||
if (!this._events[event])
|
||||
this._events[event] = [];
|
||||
this._events[event].push(fn);
|
||||
return this;
|
||||
}
|
||||
|
||||
off(event, fn)
|
||||
{
|
||||
event = event.toLocaleString();
|
||||
if (this._events[event])
|
||||
{
|
||||
if (fn)
|
||||
{
|
||||
var index = this._events[event].indexOf(fn);
|
||||
if (index > -1)
|
||||
this._events[event].splice(index, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._events[event] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
264
src/IIPAuthPacket.js
Normal file
264
src/IIPAuthPacket.js
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
var IIPAuthPacketCommand =
|
||||
{
|
||||
Action: 0,
|
||||
Declare: 1,
|
||||
Acknowledge: 2,
|
||||
Error: 3
|
||||
};
|
||||
|
||||
var IIPAuthPacketAction =
|
||||
{
|
||||
// Authenticate
|
||||
AuthenticateHash: 0,
|
||||
NewConnection: 0x20,
|
||||
ResumeConnection: 0x21,
|
||||
ConnectionEstablished: 0x28
|
||||
};
|
||||
|
||||
|
||||
var IIPAuthPacketMethod =
|
||||
{
|
||||
None: 0,
|
||||
Certificate: 1,
|
||||
Credentials: 2,
|
||||
Token: 3
|
||||
};
|
||||
|
||||
class IIPAuthPacket
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.command = 0;
|
||||
this.action = 0;
|
||||
this.errorCode = 0;
|
||||
this.errorMessage = "";
|
||||
this.localMethod = 0;
|
||||
this.sourceInfo = "";
|
||||
this.hash = "";
|
||||
this.sessionId = "";
|
||||
this.remoteMethod = 0;
|
||||
this.domain = "";
|
||||
this.CertificateId = 0;
|
||||
this.localUsername = "";
|
||||
this.remoteUsername = "";
|
||||
this.localPassword = "";
|
||||
this.remotePassword = "";
|
||||
this.localToken = [];
|
||||
this.reemoteToken = [];
|
||||
this.asymetricEncryptionKey = [];
|
||||
this.localNonce = [];
|
||||
this.remoteNonce = [];
|
||||
this.dataLengthNeeded = 0;
|
||||
}
|
||||
|
||||
notEnough(offset, ends, needed)
|
||||
{
|
||||
if (offset + needed > ends)
|
||||
{
|
||||
this.dataLengthNeeded = needed - (ends - offset);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
parse(data, offset, ends)
|
||||
{
|
||||
var oOffset = offset;
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.command = data.getUint8(offset) >> 6;
|
||||
|
||||
if (this.command == IIPAuthPacketCommand.Action)
|
||||
{
|
||||
this.action = data[offset++] & 0x3f;
|
||||
|
||||
if (this.action == IIPAuthPacketAction.AuthenticateHash)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 32))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.hash = data.getUint8Array(offset, 32);
|
||||
|
||||
offset += 32;
|
||||
}
|
||||
else if (this.action == IIPAuthPacketAction.NewConnection)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var length = data.getUint16(offset);
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, length))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.sourceInfo = data.clip(offset, length);
|
||||
|
||||
offset += 32;
|
||||
}
|
||||
else if (this.action == IIPAuthPacketAction.ResumeConnection
|
||||
|| this.action == IIPAuthPacketAction.ConnectionEstablished)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 32))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.sessionId = data.clip(offset, 32);
|
||||
|
||||
offset += 32;
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPAuthPacketCommand.Declare)
|
||||
{
|
||||
this.remoteMethod = ((data.getUint8(offset) >> 4) & 0x3);
|
||||
this.localMethod = ((data.getUint8(offset) >> 2) & 0x3);
|
||||
|
||||
var encrypt = ((data.getUint8(offset++) & 0x2) == 0x2);
|
||||
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var domainLength = data.getUint8(offset++);
|
||||
if (this.notEnough(offset, ends, domainLength))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.domain = data.getString(offset, domainLength);
|
||||
|
||||
offset += domainLength;
|
||||
|
||||
|
||||
if (this.remoteMethod == IIPAuthPacketMethod.Credentials)
|
||||
{
|
||||
if (this.localMethod == IIPAuthPacketMethod.None)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 33))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.remoteNonce = data.clip(offset, 32);
|
||||
|
||||
offset += 32;
|
||||
|
||||
var length = data.getUint8(offset++);
|
||||
|
||||
if (this.notEnough(offset, ends, length))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.remoteUsername = data.getString(offset, length);
|
||||
|
||||
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
if (encrypt)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var keyLength = data.getUint16(offset);
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, keyLength))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.asymetricEncryptionKey = data.clip(offset, keyLength);
|
||||
|
||||
offset += keyLength;
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPAuthPacketCommand.Acknowledge)
|
||||
{
|
||||
this.remoteMethod = (data.getUint8(offset) >> 4) & 0x3;
|
||||
this.localMethod = (data.getUint8(offset) >> 2) & 0x3;
|
||||
var encrypt = ((data.getUint8(offset++) & 0x2) == 0x2);
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
|
||||
if (this.remoteMethod == IIPAuthPacketMethod.Credentials)
|
||||
{
|
||||
if (this.localMethod == IIPAuthPacketMethod.None)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 32))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.remoteNonce = data.clip(offset, 32);
|
||||
|
||||
offset += 32;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (encrypt)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var keyLength = data.getUint16(offset);
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, keyLength))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.asymetricEncryptionKey = data.clip(offset, keyLength);
|
||||
|
||||
offset += keyLength;
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPAuthPacketCommand.Error)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 5))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
offset++;
|
||||
this.errorCode = data.getUint8(offset++);
|
||||
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.errorMessage = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return offset - oOffset;
|
||||
|
||||
}
|
||||
}
|
544
src/IIPPacket.js
Normal file
544
src/IIPPacket.js
Normal file
@ -0,0 +1,544 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
|
||||
var IIPPacketCommand =
|
||||
{
|
||||
Event: 0,
|
||||
Request: 1,
|
||||
Reply: 2,
|
||||
Error: 3
|
||||
};
|
||||
|
||||
var IIPPacketEvent =
|
||||
{
|
||||
// Event Manage
|
||||
ResourceReassigned : 0,
|
||||
ResourceDestroyed: 1,
|
||||
|
||||
// Event Invoke
|
||||
PropertyUpdated : 0x10,
|
||||
EventOccured: 0x11
|
||||
};
|
||||
|
||||
var IIPPacketAction =
|
||||
{
|
||||
// Request Manage
|
||||
AttachResource: 0,
|
||||
ReattachResource: 1,
|
||||
DetachResource: 2,
|
||||
CreateResource: 3,
|
||||
DeleteResource: 4,
|
||||
|
||||
// Request Inquire
|
||||
TemplateFromClassName: 0x8,
|
||||
TemplateFromClassId: 0x9,
|
||||
TemplateFromResourceLink: 0xA,
|
||||
TemplateFromResourceId: 0xB,
|
||||
ResourceIdFromResourceLink: 0xC,
|
||||
|
||||
// Request Invoke
|
||||
InvokeFunction: 0x10,
|
||||
GetProperty: 0x11,
|
||||
GetPropertyIfModified: 0x12,
|
||||
SetProperty: 0x13
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class IIPPacket
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.command = 0;
|
||||
this.action = 0;
|
||||
this.event = 0;
|
||||
this.resourceId = 0;
|
||||
this.newResourceId = 0;
|
||||
this.resourceAge = 0;
|
||||
this.content = [];
|
||||
this.errorCode = 0;
|
||||
this.errorMessage = "";
|
||||
this.className = "";
|
||||
this.resourceLink = "";
|
||||
this.classId = "";
|
||||
this.methodIndex = "";
|
||||
this.methodName = "";
|
||||
this.callbackId = 0;
|
||||
this.dataLengthNeeded = 0;
|
||||
}
|
||||
|
||||
notEnough(offset, ends, needed)
|
||||
{
|
||||
if (offset + needed > ends)
|
||||
{
|
||||
this.dataLengthNeeded = needed - (ends - offset);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
parse(data, offset, ends)
|
||||
{
|
||||
var oOffset = offset;
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.command = (data.getUint8(offset) >> 6);
|
||||
|
||||
if (this.command == IIPPacketCommand.Event)
|
||||
{
|
||||
this.event = (data.getUint8(offset++) & 0x3f);
|
||||
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.action = (data.getUint8(offset++) & 0x3f);
|
||||
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.callbackId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
if (this.command == IIPPacketCommand.Event)
|
||||
{
|
||||
if (this.event == IIPPacketEvent.ResourceReassigned)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.newResourceId = data.getUint32( offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.event == IIPPacketEvent.ResourceDestroyed)
|
||||
{
|
||||
// nothing to parse
|
||||
}
|
||||
else if (this.event == IIPPacketEvent.PropertyUpdated)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 2))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.methodIndex = data[offset++];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (this.event == IIPPacketEvent.EventOccured)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 5))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.methodIndex = data.getUint8(offset++);
|
||||
|
||||
var cl = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.content = data.clip(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Request)
|
||||
{
|
||||
if (this.action == IIPPacketAction.AttachResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ReattachResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 8))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.CreateResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint8(offset++);
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.className = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.DeleteResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromClassName)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
var cl = data.getUint8(offset++);
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.className = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromClassId)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 16))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
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))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (this.action == IIPPacketAction.ResourceIdFromResourceLink)
|
||||
{
|
||||
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.InvokeFunction)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 9))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.methodIndex = data.getUint8(offset++);
|
||||
|
||||
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.action == IIPPacketAction.GetProperty)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 5))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.methodIndex = data.getUint8(offset++);
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.GetPropertyIfModified)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 9))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.methodIndex = data[offset++];
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.SetProperty)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 6))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
this.methodIndex = data[offset++];
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Reply)
|
||||
{
|
||||
if (this.action == IIPPacketAction.AttachResource
|
||||
|| this.action == IIPPacketAction.ReattachResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 26))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
this.resourceAge = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
var cl = data.getUint16(offset);
|
||||
offset+=2;
|
||||
|
||||
if (this.notEnough(offset, ends, cl))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.resourceLink = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
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.action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
else if (this.action == IIPPacketAction.CreateResource)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 20))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.classId = data.GetGuid(offset);
|
||||
offset += 16;
|
||||
|
||||
this.resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
|
||||
}
|
||||
else if (this.action == IIPPacketAction.DetachResource)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
else if (this.action == IIPPacketAction.TemplateFromClassName
|
||||
|| this.action == IIPPacketAction.TemplateFromClassId
|
||||
|| this.action == IIPPacketAction.TemplateFromResourceLink
|
||||
|| this.action == IIPPacketAction.TemplateFromResourceId)
|
||||
{
|
||||
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.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)
|
||||
{
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (this.action == IIPPacketAction.SetProperty)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
else if (this.command == IIPPacketCommand.Error)
|
||||
{
|
||||
// Error
|
||||
if (this.notEnough(offset, ends, 4))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.callbackId = data.getUint32(offset);
|
||||
|
||||
if (this.notEnough(offset, ends, 1))
|
||||
return -this.dataLengthNeeded;
|
||||
|
||||
this.errorCode = data.getUint8(offset++);
|
||||
|
||||
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.errorMessage = data.getString(offset, cl);
|
||||
offset += cl;
|
||||
}
|
||||
|
||||
return offset - oOffset;
|
||||
}
|
||||
}
|
59
src/IResource.js
Normal file
59
src/IResource.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
var ResourceTrigger =
|
||||
{
|
||||
Loaded : 0,
|
||||
Initialize: 1,
|
||||
Terminate: 2,
|
||||
Configure: 3,
|
||||
SystemInitialized: 4,
|
||||
SystemTerminated: 5,
|
||||
SystemReload: 6
|
||||
};
|
||||
|
||||
class IResource extends IDestructible
|
||||
{
|
||||
trigger(trigger)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
static getTemplate()
|
||||
{
|
||||
return {
|
||||
namespace: "Esiur",
|
||||
properties: [],
|
||||
functions: [],
|
||||
events: []
|
||||
}
|
||||
}
|
||||
}
|
44
src/IStore.js
Normal file
44
src/IStore.js
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
|
||||
class IStore extends IResource {
|
||||
get(path) {
|
||||
|
||||
}
|
||||
|
||||
retrieve(iid) {
|
||||
|
||||
}
|
||||
|
||||
put(resource) {
|
||||
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
}
|
142
src/Instance.js
Normal file
142
src/Instance.js
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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 29/08/2017.
|
||||
*/
|
||||
class Instance extends IEventHandler
|
||||
{
|
||||
|
||||
getAge(index)
|
||||
{
|
||||
if (index < this.ages.Count)
|
||||
return this.ages[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
deserialize(properties)
|
||||
{
|
||||
for(var i = 0; i < this.template.properties.length; i++)
|
||||
this.resource[this.template.properties[i].name] = properties[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
serialize()
|
||||
{
|
||||
var props = [];
|
||||
|
||||
for (var i = 0; i < this.template.properties.length; i++)
|
||||
props.push(this.resource[this.template.properties[i].name]);
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
isStorable()
|
||||
{
|
||||
return resource instanceof Storable;
|
||||
}
|
||||
|
||||
|
||||
modified(propertyName = null, newValue = null, oldValue = null)
|
||||
{
|
||||
if (propertyName == null)
|
||||
propertyName = modified.caller.name;
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
var val = {};
|
||||
if (this.getPropertyValue(propertyName, val))
|
||||
super._emit("ResourceModified", this.resource, propertyName, val.value, oldValue);
|
||||
}
|
||||
else
|
||||
super._emit("ResourceModified", this.resource, propertyName, newValue, oldValue);
|
||||
}
|
||||
|
||||
emitResourceEvent(name, receivers, args)
|
||||
{
|
||||
super._emit("ResourceEventOccured", this.resource, name, receivers, args);
|
||||
}
|
||||
|
||||
getPropertyValue(name, resultObject)
|
||||
{
|
||||
for (var i = 0; i < this.template.properties.length; i++)
|
||||
if (this.template.properties[i].name == name)
|
||||
{
|
||||
resultObject.value = this.resource[name];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
constructor(id, name, resource, store)
|
||||
{
|
||||
super();
|
||||
|
||||
this.store = store;
|
||||
this.resource = resource;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
|
||||
this.children = new AutoList();
|
||||
this.parents = new AutoList();
|
||||
|
||||
var self = this;
|
||||
|
||||
this.children.on("add", function(value){
|
||||
value.instance.parents.add(self.resource);
|
||||
});
|
||||
|
||||
this.children.on("remove", function(value){
|
||||
value.instance.parents.remove(self.resource);
|
||||
});
|
||||
|
||||
|
||||
this.resource.on("Destroy", function(sender){
|
||||
self._emit("ResourceDestroyed", sender);
|
||||
});
|
||||
|
||||
this.template = Warehouse.getTemplateByType(this.resource.constructor);
|
||||
|
||||
// set ages
|
||||
this.ages = new Uint32Array(this.template.properties.length);
|
||||
|
||||
|
||||
// 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));
|
||||
|
||||
}
|
||||
|
||||
}
|
38
src/MemberTemplate.js
Normal file
38
src/MemberTemplate.js
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 24/08/2017.
|
||||
*/
|
||||
|
||||
|
||||
var MemberType = {
|
||||
Function: 0,
|
||||
Property: 1,
|
||||
Event: 2
|
||||
};
|
||||
|
||||
class MemberTemplate {
|
||||
compose() {
|
||||
return DC.stringToBytes(this.name);
|
||||
}
|
||||
}
|
115
src/NetworkBuffer.js
Normal file
115
src/NetworkBuffer.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 01/09/2017.
|
||||
*/
|
||||
|
||||
class NetworkBuffer {
|
||||
constructor() {
|
||||
this.neededDataLength = 0;
|
||||
this.data = new DC(0);
|
||||
}
|
||||
|
||||
get protected() {
|
||||
return this.neededDataLength > this.data.length;
|
||||
}
|
||||
|
||||
get available() {
|
||||
|
||||
return this.data.length;
|
||||
}
|
||||
|
||||
holdAllForNextWrite(src) {
|
||||
this.holdFor(src, src.length + 1);
|
||||
}
|
||||
|
||||
holdForNextWrite(src, offset, size) {
|
||||
this.holdFor(src, offset, size, size + 1);
|
||||
}
|
||||
|
||||
|
||||
holdFor(src, offset, size, needed) {
|
||||
if (size >= needed)
|
||||
throw new Exception("Size >= Needed !");
|
||||
|
||||
this.data = DC.combine(src, offset, size, this.data, 0, this.data.length);
|
||||
this.neededDataLength = needed;
|
||||
}
|
||||
|
||||
holdAllFor(src, needed) {
|
||||
this.holdFor(src, 0, src.length, needed);
|
||||
}
|
||||
|
||||
protect(data, offset, needed) {
|
||||
var dataLength = data.length - offset;
|
||||
|
||||
// protection
|
||||
if (dataLength < needed) {
|
||||
this.holdFor(data, offset, dataLength, needed);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
writeAll(src) {
|
||||
this.write(src, 0, src.length ? src.length : src.byteLength);
|
||||
}
|
||||
|
||||
write(src, offset, length) {
|
||||
this.data = this.data.append(src, offset, length);
|
||||
}
|
||||
|
||||
get canRead() {
|
||||
if (this.data.length == 0)
|
||||
return false;
|
||||
else if (this.data.length < this.neededDataLength)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
read() {
|
||||
if (this.data.length == 0)
|
||||
return null;
|
||||
|
||||
var rt = null;
|
||||
|
||||
if (this.neededDataLength == 0) {
|
||||
rt = this.data;
|
||||
this.data = new DC(0);
|
||||
}
|
||||
else {
|
||||
if (this.data.length >= this.neededDataLength) {
|
||||
rt = this.data;
|
||||
this.data = new DC(0);
|
||||
this.neededDataLength = 0;
|
||||
return rt;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
}
|
30
src/NotModified.js
Normal file
30
src/NotModified.js
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 26/08/2017.
|
||||
*/
|
||||
|
||||
class NotModified
|
||||
{
|
||||
|
||||
}
|
83
src/PropertyTemplate.js
Normal file
83
src/PropertyTemplate.js
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 27/08/2017.
|
||||
*/
|
||||
|
||||
var PropertyPermission = {
|
||||
Read: 1,
|
||||
Write: 2,
|
||||
ReadWrite: 3
|
||||
};
|
||||
|
||||
|
||||
class PropertyTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.type = MemberType.Property;
|
||||
}
|
||||
|
||||
compose()
|
||||
{
|
||||
var name = super.compose();
|
||||
var rt = new BinaryList();
|
||||
|
||||
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)
|
||||
.addUint32(wexp.length)
|
||||
.addUint8Array(wexp)
|
||||
.addUint32(rexp.length)
|
||||
.addUint8Array(rexp)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name).toArray();
|
||||
}
|
||||
else if (this.writeExpansion != null)
|
||||
{
|
||||
var wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return rt.addUint8(0x30 | this.permission)
|
||||
.addUint32(wexp.length)
|
||||
.addUint8Array(wexp)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name).toArray();
|
||||
}
|
||||
else if (this.readExpansion != null)
|
||||
{
|
||||
var rexp = DC.stringToBytes(this.readExpansion);
|
||||
return rt.addUint8(0x28 | this.permission)
|
||||
.addUint32(rexp.length)
|
||||
.addUint8Array(rexp)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name).toArray();
|
||||
}
|
||||
else
|
||||
return rt.addUint8(0x20 | this.permission)
|
||||
.addUint32(name.length)
|
||||
.addUint8Array(name).toArray();
|
||||
}
|
||||
}
|
36
src/ResourceArray.js
Normal file
36
src/ResourceArray.js
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 26/08/2017.
|
||||
*/
|
||||
|
||||
class ResourceArray extends Array
|
||||
{
|
||||
push(value)
|
||||
{
|
||||
if (value instanceof IResource)
|
||||
super.push(value);
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
284
src/ResourceTemplate.js
Normal file
284
src/ResourceTemplate.js
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class ResourceTemplate {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
getEventTemplateByName(eventName) {
|
||||
for (var i = 0; i < this.events.length; i++)
|
||||
if (this.events[i].name == eventName)
|
||||
return this.events[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
getEventTemplateByIndex(index) {
|
||||
for (var i = 0; i < this.events.length; i++)
|
||||
if (this.events[i].index == index)
|
||||
return this.events[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
getFunctionTemplateByName(functionName) {
|
||||
for (var i = 0; i < this.functions.length; i++)
|
||||
if (this.functions[i].name == functionName)
|
||||
return this.functions[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
getFunctionTemplateByIndex(index) {
|
||||
for (var i = 0; i < this.functions.length; i++)
|
||||
if (this.functions[i].index == index)
|
||||
return this.functions[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
getPropertyTemplateByName(propertyName) {
|
||||
for (var i = 0; i < this.properties.length; i++)
|
||||
if (this.properties[i].name == propertyName)
|
||||
return this.properties[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
getPropertyTemplateByIndex(index) {
|
||||
for (var i = 0; i < this.properties.length; i++)
|
||||
if (this.properties[i].index == index)
|
||||
return this.properties[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
template: {
|
||||
properties: [
|
||||
{name: 'size', read: null, write: null}
|
||||
],
|
||||
functions: [
|
||||
|
||||
],
|
||||
events: [
|
||||
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
constructor(type) {
|
||||
|
||||
|
||||
this.properties = [];
|
||||
this.events = [];
|
||||
this.functions = [];
|
||||
this.members = [];
|
||||
|
||||
if (type === undefined)
|
||||
return;
|
||||
|
||||
var template = type.getTemplate();
|
||||
|
||||
// set guid
|
||||
this.className = template.namespace + "." + type.prototype.constructor.name;
|
||||
|
||||
this.classId = (new DC(sha256.arrayBuffer(this.className))).getGuid(0);
|
||||
|
||||
//byte currentIndex = 0;
|
||||
|
||||
for (var i = 0; i < template.properties.length; i++) {
|
||||
var pt = new PropertyTemplate();
|
||||
pt.name = template.properties[i].name;
|
||||
pt.index = i;
|
||||
pt.readExpansion = template.properties[i].read;
|
||||
pt.writeExpansion = template.properties[i].write;
|
||||
this.properties.push(pt);
|
||||
}
|
||||
|
||||
for (var i = 0; i < template.events.length; i++) {
|
||||
var et = new EventTemplate();
|
||||
et.name = template.events[i].name;
|
||||
et.index = i;
|
||||
et.expansion = template.events[i].expansion;
|
||||
this.events.push(et);
|
||||
}
|
||||
|
||||
for (var i = 0; i < template.functions.length; i++) {
|
||||
var ft = new FunctionTemplate();
|
||||
ft.name = template.functions[i].name;
|
||||
ft.index = i;
|
||||
ft.isVoid = template.functions[i].void;
|
||||
ft.expansion = template.functions[i].expansion;
|
||||
this.functions.push(ft);
|
||||
}
|
||||
|
||||
|
||||
// append signals
|
||||
for (var i = 0; i < this.events.length; i++)
|
||||
this.members.push(this.events[i]);
|
||||
// append slots
|
||||
for (var i = 0; i < this.functions.length; i++)
|
||||
this.members.push(this.functions[i]);
|
||||
// append properties
|
||||
for (var i = 0; i < this.properties.length; i++)
|
||||
this.members.push(this.properties[i]);
|
||||
|
||||
// bake it binarily
|
||||
var b = new BinaryList();
|
||||
var cls = DC.stringToBytes(this.className);
|
||||
b.addUint8Array(this.classId.value)
|
||||
.addUint8(cls.length).addUint8Array(cls).addUint32(template.version).addUint16(this.members.length);
|
||||
|
||||
for (var i = 0; i < this.functions.length; i++)
|
||||
b.addUint8Array(this.functions[i].compose());
|
||||
|
||||
for (var i = 0; i < this.properties.length; i++)
|
||||
b.addUint8Array(this.properties[i].compose());
|
||||
|
||||
for (var i = 0; i < this.events.length; i++)
|
||||
b.addUint8Array(this.events[i].compose());
|
||||
|
||||
this.content = b.toArray();
|
||||
}
|
||||
|
||||
static parse(data, offset = 0, contentLength = -1) {
|
||||
|
||||
if (contentLength == -1)
|
||||
contentLength = data.length;
|
||||
|
||||
var ends = offset + contentLength;
|
||||
|
||||
var oOffset = offset;
|
||||
|
||||
// start parsing...
|
||||
|
||||
var od = new ResourceTemplate();
|
||||
od.content = data.clip(offset, contentLength);
|
||||
|
||||
od.classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
od.className = data.getString(offset + 1, data.getUint8(offset));
|
||||
offset += data.getUint8(offset) + 1;
|
||||
|
||||
od.version = data.getInt32(offset);
|
||||
offset += 4;
|
||||
|
||||
var methodsCount = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
var functionIndex = 0;
|
||||
var propertyIndex = 0;
|
||||
var eventIndex = 0;
|
||||
|
||||
for (var i = 0; i < methodsCount; i++) {
|
||||
var type = data.getUint8(offset) >> 5;
|
||||
|
||||
if (type == 0) // function
|
||||
{
|
||||
var ft = new FunctionTemplate();
|
||||
ft.index = functionIndex++;
|
||||
var expansion = ((data.getUint8(offset) & 0x10) == 0x10);
|
||||
ft.isVoid = ((data.getUint8(offset++) & 0x08) == 0x08);
|
||||
ft.name = data.getString(offset + 1, data.getUint8(offset));// Encoding.ASCII.getString(data, (int)offset + 1, data.getUint8(offset));
|
||||
offset += data.getUint8(offset) + 1;
|
||||
|
||||
if (expansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
ft.expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
od.functions.push(ft);
|
||||
}
|
||||
else if (type == 1) // property
|
||||
{
|
||||
|
||||
var pt = new PropertyTemplate();
|
||||
pt.index = propertyIndex++;
|
||||
var readExpansion = ((data.getUint8(offset) & 0x8) == 0x8);
|
||||
var writeExpansion = ((data.getUint8(offset) & 0x10) == 0x10);
|
||||
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;
|
||||
|
||||
if (readExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
pt.readExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
if (writeExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
pt.writeExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
od.properties.push(pt);
|
||||
}
|
||||
else if (type == 2) // Event
|
||||
{
|
||||
var et = new EventTemplate();
|
||||
et.index = eventIndex++;
|
||||
var expansion = ((data.getUint8(offset++) & 0x10) == 0x10);
|
||||
|
||||
et.name = data.getString(offset + 1, data.getUint8(offset));// Encoding.ASCII.getString(data, (int)offset + 1, (int)data.getUint8(offset));
|
||||
offset += data.getUint8(offset) + 1;
|
||||
|
||||
if (expansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
et.expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
od.events.push(et);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
for (var i = 0; i < od.events.length; i++)
|
||||
od.members.push(od.events[i]);
|
||||
// append slots
|
||||
for (var i = 0; i < od.functions.length; i++)
|
||||
od.members.push(od.functions[i]);
|
||||
// append properties
|
||||
for (var i = 0; i < od.properties.length; i++)
|
||||
od.members.push(od.properties[i]);
|
||||
|
||||
|
||||
return od;
|
||||
}
|
||||
}
|
39
src/SendList.js
Normal file
39
src/SendList.js
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 02/09/2017.
|
||||
*/
|
||||
|
||||
class SendList extends BinaryList
|
||||
{
|
||||
constructor(connection)
|
||||
{
|
||||
super();
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
done()
|
||||
{
|
||||
this.connection.send(this.toArray());
|
||||
}
|
||||
}
|
37
src/Structure.js
Normal file
37
src/Structure.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 26/08/2017.
|
||||
*/
|
||||
|
||||
class Structure
|
||||
{
|
||||
getKeys() {
|
||||
var rt = [];
|
||||
for (var i in this)
|
||||
if (!(this[i] instanceof Function))
|
||||
rt.push(i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
}
|
36
src/StructureArray.js
Normal file
36
src/StructureArray.js
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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/09/2017.
|
||||
*/
|
||||
|
||||
class StructureArray extends Array
|
||||
{
|
||||
push(value)
|
||||
{
|
||||
if (value instanceof Structure)
|
||||
super.push(value);
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
129
src/Warehouse.js
Normal file
129
src/Warehouse.js
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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/07/2017.
|
||||
*/
|
||||
var Warehouse = {
|
||||
|
||||
stores: [],
|
||||
resources: {},
|
||||
resourceCounter: 0,
|
||||
templates: {},
|
||||
|
||||
new(type, name, store = null, parent = null)
|
||||
{
|
||||
var res = type();
|
||||
Warehouse.put(res, name, store, parent);
|
||||
return res;
|
||||
},
|
||||
|
||||
get: function(id)
|
||||
{
|
||||
if (Warehouse.resources[id])
|
||||
return new AsyncReply(Warehouse.resources[id]);
|
||||
else
|
||||
return null;
|
||||
},
|
||||
|
||||
put: function(resource, name, store, parent){
|
||||
resource.instance = new Instance(Warehouse.resourceCounter++, name, resource, store);
|
||||
//resource.instance.children.on("add", Warehouse._onChildrenAdd).on("remove", Warehouse._onChildrenRemove);
|
||||
//resource.instance.parents.on("add", Warehouse._onParentsAdd).on("remove", Warehouse._onParentsRemove);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
parent.instance.children.add(resource);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(resource instanceof IStore))
|
||||
store.instance.children.add(resource);
|
||||
}
|
||||
|
||||
if (resource instanceof IStore)
|
||||
Warehouse.stores.push(resource);
|
||||
else
|
||||
store.put(resource);
|
||||
|
||||
Warehouse.resources[resource.instance.id] = resource;
|
||||
},
|
||||
|
||||
_onParentsRemove: function(value)
|
||||
{
|
||||
if (value.instance.children.contains(value))
|
||||
value.instance.children.remove(value);
|
||||
},
|
||||
|
||||
_onParentsAdd: function(value)
|
||||
{
|
||||
if (!value.instance.children.contains(value))
|
||||
value.instance.children.add(value);
|
||||
},
|
||||
|
||||
_onChildrenRemove: function(value)
|
||||
{
|
||||
if (value.instance.parents.contains(value))
|
||||
value.instance.parents.remove(value);
|
||||
},
|
||||
|
||||
_onChildrenAdd: function(value)
|
||||
{
|
||||
if (!value.instance.parents.contains(value))
|
||||
value.instance.parents.add(value);
|
||||
},
|
||||
|
||||
putTemplate: function(template)
|
||||
{
|
||||
if (Warehouse.templates[template.classId])
|
||||
Warehouse.templates[template.classId] = template;
|
||||
},
|
||||
|
||||
getTemplateByType: function(type)
|
||||
{
|
||||
// loaded ?
|
||||
for (var t in Warehouse.templates)
|
||||
if (Warehouse.templates[t].className == typeof(type))
|
||||
return t;
|
||||
|
||||
var template = new ResourceTemplate(type);
|
||||
Warehouse.templates[template.classId] = 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;
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user