mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-05-06 12:02:57 +00:00
1.0
This commit is contained in:
parent
de338a3350
commit
29c8252c10
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Dart",
|
||||||
|
"program": "bin/main.dart",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
58
bin/Core/AsyncBag.dart
Normal file
58
bin/Core/AsyncBag.dart
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import 'AsyncReply.dart';
|
||||||
|
|
||||||
|
class AsyncBag<T> extends AsyncReply<List<T>>
|
||||||
|
{
|
||||||
|
|
||||||
|
List<AsyncReply<T>> _replies = new List<AsyncReply<T>>();
|
||||||
|
List<T> _results = new List<T>();
|
||||||
|
|
||||||
|
int _count = 0;
|
||||||
|
bool _sealedBag = false;
|
||||||
|
|
||||||
|
seal()
|
||||||
|
{
|
||||||
|
if (_sealedBag)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_sealedBag = true;
|
||||||
|
|
||||||
|
if (_results.length == 0)
|
||||||
|
trigger(new List<T>());
|
||||||
|
|
||||||
|
for (var i = 0; i < _results.length; i++)
|
||||||
|
{
|
||||||
|
var k = _replies[i];
|
||||||
|
var index = i;
|
||||||
|
|
||||||
|
k.then((r)
|
||||||
|
{
|
||||||
|
_results[index] = r;
|
||||||
|
_count++;
|
||||||
|
if (_count == _results.length)
|
||||||
|
trigger(_results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add(AsyncReply<T> reply)
|
||||||
|
{
|
||||||
|
if (!_sealedBag)
|
||||||
|
{
|
||||||
|
_results.add(null);
|
||||||
|
_replies.add(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addBag(AsyncBag<T> bag)
|
||||||
|
{
|
||||||
|
bag._replies.forEach((r) {
|
||||||
|
add(r);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncBag()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
bin/Core/AsyncException.dart
Normal file
33
bin/Core/AsyncException.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
import 'ExceptionCode.dart';
|
||||||
|
import 'ErrorType.dart';
|
||||||
|
|
||||||
|
class AsyncException implements Exception
|
||||||
|
{
|
||||||
|
final ErrorType type;
|
||||||
|
final int code;
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
AsyncException(this.type, this.code, this.message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static toAsyncException(Exception ex)
|
||||||
|
{
|
||||||
|
return ex is AsyncException ? ex
|
||||||
|
: new AsyncException(ErrorType.Exception, 0, ex.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
String errMsg() {
|
||||||
|
if (type == ErrorType.Management)
|
||||||
|
return ExceptionCode.values.elementAt(code).toString() + ": " + (message ?? "");
|
||||||
|
else
|
||||||
|
return code.toString() + ": " + message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return errMsg();
|
||||||
|
}
|
||||||
|
}
|
51
bin/Core/AsyncQueue.dart
Normal file
51
bin/Core/AsyncQueue.dart
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
library esiur;
|
||||||
|
|
||||||
|
import 'AsyncReply.dart';
|
||||||
|
|
||||||
|
class AsyncQueue<T> extends AsyncReply<T>
|
||||||
|
{
|
||||||
|
List<AsyncReply<T>> _list = new List<AsyncReply<T>>();
|
||||||
|
|
||||||
|
// object queueLock = new object();
|
||||||
|
|
||||||
|
add(AsyncReply<T> reply)
|
||||||
|
{
|
||||||
|
//lock (queueLock)
|
||||||
|
_list.add(reply);
|
||||||
|
|
||||||
|
//super._resultReady = false;
|
||||||
|
super.setResultReady(false);
|
||||||
|
|
||||||
|
reply.then(processQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(AsyncReply<T> reply)
|
||||||
|
{
|
||||||
|
//lock (queueLock)
|
||||||
|
_list.remove(reply);
|
||||||
|
processQueue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void processQueue(T o)
|
||||||
|
{
|
||||||
|
//lock (queueLock)
|
||||||
|
for (var i = 0; i < _list.length; i++)
|
||||||
|
if (_list[i].ready)
|
||||||
|
{
|
||||||
|
super.trigger(_list[i].result);
|
||||||
|
_list.removeAt(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
//super._resultReady = (_list.length == 0);
|
||||||
|
super.setResultReady(_list.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncQueue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
220
bin/Core/AsyncReply.dart
Normal file
220
bin/Core/AsyncReply.dart
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:core';
|
||||||
|
import 'AsyncException.dart';
|
||||||
|
import 'ProgressType.dart';
|
||||||
|
|
||||||
|
class AsyncReply<T> implements Future<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
List<Function(T)> _callbacks = new List<Function(T)>();
|
||||||
|
|
||||||
|
T _result;
|
||||||
|
|
||||||
|
List<Function(AsyncException)> _errorCallbacks = new List<Function(AsyncException)>();
|
||||||
|
|
||||||
|
List<Function(ProgressType, int, int)> _progressCallbacks = new List<Function(ProgressType, int, int)>();
|
||||||
|
|
||||||
|
List<Function(T)> _chunkCallbacks = new List<Function(T)>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool _resultReady = false;
|
||||||
|
AsyncException _exception;
|
||||||
|
|
||||||
|
|
||||||
|
bool get ready
|
||||||
|
{
|
||||||
|
return _resultReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
T get result
|
||||||
|
{
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
|
||||||
|
setResultReady(bool val)
|
||||||
|
{
|
||||||
|
_resultReady = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<R> then<R>(FutureOr<R> onValue(T value), {Function onError})
|
||||||
|
{
|
||||||
|
_callbacks.add(onValue);
|
||||||
|
if (onError != null)
|
||||||
|
{
|
||||||
|
if (onError is Function(dynamic, dynamic))
|
||||||
|
{
|
||||||
|
_errorCallbacks.add((ex)=>onError(ex, null));
|
||||||
|
}
|
||||||
|
else if (onError is Function(dynamic))
|
||||||
|
{
|
||||||
|
_errorCallbacks.add(onError);
|
||||||
|
}
|
||||||
|
else if (onError is Function())
|
||||||
|
{
|
||||||
|
_errorCallbacks.add((ex)=>onError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (_resultReady)
|
||||||
|
onValue(result);
|
||||||
|
|
||||||
|
return this as AsyncReply<R>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<T> whenComplete(FutureOr action())
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
//_callbacks.add(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<T> asStream()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<T> catchError(Function onError, {bool test(Object error)})
|
||||||
|
{
|
||||||
|
return this.error(onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()})
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<T> _then_old(Function(T) callback)
|
||||||
|
{
|
||||||
|
_callbacks.add(callback);
|
||||||
|
|
||||||
|
if (_resultReady)
|
||||||
|
callback(result);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AsyncReply<T> error(Function(dynamic) callback)
|
||||||
|
{
|
||||||
|
_errorCallbacks.add(callback);
|
||||||
|
|
||||||
|
if (_exception != null)
|
||||||
|
callback(_exception);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<T> progress(Function(ProgressType, int, int) callback)
|
||||||
|
{
|
||||||
|
_progressCallbacks.add(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AsyncReply<T> chunk(Function(T) callback)
|
||||||
|
{
|
||||||
|
_chunkCallbacks.add(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger(T result)
|
||||||
|
{
|
||||||
|
|
||||||
|
// lock (callbacksLock)
|
||||||
|
// {
|
||||||
|
if (_resultReady)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_result = result;
|
||||||
|
_resultReady = true;
|
||||||
|
|
||||||
|
_callbacks.forEach((x) {
|
||||||
|
x(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerError(Exception exception)
|
||||||
|
{
|
||||||
|
if (_resultReady)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_exception = AsyncException.toAsyncException(exception);
|
||||||
|
|
||||||
|
///lock (callbacksLock)
|
||||||
|
//{
|
||||||
|
_errorCallbacks.forEach((x) {
|
||||||
|
x(_exception);
|
||||||
|
});
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerProgress(ProgressType type, int value, int max)
|
||||||
|
{
|
||||||
|
if (_resultReady)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//lock (callbacksLock)
|
||||||
|
//{
|
||||||
|
_progressCallbacks.forEach((x) {
|
||||||
|
x(type, value, max);
|
||||||
|
});
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
triggerChunk(T value)
|
||||||
|
{
|
||||||
|
if (_resultReady)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//lock (callbacksLock)
|
||||||
|
//{
|
||||||
|
_chunkCallbacks.forEach((x) {
|
||||||
|
x(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AsyncReply.ready(T result)
|
||||||
|
{
|
||||||
|
_resultReady = true;
|
||||||
|
_result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
bin/Core/ErrorType.dart
Normal file
5
bin/Core/ErrorType.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
enum ErrorType
|
||||||
|
{
|
||||||
|
Management,
|
||||||
|
Exception
|
||||||
|
}
|
31
bin/Core/ExceptionCode.dart
Normal file
31
bin/Core/ExceptionCode.dart
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
enum ExceptionCode
|
||||||
|
{
|
||||||
|
HostNotReachable,
|
||||||
|
AccessDenied,
|
||||||
|
ResourceNotFound,
|
||||||
|
AttachDenied,
|
||||||
|
InvalidMethod,
|
||||||
|
InvokeDenied,
|
||||||
|
CreateDenied,
|
||||||
|
AddParentDenied,
|
||||||
|
AddChildDenied,
|
||||||
|
ViewAttributeDenied,
|
||||||
|
UpdateAttributeDenied,
|
||||||
|
StoreNotFound,
|
||||||
|
ParentNotFound,
|
||||||
|
ChildNotFound,
|
||||||
|
ResourceIsNotStore,
|
||||||
|
DeleteDenied,
|
||||||
|
DeleteFailed,
|
||||||
|
UpdateAttributeFailed,
|
||||||
|
GetAttributesFailed,
|
||||||
|
ClearAttributesFailed,
|
||||||
|
TemplateNotFound,
|
||||||
|
RenameDenied,
|
||||||
|
ClassNotFound,
|
||||||
|
MethodNotFound,
|
||||||
|
PropertyNotFound,
|
||||||
|
SetPropertyDenied,
|
||||||
|
ReadOnlyProperty
|
||||||
|
}
|
10
bin/Core/IDestructible.dart
Normal file
10
bin/Core/IDestructible.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
library esiur;
|
||||||
|
|
||||||
|
import 'IEventHandler.dart';
|
||||||
|
|
||||||
|
typedef DestroyedEvent(sender);
|
||||||
|
|
||||||
|
abstract class IDestructible extends IEventHandler
|
||||||
|
{
|
||||||
|
void destroy();
|
||||||
|
}
|
48
bin/Core/IEventHandler.dart
Normal file
48
bin/Core/IEventHandler.dart
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
class IEventHandler
|
||||||
|
{
|
||||||
|
Map<String, List<Function>> _events;
|
||||||
|
|
||||||
|
register(String event)
|
||||||
|
{
|
||||||
|
_events[event.toLowerCase()] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
IEventHandler()
|
||||||
|
{
|
||||||
|
_events = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
emitArgs(String event, List arguments)
|
||||||
|
{
|
||||||
|
event = event.toLowerCase();
|
||||||
|
if (_events.containsKey(event))
|
||||||
|
for(var i = 0; i < _events[event].length; i++)
|
||||||
|
if (Function.apply(_events[event][i], arguments) != null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
on(String event, Function callback)
|
||||||
|
{
|
||||||
|
event = event.toLowerCase();
|
||||||
|
// add
|
||||||
|
if (!_events.containsKey(event))
|
||||||
|
register(event);
|
||||||
|
|
||||||
|
_events[event].add(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
off(event, callback)
|
||||||
|
{
|
||||||
|
event = event.toString();
|
||||||
|
if (_events.containsKey(event))
|
||||||
|
{
|
||||||
|
if (callback != null)
|
||||||
|
_events[event].remove(callback);
|
||||||
|
else
|
||||||
|
this._events[event] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
bin/Core/ProgressType.dart
Normal file
5
bin/Core/ProgressType.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
enum ProgressType
|
||||||
|
{
|
||||||
|
Execution,
|
||||||
|
Network,
|
||||||
|
}
|
200
bin/Data/AutoList.dart
Normal file
200
bin/Data/AutoList.dart
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
import '../Core/IDestructible.dart';
|
||||||
|
import 'Codec.dart';
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
class AutoList<T, ST> extends IDestructible with IterableMixin
|
||||||
|
{
|
||||||
|
|
||||||
|
List<T> _list = new List<T>();
|
||||||
|
|
||||||
|
|
||||||
|
ST _state;
|
||||||
|
bool _removableList;
|
||||||
|
|
||||||
|
sort(Function comparer)
|
||||||
|
{
|
||||||
|
_list.sort(comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<T> get iterator => _list.iterator;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert AutoList to array
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Array</returns>
|
||||||
|
//List<T> toList()
|
||||||
|
//{
|
||||||
|
// list.OrderBy()
|
||||||
|
// return _list;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
/// Create a new instance of AutoList
|
||||||
|
/// <param name="state">State object to be included when an event is raised.</param>
|
||||||
|
AutoList([ST state, List<T> values])
|
||||||
|
{
|
||||||
|
this._state = state;
|
||||||
|
this._removableList = Codec.implementsInterface<T, IDestructible>();
|
||||||
|
|
||||||
|
if (values != null)
|
||||||
|
addRange(values);
|
||||||
|
|
||||||
|
register("modified");
|
||||||
|
register("added");
|
||||||
|
register("removed");
|
||||||
|
register("cleared");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Synchronization lock of the list
|
||||||
|
/// </summary>
|
||||||
|
//public object SyncRoot
|
||||||
|
//{
|
||||||
|
// get
|
||||||
|
// {
|
||||||
|
// return syncRoot;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// First item in the list
|
||||||
|
/// </summary>
|
||||||
|
//T first()
|
||||||
|
//{
|
||||||
|
// return _list.first;
|
||||||
|
//}
|
||||||
|
|
||||||
|
operator [](index)
|
||||||
|
{
|
||||||
|
return _list[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
operator []=(index, value)
|
||||||
|
{
|
||||||
|
var oldValue = _list[index];
|
||||||
|
|
||||||
|
if (_removableList)
|
||||||
|
{
|
||||||
|
if (oldValue != null)
|
||||||
|
(oldValue as IDestructible).off("destroy", _itemDestroyed);
|
||||||
|
if (value != null)
|
||||||
|
value.on("destroy", _itemDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
//lock (syncRoot)
|
||||||
|
_list[index] = value;
|
||||||
|
|
||||||
|
emitArgs("modified", [_state, index, oldValue, value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add item to the list
|
||||||
|
/// </summary>
|
||||||
|
add(T value)
|
||||||
|
{
|
||||||
|
if (_removableList)
|
||||||
|
if (value != null)
|
||||||
|
(value as IDestructible).on("destroy", _itemDestroyed);
|
||||||
|
|
||||||
|
// lock (syncRoot)
|
||||||
|
_list.add(value);
|
||||||
|
|
||||||
|
emitArgs("add",[_state, value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an array of items to the list
|
||||||
|
/// </summary>
|
||||||
|
addRange(List<T> values)
|
||||||
|
{
|
||||||
|
values.forEach((x)=>add(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
_itemDestroyed(T sender)
|
||||||
|
{
|
||||||
|
remove(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear the list
|
||||||
|
/// </summary>
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
if (_removableList)
|
||||||
|
_list.forEach((x)=>(x as IDestructible)?.off("destroy", _itemDestroyed));
|
||||||
|
|
||||||
|
|
||||||
|
// lock (syncRoot)
|
||||||
|
_list.clear();
|
||||||
|
|
||||||
|
emitArgs("cleared", [_state]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove an item from the list
|
||||||
|
/// <param name="value">Item to remove</param>
|
||||||
|
/// </summary>
|
||||||
|
remove(T value)
|
||||||
|
{
|
||||||
|
if (!_list.contains(value))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_removableList)
|
||||||
|
if (value != null)
|
||||||
|
(value as IDestructible).off("destroy", _itemDestroyed);
|
||||||
|
|
||||||
|
//lock (syncRoot)
|
||||||
|
_list.remove(value);
|
||||||
|
|
||||||
|
emitArgs("removed", [_state, value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of items in the list
|
||||||
|
/// </summary>
|
||||||
|
get count => _list.length;
|
||||||
|
get length => _list.length;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if an item exists in the list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Item to check if exists</param>
|
||||||
|
//contains(T value) => _list.contains(value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if any item of the given array is in the list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="values">Array of items</param>
|
||||||
|
containsAny(values)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (values is List<T>)
|
||||||
|
{
|
||||||
|
for(var v in values)
|
||||||
|
{
|
||||||
|
if (_list.contains(v))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (values is AutoList<T, ST>)
|
||||||
|
{
|
||||||
|
|
||||||
|
for(var v in values._list)
|
||||||
|
{
|
||||||
|
if (_list.contains(v))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void destroy() {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
}
|
550
bin/Data/BinaryList.dart
Normal file
550
bin/Data/BinaryList.dart
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 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/07/2019.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../Core/AsyncReply.dart';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'DC.dart';
|
||||||
|
import 'DataType.dart';
|
||||||
|
import 'Guid.dart';
|
||||||
|
|
||||||
|
class BinaryList
|
||||||
|
{
|
||||||
|
var _list = new List<int>();
|
||||||
|
|
||||||
|
int get length => _list.length;
|
||||||
|
|
||||||
|
BinaryList addDateTime(DateTime value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.dateTimeToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertDateTime(int position, DateTime value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.dateTimeToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addDateTimeArray(List<DateTime> value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.dateTimeArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertDateTimeArray(int position, List<DateTime> value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.dateTimeArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addGuid(Guid value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.guidToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertGuid(int position, Guid value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.guidToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addGuidArray(List<Guid> value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.guidArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertGuidArray(int position, List<Guid> value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.guidArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addUint8Array(Uint8List value)
|
||||||
|
{
|
||||||
|
_list.addAll(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addDC(DC value)
|
||||||
|
{
|
||||||
|
_list.addAll(value.toArray());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertUint8Array(int position, Uint8List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
BinaryList addHex(String value)
|
||||||
|
{
|
||||||
|
return this.addUint8Array(DC.fromHex(value, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertHex(int position, String value)
|
||||||
|
{
|
||||||
|
return this.insertUint8Array(position, DC.fromHex(value, null));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addString(String value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.stringToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertString(int position, String value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.stringToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addStringArray(List<String> value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.stringArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertStringArray(int position, List<String> value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.stringArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertUint8(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insert(position, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addUint8(int value)
|
||||||
|
{
|
||||||
|
_list.add(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addInt8(int value)
|
||||||
|
{
|
||||||
|
_list.add(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt8(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insert(position, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addInt8Array(Int8List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int8ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt8Array(int position, Int8List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int8ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addChar(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.charToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList InsertChar(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.charToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addCharArray(Uint16List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.charArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList InsertCharArray(int position, Uint16List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.charArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addBoolean(bool value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.boolToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertBoolean(int position, bool value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.boolToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addBooleanArray(List<bool> value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.boolToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertBooleanArray(int position, List<bool> value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.boolToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addUint16(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.uint16ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertUint16(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.uint16ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addUint16Array(Uint16List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.uint16ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertUint16Array(int position, Uint16List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.uint16ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addInt16(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int16ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt16(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int16ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addInt16Array(Int16List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int16ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt16Array(int position, Int16List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int16ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addUint32(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.uint32ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertUint32(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.uint32ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addUint32Array(Uint32List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.uint32ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
BinaryList InsertUint32Array(int position, Uint32List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.uint32ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addInt32(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int32ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt32(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int32ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addInt32Array(Int32List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int32ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt32Array(int position, Int32List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int32ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addUint64(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.uint64ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertUint64(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.uint64ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addUint64Array(Uint64List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.uint64ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList InsertUint64Array(int position, Uint64List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.uint64ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addInt64(int value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int64ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt64(int position, int value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int64ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addInt64Array(Int64List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.int64ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertInt64Array(int position, Int64List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.int64ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addFloat32(double value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.float32ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertFloat32(int position, double value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.float32ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addFloat32Array(Float32List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.float32ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertFloat32Array(int position, Float32List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.float32ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList addFloat64(double value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.float64ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertFloat64(int position, double value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.float64ToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList addFloat64Array(Float64List value)
|
||||||
|
{
|
||||||
|
_list.addAll(DC.float64ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryList insertFloat64Array(int position, Float64List value)
|
||||||
|
{
|
||||||
|
_list.insertAll(position, DC.float64ArrayToBytes(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BinaryList add(type, value)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataType.Bool:
|
||||||
|
addBoolean(value);
|
||||||
|
return this;
|
||||||
|
case DataType.BoolArray:
|
||||||
|
addBooleanArray(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt8:
|
||||||
|
addUint8(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt8Array:
|
||||||
|
addUint8Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int8:
|
||||||
|
addInt8(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int8Array:
|
||||||
|
addInt8Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Char:
|
||||||
|
addChar(value);
|
||||||
|
return this;
|
||||||
|
case DataType.CharArray:
|
||||||
|
addCharArray(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt16:
|
||||||
|
addUint16(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt16Array:
|
||||||
|
addUint16Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int16:
|
||||||
|
addInt16(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int16Array:
|
||||||
|
addInt16Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt32:
|
||||||
|
addUint32(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt32Array:
|
||||||
|
addUint32Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int32:
|
||||||
|
addInt32(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int32Array:
|
||||||
|
addInt32Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt64:
|
||||||
|
addUint64(value);
|
||||||
|
return this;
|
||||||
|
case DataType.UInt64Array:
|
||||||
|
addUint64Array(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int64:
|
||||||
|
addInt64(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Int64Array:
|
||||||
|
addInt64Array(value);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
case DataType.Float32:
|
||||||
|
addFloat32(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Float32Array:
|
||||||
|
addFloat32Array(value);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
case DataType.Float64:
|
||||||
|
addFloat64(value);
|
||||||
|
return this;
|
||||||
|
case DataType.Float64Array:
|
||||||
|
addFloat64Array(value);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
case DataType.String:
|
||||||
|
addString(value);
|
||||||
|
return this;
|
||||||
|
case DataType.StringArray:
|
||||||
|
addStringArray(value);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
case DataType.DateTime:
|
||||||
|
addDateTime(value);
|
||||||
|
return this;
|
||||||
|
case DataType.DateTimeArray:
|
||||||
|
addDateTimeArray(value);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Exception("Not Implemented " + type.ToString());
|
||||||
|
//return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Convert the _list to an array of bytes
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Bytes array</returns>
|
||||||
|
Uint8List toArray()
|
||||||
|
{
|
||||||
|
return Uint8List.fromList(_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DC toDC()
|
||||||
|
{
|
||||||
|
return new DC.fromUint8Array(toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AsyncReply<dynamic> done()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
1074
bin/Data/Codec.dart
Normal file
1074
bin/Data/Codec.dart
Normal file
File diff suppressed because it is too large
Load Diff
643
bin/Data/DC.dart
Normal file
643
bin/Data/DC.dart
Normal file
@ -0,0 +1,643 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'BinaryList.dart';
|
||||||
|
import 'dart:collection';
|
||||||
|
import 'Guid.dart';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ahmed Zamil on 6/10/2019.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
const UNIX_EPOCH = 621355968000000000;
|
||||||
|
const TWO_PWR_32 = (1 << 16) * (1 << 16);
|
||||||
|
|
||||||
|
class DC with IterableMixin<int>
|
||||||
|
{
|
||||||
|
|
||||||
|
Uint8List _data;
|
||||||
|
ByteData _dv;
|
||||||
|
|
||||||
|
DC(int length)
|
||||||
|
{
|
||||||
|
_data = new Uint8List(length);
|
||||||
|
_dv = ByteData.view(_data.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
DC.fromUint8Array(Uint8List array)
|
||||||
|
{
|
||||||
|
_data = array;
|
||||||
|
_dv = ByteData.view(_data.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
DC.fromList(List<int> list)
|
||||||
|
{
|
||||||
|
_data = Uint8List.fromList(list);
|
||||||
|
_dv = ByteData.view(_data.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator [](index) => _data[index];
|
||||||
|
operator []=(index,value) => _data[index] = value;
|
||||||
|
int get length => _data.length;
|
||||||
|
|
||||||
|
Iterator<int> get iterator => _data.iterator;
|
||||||
|
|
||||||
|
static DC hexToBytes(String value)
|
||||||
|
{
|
||||||
|
// convert hex to Uint8Array
|
||||||
|
var rt = new DC(value.length~/2);
|
||||||
|
for(var i = 0; i < rt.length; i++)
|
||||||
|
rt[i] = int.parse(value.substring(i*2, 2), radix: 16);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC boolToBytes(value)
|
||||||
|
{
|
||||||
|
var rt = new DC(1);
|
||||||
|
rt.setBoolean(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DC guidToBytes(Guid value)
|
||||||
|
{
|
||||||
|
var rt = new DC(16);
|
||||||
|
rt.setGuid(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC guidArrayToBytes(List<Guid> value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 16);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setGuid(i * 16, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC boolArrayToBytes(List<bool> value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt[i] = value[i] ? 1 : 0;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int8ToBytes(value)
|
||||||
|
{
|
||||||
|
var rt = new DC(1);
|
||||||
|
rt.setInt8(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int8ArrayToBytes(Int8List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setInt8(i, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static DC uint8ToBytes(value)
|
||||||
|
{
|
||||||
|
var rt = new DC(1);
|
||||||
|
rt.setUint8(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint8ArrayToBytes(Uint8List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setUint8(i, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC charToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(2);
|
||||||
|
rt.setChar(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC charArrayToBytes(Uint16List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 2);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setChar(i*2, value[i]);
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int16ToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(2);
|
||||||
|
rt.setInt16(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int16ArrayToBytes(List<int> value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 2);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setInt16(i*2, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint16ToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(2);
|
||||||
|
rt.setUint16(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint16ArrayToBytes(Uint16List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 2);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setUint16(i*2, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int32ToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(4);
|
||||||
|
rt.setInt32(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int32ArrayToBytes(Int32List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 4);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setInt32(i*4, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint32ToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(4);
|
||||||
|
rt.setUint32(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint32ArrayToBytes(Uint32List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 4);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setUint32(i*4, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC float32ToBytes(double value)
|
||||||
|
{
|
||||||
|
var rt = new DC(4);
|
||||||
|
rt.setFloat32(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC float32ArrayToBytes(Float32List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 4);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setFloat32(i*4, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int64ToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(8);
|
||||||
|
rt.setInt64(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC int64ArrayToBytes(Int64List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 8);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setInt64(i*8, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint64ToBytes(int value)
|
||||||
|
{
|
||||||
|
var rt = new DC(8);
|
||||||
|
rt.setUint64(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC uint64ArrayToBytes(Uint64List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 8);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setUint64(i*8, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC float64ToBytes(double value)
|
||||||
|
{
|
||||||
|
var rt = new DC(8);
|
||||||
|
rt.setFloat64(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC float64ArrayToBytes(Float64List value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 8);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setFloat64(i*8, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC dateTimeToBytes(DateTime value)
|
||||||
|
{
|
||||||
|
var rt = new DC(8);
|
||||||
|
rt.setDateTime(0, value);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static DC dateTimeArrayToBytes(List<DateTime> value)
|
||||||
|
{
|
||||||
|
var rt = new DC(value.length * 8);
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
rt.setDateTime(i*8, value[i]);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static DC stringToBytes(String value)
|
||||||
|
{
|
||||||
|
var bytes = utf8.encode(value);
|
||||||
|
var rt = new DC.fromList(bytes);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC stringArrayToBytes(List<String> value)
|
||||||
|
{
|
||||||
|
var list = new BinaryList();
|
||||||
|
for(var i = 0; i < value.length; i++)
|
||||||
|
{
|
||||||
|
var s = DC.stringToBytes(value[i]);
|
||||||
|
list.addUint32(s.length).addUint8Array(s.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.toDC();
|
||||||
|
}
|
||||||
|
|
||||||
|
DC append(DC src, int offset, int length)
|
||||||
|
{
|
||||||
|
//if (!(src is 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);
|
||||||
|
|
||||||
|
this._data = rt._data;
|
||||||
|
this._dv = rt._dv;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(DC dc, int offset)
|
||||||
|
{
|
||||||
|
_data.setRange(offset, offset + dc.length, dc._data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static combine(a, aOffset, aLength, b, bOffset, bLength)
|
||||||
|
{
|
||||||
|
if (!(a is DC))
|
||||||
|
a = new DC(a);
|
||||||
|
if (!(b is 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
DC clip(offset, length)
|
||||||
|
{
|
||||||
|
return DC.fromUint8Array(Uint8List.fromList(_data.getRange(offset, offset + length).toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
getInt8(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getInt8(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUint8(int offset)
|
||||||
|
{
|
||||||
|
return _data[offset];// this.dv.getUint8(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getInt16(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getInt16(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUint16(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getUint16(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getInt32(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getInt32(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUint32(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getUint32(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFloat32(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getFloat32(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFloat64(int offset)
|
||||||
|
{
|
||||||
|
return _dv.getFloat64(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
setInt8(int offset, int value)
|
||||||
|
{
|
||||||
|
return _dv.setInt8(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setUint8(int offset, int value)
|
||||||
|
{
|
||||||
|
return _dv.setUint8(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setInt16(int offset, int value)
|
||||||
|
{
|
||||||
|
return _dv.setInt16(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setUint16(int offset, int value)
|
||||||
|
{
|
||||||
|
return _dv.setUint16(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setInt32(int offset, int value)
|
||||||
|
{
|
||||||
|
return _dv.setInt32(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setUint32(int offset, int value)
|
||||||
|
{
|
||||||
|
return _dv.setUint32(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setFloat32(int offset, double value)
|
||||||
|
{
|
||||||
|
return _dv.setFloat32(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setFloat64(int offset, double value)
|
||||||
|
{
|
||||||
|
return _dv.setFloat64(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int8List getInt8Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asInt8List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8List getUint8Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asUint8List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int16List getInt16Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asInt16List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint16List getUint16Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asUint16List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int32List getInt32Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asInt32List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32List getUint32Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asUint32List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Float32List getFloat32Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asFloat32List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Float64List getFloat64Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asFloat64List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64List getInt64Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asInt64List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint64List getUint64Array(int offset, int length)
|
||||||
|
{
|
||||||
|
return _data.buffer.asUint64List(offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getBoolean(int offset)
|
||||||
|
{
|
||||||
|
return this.getUint8(offset) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setBoolean(int offset, bool value)
|
||||||
|
{
|
||||||
|
this.setUint8(offset, value ? 1: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<bool> getBooleanArray(int offset, int length)
|
||||||
|
{
|
||||||
|
var rt = new List<bool>();
|
||||||
|
for(var i = 0; i < length; i++)
|
||||||
|
rt.add(this.getBoolean(offset+i));
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getChar(int offset)
|
||||||
|
{
|
||||||
|
return String.fromCharCode(this.getUint16(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
setChar(int offset, int value)
|
||||||
|
{
|
||||||
|
this.setUint16(offset, value); //value.codeUnitAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> getCharArray(int offset, int length)
|
||||||
|
{
|
||||||
|
var rt = new List<String>();
|
||||||
|
for(var i = 0; i < length; i+=2)
|
||||||
|
rt.add(this.getChar(offset+i));
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
String 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
List<T> toList<T>(offset, length)
|
||||||
|
{
|
||||||
|
var rt = new List<T>();
|
||||||
|
for(var i = 0; i < length; i++)
|
||||||
|
rt[i] = _data[offset+i] as T;
|
||||||
|
return rt;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
Uint8List toArray() => _data;
|
||||||
|
|
||||||
|
|
||||||
|
String getString(offset, length)
|
||||||
|
{
|
||||||
|
var bytes = clip(offset, length)._data;// toList(offset, length);
|
||||||
|
var str = utf8.decode(bytes);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> getStringArray(offset, length)
|
||||||
|
{
|
||||||
|
var rt = List<String>();
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
while (i < length)
|
||||||
|
{
|
||||||
|
var cl = this.getUint32(offset + i);
|
||||||
|
i += 4;
|
||||||
|
rt.add(this.getString(offset + i, cl));
|
||||||
|
i += cl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
getInt64(offset)
|
||||||
|
{
|
||||||
|
return _dv.getUint64(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUint64(offset)
|
||||||
|
{
|
||||||
|
return _dv.getInt64(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInt64(offset, value)
|
||||||
|
{
|
||||||
|
_dv.setInt64(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUint64(offset, value)
|
||||||
|
{
|
||||||
|
|
||||||
|
_dv.setUint64(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setDateTime(offset, value)
|
||||||
|
{
|
||||||
|
// Unix Epoch
|
||||||
|
var ticks = 621355968000000000 + (value.getTime() * 10000);
|
||||||
|
this.setUint64(offset, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime getDateTime(int offset)
|
||||||
|
{
|
||||||
|
var ticks = this.getUint64(offset);
|
||||||
|
// there are 10,000 ticks in a millisecond
|
||||||
|
return DateTime.fromMillisecondsSinceEpoch((ticks-UNIX_EPOCH)~/10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DateTime> getDateTimeArray(int offset, int length)
|
||||||
|
{
|
||||||
|
var rt = new List<DateTime>();
|
||||||
|
for(var i = 0; i < length; i+=8)
|
||||||
|
rt.add(this.getDateTime(offset+i));
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Guid getGuid(int offset)
|
||||||
|
{
|
||||||
|
return new Guid(this.clip(offset, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
setGuid(int offset, Guid guid)
|
||||||
|
{
|
||||||
|
set(guid.value, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Guid> getGuidArray(int offset, int length)
|
||||||
|
{
|
||||||
|
var rt = [];
|
||||||
|
for(var i = 0; i < length; i+=16)
|
||||||
|
rt.add(this.getGuid(offset+i));
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool 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;
|
||||||
|
}
|
||||||
|
}
|
115
bin/Data/DataType.dart
Normal file
115
bin/Data/DataType.dart
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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 DataType
|
||||||
|
{
|
||||||
|
static const int Void = 0x0,
|
||||||
|
//Variant,
|
||||||
|
Bool = 1,
|
||||||
|
Int8 = 2,
|
||||||
|
UInt8 = 3,
|
||||||
|
Char = 4,
|
||||||
|
Int16 = 5,
|
||||||
|
UInt16 = 6,
|
||||||
|
Int32 = 7,
|
||||||
|
UInt32 = 8,
|
||||||
|
Int64 = 9,
|
||||||
|
UInt64 = 0xA,
|
||||||
|
Float32 = 0xB,
|
||||||
|
Float64 = 0xC,
|
||||||
|
Decimal = 0xD,
|
||||||
|
DateTime = 0xE,
|
||||||
|
Resource = 0xF,
|
||||||
|
DistributedResource = 0x10,
|
||||||
|
ResourceLink = 0x11,
|
||||||
|
String = 0x12,
|
||||||
|
Structure = 0x13,
|
||||||
|
//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;
|
||||||
|
|
||||||
|
static bool isArray(int type)
|
||||||
|
{
|
||||||
|
return ((type & 0x80) == 0x80) && (type != NotModified);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getElementType(int type)
|
||||||
|
{
|
||||||
|
return type & 0x7F;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int size(int type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DataType.Void:
|
||||||
|
case DataType.NotModified:
|
||||||
|
return 0;
|
||||||
|
case DataType.Bool:
|
||||||
|
case DataType.UInt8:
|
||||||
|
case DataType.Int8:
|
||||||
|
return 1;
|
||||||
|
case DataType.Char:
|
||||||
|
case DataType.UInt16:
|
||||||
|
case DataType.Int16:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
bin/Data/Guid.dart
Normal file
18
bin/Data/Guid.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'DC.dart';
|
||||||
|
|
||||||
|
class Guid
|
||||||
|
{
|
||||||
|
DC _data;
|
||||||
|
|
||||||
|
Guid(DC data)
|
||||||
|
{
|
||||||
|
_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
DC get value => _data;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return _data.getString(0, _data.length);
|
||||||
|
}
|
||||||
|
}
|
156
bin/Data/KeyList.dart
Normal file
156
bin/Data/KeyList.dart
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import '../Core/IEventHandler.dart';
|
||||||
|
import '../Core/IDestructible.dart';
|
||||||
|
|
||||||
|
import 'dart:collection';
|
||||||
|
import 'Codec.dart';
|
||||||
|
|
||||||
|
class KeyList<KT, T> extends IEventHandler with MapMixin<KT, T>
|
||||||
|
{
|
||||||
|
|
||||||
|
dynamic owner;
|
||||||
|
|
||||||
|
Map<KT, T> _map = new Map<KT, T>();
|
||||||
|
|
||||||
|
Iterator<KT> get iterator => _map.keys.iterator;
|
||||||
|
|
||||||
|
Iterable<KT> get keys => _map.keys;
|
||||||
|
Iterable<T> get values => _map.values;
|
||||||
|
|
||||||
|
|
||||||
|
operator[](index) => _map[index];
|
||||||
|
|
||||||
|
operator []= (index, value) => add(index, value);
|
||||||
|
|
||||||
|
|
||||||
|
at(int index) => _map.values.elementAt(index);
|
||||||
|
|
||||||
|
|
||||||
|
bool _removableList;
|
||||||
|
|
||||||
|
|
||||||
|
T take(KT key)
|
||||||
|
{
|
||||||
|
if (_map.containsKey(key))
|
||||||
|
{
|
||||||
|
var v = _map[key];
|
||||||
|
remove(key);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<T> toArray() => _map.values.toList();
|
||||||
|
|
||||||
|
void add(KT key, T value)
|
||||||
|
{
|
||||||
|
if (_removableList)
|
||||||
|
if (value != null)
|
||||||
|
(value as IDestructible).on("destroy", _itemDestroyed);
|
||||||
|
|
||||||
|
if (_map.containsKey(key))
|
||||||
|
{
|
||||||
|
var oldValue = _map[key];
|
||||||
|
if (_removableList)
|
||||||
|
if (oldValue != null)
|
||||||
|
(oldValue as IDestructible).off("destroy", _itemDestroyed);
|
||||||
|
|
||||||
|
_map[key] = value;
|
||||||
|
|
||||||
|
emitArgs("modified", [key, oldValue, value, this]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_map[key] = value;
|
||||||
|
|
||||||
|
emitArgs("add", [value, this]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_itemDestroyed(T sender)
|
||||||
|
{
|
||||||
|
removeValue(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeValue(T value)
|
||||||
|
{
|
||||||
|
var toRemove = new List<KT>();
|
||||||
|
for (var k in _map.keys)
|
||||||
|
if (_map[k] == value)
|
||||||
|
toRemove.add(k);
|
||||||
|
|
||||||
|
for (var k in toRemove)
|
||||||
|
remove(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
if (_removableList)
|
||||||
|
for (var v in _map.values)
|
||||||
|
(v as IDestructible)?.off("destroy", _itemDestroyed);
|
||||||
|
|
||||||
|
_map.clear();
|
||||||
|
|
||||||
|
emitArgs("cleared", [this]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
T remove(key)
|
||||||
|
{
|
||||||
|
if (!_map.containsKey(key))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var value = _map[key];
|
||||||
|
|
||||||
|
if (_removableList)
|
||||||
|
(value as IDestructible)?.off("destroy", _itemDestroyed);
|
||||||
|
|
||||||
|
|
||||||
|
_map.remove(key);
|
||||||
|
|
||||||
|
emitArgs("removed", [key, value, this]);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int get count => _map.length;
|
||||||
|
|
||||||
|
bool contains(KT key) => _map.containsKey(key);
|
||||||
|
|
||||||
|
|
||||||
|
KeyList([owner = null])
|
||||||
|
{
|
||||||
|
_removableList = Codec.implementsInterface<T, IDestructible>();
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
}
|
4
bin/Data/NotModified.dart
Normal file
4
bin/Data/NotModified.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class NotModified
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
23
bin/Data/PropertyValue.dart
Normal file
23
bin/Data/PropertyValue.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
class PropertyValue
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the value.
|
||||||
|
/// </summary>
|
||||||
|
dynamic value;
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set date of modification or occurrence.
|
||||||
|
/// </summary>
|
||||||
|
DateTime date;
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set property age.
|
||||||
|
/// </summary>
|
||||||
|
int age;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create an instance of PropertyValue.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Value.</param>
|
||||||
|
/// <param name="age">Age.</param>
|
||||||
|
/// <param name="date">Date.</param>
|
||||||
|
PropertyValue(this.value, this.age, this.date);
|
||||||
|
}
|
7
bin/Data/ResourceComparisonResult.dart
Normal file
7
bin/Data/ResourceComparisonResult.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class ResourceComparisonResult
|
||||||
|
{
|
||||||
|
static const Null = 0;
|
||||||
|
static const Distributed = 1;
|
||||||
|
static const Local = 2;
|
||||||
|
static const Same = 3;
|
||||||
|
}
|
4
bin/Data/SizeObject.dart
Normal file
4
bin/Data/SizeObject.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class SizeObject
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
}
|
59
bin/Data/Structure.dart
Normal file
59
bin/Data/Structure.dart
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
class Structure with MapMixin<String, Object>//, IterableMixin<String>
|
||||||
|
{
|
||||||
|
|
||||||
|
Map<String, Object> _map = new Map<String, Object>();
|
||||||
|
|
||||||
|
Iterator<String> get iterator => _map.keys.iterator;
|
||||||
|
|
||||||
|
Iterable<String> get keys => _map.keys;
|
||||||
|
|
||||||
|
operator[](index) => _map[index];
|
||||||
|
|
||||||
|
operator []= (index, value) => _map[index] = value;
|
||||||
|
|
||||||
|
remove(key) => _map.remove(key);
|
||||||
|
|
||||||
|
clear() => _map.clear();
|
||||||
|
|
||||||
|
|
||||||
|
at(int index) => _map.values.elementAt(index);
|
||||||
|
|
||||||
|
List<String> getKeys() => _map.keys.toList();
|
||||||
|
|
||||||
|
|
||||||
|
Structure.fromMap(Map map)
|
||||||
|
{
|
||||||
|
for(var i in map.keys)
|
||||||
|
_map[i.toString()] = map[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Structure()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
8
bin/Data/StructureComparisonResult.dart
Normal file
8
bin/Data/StructureComparisonResult.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class StructureComparisonResult
|
||||||
|
{
|
||||||
|
static const int Null = 0;
|
||||||
|
static const int Structure = 1;
|
||||||
|
static const int StructureSameKeys = 2;
|
||||||
|
static const int StructureSameTypes = 3;
|
||||||
|
static const int Same = 4;
|
||||||
|
}
|
8
bin/Data/StructureMetadata.dart
Normal file
8
bin/Data/StructureMetadata.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class StructureMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
List<String> keys;
|
||||||
|
List<int> types;
|
||||||
|
|
||||||
|
//const StructureMetadata(this.keys, this.types);
|
||||||
|
}
|
4
bin/Data/ValueObject.dart
Normal file
4
bin/Data/ValueObject.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class ValueObject
|
||||||
|
{
|
||||||
|
dynamic value;
|
||||||
|
}
|
2466
bin/Net/IIP/DistributedConnection.dart
Normal file
2466
bin/Net/IIP/DistributedConnection.dart
Normal file
File diff suppressed because it is too large
Load Diff
18
bin/Net/IIP/DistributedPropertyContext.dart
Normal file
18
bin/Net/IIP/DistributedPropertyContext.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'DistributedConnection.dart';
|
||||||
|
class DistributedPropertyContext
|
||||||
|
{
|
||||||
|
dynamic value;
|
||||||
|
DistributedConnection connection;
|
||||||
|
dynamic Function(DistributedConnection) method;
|
||||||
|
|
||||||
|
|
||||||
|
DistributedPropertyContext(this.method)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DistributedPropertyContext.setter(this.value, this.connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
300
bin/Net/IIP/DistributedResource.dart
Normal file
300
bin/Net/IIP/DistributedResource.dart
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../../Resource/IResource.dart';
|
||||||
|
import '../../Core/AsyncReply.dart';
|
||||||
|
import '../../Data/PropertyValue.dart';
|
||||||
|
import '../../Data/Structure.dart';
|
||||||
|
import '../../Data/Codec.dart';
|
||||||
|
import './DistributedConnection.dart';
|
||||||
|
import '../Packets/IIPPacketAction.dart';
|
||||||
|
|
||||||
|
class DistributedResource extends IResource
|
||||||
|
{
|
||||||
|
|
||||||
|
int _instanceId;
|
||||||
|
DistributedConnection _connection;
|
||||||
|
|
||||||
|
|
||||||
|
bool _isAttached = false;
|
||||||
|
bool _isReady = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String _link;
|
||||||
|
List _properties;
|
||||||
|
|
||||||
|
|
||||||
|
bool _destroyed = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connection responsible for the distributed resource.
|
||||||
|
/// </summary>
|
||||||
|
DistributedConnection get connection => _connection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource link
|
||||||
|
/// </summary>
|
||||||
|
String get link => _link;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instance Id given by the other end.
|
||||||
|
/// </summary>
|
||||||
|
int get id => _instanceId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IDestructible interface.
|
||||||
|
/// </summary>
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
_destroyed = true;
|
||||||
|
emitArgs("destroy", [this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource is ready when all its properties are attached.
|
||||||
|
/// </summary>
|
||||||
|
bool get isReady => _isReady;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource is attached when all its properties are received.
|
||||||
|
/// </summary>
|
||||||
|
bool get IsAttached => _isAttached;
|
||||||
|
|
||||||
|
|
||||||
|
// public DistributedResourceStack Stack
|
||||||
|
//{
|
||||||
|
// get { return stack; }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new distributed resource.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection">Connection responsible for the distributed resource.</param>
|
||||||
|
/// <param name="template">Resource template.</param>
|
||||||
|
/// <param name="instanceId">Instance Id given by the other end.</param>
|
||||||
|
/// <param name="age">Resource age.</param>
|
||||||
|
DistributedResource(DistributedConnection connection, int instanceId, int age, String link)
|
||||||
|
{
|
||||||
|
this._link = link;
|
||||||
|
this._connection = connection;
|
||||||
|
this._instanceId = instanceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ready()
|
||||||
|
{
|
||||||
|
_isReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Export all properties with ResourceProperty attributed as bytes array.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
List<PropertyValue> serialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
var props = new List<PropertyValue>(_properties.length);
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < _properties.length; i++)
|
||||||
|
props[i] = new PropertyValue(_properties[i], instance.getAge(i), instance.getModificationDate(i));
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool attached(List<PropertyValue> properties)
|
||||||
|
{
|
||||||
|
if (_isAttached)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_properties = new List(properties.length);// object[properties.Length];
|
||||||
|
|
||||||
|
//_events = new DistributedResourceEvent[Instance.Template.Events.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < properties.length; i++)
|
||||||
|
{
|
||||||
|
instance.setAge(i, properties[i].age);
|
||||||
|
instance.setModificationDate(i, properties[i].date);
|
||||||
|
_properties[i] = properties[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger holded events/property updates.
|
||||||
|
//foreach (var r in afterAttachmentTriggers)
|
||||||
|
// r.Key.Trigger(r.Value);
|
||||||
|
|
||||||
|
//afterAttachmentTriggers.Clear();
|
||||||
|
|
||||||
|
_isAttached = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitEventByIndex(int index, List<dynamic> args)
|
||||||
|
{
|
||||||
|
var et = instance.template.getEventTemplateByIndex(index);
|
||||||
|
//events[index]?.Invoke(this, args);
|
||||||
|
emitArgs(et.name, args);
|
||||||
|
|
||||||
|
instance.emitResourceEvent(null, null, et.name, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<dynamic> invokeByNamedArguments(int index, Structure namedArgs)
|
||||||
|
{
|
||||||
|
if (_destroyed)
|
||||||
|
throw new Exception("Trying to access destroyed object");
|
||||||
|
|
||||||
|
if (index >= instance.template.functions.length)
|
||||||
|
throw new Exception("Function index is incorrect");
|
||||||
|
|
||||||
|
|
||||||
|
return connection.sendInvokeByNamedArguments(_instanceId, index, namedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<dynamic> invokeByArrayArguments(int index, List<dynamic> args)
|
||||||
|
{
|
||||||
|
if (_destroyed)
|
||||||
|
throw new Exception("Trying to access destroyed object");
|
||||||
|
|
||||||
|
if (index >= instance.template.functions.length)
|
||||||
|
throw new Exception("Function index is incorrect");
|
||||||
|
|
||||||
|
|
||||||
|
return connection.sendInvokeByArrayArguments(_instanceId, index, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String _getMemberName(Symbol symbol)
|
||||||
|
{
|
||||||
|
var memberName = symbol.toString();
|
||||||
|
if (memberName.endsWith("=\")"))
|
||||||
|
return memberName.substring(8, memberName.length - 3);
|
||||||
|
else
|
||||||
|
return memberName.substring(8, memberName.length - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override //overring noSuchMethod
|
||||||
|
noSuchMethod(Invocation invocation)
|
||||||
|
{
|
||||||
|
var memberName = _getMemberName(invocation.memberName);
|
||||||
|
|
||||||
|
if (invocation.isMethod)
|
||||||
|
{
|
||||||
|
var ft = instance.template.getFunctionTemplateByName(memberName);
|
||||||
|
|
||||||
|
if (_isAttached && ft!=null)
|
||||||
|
{
|
||||||
|
if (invocation.namedArguments.length > 0)
|
||||||
|
{
|
||||||
|
var namedArgs = new Structure();
|
||||||
|
for(var p in invocation.namedArguments.keys)
|
||||||
|
namedArgs[_getMemberName(p)] = invocation.namedArguments[p];
|
||||||
|
|
||||||
|
return invokeByNamedArguments(ft.index, namedArgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return invokeByArrayArguments(ft.index, invocation.positionalArguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (invocation.isSetter)
|
||||||
|
{
|
||||||
|
var pt = instance.template.getPropertyTemplateByName(memberName);
|
||||||
|
|
||||||
|
if (pt != null)
|
||||||
|
{
|
||||||
|
set(pt.index, invocation.positionalArguments[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (invocation.isGetter)
|
||||||
|
{
|
||||||
|
|
||||||
|
var pt = instance.template.getPropertyTemplateByName(memberName);
|
||||||
|
|
||||||
|
if (pt != null)
|
||||||
|
{
|
||||||
|
return get(pt.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a property value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Zero-based property index.</param>
|
||||||
|
/// <returns>Value</returns>
|
||||||
|
get(int index)
|
||||||
|
{
|
||||||
|
if (index >= _properties.length)
|
||||||
|
return null;
|
||||||
|
return _properties[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void updatePropertyByIndex(int index, dynamic value)
|
||||||
|
{
|
||||||
|
var pt = instance.template.getPropertyTemplateByIndex(index);
|
||||||
|
_properties[index] = value;
|
||||||
|
instance.emitModification(pt, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set property value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Zero-based property index.</param>
|
||||||
|
/// <param name="value">Value</param>
|
||||||
|
/// <returns>Indicator when the property is set.</returns>
|
||||||
|
AsyncReply<dynamic> set(int index, dynamic value)
|
||||||
|
{
|
||||||
|
if (index >= _properties.length)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var reply = new AsyncReply<dynamic>();
|
||||||
|
|
||||||
|
var parameters = Codec.compose(value, connection);
|
||||||
|
connection.sendRequest(IIPPacketAction.SetProperty)
|
||||||
|
.addUint32(_instanceId)
|
||||||
|
.addUint8(index)
|
||||||
|
.addDC(parameters)
|
||||||
|
.done()
|
||||||
|
.then((res)
|
||||||
|
{
|
||||||
|
// not really needed, server will always send property modified,
|
||||||
|
// this only happens if the programmer forgot to emit in property setter
|
||||||
|
_properties[index] = value;
|
||||||
|
reply.trigger(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
39
bin/Net/IIP/DistributedResourceQueueItem.dart
Normal file
39
bin/Net/IIP/DistributedResourceQueueItem.dart
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'DistributedResourceQueueItemType.dart';
|
||||||
|
import 'DistributedResource.dart';
|
||||||
|
|
||||||
|
class DistributedResourceQueueItem
|
||||||
|
{
|
||||||
|
final DistributedResourceQueueItemType type;
|
||||||
|
final int index;
|
||||||
|
final dynamic value;
|
||||||
|
final DistributedResource resource;
|
||||||
|
|
||||||
|
DistributedResourceQueueItem(this.resource, this.type, this.value, this.index)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
5
bin/Net/IIP/DistributedResourceQueueItemType.dart
Normal file
5
bin/Net/IIP/DistributedResourceQueueItemType.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
enum DistributedResourceQueueItemType
|
||||||
|
{
|
||||||
|
Propery,
|
||||||
|
Event
|
||||||
|
}
|
134
bin/Net/NetworkBuffer.dart
Normal file
134
bin/Net/NetworkBuffer.dart
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../Data/DC.dart';
|
||||||
|
import 'dart:core';
|
||||||
|
|
||||||
|
class NetworkBuffer
|
||||||
|
{
|
||||||
|
DC _data;
|
||||||
|
|
||||||
|
int _neededDataLength = 0;
|
||||||
|
|
||||||
|
NetworkBuffer()
|
||||||
|
{
|
||||||
|
_data = new DC(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get protected => _neededDataLength > _data.length;
|
||||||
|
|
||||||
|
int get available => _data.length;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void holdForNextWrite(DC src, int offset, int size)
|
||||||
|
{
|
||||||
|
holdFor(src, offset, size, size + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void holdFor(DC src, int offset, int size, int needed)
|
||||||
|
{
|
||||||
|
//lock (syncLock)
|
||||||
|
//{
|
||||||
|
if (size >= needed)
|
||||||
|
throw new Exception("Size >= Needed !");
|
||||||
|
|
||||||
|
//trim = true;
|
||||||
|
_data = DC.combine(src, offset, size, _data, 0, _data.length);
|
||||||
|
_neededDataLength = needed;
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void holdForNeeded(DC src, int needed)
|
||||||
|
{
|
||||||
|
holdFor(src, 0, src.length, needed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool protect(DC data, int offset, int needed)
|
||||||
|
{
|
||||||
|
int dataLength = _data.length - offset;
|
||||||
|
|
||||||
|
// protection
|
||||||
|
if (dataLength < needed)
|
||||||
|
{
|
||||||
|
holdFor(data, offset, dataLength, needed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void write(DC src, int offset, int length)
|
||||||
|
{
|
||||||
|
//lock(syncLock)
|
||||||
|
_data.append(src, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get canRead
|
||||||
|
{
|
||||||
|
if (_data.length == 0)
|
||||||
|
return false;
|
||||||
|
if (_data.length < _neededDataLength)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DC read()
|
||||||
|
{
|
||||||
|
//lock (syncLock)
|
||||||
|
//{
|
||||||
|
if (_data.length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
DC rt = null;
|
||||||
|
|
||||||
|
if (_neededDataLength == 0)
|
||||||
|
{
|
||||||
|
rt = _data;
|
||||||
|
_data = new DC(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_data.length >= _neededDataLength)
|
||||||
|
{
|
||||||
|
rt = _data;
|
||||||
|
_data = new DC(0);
|
||||||
|
_neededDataLength = 0;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
}
|
198
bin/Net/NetworkConnection.dart
Normal file
198
bin/Net/NetworkConnection.dart
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../Core/IDestructible.dart';
|
||||||
|
import 'Sockets/ISocket.dart';
|
||||||
|
import 'Sockets/SocketState.dart';
|
||||||
|
import 'NetworkBuffer.dart';
|
||||||
|
import '../Data/DC.dart';
|
||||||
|
import 'Sockets/IPEndPoint.dart';
|
||||||
|
|
||||||
|
class NetworkConnection extends IDestructible
|
||||||
|
{
|
||||||
|
ISocket _sock;
|
||||||
|
|
||||||
|
DateTime _lastAction;
|
||||||
|
|
||||||
|
//public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data);
|
||||||
|
//public delegate void ConnectionClosedEvent(NetworkConnection sender);
|
||||||
|
//public delegate void ConnectionEstablishedEvent(NetworkConnection sender);
|
||||||
|
|
||||||
|
//public event ConnectionEstablishedEvent OnConnect;
|
||||||
|
//public event DataReceivedEvent OnDataReceived;
|
||||||
|
//public event ConnectionClosedEvent OnClose;
|
||||||
|
//public event DestroyedEvent OnDestroy;
|
||||||
|
//object receivingLock = new object();
|
||||||
|
|
||||||
|
bool _processing = false;
|
||||||
|
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
// if (connected)
|
||||||
|
close();
|
||||||
|
emitArgs("close", [this]);
|
||||||
|
//OnDestroy?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConnection()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ISocket get socket => _sock;
|
||||||
|
|
||||||
|
void assign(ISocket socket)
|
||||||
|
{
|
||||||
|
_lastAction = DateTime.now();
|
||||||
|
_sock = socket;
|
||||||
|
|
||||||
|
socket.on("receive", socket_OnReceive);
|
||||||
|
socket.on("close", socket_OnClose);
|
||||||
|
socket.on("connect", socket_OnConnect);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void socket_OnConnect()
|
||||||
|
{
|
||||||
|
emitArgs("connect", [this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void socket_OnClose()
|
||||||
|
{
|
||||||
|
emitArgs("close", [this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void socket_OnReceive(NetworkBuffer buffer)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Unassigned ?
|
||||||
|
if (_sock == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Closed ?
|
||||||
|
if (_sock.state == SocketState.Closed || _sock.state == SocketState.Terminated) // || !connected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastAction = DateTime.now();
|
||||||
|
|
||||||
|
if (!_processing)
|
||||||
|
{
|
||||||
|
_processing = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (buffer.available > 0 && !buffer.protected)
|
||||||
|
dataReceived(buffer);
|
||||||
|
}
|
||||||
|
catch(ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_processing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (ex)
|
||||||
|
{
|
||||||
|
//Global.Log("NetworkConnection", LogType.Warning, ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISocket unassign()
|
||||||
|
{
|
||||||
|
if (_sock != null)
|
||||||
|
{
|
||||||
|
// connected = false;
|
||||||
|
_sock.off("close", socket_OnClose);
|
||||||
|
_sock.off("connect", socket_OnConnect);
|
||||||
|
_sock.off("receive", socket_OnReceive);
|
||||||
|
|
||||||
|
var rt = _sock;
|
||||||
|
_sock = null;
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dataReceived(NetworkBuffer data)
|
||||||
|
{
|
||||||
|
emitArgs("dataReceived", [data]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_sock != null)
|
||||||
|
_sock.close();
|
||||||
|
}
|
||||||
|
catch(ex)
|
||||||
|
{
|
||||||
|
//Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime get lastAction => _lastAction;
|
||||||
|
|
||||||
|
|
||||||
|
IPEndPoint get remoteEndPoint => _sock?.remoteEndPoint;
|
||||||
|
|
||||||
|
IPEndPoint get localEndPoint => _sock?.localEndPoint;
|
||||||
|
|
||||||
|
bool get connected => _sock.state == SocketState.Established;
|
||||||
|
|
||||||
|
|
||||||
|
void send(DC msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_sock != null)
|
||||||
|
{
|
||||||
|
_lastAction = DateTime.now();
|
||||||
|
_sock.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex)
|
||||||
|
{
|
||||||
|
//Console.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendString(String data)
|
||||||
|
{
|
||||||
|
send(DC.stringToBytes(data));
|
||||||
|
}
|
||||||
|
}
|
278
bin/Net/Packets/IIPAuthPacket.dart
Normal file
278
bin/Net/Packets/IIPAuthPacket.dart
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import 'IIPAuthPacketAction.dart';
|
||||||
|
import 'IIPAuthPacketCommand.dart';
|
||||||
|
import 'IIPAuthPacketMethod.dart';
|
||||||
|
|
||||||
|
class IIPAuthPacket
|
||||||
|
{
|
||||||
|
|
||||||
|
int command;
|
||||||
|
int action;
|
||||||
|
|
||||||
|
int errorCode;
|
||||||
|
String errorMessage;
|
||||||
|
|
||||||
|
int localMethod;
|
||||||
|
|
||||||
|
DC sourceInfo;
|
||||||
|
|
||||||
|
DC hash;
|
||||||
|
|
||||||
|
DC sessionId;
|
||||||
|
|
||||||
|
int remoteMethod;
|
||||||
|
|
||||||
|
String domain;
|
||||||
|
|
||||||
|
int certificateId;
|
||||||
|
|
||||||
|
String localUsername;
|
||||||
|
|
||||||
|
String remoteUsername;
|
||||||
|
|
||||||
|
DC localPassword;
|
||||||
|
|
||||||
|
DC remotePassword;
|
||||||
|
|
||||||
|
DC localToken;
|
||||||
|
|
||||||
|
DC remoteToken;
|
||||||
|
|
||||||
|
DC asymetricEncryptionKey;
|
||||||
|
|
||||||
|
DC localNonce;
|
||||||
|
|
||||||
|
DC remoteNonce;
|
||||||
|
|
||||||
|
int _dataLengthNeeded;
|
||||||
|
|
||||||
|
bool _notEnough(int offset, int ends, int needed)
|
||||||
|
{
|
||||||
|
if (offset + needed > ends)
|
||||||
|
{
|
||||||
|
_dataLengthNeeded = needed - (ends - offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
return command.toString() + " " + action.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse(DC data, int offset, int ends)
|
||||||
|
{
|
||||||
|
var oOffset = offset;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
command = (data[offset] >> 6);
|
||||||
|
|
||||||
|
if (command == IIPAuthPacketCommand.Action)
|
||||||
|
{
|
||||||
|
action = (data[offset++] & 0x3f);
|
||||||
|
|
||||||
|
if (action == IIPAuthPacketAction.AuthenticateHash)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 32))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
hash = data.clip(offset, 32);
|
||||||
|
|
||||||
|
//var hash = new byte[32];
|
||||||
|
//Buffer.BlockCopy(data, (int)offset, hash, 0, 32);
|
||||||
|
//Hash = hash;
|
||||||
|
|
||||||
|
offset += 32;
|
||||||
|
}
|
||||||
|
else if (action == IIPAuthPacketAction.NewConnection)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var length = data.getUint16(offset);
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, length))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
sourceInfo = data.clip(offset, length);
|
||||||
|
|
||||||
|
//var sourceInfo = new byte[length];
|
||||||
|
//Buffer.BlockCopy(data, (int)offset, sourceInfo, 0, length);
|
||||||
|
//SourceInfo = sourceInfo;
|
||||||
|
|
||||||
|
offset += 32;
|
||||||
|
}
|
||||||
|
else if (action == IIPAuthPacketAction.ResumeConnection
|
||||||
|
|| action == IIPAuthPacketAction.ConnectionEstablished)
|
||||||
|
{
|
||||||
|
//var sessionId = new byte[32];
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 32))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
sessionId = data.clip(offset, 32);
|
||||||
|
|
||||||
|
//Buffer.BlockCopy(data, (int)offset, sessionId, 0, 32);
|
||||||
|
//SessionId = sessionId;
|
||||||
|
|
||||||
|
offset += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPAuthPacketCommand.Declare)
|
||||||
|
{
|
||||||
|
remoteMethod = ((data[offset] >> 4) & 0x3);
|
||||||
|
localMethod = ((data[offset] >> 2) & 0x3);
|
||||||
|
var encrypt = ((data[offset++] & 0x2) == 0x2);
|
||||||
|
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var domainLength = data[offset++];
|
||||||
|
if (_notEnough(offset, ends, domainLength))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var domain = data.getString(offset, domainLength);
|
||||||
|
|
||||||
|
this.domain = domain;
|
||||||
|
|
||||||
|
offset += domainLength;
|
||||||
|
|
||||||
|
|
||||||
|
if (remoteMethod == IIPAuthPacketMethod.Credentials)
|
||||||
|
{
|
||||||
|
if (localMethod == IIPAuthPacketMethod.None)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 33))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
|
||||||
|
remoteNonce = data.clip(offset, 32);
|
||||||
|
|
||||||
|
offset += 32;
|
||||||
|
|
||||||
|
var length = data[offset++];
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, length))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
remoteUsername = data.getString(offset, length);
|
||||||
|
|
||||||
|
|
||||||
|
offset += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encrypt)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var keyLength = data.getUint16(offset);
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, keyLength))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
|
||||||
|
asymetricEncryptionKey = data.clip(offset, keyLength);
|
||||||
|
|
||||||
|
offset += keyLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPAuthPacketCommand.Acknowledge)
|
||||||
|
{
|
||||||
|
remoteMethod = ((data[offset] >> 4) & 0x3);
|
||||||
|
localMethod = ((data[offset] >> 2) & 0x3);
|
||||||
|
var encrypt = ((data[offset++] & 0x2) == 0x2);
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
|
||||||
|
if (remoteMethod == IIPAuthPacketMethod.Credentials)
|
||||||
|
{
|
||||||
|
if (localMethod == IIPAuthPacketMethod.None)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 32))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
remoteNonce = data.clip(offset, 32);
|
||||||
|
offset += 32;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encrypt)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var keyLength = data.getUint16(offset);
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, keyLength))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
asymetricEncryptionKey = data.clip(offset, keyLength);
|
||||||
|
|
||||||
|
offset += keyLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPAuthPacketCommand.Error)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
errorCode = data[offset++];
|
||||||
|
|
||||||
|
|
||||||
|
var cl = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
errorMessage = data.getString(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return offset - oOffset;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
bin/Net/Packets/IIPAuthPacketAction.dart
Normal file
16
bin/Net/Packets/IIPAuthPacketAction.dart
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class IIPAuthPacketAction
|
||||||
|
{
|
||||||
|
// Authenticate
|
||||||
|
static const int AuthenticateHash = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//Challenge,
|
||||||
|
//CertificateRequest,
|
||||||
|
//CertificateReply,
|
||||||
|
//EstablishRequest,
|
||||||
|
//EstablishReply
|
||||||
|
|
||||||
|
static const int NewConnection = 0x20;
|
||||||
|
static const int ResumeConnection = 0x21;
|
||||||
|
static const int ConnectionEstablished = 0x28;
|
||||||
|
}
|
7
bin/Net/Packets/IIPAuthPacketCommand.dart
Normal file
7
bin/Net/Packets/IIPAuthPacketCommand.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class IIPAuthPacketCommand
|
||||||
|
{
|
||||||
|
static const int Action = 0;
|
||||||
|
static const int Declare = 1;
|
||||||
|
static const int Acknowledge = 2;
|
||||||
|
static const int Error = 3;
|
||||||
|
}
|
8
bin/Net/Packets/IIPAuthPacketMethod.dart
Normal file
8
bin/Net/Packets/IIPAuthPacketMethod.dart
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
class IIPAuthPacketMethod
|
||||||
|
{
|
||||||
|
static const int None = 0;
|
||||||
|
static const int Certificate = 1;
|
||||||
|
static const int Credentials = 2;
|
||||||
|
static const int Token = 3;
|
||||||
|
}
|
727
bin/Net/Packets/IIPPacket.dart
Normal file
727
bin/Net/Packets/IIPPacket.dart
Normal file
@ -0,0 +1,727 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import '../../Data/Guid.dart';
|
||||||
|
|
||||||
|
import 'IIPPacketAction.dart';
|
||||||
|
import 'IIPPacketCommand.dart';
|
||||||
|
import 'IIPPacketEvent.dart';
|
||||||
|
import 'IIPPacketReport.dart';
|
||||||
|
import '../../Data/Codec.dart';
|
||||||
|
import '../../Data/DataType.dart';
|
||||||
|
|
||||||
|
class IIPPacket
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int report;
|
||||||
|
|
||||||
|
int command;
|
||||||
|
|
||||||
|
int action;
|
||||||
|
|
||||||
|
int event;
|
||||||
|
|
||||||
|
int previousCommand;
|
||||||
|
|
||||||
|
|
||||||
|
int previousAction;
|
||||||
|
|
||||||
|
int previousEvent;
|
||||||
|
|
||||||
|
|
||||||
|
int resourceId;
|
||||||
|
int newResourceId;
|
||||||
|
|
||||||
|
int childId;
|
||||||
|
int storeId;
|
||||||
|
|
||||||
|
int resourceAge;
|
||||||
|
DC content;
|
||||||
|
int errorCode;
|
||||||
|
String errorMessage;
|
||||||
|
String className ;
|
||||||
|
String resourceLink ;
|
||||||
|
Guid classId ;
|
||||||
|
int methodIndex ;
|
||||||
|
String methodName;
|
||||||
|
int callbackId ;
|
||||||
|
int progressValue;
|
||||||
|
int progressMax ;
|
||||||
|
DateTime fromDate ;
|
||||||
|
DateTime toDate;
|
||||||
|
int fromAge;
|
||||||
|
int toAge;
|
||||||
|
|
||||||
|
int _dataLengthNeeded;
|
||||||
|
int _originalOffset;
|
||||||
|
|
||||||
|
|
||||||
|
bool _notEnough(int offset, int ends, int needed)
|
||||||
|
{
|
||||||
|
if (offset + needed > ends)
|
||||||
|
{
|
||||||
|
//dataLengthNeeded = needed - (ends - offset);
|
||||||
|
_dataLengthNeeded = needed - (ends - _originalOffset);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse(DC data, int offset, int ends)
|
||||||
|
{
|
||||||
|
_originalOffset = offset;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
previousCommand = command;
|
||||||
|
|
||||||
|
command = (data[offset] >> 6);
|
||||||
|
|
||||||
|
if (command == IIPPacketCommand.Event)
|
||||||
|
{
|
||||||
|
event = (data[offset++] & 0x3f);
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if (command == IIPPacketCommand.Report)
|
||||||
|
{
|
||||||
|
report = (data[offset++] & 0x3f);
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
callbackId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
previousAction = action;
|
||||||
|
action = (data[offset++] & 0x3f);
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
callbackId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == IIPPacketCommand.Event)
|
||||||
|
{
|
||||||
|
if (event == IIPPacketEvent.ResourceReassigned)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
newResourceId = data.getUint32( offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (event == IIPPacketEvent.ResourceDestroyed)
|
||||||
|
{
|
||||||
|
// nothing to parse
|
||||||
|
}
|
||||||
|
else if (event == IIPPacketEvent.ChildAdded
|
||||||
|
|| event == IIPPacketEvent.ChildRemoved)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
childId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if(event == IIPPacketEvent.Renamed)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else if (event == IIPPacketEvent.PropertyUpdated)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
methodIndex = data[offset++];
|
||||||
|
|
||||||
|
var dt = data[offset++];
|
||||||
|
var size = DataType.size(dt);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint32( offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip( offset - 5, cl + 5);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, size))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset - 1, size + 1);
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event == IIPPacketEvent.EventOccurred)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 5))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
methodIndex = data[offset++];
|
||||||
|
|
||||||
|
var cl = data.getUint32( offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
|
||||||
|
}
|
||||||
|
// Attribute
|
||||||
|
else if (event == IIPPacketEvent.AttributesUpdated)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPPacketCommand.Request)
|
||||||
|
{
|
||||||
|
if (action == IIPPacketAction.AttachResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.ReattachResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 12))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
resourceAge = data.getUint64(offset);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.DetachResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.CreateResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 12))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
storeId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.DeleteResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.AddChild
|
||||||
|
|| action == IIPPacketAction.RemoveChild)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 8))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
childId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.RenameResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 6))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
var cl = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.TemplateFromClassName)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data[offset++];
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
className = data.getString(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.TemplateFromClassId)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 16))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
classId = data.getGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.TemplateFromResourceId)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.QueryLink)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceLink = data.getString(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.ResourceChildren
|
||||||
|
|| action == IIPPacketAction.ResourceParents)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.ResourceHistory)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 20))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
fromDate = data.getDateTime(offset);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
toDate = data.getDateTime(offset);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.InvokeFunctionArrayArguments
|
||||||
|
|| action == IIPPacketAction.InvokeFunctionNamedArguments)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 9))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
methodIndex = data[offset++];
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.GetProperty)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 5))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
methodIndex = data[offset++];
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.GetPropertyIfModified)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 9))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
methodIndex = data[offset++];
|
||||||
|
|
||||||
|
resourceAge = data.getUint64(offset);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.SetProperty)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 6))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
methodIndex = data[offset++];
|
||||||
|
|
||||||
|
|
||||||
|
var dt = data[offset++];
|
||||||
|
var size = DataType.size(dt);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset-5, cl + 5);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, size))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset-1, size + 1);
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Attributes
|
||||||
|
else if (action == IIPPacketAction.UpdateAllAttributes
|
||||||
|
|| action == IIPPacketAction.GetAttributes
|
||||||
|
|| action == IIPPacketAction.UpdateAttributes
|
||||||
|
|| action == IIPPacketAction.ClearAttributes)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 8))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPPacketCommand.Reply)
|
||||||
|
{
|
||||||
|
if (action == IIPPacketAction.AttachResource
|
||||||
|
|| action == IIPPacketAction.ReattachResource)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 26))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
classId = data.getGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
|
||||||
|
resourceAge = data.getUint64(offset);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
var cl = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
resourceLink = data.getString(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.DetachResource)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.CreateResource)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 20))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
//ClassId = data.GetGuid(offset);
|
||||||
|
//offset += 16;
|
||||||
|
|
||||||
|
resourceId = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.DetachResource)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
// Inquire
|
||||||
|
else if (action == IIPPacketAction.TemplateFromClassName
|
||||||
|
|| action == IIPPacketAction.TemplateFromClassId
|
||||||
|
|| action == IIPPacketAction.TemplateFromResourceId
|
||||||
|
|| action == IIPPacketAction.QueryLink
|
||||||
|
|| action == IIPPacketAction.ResourceChildren
|
||||||
|
|| action == IIPPacketAction.ResourceParents
|
||||||
|
|| action == IIPPacketAction.ResourceHistory
|
||||||
|
// Attribute
|
||||||
|
|| action == IIPPacketAction.GetAllAttributes
|
||||||
|
|| action == IIPPacketAction.GetAttributes)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.InvokeFunctionArrayArguments
|
||||||
|
|| action == IIPPacketAction.InvokeFunctionNamedArguments
|
||||||
|
|| action == IIPPacketAction.GetProperty
|
||||||
|
|| action == IIPPacketAction.GetPropertyIfModified)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var dt = data[offset++];
|
||||||
|
var size = DataType.size(dt);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset - 5, cl + 5);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, size))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset - 1, size + 1);
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action == IIPPacketAction.SetProperty)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPPacketCommand.Report)
|
||||||
|
{
|
||||||
|
if (report == IIPPacketReport.ManagementError)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
errorCode = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
else if (report == IIPPacketReport.ExecutionError)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
errorCode = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, 2))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
errorMessage = data.getString(offset, cl);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else if (report == IIPPacketReport.ProgressReport)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 8))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
progressValue = data.getInt32(offset);
|
||||||
|
offset += 4;
|
||||||
|
progressMax = data.getInt32(offset);
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else if (report == IIPPacketReport.ChunkStream)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 1))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var dt = data[offset++];
|
||||||
|
var size = DataType.size(dt);
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, 4))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
var cl = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
if (_notEnough(offset, ends, cl))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset - 5, cl + 5);
|
||||||
|
offset += cl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_notEnough(offset, ends, size))
|
||||||
|
return -_dataLengthNeeded;
|
||||||
|
|
||||||
|
content = data.clip(offset - 1, size + 1);
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset - _originalOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
var rt = command.toString();
|
||||||
|
|
||||||
|
if (command == IIPPacketCommand.Event)
|
||||||
|
{
|
||||||
|
rt += " " + event.toString();
|
||||||
|
}
|
||||||
|
else if (command == IIPPacketCommand.Request)
|
||||||
|
{
|
||||||
|
rt += " " + action.toString();
|
||||||
|
if (action == IIPPacketAction.AttachResource)
|
||||||
|
{
|
||||||
|
rt += " CID: " + callbackId.toString() + " RID: " + resourceId.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == IIPPacketCommand.Reply)
|
||||||
|
rt += " " + action.toString();
|
||||||
|
else if (command == IIPPacketCommand.Report)
|
||||||
|
rt += " " + report.toString();
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
36
bin/Net/Packets/IIPPacketAction.dart
Normal file
36
bin/Net/Packets/IIPPacketAction.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
class IIPPacketAction
|
||||||
|
{
|
||||||
|
// Request Manage
|
||||||
|
static const int AttachResource = 0x0;
|
||||||
|
static const int ReattachResource = 0x1;
|
||||||
|
static const int DetachResource = 0x2;
|
||||||
|
static const int CreateResource = 0x3;
|
||||||
|
static const int DeleteResource = 0x4;
|
||||||
|
static const int AddChild = 0x5;
|
||||||
|
static const int RemoveChild = 0x6;
|
||||||
|
static const int RenameResource = 0x7;
|
||||||
|
|
||||||
|
// Request Inquire
|
||||||
|
static const int TemplateFromClassName = 0x8;
|
||||||
|
static const int TemplateFromClassId = 0x9;
|
||||||
|
static const int TemplateFromResourceId = 0xA;
|
||||||
|
static const int QueryLink = 0xB;
|
||||||
|
static const int ResourceHistory = 0xC;
|
||||||
|
static const int ResourceChildren = 0xD;
|
||||||
|
static const int ResourceParents = 0xE;
|
||||||
|
|
||||||
|
// Request Invoke
|
||||||
|
static const int InvokeFunctionArrayArguments = 0x10;
|
||||||
|
static const int GetProperty = 0x11;
|
||||||
|
static const int GetPropertyIfModified = 0x12;
|
||||||
|
static const int SetProperty = 0x13;
|
||||||
|
static const int InvokeFunctionNamedArguments = 0x14;
|
||||||
|
|
||||||
|
// Request Attribute
|
||||||
|
static const int GetAllAttributes = 0x18;
|
||||||
|
static const int UpdateAllAttributes = 0x19;
|
||||||
|
static const int ClearAllAttributes = 0x1A;
|
||||||
|
static const int GetAttributes = 0x1B;
|
||||||
|
static const int UpdateAttributes = 0x1C;
|
||||||
|
static const int ClearAttributes = 0x1D;
|
||||||
|
}
|
7
bin/Net/Packets/IIPPacketCommand.dart
Normal file
7
bin/Net/Packets/IIPPacketCommand.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class IIPPacketCommand
|
||||||
|
{
|
||||||
|
static const int Event = 0;
|
||||||
|
static const int Request = 1;
|
||||||
|
static const int Reply = 2;
|
||||||
|
static const int Report = 3;
|
||||||
|
}
|
15
bin/Net/Packets/IIPPacketEvent.dart
Normal file
15
bin/Net/Packets/IIPPacketEvent.dart
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class IIPPacketEvent
|
||||||
|
{
|
||||||
|
// Event Manage
|
||||||
|
static const int ResourceReassigned = 0;
|
||||||
|
static const int ResourceDestroyed = 1;
|
||||||
|
static const int ChildAdded = 2;
|
||||||
|
static const int ChildRemoved = 3;
|
||||||
|
static const int Renamed = 4;
|
||||||
|
// Event Invoke
|
||||||
|
static const int PropertyUpdated = 0x10;
|
||||||
|
static const int EventOccurred = 0x11;
|
||||||
|
|
||||||
|
// Attribute
|
||||||
|
static const int AttributesUpdated = 0x18;
|
||||||
|
}
|
7
bin/Net/Packets/IIPPacketReport.dart
Normal file
7
bin/Net/Packets/IIPPacketReport.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class IIPPacketReport
|
||||||
|
{
|
||||||
|
static const int ManagementError = 0;
|
||||||
|
static const int ExecutionError = 1;
|
||||||
|
static const int ProgressReport = 0x8;
|
||||||
|
static const int ChunkStream = 0x9;
|
||||||
|
}
|
22
bin/Net/SendList.dart
Normal file
22
bin/Net/SendList.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import '../Data/BinaryList.dart';
|
||||||
|
import '../Core/AsyncReply.dart';
|
||||||
|
import 'NetworkConnection.dart';
|
||||||
|
|
||||||
|
class SendList extends BinaryList
|
||||||
|
{
|
||||||
|
NetworkConnection connection;
|
||||||
|
AsyncReply<List<dynamic>> reply;
|
||||||
|
|
||||||
|
SendList(NetworkConnection connection, AsyncReply<List<dynamic>> reply)
|
||||||
|
{
|
||||||
|
this.reply = reply;
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AsyncReply<List<dynamic>> done()
|
||||||
|
{
|
||||||
|
connection.send(super.toDC());
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
}
|
25
bin/Net/Sockets/IPEndPoint.dart
Normal file
25
bin/Net/Sockets/IPEndPoint.dart
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
class IPEndPoint
|
||||||
|
{
|
||||||
|
List<int> ip;
|
||||||
|
int port;
|
||||||
|
|
||||||
|
|
||||||
|
String getIP()
|
||||||
|
{
|
||||||
|
return ip.join(".");
|
||||||
|
//return "${(ip >> 24) & 0xFF}.${(ip >> 16) & 0xFF}.${(ip >> 8) & 0xFF}.${ip & 0xFF}";
|
||||||
|
}
|
||||||
|
|
||||||
|
String get address => getIP();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return "${getIP()}:${port}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IPEndPoint(this.ip, this.port)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
47
bin/Net/Sockets/ISocket.dart
Normal file
47
bin/Net/Sockets/ISocket.dart
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import '../../Core/IDestructible.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import 'IPEndPoint.dart';
|
||||||
|
import '../../Core/AsyncReply.dart';
|
||||||
|
import 'SocketState.dart';
|
||||||
|
|
||||||
|
abstract class ISocket extends IDestructible
|
||||||
|
{
|
||||||
|
SocketState get state ; //{ get; }
|
||||||
|
|
||||||
|
//event ISocketReceiveEvent OnReceive;
|
||||||
|
//event ISocketConnectEvent OnConnect;
|
||||||
|
//event ISocketCloseEvent OnClose;
|
||||||
|
|
||||||
|
//void send(DC message);
|
||||||
|
void send(DC message, [int offset, int size]);
|
||||||
|
void close();
|
||||||
|
AsyncReply<bool> connect(String hostname, int port);
|
||||||
|
bool begin();
|
||||||
|
|
||||||
|
AsyncReply<ISocket> accept();
|
||||||
|
IPEndPoint remoteEndPoint;
|
||||||
|
IPEndPoint localEndPoint;
|
||||||
|
}
|
9
bin/Net/Sockets/SocketState.dart
Normal file
9
bin/Net/Sockets/SocketState.dart
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
enum SocketState
|
||||||
|
{
|
||||||
|
Initial,
|
||||||
|
Listening,
|
||||||
|
Connecting,
|
||||||
|
Established,
|
||||||
|
Closed,
|
||||||
|
Terminated
|
||||||
|
}
|
212
bin/Net/Sockets/TCPSocket.dart
Normal file
212
bin/Net/Sockets/TCPSocket.dart
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
import 'ISocket.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import '../NetworkBuffer.dart';
|
||||||
|
import 'SocketState.dart';
|
||||||
|
import 'IPEndPoint.dart';
|
||||||
|
import '../../Core/AsyncReply.dart';
|
||||||
|
|
||||||
|
class TCPSocket extends ISocket
|
||||||
|
{
|
||||||
|
Socket sock;
|
||||||
|
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
|
||||||
|
|
||||||
|
//bool asyncSending;
|
||||||
|
bool began = false;
|
||||||
|
|
||||||
|
SocketState _state = SocketState.Initial;
|
||||||
|
|
||||||
|
//public event ISocketReceiveEvent OnReceive;
|
||||||
|
//public event ISocketConnectEvent OnConnect;
|
||||||
|
//public event ISocketCloseEvent OnClose;
|
||||||
|
//public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
//SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs();
|
||||||
|
|
||||||
|
/*
|
||||||
|
void connected(Task t)
|
||||||
|
{
|
||||||
|
state = SocketState.Established;
|
||||||
|
OnConnect?.Invoke();
|
||||||
|
Begin();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
IPEndPoint _localEP, _remoteEP;
|
||||||
|
|
||||||
|
bool begin()
|
||||||
|
{
|
||||||
|
if (began)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
began = true;
|
||||||
|
|
||||||
|
_localEP = IPEndPoint(sock.address.rawAddress, sock.port);
|
||||||
|
_remoteEP = IPEndPoint(sock.remoteAddress.rawAddress, sock.remotePort);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dataHandler(List<int> data){
|
||||||
|
//print(new String.fromCharCodes(data).trim());
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_state == SocketState.Closed || _state == SocketState.Terminated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var dc = new DC.fromList(data);
|
||||||
|
receiveNetworkBuffer.write(dc, 0, dc.length);
|
||||||
|
emitArgs("receive", [receiveNetworkBuffer]);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (ex)
|
||||||
|
{
|
||||||
|
if (_state != SocketState.Closed)// && !sock.connected)
|
||||||
|
{
|
||||||
|
_state = SocketState.Terminated;
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void errorHandler(error, StackTrace trace){
|
||||||
|
print(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doneHandler(){
|
||||||
|
sock.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<bool> connect(String hostname, int port)
|
||||||
|
{
|
||||||
|
var rt = new AsyncReply<bool>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_state = SocketState.Connecting;
|
||||||
|
|
||||||
|
Socket.connect(hostname, port).then((s){
|
||||||
|
sock = s;
|
||||||
|
s.listen(dataHandler,
|
||||||
|
onError: errorHandler,
|
||||||
|
onDone: doneHandler,
|
||||||
|
cancelOnError: false);
|
||||||
|
_state = SocketState.Established;
|
||||||
|
emitArgs("connect", []);
|
||||||
|
begin();
|
||||||
|
rt.trigger(true);
|
||||||
|
|
||||||
|
}).catchError((ex){
|
||||||
|
close();
|
||||||
|
rt.triggerError(ex);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(ex)
|
||||||
|
{
|
||||||
|
rt.triggerError(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IPEndPoint get localEndPoint => _localEP;
|
||||||
|
IPEndPoint get remoteEndPoint => _remoteEP;
|
||||||
|
|
||||||
|
|
||||||
|
SocketState get state => _state;
|
||||||
|
|
||||||
|
|
||||||
|
TCPSocket.fromSocket(Socket socket)
|
||||||
|
{
|
||||||
|
sock = socket;
|
||||||
|
//if (socket.)
|
||||||
|
// _state = SocketState.Established;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPSocket()
|
||||||
|
{
|
||||||
|
// default constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
if (state != SocketState.Closed && state != SocketState.Terminated)
|
||||||
|
_state = SocketState.Closed;
|
||||||
|
|
||||||
|
sock?.close();
|
||||||
|
|
||||||
|
emitArgs("close", []);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void send(DC message, [int offset, int size])
|
||||||
|
{
|
||||||
|
if (state == SocketState.Established)
|
||||||
|
sock.add(message.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
emitArgs("destroy", [this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncReply<ISocket> accept()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var reply = new AsyncReply<ISocket>();
|
||||||
|
return reply;
|
||||||
|
|
||||||
|
/*
|
||||||
|
ServerSocket.bind(InternetAddress.ANY_IP_V4, 4567).then(
|
||||||
|
(ServerSocket server) {
|
||||||
|
server.listen(handleClient);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
void handleClient(Socket client){
|
||||||
|
print('Connection from '
|
||||||
|
'${client.remoteAddress.address}:${client.remotePort}');
|
||||||
|
|
||||||
|
client.write("Hello from simple server!\n");
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
46
bin/Resource/IResource.dart
Normal file
46
bin/Resource/IResource.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../Core/IDestructible.dart';
|
||||||
|
import 'ResourceTrigger.dart';
|
||||||
|
import '../Core/AsyncReply.dart';
|
||||||
|
import 'Instance.dart';
|
||||||
|
|
||||||
|
abstract class IResource extends IDestructible
|
||||||
|
{
|
||||||
|
|
||||||
|
AsyncReply<bool> trigger(ResourceTrigger trigger);
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
return new AsyncReply.ready(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
// Destroyed
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Instance instance;
|
||||||
|
}
|
43
bin/Resource/IStore.dart
Normal file
43
bin/Resource/IStore.dart
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import './IResource.dart';
|
||||||
|
import '../Core/AsyncReply.dart';
|
||||||
|
import '../Data/KeyList.dart';
|
||||||
|
import './Template/PropertyTemplate.dart';
|
||||||
|
import '../Data/PropertyValue.dart';
|
||||||
|
|
||||||
|
abstract class IStore extends IResource
|
||||||
|
{
|
||||||
|
AsyncReply<IResource> get(String path);
|
||||||
|
AsyncReply<IResource> retrieve(int iid);
|
||||||
|
bool put(IResource resource);
|
||||||
|
String link(IResource resource);
|
||||||
|
bool record(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime);
|
||||||
|
bool modify(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime);
|
||||||
|
bool remove(IResource resource);
|
||||||
|
|
||||||
|
|
||||||
|
AsyncReply<KeyList<PropertyTemplate, List<PropertyValue>>> getRecord(IResource resource, DateTime fromDate, DateTime toDate);
|
||||||
|
}
|
680
bin/Resource/Instance.dart
Normal file
680
bin/Resource/Instance.dart
Normal file
@ -0,0 +1,680 @@
|
|||||||
|
import 'dart:core';
|
||||||
|
import '../Data/DC.dart';
|
||||||
|
import '../Data/Structure.dart';
|
||||||
|
import '../Data/AutoList.dart';
|
||||||
|
import './IStore.dart';
|
||||||
|
import './IResource.dart';
|
||||||
|
import '../Data/KeyList.dart';
|
||||||
|
import './StorageMode.dart';
|
||||||
|
import '../Data/ValueObject.dart';
|
||||||
|
import '../Core/IEventHandler.dart';
|
||||||
|
import '../Security/Permissions/Ruling.dart';
|
||||||
|
import '../Security/Permissions/IPermissionsManager.dart';
|
||||||
|
import '../Security/Permissions/ActionType.dart';
|
||||||
|
import './Template/ResourceTemplate.dart';
|
||||||
|
import './Template/PropertyTemplate.dart';
|
||||||
|
import './Template/FunctionTemplate.dart';
|
||||||
|
import './Template/EventTemplate.dart';
|
||||||
|
|
||||||
|
import '../Security/Authority/Session.dart';
|
||||||
|
import './Template/MemberTemplate.dart';
|
||||||
|
import '../Data/PropertyValue.dart';
|
||||||
|
import 'Warehouse.dart';
|
||||||
|
|
||||||
|
class Instance extends IEventHandler
|
||||||
|
{
|
||||||
|
String _name;
|
||||||
|
|
||||||
|
AutoList<IResource, Instance> _children;
|
||||||
|
IResource _resource;
|
||||||
|
IStore _store;
|
||||||
|
AutoList<IResource, Instance> _parents;
|
||||||
|
//bool inherit;
|
||||||
|
ResourceTemplate _template;
|
||||||
|
|
||||||
|
AutoList<IPermissionsManager, Instance> _managers;
|
||||||
|
|
||||||
|
|
||||||
|
KeyList<String, dynamic> _attributes;
|
||||||
|
|
||||||
|
List<int> _ages = new List<int>();
|
||||||
|
List<DateTime> _modificationDates = new List<DateTime>();
|
||||||
|
int _instanceAge;
|
||||||
|
DateTime _instanceModificationDate;
|
||||||
|
|
||||||
|
int _id;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instance attributes are custom properties associated with the instance, a place to store information by IStore.
|
||||||
|
/// </summary>
|
||||||
|
KeyList<String, dynamic> get attributes => _attributes;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _name + " (" + link + ")";
|
||||||
|
|
||||||
|
|
||||||
|
bool removeAttributes([List<String> attributes = null])
|
||||||
|
{
|
||||||
|
if (attributes == null)
|
||||||
|
this._attributes.clear();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var attr in attributes)
|
||||||
|
this.attributes.remove(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Structure getAttributes([List<String> attributes = null])
|
||||||
|
{
|
||||||
|
var st = new Structure();
|
||||||
|
|
||||||
|
if (attributes == null)
|
||||||
|
{
|
||||||
|
var clone = this.attributes.keys.toList();
|
||||||
|
clone.add("managers");
|
||||||
|
attributes = clone.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var attr in attributes)
|
||||||
|
{
|
||||||
|
if (attr == "name")
|
||||||
|
st["name"] = _name;
|
||||||
|
else if (attr == "managers")
|
||||||
|
{
|
||||||
|
var mngrs = new List<Structure>();
|
||||||
|
|
||||||
|
for (var i = 0; i < _managers.length; i++)
|
||||||
|
{
|
||||||
|
var mst = new Structure();
|
||||||
|
mst["type"] = _managers[i].runtimeType;
|
||||||
|
mst["settings"] = _managers[i].settings;
|
||||||
|
|
||||||
|
mngrs.add(mst);
|
||||||
|
}
|
||||||
|
|
||||||
|
st["managers"] = mngrs;
|
||||||
|
}
|
||||||
|
else if (attr == "parents")
|
||||||
|
{
|
||||||
|
st["parents"] = _parents.toList();
|
||||||
|
}
|
||||||
|
else if (attr == "children")
|
||||||
|
{
|
||||||
|
st["children"] = _children.toList();
|
||||||
|
}
|
||||||
|
else if (attr == "childrenCount")
|
||||||
|
{
|
||||||
|
st["childrenCount"] = _children.count;
|
||||||
|
}
|
||||||
|
else if (attr == "type")
|
||||||
|
{
|
||||||
|
st["type"] = resource.runtimeType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
st[attr] = _attributes[attr];
|
||||||
|
}
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setAttributes(Structure attributes, [bool clearAttributes = false])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
if (clearAttributes)
|
||||||
|
_attributes.clear();
|
||||||
|
|
||||||
|
for (var attrKey in attributes.keys)
|
||||||
|
if (attrKey == "name")
|
||||||
|
_name = attributes[attrKey];
|
||||||
|
else if (attrKey == "managers")
|
||||||
|
{
|
||||||
|
_managers.clear();
|
||||||
|
|
||||||
|
var mngrs = attributes[attrKey] as List;
|
||||||
|
// this is not implemented now, Flutter doesn't support mirrors, needs a workaround @ Warehouse.registerManager
|
||||||
|
/*
|
||||||
|
for (var mngr in mngrs)
|
||||||
|
{
|
||||||
|
var m = mngr as Structure;
|
||||||
|
var type = Type.GetType(m["type"] as string);
|
||||||
|
if (Codec.implementsInterface<type, typeof(IPermissionsManager)))
|
||||||
|
{
|
||||||
|
var settings = m["settings"] as Structure;
|
||||||
|
var manager = Activator.CreateInstance(type) as IPermissionsManager;
|
||||||
|
manager.Initialize(settings, this.resource);
|
||||||
|
this.managers.Add(manager);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_attributes[attrKey] = attributes[attrKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(ex)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public Structure GetAttributes()
|
||||||
|
{
|
||||||
|
var st = new Structure();
|
||||||
|
foreach (var a in attributes.Keys)
|
||||||
|
st[a] = attributes[a];
|
||||||
|
|
||||||
|
st["name"] = name;
|
||||||
|
|
||||||
|
var mngrs = new List<Structure>();
|
||||||
|
|
||||||
|
foreach (var manager in managers)
|
||||||
|
{
|
||||||
|
var mngr = new Structure();
|
||||||
|
mngr["settings"] = manager.Settings;
|
||||||
|
mngr["type"] = manager.GetType().FullName;
|
||||||
|
mngrs.Add(mngr);
|
||||||
|
}
|
||||||
|
|
||||||
|
st["managers"] = mngrs;
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the age of a given property index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Zero-based property index.</param>
|
||||||
|
/// <returns>Age.</returns>
|
||||||
|
int getAge(int index)
|
||||||
|
{
|
||||||
|
if (index < _ages.length)
|
||||||
|
return _ages[index];
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the age of a property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Zero-based property index.</param>
|
||||||
|
/// <param name="value">Age.</param>
|
||||||
|
void setAge(int index, int value)
|
||||||
|
{
|
||||||
|
if (index < _ages.length)
|
||||||
|
{
|
||||||
|
_ages[index] = value;
|
||||||
|
if (value > _instanceAge)
|
||||||
|
_instanceAge = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the modification date of a property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Zero-based property index.</param>
|
||||||
|
/// <param name="value">Modification date.</param>
|
||||||
|
void setModificationDate(int index, DateTime value)
|
||||||
|
{
|
||||||
|
if (index < _modificationDates.length)
|
||||||
|
{
|
||||||
|
_modificationDates[index] = value;
|
||||||
|
if (_instanceModificationDate == null || value.millisecondsSinceEpoch > _instanceModificationDate.millisecondsSinceEpoch)
|
||||||
|
_instanceModificationDate = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get modification date of a specific property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Zero-based property index</param>
|
||||||
|
/// <returns>Modification date.</returns>
|
||||||
|
DateTime getModificationDate(int index)
|
||||||
|
{
|
||||||
|
if (index < _modificationDates.length)
|
||||||
|
return _modificationDates[index];
|
||||||
|
else
|
||||||
|
return new DateTime(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load property value (used by stores)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Property name</param>
|
||||||
|
/// <param name="age">Property age</param>
|
||||||
|
/// <param name="value">Property value</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool loadProperty(String name, int age, DateTime modificationDate, dynamic value)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
var pt = _template.getPropertyTemplate(name);
|
||||||
|
|
||||||
|
if (pt == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pt.info.propertyType == typeof(DistributedPropertyContext))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pt.into.canWrite)
|
||||||
|
pt.info.setValue(resource, DC.CastConvert(value, pt.Info.PropertyType));
|
||||||
|
}
|
||||||
|
catch(ex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
setAge(pt.index, age);
|
||||||
|
setModificationDate(pt.index, modificationDate);
|
||||||
|
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Age of the instance, incremented by 1 in every modification.
|
||||||
|
/// </summary>
|
||||||
|
int get age => _instanceAge;
|
||||||
|
// this must be internal
|
||||||
|
set age (value) => _instanceAge = value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last modification date.
|
||||||
|
/// </summary>
|
||||||
|
DateTime get modificationDate => _instanceModificationDate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instance Id.
|
||||||
|
/// </summary>
|
||||||
|
int get id => _id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Import properties from bytes array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="properties"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool deserialize(List<PropertyValue> properties)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < properties.length; i++)
|
||||||
|
{
|
||||||
|
var pt = _template.getPropertyTemplateByIndex(i);
|
||||||
|
if (pt != null)
|
||||||
|
{
|
||||||
|
var pv = properties[i];
|
||||||
|
loadProperty(pt.name, pv.age, pv.date, pv.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Export all properties with ResourceProperty attributed as bytes array.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
List<PropertyValue> serialize()
|
||||||
|
{
|
||||||
|
List<PropertyValue> props = new List<PropertyValue>();
|
||||||
|
|
||||||
|
for (var pt in _template.properties)
|
||||||
|
{
|
||||||
|
// var rt = pt.info.getValue(resource, null);
|
||||||
|
// props.add(new PropertyValue(rt, _ages[pt.index], _modificationDates[pt.index]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public bool Deserialize(byte[] data, uint offset, uint length)
|
||||||
|
{
|
||||||
|
|
||||||
|
var props = Codec.ParseValues(data, offset, length);
|
||||||
|
Deserialize(props);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
public byte[] Serialize(bool includeLength = false, DistributedConnection sender = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
//var bl = new BinaryList();
|
||||||
|
List<object> props = new List<object>();
|
||||||
|
|
||||||
|
foreach (var pt in template.Properties)
|
||||||
|
{
|
||||||
|
|
||||||
|
var pi = resource.GetType().GetProperty(pt.Name);
|
||||||
|
|
||||||
|
var rt = pi.GetValue(resource, null);
|
||||||
|
|
||||||
|
// this is a cool hack to let the property know the sender
|
||||||
|
if (rt is Func<DistributedConnection, object>)
|
||||||
|
rt = (rt as Func<DistributedConnection, object>)(sender);
|
||||||
|
|
||||||
|
props.Add(rt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeLength)
|
||||||
|
{
|
||||||
|
return Codec.Compose(props.ToArray(), false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var rt = Codec.Compose(props.ToArray(), false);
|
||||||
|
return DC.Clip(rt, 4, (uint)(rt.Length - 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] StorageSerialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
var props = new List<object>();
|
||||||
|
|
||||||
|
foreach(var pt in template.Properties)
|
||||||
|
{
|
||||||
|
if (!pt.Storable)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var pi = resource.GetType().GetProperty(pt.Name);
|
||||||
|
|
||||||
|
if (!pi.CanWrite)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var rt = pi.GetValue(resource, null);
|
||||||
|
|
||||||
|
props.Add(rt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Codec.Compose(props.ToArray(), false);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If True, the instance can be stored to disk.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool isStorable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void emitModification(PropertyTemplate pt, dynamic value)
|
||||||
|
{
|
||||||
|
_instanceAge++;
|
||||||
|
var now = DateTime.now().toUtc();
|
||||||
|
|
||||||
|
_ages[pt.index] = _instanceAge;
|
||||||
|
_modificationDates[pt.index] = now;
|
||||||
|
|
||||||
|
if (pt.storage == StorageMode.NonVolatile)
|
||||||
|
{
|
||||||
|
_store.modify(_resource, pt.name, value, _ages[pt.index], now);
|
||||||
|
}
|
||||||
|
else if (pt.storage == StorageMode.Recordable)
|
||||||
|
{
|
||||||
|
_store.record(_resource, pt.name, value, _ages[pt.index], now);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitArgs("resourceModified", [_resource, pt.name, value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notify listeners that a property was modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyName"></param>
|
||||||
|
/// <param name="newValue"></param>
|
||||||
|
/// <param name="oldValue"></param>
|
||||||
|
modified(String propertyName)
|
||||||
|
{
|
||||||
|
var valueObject = new ValueObject();
|
||||||
|
if (getPropertyValue(propertyName, valueObject))
|
||||||
|
{
|
||||||
|
var pt = _template.getPropertyTemplateByName(propertyName);
|
||||||
|
emitModification(pt, valueObject.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitResourceEvent(issuer, List<Session> receivers, String name, List<dynamic> args)
|
||||||
|
{
|
||||||
|
emitArgs("resourceEventOccurred", [_resource, issuer, receivers, name, args]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value of a given property by name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Property name</param>
|
||||||
|
/// <param name="value">Output value</param>
|
||||||
|
/// <returns>True, if the resource has the property.</returns>
|
||||||
|
bool getPropertyValue(String name, ValueObject valueObject)
|
||||||
|
{
|
||||||
|
var pt = _template.getPropertyTemplateByName(name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (pt != null && pt.info != null)
|
||||||
|
{
|
||||||
|
valueObject.value = pt.info.getValue(_resource, null);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
valueObject.value = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
public bool Inherit
|
||||||
|
{
|
||||||
|
get { return inherit; }
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of parents.
|
||||||
|
/// </summary>
|
||||||
|
AutoList<IResource, Instance> get parents => _parents;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Store responsible for creating and keeping the resource.
|
||||||
|
/// </summary>
|
||||||
|
IStore get store => _store;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of children.
|
||||||
|
/// </summary>
|
||||||
|
AutoList<IResource, Instance> get children => _children;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The unique and permanent link to the resource.
|
||||||
|
/// </summary>
|
||||||
|
String get link
|
||||||
|
{
|
||||||
|
if (_store != null)
|
||||||
|
return _store.link(_resource);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var l = new List<String>();
|
||||||
|
|
||||||
|
var p = _resource;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
l.insert(0, p.instance.name);
|
||||||
|
|
||||||
|
if (p.instance.parents.count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
p = p.instance.parents.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.join("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instance name.
|
||||||
|
/// </summary>
|
||||||
|
String get name => _name;
|
||||||
|
set name(value) => name = value;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource managed by this instance.
|
||||||
|
/// </summary>
|
||||||
|
IResource get resource => _resource;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource template describes the properties, functions and events of the resource.
|
||||||
|
/// </summary>
|
||||||
|
ResourceTemplate get template => _template;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check for permission.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">Caller sessions.</param>
|
||||||
|
/// <param name="action">Action type</param>
|
||||||
|
/// <param name="member">Function, property or event to check for permission.</param>
|
||||||
|
/// <param name="inquirer">Permission inquirer.</param>
|
||||||
|
/// <returns>Ruling.</returns>
|
||||||
|
Ruling applicable(Session session, ActionType action, MemberTemplate member, [dynamic inquirer = null])
|
||||||
|
{
|
||||||
|
|
||||||
|
for(var i = 0; i < _managers.length; i++)
|
||||||
|
{
|
||||||
|
var r = _managers[i].applicable(this.resource, session, action, member, inquirer);
|
||||||
|
if (r != Ruling.DontCare)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ruling.DontCare;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execution managers.
|
||||||
|
/// </summary>
|
||||||
|
AutoList<IPermissionsManager, Instance> get managers => _managers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create new instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Instance Id.</param>
|
||||||
|
/// <param name="name">Name of the instance.</param>
|
||||||
|
/// <param name="resource">Resource to manage.</param>
|
||||||
|
/// <param name="store">Store responsible for the resource.</param>
|
||||||
|
Instance(int id, String name, IResource resource, IStore store, [ResourceTemplate customTemplate = null, int age = 0])
|
||||||
|
{
|
||||||
|
_store = store;
|
||||||
|
_resource = resource;
|
||||||
|
_id = id;
|
||||||
|
_name = name;
|
||||||
|
_instanceAge = age;
|
||||||
|
|
||||||
|
_attributes = new KeyList<String, dynamic>(this);
|
||||||
|
_children = new AutoList<IResource, Instance>(this);
|
||||||
|
_parents = new AutoList<IResource, Instance>(this);
|
||||||
|
_managers = new AutoList<IPermissionsManager, Instance>(this);
|
||||||
|
|
||||||
|
_children.on("add", children_OnAdd);
|
||||||
|
_children.on("remove", children_OnRemoved);
|
||||||
|
_parents.on("add", parents_OnAdd);
|
||||||
|
_parents.on("remove", parents_OnRemoved);
|
||||||
|
|
||||||
|
resource.on("destroy", resource_OnDestroy);
|
||||||
|
|
||||||
|
if (customTemplate != null)
|
||||||
|
_template = customTemplate;
|
||||||
|
else
|
||||||
|
_template = Warehouse.getTemplateByType(resource.runtimeType);
|
||||||
|
|
||||||
|
// set ages
|
||||||
|
for (int i = 0; i < _template.properties.length; i++)
|
||||||
|
{
|
||||||
|
_ages.add(0);
|
||||||
|
_modificationDates.add(new DateTime(0));//DateTime.MinValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// connect events
|
||||||
|
Type t = resource.runtimeType;
|
||||||
|
|
||||||
|
var events = t.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
|
||||||
|
foreach (var evt in events)
|
||||||
|
{
|
||||||
|
//if (evt.EventHandlerType != typeof(ResourceEventHanlder))
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
|
||||||
|
if (evt.EventHandlerType == typeof(ResourceEventHanlder))
|
||||||
|
{
|
||||||
|
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||||
|
if (ca.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(null, null, evt.Name, args);
|
||||||
|
evt.AddEventHandler(resource, proxyDelegate);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (evt.EventHandlerType == typeof(CustomResourceEventHanlder))
|
||||||
|
{
|
||||||
|
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||||
|
if (ca.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CustomResourceEventHanlder proxyDelegate = (issuer, receivers, args) => EmitResourceEvent(issuer, receivers, evt.Name, args);
|
||||||
|
evt.AddEventHandler(resource, proxyDelegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void children_OnRemoved(Instance parent, IResource value)
|
||||||
|
{
|
||||||
|
value.instance.parents.remove(_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void children_OnAdd(Instance parent, IResource value)
|
||||||
|
{
|
||||||
|
if (!value.instance.parents.contains(_resource))
|
||||||
|
value.instance.parents.add(_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parents_OnRemoved(Instance parent, IResource value)
|
||||||
|
{
|
||||||
|
value.instance.children.remove(_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parents_OnAdd(Instance parent, IResource value)
|
||||||
|
{
|
||||||
|
if (!value.instance.children.contains(_resource))
|
||||||
|
value.instance.children.add(_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void resource_OnDestroy(sender)
|
||||||
|
{
|
||||||
|
emitArgs("resourceDestroyed", [sender]);
|
||||||
|
}
|
||||||
|
}
|
34
bin/Resource/ResourceTrigger.dart
Normal file
34
bin/Resource/ResourceTrigger.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum ResourceTrigger
|
||||||
|
{
|
||||||
|
Open,
|
||||||
|
Initialize,
|
||||||
|
Terminate,
|
||||||
|
Configure,
|
||||||
|
SystemInitialized,
|
||||||
|
SystemTerminated,
|
||||||
|
SystemReload,
|
||||||
|
}
|
6
bin/Resource/StorageMode.dart
Normal file
6
bin/Resource/StorageMode.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class StorageMode
|
||||||
|
{
|
||||||
|
static const NonVolatile = 0;
|
||||||
|
static const Volatile = 1;
|
||||||
|
static const Recordable = 2;
|
||||||
|
}
|
45
bin/Resource/Template/EventTemplate.dart
Normal file
45
bin/Resource/Template/EventTemplate.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
import 'MemberTemplate.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import '../../Data/BinaryList.dart';
|
||||||
|
import 'ResourceTemplate.dart';
|
||||||
|
import 'MemberType.dart';
|
||||||
|
|
||||||
|
class EventTemplate extends MemberTemplate
|
||||||
|
{
|
||||||
|
|
||||||
|
String expansion;
|
||||||
|
|
||||||
|
|
||||||
|
DC compose()
|
||||||
|
{
|
||||||
|
var name = super.compose();
|
||||||
|
|
||||||
|
if (expansion != null)
|
||||||
|
{
|
||||||
|
var exp = DC.stringToBytes(expansion);
|
||||||
|
return new BinaryList()
|
||||||
|
.addUint8(0x50)
|
||||||
|
.addInt32(exp.length)
|
||||||
|
.addDC(exp)
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new BinaryList()
|
||||||
|
.addUint8(0x40)
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EventTemplate(ResourceTemplate template, int index, String name, String expansion)
|
||||||
|
: super(template, MemberType.Property, index, name)
|
||||||
|
{
|
||||||
|
this.expansion = expansion;
|
||||||
|
}
|
||||||
|
}
|
42
bin/Resource/Template/FunctionTemplate.dart
Normal file
42
bin/Resource/Template/FunctionTemplate.dart
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import 'MemberTemplate.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import '../../Data/BinaryList.dart';
|
||||||
|
import 'ResourceTemplate.dart';
|
||||||
|
import 'MemberType.dart';
|
||||||
|
|
||||||
|
class FunctionTemplate extends MemberTemplate
|
||||||
|
{
|
||||||
|
|
||||||
|
String expansion;
|
||||||
|
bool isVoid;
|
||||||
|
|
||||||
|
|
||||||
|
DC compose()
|
||||||
|
{
|
||||||
|
var name = super.compose();
|
||||||
|
|
||||||
|
if (expansion != null)
|
||||||
|
{
|
||||||
|
var exp = DC.stringToBytes(expansion);
|
||||||
|
return new BinaryList().addUint8((0x10 | (isVoid ? 0x8 : 0x0)))
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.addInt32(exp.length)
|
||||||
|
.addDC(exp)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return new BinaryList().addUint8((isVoid ? 0x8 : 0x0))
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FunctionTemplate(ResourceTemplate template, int index, String name, bool isVoid, String expansion)
|
||||||
|
:super(template, MemberType.Property, index, name)
|
||||||
|
{
|
||||||
|
this.isVoid = isVoid;
|
||||||
|
this.expansion = expansion;
|
||||||
|
}
|
||||||
|
}
|
34
bin/Resource/Template/MemberTemplate.dart
Normal file
34
bin/Resource/Template/MemberTemplate.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
import 'MemberType.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import './ResourceTemplate.dart';
|
||||||
|
|
||||||
|
class MemberTemplate
|
||||||
|
{
|
||||||
|
|
||||||
|
int get index => _index;
|
||||||
|
String get name => _name;
|
||||||
|
MemberType get type => _type;
|
||||||
|
|
||||||
|
ResourceTemplate _template;
|
||||||
|
String _name;
|
||||||
|
MemberType _type;
|
||||||
|
int _index;
|
||||||
|
|
||||||
|
ResourceTemplate get template => _template;
|
||||||
|
|
||||||
|
MemberTemplate(ResourceTemplate template, MemberType type, int index, String name)
|
||||||
|
{
|
||||||
|
this._template = template;
|
||||||
|
this._type = type;
|
||||||
|
this._index = index;
|
||||||
|
this._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
String get fullname => _template.className + "." + _name;
|
||||||
|
|
||||||
|
DC compose()
|
||||||
|
{
|
||||||
|
// return DC.ToBytes(Name);
|
||||||
|
}
|
||||||
|
}
|
6
bin/Resource/Template/MemberType.dart
Normal file
6
bin/Resource/Template/MemberType.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
enum MemberType
|
||||||
|
{
|
||||||
|
Function,// = 0,
|
||||||
|
Property,// = 1,
|
||||||
|
Event// = 2,
|
||||||
|
}
|
6
bin/Resource/Template/PropertyPermission.dart
Normal file
6
bin/Resource/Template/PropertyPermission.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class PropertyPermission
|
||||||
|
{
|
||||||
|
static const int Read = 1;
|
||||||
|
static const int Write = 2;
|
||||||
|
static const int ReadWrite = 3;
|
||||||
|
}
|
80
bin/Resource/Template/PropertyTemplate.dart
Normal file
80
bin/Resource/Template/PropertyTemplate.dart
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
import 'MemberTemplate.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import '../../Data/BinaryList.dart';
|
||||||
|
import 'ResourceTemplate.dart';
|
||||||
|
import 'MemberType.dart';
|
||||||
|
import 'PropertyPermission.dart';
|
||||||
|
import '../StorageMode.dart';
|
||||||
|
|
||||||
|
class PropertyTemplate extends MemberTemplate
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
int permission;
|
||||||
|
|
||||||
|
|
||||||
|
int storage;
|
||||||
|
|
||||||
|
String readExpansion;
|
||||||
|
|
||||||
|
String writeExpansion;
|
||||||
|
|
||||||
|
DC compose()
|
||||||
|
{
|
||||||
|
var name = super.compose();
|
||||||
|
var pv = ((permission) << 1) | (storage == StorageMode.Recordable ? 1 : 0);
|
||||||
|
|
||||||
|
if (writeExpansion != null && readExpansion != null)
|
||||||
|
{
|
||||||
|
var rexp = DC.stringToBytes(readExpansion);
|
||||||
|
var wexp = DC.stringToBytes(writeExpansion);
|
||||||
|
return new BinaryList()
|
||||||
|
.addUint8(0x38 | pv)
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.addInt32(wexp.length)
|
||||||
|
.addDC(wexp)
|
||||||
|
.addInt32(rexp.length)
|
||||||
|
.addDC(rexp)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
else if (writeExpansion != null)
|
||||||
|
{
|
||||||
|
var wexp = DC.stringToBytes(writeExpansion);
|
||||||
|
return new BinaryList()
|
||||||
|
.addUint8(0x30 | pv)
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.addInt32(wexp.length)
|
||||||
|
.addDC(wexp)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
else if (readExpansion != null)
|
||||||
|
{
|
||||||
|
var rexp = DC.stringToBytes(readExpansion);
|
||||||
|
return new BinaryList()
|
||||||
|
.addUint8(0x28 | pv)
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.addInt32(rexp.length)
|
||||||
|
.addDC(rexp)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return new BinaryList()
|
||||||
|
.addUint8(0x20 | pv)
|
||||||
|
.addUint8(name.length)
|
||||||
|
.addDC(name)
|
||||||
|
.toDC();
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyTemplate(ResourceTemplate template, int index, String name, String read, String write, int storage)
|
||||||
|
:super(template, MemberType.Property, index, name)
|
||||||
|
{
|
||||||
|
//this.Recordable = recordable;
|
||||||
|
this.storage = storage;
|
||||||
|
this.readExpansion = read;
|
||||||
|
this.writeExpansion = write;
|
||||||
|
}
|
||||||
|
}
|
330
bin/Resource/Template/ResourceTemplate.dart
Normal file
330
bin/Resource/Template/ResourceTemplate.dart
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
|
||||||
|
import './MemberTemplate.dart';
|
||||||
|
import '../../Data/Guid.dart';
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import './EventTemplate.dart';
|
||||||
|
import './PropertyTemplate.dart';
|
||||||
|
import './FunctionTemplate.dart';
|
||||||
|
import '../StorageMode.dart';
|
||||||
|
|
||||||
|
class ResourceTemplate
|
||||||
|
{
|
||||||
|
Guid _classId;
|
||||||
|
String _className;
|
||||||
|
List<MemberTemplate> _members = new List<MemberTemplate>();
|
||||||
|
List<FunctionTemplate> _functions = new List<FunctionTemplate>();
|
||||||
|
List<EventTemplate> _events = new List<EventTemplate>();
|
||||||
|
List<PropertyTemplate> _properties = new List<PropertyTemplate>();
|
||||||
|
int _version;
|
||||||
|
//bool isReady;
|
||||||
|
|
||||||
|
DC _content;
|
||||||
|
|
||||||
|
DC get content => _content;
|
||||||
|
|
||||||
|
/*
|
||||||
|
MemberTemplate getMemberTemplate(MemberInfo member)
|
||||||
|
{
|
||||||
|
if (member is MethodInfo)
|
||||||
|
return getFunctionTemplate(member.Name);
|
||||||
|
else if (member is EventInfo)
|
||||||
|
return getEventTemplate(member.Name);
|
||||||
|
else if (member is PropertyInfo)
|
||||||
|
return getPropertyTemplate(member.Name);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
EventTemplate getEventTemplateByName(String eventName)
|
||||||
|
{
|
||||||
|
for (var i in _events)
|
||||||
|
if (i.name == eventName)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventTemplate getEventTemplateByIndex(int index)
|
||||||
|
{
|
||||||
|
for (var i in _events)
|
||||||
|
if (i.index == index)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionTemplate getFunctionTemplateByName(String functionName)
|
||||||
|
{
|
||||||
|
for (var i in _functions)
|
||||||
|
if (i.name == functionName)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionTemplate getFunctionTemplateByIndex(int index)
|
||||||
|
{
|
||||||
|
for (var i in _functions)
|
||||||
|
if (i.index == index)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyTemplate getPropertyTemplateByIndex(int index)
|
||||||
|
{
|
||||||
|
for (var i in _properties)
|
||||||
|
if (i.index == index)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyTemplate getPropertyTemplateByName(String propertyName)
|
||||||
|
{
|
||||||
|
for (var i in _properties)
|
||||||
|
if (i.name == propertyName)
|
||||||
|
return i;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Guid get classId => _classId;
|
||||||
|
|
||||||
|
String get className => _className;
|
||||||
|
|
||||||
|
List<MemberTemplate> get methods => _members;
|
||||||
|
|
||||||
|
List<FunctionTemplate> get functions => _functions;
|
||||||
|
|
||||||
|
List<EventTemplate> get events => _events;
|
||||||
|
|
||||||
|
List<PropertyTemplate> get properties => _properties;
|
||||||
|
|
||||||
|
ResourceTemplate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ResourceTemplate.fromType(Type type)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ResourceTemplate(Type type)
|
||||||
|
{
|
||||||
|
|
||||||
|
type = ResourceProxy.GetBaseType(type);
|
||||||
|
|
||||||
|
// set guid
|
||||||
|
|
||||||
|
var typeName = Encoding.UTF8.GetBytes(type.FullName);
|
||||||
|
var hash = SHA256.Create().ComputeHash(typeName).Clip(0, 16);
|
||||||
|
|
||||||
|
classId = new Guid(hash);
|
||||||
|
className = type.FullName;
|
||||||
|
|
||||||
|
|
||||||
|
#if NETSTANDARD1_5
|
||||||
|
PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
|
||||||
|
#else
|
||||||
|
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//byte currentIndex = 0;
|
||||||
|
|
||||||
|
byte i = 0;
|
||||||
|
|
||||||
|
foreach (var pi in propsInfo)
|
||||||
|
{
|
||||||
|
var ps = (ResourceProperty[])pi.GetCustomAttributes(typeof(ResourceProperty), true);
|
||||||
|
if (ps.Length > 0)
|
||||||
|
{
|
||||||
|
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
|
||||||
|
pt.Info = pi;
|
||||||
|
properties.Add(pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
foreach (var ei in eventsInfo)
|
||||||
|
{
|
||||||
|
var es = (ResourceEvent[])ei.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||||
|
if (es.Length > 0)
|
||||||
|
{
|
||||||
|
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
|
||||||
|
events.Add(et);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
|
{
|
||||||
|
var fs = (ResourceFunction[])mi.GetCustomAttributes(typeof(ResourceFunction), true);
|
||||||
|
if (fs.Length > 0)
|
||||||
|
{
|
||||||
|
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
|
||||||
|
functions.Add(ft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// append signals
|
||||||
|
for (i = 0; i < events.Count; i++)
|
||||||
|
members.Add(events[i]);
|
||||||
|
// append slots
|
||||||
|
for (i = 0; i < functions.Count; i++)
|
||||||
|
members.Add(functions[i]);
|
||||||
|
// append properties
|
||||||
|
for (i = 0; i < properties.Count; i++)
|
||||||
|
members.Add(properties[i]);
|
||||||
|
|
||||||
|
// bake it binarily
|
||||||
|
var b = new BinaryList();
|
||||||
|
b.AddGuid(classId)
|
||||||
|
.AddUInt8((byte)className.Length)
|
||||||
|
.AddString(className)
|
||||||
|
.AddInt32(version)
|
||||||
|
.AddUInt16((ushort)members.Count);
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var ft in functions)
|
||||||
|
b.AddUInt8Array(ft.Compose());
|
||||||
|
foreach (var pt in properties)
|
||||||
|
b.AddUInt8Array(pt.Compose());
|
||||||
|
foreach (var et in events)
|
||||||
|
b.AddUInt8Array(et.Compose());
|
||||||
|
|
||||||
|
content = b.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
ResourceTemplate.parse(DC data, [int offset = 0, int contentLength])
|
||||||
|
{
|
||||||
|
|
||||||
|
// cool Dart feature
|
||||||
|
contentLength ??= data.length;
|
||||||
|
|
||||||
|
|
||||||
|
int ends = offset + contentLength;
|
||||||
|
|
||||||
|
int oOffset = offset;
|
||||||
|
|
||||||
|
// start parsing...
|
||||||
|
|
||||||
|
//var od = new ResourceTemplate();
|
||||||
|
_content = data.clip(offset, contentLength);
|
||||||
|
|
||||||
|
_classId = data.getGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
_className = data.getString(offset + 1, data[offset]);
|
||||||
|
offset += data[offset] + 1;
|
||||||
|
|
||||||
|
_version = data.getInt32(offset);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
var methodsCount = data.getUint16(offset);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
var functionIndex = 0;
|
||||||
|
var propertyIndex = 0;
|
||||||
|
var eventIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < methodsCount; i++)
|
||||||
|
{
|
||||||
|
var type = data[offset] >> 5;
|
||||||
|
|
||||||
|
if (type == 0) // function
|
||||||
|
{
|
||||||
|
String expansion = null;
|
||||||
|
var hasExpansion = ((data[offset] & 0x10) == 0x10);
|
||||||
|
var isVoid = ((data[offset++] & 0x08) == 0x08);
|
||||||
|
var name = data.getString(offset + 1, data[offset]);
|
||||||
|
offset += data[offset] + 1;
|
||||||
|
|
||||||
|
if (hasExpansion) // expansion ?
|
||||||
|
{
|
||||||
|
var cs = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
expansion = data.getString(offset, cs);
|
||||||
|
offset += cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ft = new FunctionTemplate(this, functionIndex++, name, isVoid, expansion);
|
||||||
|
|
||||||
|
_functions.add(ft);
|
||||||
|
}
|
||||||
|
else if (type == 1) // property
|
||||||
|
{
|
||||||
|
|
||||||
|
String readExpansion = null, writeExpansion = null;
|
||||||
|
|
||||||
|
var hasReadExpansion = ((data[offset] & 0x8) == 0x8);
|
||||||
|
var hasWriteExpansion = ((data[offset] & 0x10) == 0x10);
|
||||||
|
var recordable = ((data[offset] & 1) == 1);
|
||||||
|
var permission = (data[offset++] >> 1) & 0x3;
|
||||||
|
var name = data.getString(offset + 1, data[offset]);
|
||||||
|
|
||||||
|
offset += data[offset] + 1;
|
||||||
|
|
||||||
|
if (hasReadExpansion) // expansion ?
|
||||||
|
{
|
||||||
|
var cs = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
readExpansion = data.getString(offset, cs);
|
||||||
|
offset += cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasWriteExpansion) // expansion ?
|
||||||
|
{
|
||||||
|
var cs = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
writeExpansion = data.getString(offset, cs);
|
||||||
|
offset += cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pt = new PropertyTemplate(this, propertyIndex++, name, readExpansion, writeExpansion, recordable ? StorageMode.Recordable : StorageMode.Volatile);
|
||||||
|
|
||||||
|
_properties.add(pt);
|
||||||
|
}
|
||||||
|
else if (type == 2) // Event
|
||||||
|
{
|
||||||
|
|
||||||
|
String expansion = null;
|
||||||
|
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
||||||
|
|
||||||
|
var name = data.getString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
|
||||||
|
offset += data[offset] + 1;
|
||||||
|
|
||||||
|
if (hasExpansion) // expansion ?
|
||||||
|
{
|
||||||
|
var cs = data.getUint32(offset);
|
||||||
|
offset += 4;
|
||||||
|
expansion = data.getString(offset, cs);
|
||||||
|
offset += cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
var et = new EventTemplate(this, eventIndex++, name, expansion);
|
||||||
|
|
||||||
|
_events.add(et);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// append signals
|
||||||
|
for (int i = 0; i < _events.length; i++)
|
||||||
|
_members.add(_events[i]);
|
||||||
|
// append slots
|
||||||
|
for (int i = 0; i < _functions.length; i++)
|
||||||
|
_members.add(_functions[i]);
|
||||||
|
// append properties
|
||||||
|
for (int i = 0; i < _properties.length; i++)
|
||||||
|
_members.add(_properties[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
458
bin/Resource/Warehouse.dart
Normal file
458
bin/Resource/Warehouse.dart
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../Data/AutoList.dart';
|
||||||
|
import './Template/ResourceTemplate.dart';
|
||||||
|
import '../Data/Guid.dart';
|
||||||
|
import '../Data/KeyList.dart';
|
||||||
|
import '../Data/Structure.dart';
|
||||||
|
import '../Security/Permissions/IPermissionsManager.dart';
|
||||||
|
import 'IResource.dart';
|
||||||
|
import 'Instance.dart';
|
||||||
|
import 'IStore.dart';
|
||||||
|
import '../Core/AsyncReply.dart';
|
||||||
|
import '../Core/AsyncBag.dart';
|
||||||
|
import 'ResourceTrigger.dart';
|
||||||
|
|
||||||
|
import '../Net/IIP/DistributedConnection.dart';
|
||||||
|
|
||||||
|
// Centeral Resource Issuer
|
||||||
|
class Warehouse
|
||||||
|
{
|
||||||
|
static AutoList<IResource, Instance> _stores = new AutoList<IResource, Instance>(null);
|
||||||
|
static Map<int, IResource> _resources = new Map<int, IResource>();
|
||||||
|
static int resourceCounter = 0;
|
||||||
|
|
||||||
|
static KeyList<Guid, ResourceTemplate> _templates = new KeyList<Guid, ResourceTemplate>();
|
||||||
|
|
||||||
|
static bool storeIsOpen = false;
|
||||||
|
|
||||||
|
//public delegate void StoreConnectedEvent(IStore store, string name);
|
||||||
|
//public delegate void StoreDisconnectedEvent(IStore store);
|
||||||
|
|
||||||
|
//public static event StoreConnectedEvent StoreConnected;
|
||||||
|
///public static event StoreDisconnectedEvent StoreDisconnected;
|
||||||
|
|
||||||
|
static KeyList<String, IStore Function()> protocols = getProtocols();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a store by its name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Store instance name</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static IStore getStore(String name)
|
||||||
|
{
|
||||||
|
for(var s in _stores)
|
||||||
|
if (s.instance.name == name)
|
||||||
|
return s;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a resource by instance Id.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Instance Id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static AsyncReply<IResource> getById(int id)
|
||||||
|
{
|
||||||
|
if (_resources.containsKey(id))
|
||||||
|
return new AsyncReply<IResource>.ready(_resources[id]);
|
||||||
|
else
|
||||||
|
return new AsyncReply<IResource>.ready(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open the warehouse.
|
||||||
|
/// This function issues the initialize trigger to all stores and resources.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True, if no problem occurred.</returns>
|
||||||
|
static AsyncReply<bool> open()
|
||||||
|
{
|
||||||
|
var bag = new AsyncBag<bool>();
|
||||||
|
|
||||||
|
|
||||||
|
for(var s in _stores)
|
||||||
|
bag.add(s.trigger(ResourceTrigger.Initialize));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bag.seal();
|
||||||
|
|
||||||
|
var rt = new AsyncReply<bool>();
|
||||||
|
bag.then((x)
|
||||||
|
{
|
||||||
|
for (var b in x)
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
rt.trigger(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rBag = new AsyncBag<bool>();
|
||||||
|
for (var rk in _resources.keys)
|
||||||
|
rBag.add(_resources[rk].trigger(ResourceTrigger.SystemInitialized));
|
||||||
|
|
||||||
|
rBag.seal();
|
||||||
|
|
||||||
|
rBag.then((y)
|
||||||
|
{
|
||||||
|
for (var b in y)
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
rt.trigger(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt.trigger(true);
|
||||||
|
storeIsOpen = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Close the warehouse.
|
||||||
|
/// This function issues terminate trigger to all resources and stores.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True, if no problem occurred.</returns>
|
||||||
|
static AsyncReply<bool> close()
|
||||||
|
{
|
||||||
|
|
||||||
|
var bag = new AsyncBag<bool>();
|
||||||
|
|
||||||
|
for (var resource in _resources.values)
|
||||||
|
if (!(resource is IStore))
|
||||||
|
bag.add(resource.trigger(ResourceTrigger.Terminate));
|
||||||
|
|
||||||
|
for (var s in _stores)
|
||||||
|
bag.add(s.trigger(ResourceTrigger.Terminate));
|
||||||
|
|
||||||
|
for (var resource in _resources.values)
|
||||||
|
if (!(resource is IStore))
|
||||||
|
bag.add(resource.trigger(ResourceTrigger.SystemTerminated));
|
||||||
|
|
||||||
|
for (var store in _stores)
|
||||||
|
bag.add(store.trigger(ResourceTrigger.SystemTerminated));
|
||||||
|
|
||||||
|
bag.seal();
|
||||||
|
|
||||||
|
var rt = new AsyncReply<bool>();
|
||||||
|
bag.then((x)
|
||||||
|
{
|
||||||
|
for (var b in x)
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
rt.trigger(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt.trigger(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static List<IResource> qureyIn(List<String> path, int index, AutoList<IResource, Instance> resources)
|
||||||
|
{
|
||||||
|
var rt = new List<IResource>();
|
||||||
|
|
||||||
|
if (index == path.length - 1)
|
||||||
|
{
|
||||||
|
if (path[index] == "")
|
||||||
|
for (var child in resources)
|
||||||
|
rt.add(child);
|
||||||
|
else
|
||||||
|
for (var child in resources)
|
||||||
|
if (child.instance.name == path[index])
|
||||||
|
rt.add(child);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (var child in resources)
|
||||||
|
if (child.instance.name == path[index])
|
||||||
|
rt.addAll(qureyIn(path, index+1, child.instance.children));
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AsyncReply<List<IResource>> query(String path)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (path == null || path == "")
|
||||||
|
{
|
||||||
|
var roots = _stores.where((s) => s.instance.parents.length == 0).toList();
|
||||||
|
return new AsyncReply<List<IResource>>.ready(roots);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var rt = new AsyncReply<List<IResource>>();
|
||||||
|
get(path).then((x)
|
||||||
|
{
|
||||||
|
var p = path.split('/');
|
||||||
|
|
||||||
|
if (x == null)
|
||||||
|
{
|
||||||
|
rt.trigger(qureyIn(p, 0, _stores));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var ar = qureyIn(p, 0, _stores).where((r) => r != x).toList();
|
||||||
|
ar.insert(0, x);
|
||||||
|
rt.trigger(ar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a resource by its path.
|
||||||
|
/// Resource path is sperated by '/' character, e.g. "system/http".
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <returns>Resource instance.</returns>
|
||||||
|
static AsyncReply<dynamic> get(String path, [attributes = null, IResource parent = null, IPermissionsManager manager = null])
|
||||||
|
{
|
||||||
|
|
||||||
|
var p = path.split('/');
|
||||||
|
IResource res;
|
||||||
|
|
||||||
|
for(IStore d in _stores)
|
||||||
|
if (p[0] == d.instance.name)
|
||||||
|
{
|
||||||
|
var i = 1;
|
||||||
|
res = d;
|
||||||
|
while(p.length > i)
|
||||||
|
{
|
||||||
|
var si = i;
|
||||||
|
|
||||||
|
for (IResource r in res.instance.children)
|
||||||
|
if (r.instance.name == p[i])
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
res = r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (si == i)
|
||||||
|
// not found, ask the store
|
||||||
|
return d.get(path.substring(p[0].length + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AsyncReply<IResource>.ready(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should we create a new store ?
|
||||||
|
if (path.contains("://"))
|
||||||
|
{
|
||||||
|
var url = path.split("://");
|
||||||
|
var hostname = url[1].split('/')[0];
|
||||||
|
var pathname = url[1].split('/').skip(1).join("/");
|
||||||
|
|
||||||
|
var rt = new AsyncReply<IResource>();
|
||||||
|
|
||||||
|
if (protocols.containsKey(url[0]))
|
||||||
|
{
|
||||||
|
var handler = protocols[url[0]];
|
||||||
|
|
||||||
|
var store = handler();
|
||||||
|
put(store, url[0] + "://" + hostname, null, parent, null, 0, manager, attributes);
|
||||||
|
|
||||||
|
|
||||||
|
store.trigger(ResourceTrigger.Open).then((x){
|
||||||
|
if (pathname.length > 0 && pathname != "")
|
||||||
|
store.get(pathname).then((r) => rt.trigger(r)
|
||||||
|
).error((e) =>
|
||||||
|
|
||||||
|
rt.triggerError(e)
|
||||||
|
|
||||||
|
);
|
||||||
|
else
|
||||||
|
rt.trigger(store);
|
||||||
|
}).error((e) {
|
||||||
|
rt.triggerError(e);
|
||||||
|
Warehouse.remove(store);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new AsyncReply<IResource>.ready(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Put a resource in the warehouse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="resource">Resource instance.</param>
|
||||||
|
/// <param name="name">Resource name.</param>
|
||||||
|
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
|
||||||
|
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
|
||||||
|
static void put(IResource resource, String name, [IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, int age = 0, IPermissionsManager manager = null, attributes = null])
|
||||||
|
{
|
||||||
|
resource.instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age);
|
||||||
|
|
||||||
|
if (attributes != null)
|
||||||
|
resource.instance.setAttributes(Structure.fromMap(attributes));
|
||||||
|
|
||||||
|
if (manager != null)
|
||||||
|
resource.instance.managers.add(manager);
|
||||||
|
|
||||||
|
if (store == parent)
|
||||||
|
parent = null;
|
||||||
|
|
||||||
|
if (parent == null)
|
||||||
|
{
|
||||||
|
if (!(resource is IStore))
|
||||||
|
store.instance.children.add(resource);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parent.instance.children.add(resource);
|
||||||
|
|
||||||
|
|
||||||
|
if (resource is IStore)
|
||||||
|
{
|
||||||
|
_stores.add(resource);
|
||||||
|
//StoreConnected?.Invoke(resource as IStore, name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
store.put(resource);
|
||||||
|
|
||||||
|
_resources[resource.instance.id] = resource;
|
||||||
|
|
||||||
|
//if (!storeIsOpen)
|
||||||
|
// resource.trigger(ResourceTrigger.Initialize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static T New<T extends IResource>(String name, [IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null])
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
var type = ResourceProxy.GetProxy<T>();
|
||||||
|
var res = Activator.CreateInstance(type) as IResource;
|
||||||
|
put(res, name, store, parent, null, 0, manager, attributes);
|
||||||
|
return (T)res;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Put a resource template in the templates warehouse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="template">Resource template.</param>
|
||||||
|
static void putTemplate(ResourceTemplate template)
|
||||||
|
{
|
||||||
|
if (!_templates.containsKey(template.classId))
|
||||||
|
_templates.add(template.classId, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a template by type from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">.Net type.</param>
|
||||||
|
/// <returns>Resource template.</returns>
|
||||||
|
static ResourceTemplate getTemplateByType(Type type)
|
||||||
|
{
|
||||||
|
// loaded ?
|
||||||
|
for (var t in _templates.values)
|
||||||
|
if (t.className == type.toString())
|
||||||
|
return t;
|
||||||
|
|
||||||
|
var template = new ResourceTemplate.fromType(type);
|
||||||
|
_templates.add(template.classId, template);
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a template by class Id from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="classId">Class Id.</param>
|
||||||
|
/// <returns>Resource template.</returns>
|
||||||
|
static AsyncReply<ResourceTemplate> getTemplateByClassId(Guid classId)
|
||||||
|
{
|
||||||
|
if (_templates.containsKey(classId))
|
||||||
|
return new AsyncReply<ResourceTemplate>.ready(_templates[classId]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a template by class name from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="className">Class name.</param>
|
||||||
|
/// <returns>Resource template.</returns>
|
||||||
|
static AsyncReply<ResourceTemplate> getTemplateByClassName(String className)
|
||||||
|
{
|
||||||
|
for (var t in _templates.values)
|
||||||
|
if (t.className == className)
|
||||||
|
return new AsyncReply<ResourceTemplate>.ready(t);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool remove(IResource resource)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (resource.instance == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (_resources.containsKey(resource.instance.id))
|
||||||
|
_resources.remove(resource.instance.id);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (resource is IStore)
|
||||||
|
{
|
||||||
|
_stores.remove(resource);
|
||||||
|
|
||||||
|
// remove all objects associated with the store
|
||||||
|
var toBeRemoved = _resources.values.where((x) => x.instance.store == resource);
|
||||||
|
for (var o in toBeRemoved)
|
||||||
|
remove(o);
|
||||||
|
|
||||||
|
// StoreDisconnected?.Invoke(resource as IStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource.instance.store != null)
|
||||||
|
resource.instance.store.remove(resource);
|
||||||
|
|
||||||
|
resource.destroy();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyList<String, IStore Function()> getProtocols()
|
||||||
|
{
|
||||||
|
var rt = new KeyList<String, IStore Function()>();
|
||||||
|
rt.add("iip", () => new DistributedConnection());
|
||||||
|
return rt;
|
||||||
|
}
|
48
bin/Security/Authority/Authentication.dart
Normal file
48
bin/Security/Authority/Authentication.dart
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'AuthenticationType.dart';
|
||||||
|
import 'Source.dart';
|
||||||
|
|
||||||
|
class Authentication
|
||||||
|
{
|
||||||
|
|
||||||
|
String username;
|
||||||
|
//Certificate certificate;
|
||||||
|
String domain;
|
||||||
|
|
||||||
|
String get fullName => username + "@" + domain;
|
||||||
|
int state;
|
||||||
|
|
||||||
|
Source source = new Source();
|
||||||
|
|
||||||
|
|
||||||
|
final AuthenticationType type;
|
||||||
|
|
||||||
|
Authentication(this.type)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
34
bin/Security/Authority/AuthenticationState.dart
Normal file
34
bin/Security/Authority/AuthenticationState.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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 AuthenticationState
|
||||||
|
{
|
||||||
|
static const int Denied = 0x1;
|
||||||
|
static const int Succeeded = 0x2;
|
||||||
|
static const int Blocked = 0x4;
|
||||||
|
static const int Rejected = 0x8;
|
||||||
|
static const int NeedsUpdate = 0x10;
|
||||||
|
static const int NotFound = 0x20;
|
||||||
|
}
|
31
bin/Security/Authority/AuthenticationType.dart
Normal file
31
bin/Security/Authority/AuthenticationType.dart
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum AuthenticationType
|
||||||
|
{
|
||||||
|
Host,
|
||||||
|
CoHost,
|
||||||
|
Client,
|
||||||
|
Alien
|
||||||
|
}
|
34
bin/Security/Authority/ClientAuthentication.dart
Normal file
34
bin/Security/Authority/ClientAuthentication.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import 'Authentication.dart';
|
||||||
|
import 'AuthenticationType.dart';
|
||||||
|
|
||||||
|
class ClientAuthentication extends Authentication
|
||||||
|
{
|
||||||
|
ClientAuthentication()
|
||||||
|
:super(AuthenticationType.Client)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
34
bin/Security/Authority/CoHostAuthentication.dart
Normal file
34
bin/Security/Authority/CoHostAuthentication.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import 'Authentication.dart';
|
||||||
|
import 'AuthenticationType.dart';
|
||||||
|
|
||||||
|
class CoHostAuthentication extends Authentication
|
||||||
|
{
|
||||||
|
CoHostAuthentication()
|
||||||
|
:super(AuthenticationType.Client)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
34
bin/Security/Authority/HostAuthentication.dart
Normal file
34
bin/Security/Authority/HostAuthentication.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import 'Authentication.dart';
|
||||||
|
import 'AuthenticationType.dart';
|
||||||
|
|
||||||
|
class HostAuthentication extends Authentication
|
||||||
|
{
|
||||||
|
HostAuthentication()
|
||||||
|
:super(AuthenticationType.Client)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
54
bin/Security/Authority/Session.dart
Normal file
54
bin/Security/Authority/Session.dart
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import '../../Data/DC.dart';
|
||||||
|
import 'Authentication.dart';
|
||||||
|
import '../../Data/KeyList.dart';
|
||||||
|
|
||||||
|
class Session
|
||||||
|
{
|
||||||
|
Authentication get localAuthentication => _localAuth;
|
||||||
|
Authentication get remoteAuthentication => _remoteAuth;
|
||||||
|
|
||||||
|
// public Source Source { get; }
|
||||||
|
DC id;
|
||||||
|
|
||||||
|
//DateTime get creation => _creation;
|
||||||
|
|
||||||
|
//public DateTime Modification { get; }
|
||||||
|
final KeyList<String, dynamic> variables = new KeyList<String, dynamic>();
|
||||||
|
|
||||||
|
//KeyList<string, object> Variables { get; }
|
||||||
|
//IStore Store { get; }
|
||||||
|
|
||||||
|
//string id;
|
||||||
|
Authentication _localAuth, _remoteAuth;
|
||||||
|
|
||||||
|
|
||||||
|
Session(Authentication localAuthentication, Authentication remoteAuthentication)
|
||||||
|
{
|
||||||
|
|
||||||
|
this._localAuth = localAuthentication;
|
||||||
|
this._remoteAuth = remoteAuthentication;
|
||||||
|
}
|
||||||
|
}
|
46
bin/Security/Authority/Source.dart
Normal file
46
bin/Security/Authority/Source.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import '../../Data/KeyList.dart';
|
||||||
|
import 'SourceAttributeType.dart';
|
||||||
|
|
||||||
|
class Source
|
||||||
|
{
|
||||||
|
|
||||||
|
//string id;
|
||||||
|
String id;
|
||||||
|
|
||||||
|
KeyList<SourceAttributeType, dynamic> attributes;
|
||||||
|
|
||||||
|
Source.from(this.id, this.attributes)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Source()
|
||||||
|
{
|
||||||
|
attributes = new KeyList<SourceAttributeType, dynamic>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
bin/Security/Authority/SourceAttributeType.dart
Normal file
42
bin/Security/Authority/SourceAttributeType.dart
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
enum SourceAttributeType
|
||||||
|
{
|
||||||
|
Mobility, // Stationary/Mobile
|
||||||
|
CPU, // Arc, Speed, Cores
|
||||||
|
IPv4, // IPv4, IPv6 Address
|
||||||
|
IPv6, // IPv4, IPv6 Address
|
||||||
|
Port, // TCP or UDP port
|
||||||
|
Proxy, // Proxy
|
||||||
|
Route, // Trace Root
|
||||||
|
Location, // Lon, Lat, Alt, Accuracy
|
||||||
|
OS, // OS name, version, distro, kernel
|
||||||
|
Application, // lib version, app version
|
||||||
|
Network, // Bandwidth, MAC, IP, Route
|
||||||
|
Display, // Screen WxH
|
||||||
|
Media, // AudioIn, AudioOut, VideoIn,
|
||||||
|
Identity, // IMEI, IMSI, Manufacture
|
||||||
|
}
|
160
bin/Security/Integrity/SHA256.dart
Normal file
160
bin/Security/Integrity/SHA256.dart
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import '../../Data/DC.dart';
|
||||||
|
import '../../Data/BinaryList.dart';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
class SHA256
|
||||||
|
{
|
||||||
|
|
||||||
|
static int RROT(int n, int d)
|
||||||
|
{
|
||||||
|
return ZSHIFT(n, d) | (n << (32 - d));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero-fill right shift
|
||||||
|
static int ZSHIFT(int n, int d)
|
||||||
|
{
|
||||||
|
return (n & 0xFFFFFFFF) >> d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DC compute(DC msg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Note 1: All variables are 32 bit unsigned integers and addition is calculated modulo 2^32
|
||||||
|
Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 ≤ i ≤ 63
|
||||||
|
Note 3: The compression function uses 8 working variables, a through h
|
||||||
|
Note 4: Big-endian convention is used when expressing the constants in this pseudocode,
|
||||||
|
and when parsing message block data from bytes to words, for example,
|
||||||
|
the first word of the input message "abc" after padding is 0x61626380
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Initialize hash values:
|
||||||
|
// (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
|
||||||
|
|
||||||
|
var hash = new Uint32List.fromList([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f,
|
||||||
|
0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]);
|
||||||
|
|
||||||
|
// Initialize array of round constants:
|
||||||
|
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
|
||||||
|
var k = new Uint32List.fromList([
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Pre-processing:
|
||||||
|
// begin with the original message of length L bits
|
||||||
|
int L = msg.length * 8;
|
||||||
|
|
||||||
|
// append a single '1' bit
|
||||||
|
// append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 64 is a multiple of 512
|
||||||
|
|
||||||
|
var K = 512 - ((L + 1 + 64) % 512);
|
||||||
|
|
||||||
|
if (K == 512)
|
||||||
|
K = 0;
|
||||||
|
|
||||||
|
var paddingLength = (K + 1) ~/ 8;
|
||||||
|
var paddingBytes = new DC(paddingLength);
|
||||||
|
paddingBytes[0] = 0x80;
|
||||||
|
|
||||||
|
var data = new BinaryList().addDC(msg).addDC(paddingBytes).addUint64(L).toDC();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bits
|
||||||
|
|
||||||
|
// Process the message in successive 512-bit chunks:
|
||||||
|
// break message into 512-bit chunks
|
||||||
|
// for each chunk
|
||||||
|
|
||||||
|
for (var chunk = 0; chunk < data.length; chunk += 64)
|
||||||
|
{
|
||||||
|
// create a 64-entry message schedule array w[0..63] of 32-bit words
|
||||||
|
// (The initial values in w[0..63] don't matter, so many implementations zero them here)
|
||||||
|
// copy chunk into first 16 words w[0..15] of the message schedule array
|
||||||
|
|
||||||
|
var w = new Uint64List(64);// uint[64];
|
||||||
|
for (var i = 0; i < 16; i++)
|
||||||
|
w[i] = data.getUint32(chunk + (i * 4));
|
||||||
|
|
||||||
|
//for(var i = 16; i < 64; i++)
|
||||||
|
// w[i] = 0;
|
||||||
|
|
||||||
|
// Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array:
|
||||||
|
// for i from 16 to 63
|
||||||
|
// s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)
|
||||||
|
// s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)
|
||||||
|
// w[i] := w[i-16] + s0 + w[i-7] + s1
|
||||||
|
|
||||||
|
for (var i = 16; i < 64; i++)
|
||||||
|
{
|
||||||
|
var s0 = SHA256.RROT(w[i - 15], 7) ^ SHA256.RROT(w[i - 15], 18) ^ ZSHIFT(w[i - 15], 3);
|
||||||
|
var s1 = SHA256.RROT(w[i - 2], 17) ^ SHA256.RROT(w[i - 2], 19) ^ ZSHIFT(w[i - 2], 10);
|
||||||
|
w[i] = w[i - 16] + s0 + w[i - 7] + s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize working variables to current hash value:
|
||||||
|
var a = hash[0];
|
||||||
|
var b = hash[1];
|
||||||
|
var c = hash[2];
|
||||||
|
var d = hash[3];
|
||||||
|
var e = hash[4];
|
||||||
|
var f = hash[5];
|
||||||
|
var g = hash[6];
|
||||||
|
var h = hash[7];
|
||||||
|
|
||||||
|
|
||||||
|
// Compression function main loop:
|
||||||
|
for (var i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
var S1 = SHA256.RROT(e, 6) ^ SHA256.RROT(e, 11) ^ SHA256.RROT(e, 25);
|
||||||
|
var ch = (e & f) ^ ((~e) & g);
|
||||||
|
var temp1 = h + S1 + ch + k[i] + w[i];
|
||||||
|
var S0 = SHA256.RROT(a, 2) ^ SHA256.RROT(a, 13) ^ SHA256.RROT(a, 22);
|
||||||
|
var maj = (a & b) ^ (a & c) ^ (b & c);
|
||||||
|
int temp2 = S0 + maj;
|
||||||
|
|
||||||
|
h = g;
|
||||||
|
g = f;
|
||||||
|
f = e;
|
||||||
|
e = ZSHIFT(d + temp1, 0);
|
||||||
|
d = c;
|
||||||
|
c = b;
|
||||||
|
b = a;
|
||||||
|
a = ZSHIFT(temp1 + temp2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the compressed chunk to the current hash value:
|
||||||
|
|
||||||
|
hash[0] = ZSHIFT(hash[0] + a, 0);
|
||||||
|
hash[1] = ZSHIFT(hash[1] + b , 0);
|
||||||
|
hash[2] = ZSHIFT(hash[2] + c , 0);
|
||||||
|
hash[3] = ZSHIFT(hash[3] + d , 0);
|
||||||
|
hash[4] = ZSHIFT(hash[4] + e , 0);
|
||||||
|
hash[5] = ZSHIFT(hash[5] + f , 0);
|
||||||
|
hash[6] = ZSHIFT(hash[6] + g , 0);
|
||||||
|
hash[7] = ZSHIFT(hash[7] + h, 0);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Produce the final hash value (big-endian):
|
||||||
|
//digest := hash := h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
|
||||||
|
|
||||||
|
var results = new BinaryList();
|
||||||
|
for (var i = 0; i < 8; i++)
|
||||||
|
results.addUint32(hash[i]);
|
||||||
|
|
||||||
|
|
||||||
|
return results.toDC();
|
||||||
|
}
|
||||||
|
}
|
40
bin/Security/Permissions/ActionType.dart
Normal file
40
bin/Security/Permissions/ActionType.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2019 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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
enum ActionType
|
||||||
|
{
|
||||||
|
Attach,
|
||||||
|
Delete,
|
||||||
|
Execute,
|
||||||
|
GetProperty,
|
||||||
|
SetProperty,
|
||||||
|
CreateResource,
|
||||||
|
UpdateAttributes,
|
||||||
|
InquireAttributes,
|
||||||
|
AddParent,
|
||||||
|
RemoveParent,
|
||||||
|
AddChild,
|
||||||
|
RemoveChild,
|
||||||
|
Rename,
|
||||||
|
ReceiveEvent
|
||||||
|
}
|
48
bin/Security/Permissions/IPermissionsManager.dart
Normal file
48
bin/Security/Permissions/IPermissionsManager.dart
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'Ruling.dart';
|
||||||
|
import 'ActionType.dart';
|
||||||
|
import '../../Data/Structure.dart';
|
||||||
|
import '../../Resource/IResource.dart';
|
||||||
|
import '../Authority/Session.dart';
|
||||||
|
import '../../Resource/Template/MemberTemplate.dart';
|
||||||
|
|
||||||
|
abstract class IPermissionsManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Check for permission.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="resource">IResource.</param>
|
||||||
|
/// <param name="session">Caller sessions.</param>
|
||||||
|
/// <param name="action">Action type</param>
|
||||||
|
/// <param name="member">Function, property or event to check for permission.</param>
|
||||||
|
/// <param name="inquirer">Permission inquirer object.</param>
|
||||||
|
/// <returns>Allowed or denined.</returns>
|
||||||
|
Ruling applicable(IResource resource, Session session, ActionType action, MemberTemplate member, [dynamic inquirer = null]);
|
||||||
|
|
||||||
|
bool initialize(Structure settings, IResource resource);
|
||||||
|
|
||||||
|
Structure get settings;
|
||||||
|
}
|
6
bin/Security/Permissions/Ruling.dart
Normal file
6
bin/Security/Permissions/Ruling.dart
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
enum Ruling
|
||||||
|
{
|
||||||
|
Denied,
|
||||||
|
Allowed,
|
||||||
|
DontCare
|
||||||
|
}
|
2
bin/esiur.dart
Normal file
2
bin/esiur.dart
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export 'Resource/Warehouse.dart';
|
||||||
|
|
24
bin/main.dart
Normal file
24
bin/main.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//import 'Net/IIP/DistributedConnection.dart';
|
||||||
|
//import 'Resource/Warehouse.dart';
|
||||||
|
|
||||||
|
import 'esiur.dart';
|
||||||
|
|
||||||
|
main() async
|
||||||
|
{
|
||||||
|
var x = await Warehouse.get("iip://localhost:5000/db/my", {"username": "demo", "password": "1234"});//.then((x){
|
||||||
|
|
||||||
|
// get property
|
||||||
|
print(x.Level);
|
||||||
|
// listen to event
|
||||||
|
x.on("LevelUp", (v,y,z)=>print("Level up ${v} ${y}${z}"));
|
||||||
|
// use await
|
||||||
|
print("Added successfully ${await x.Add(40)}");
|
||||||
|
// use named arguments
|
||||||
|
await x.Add(value: 20);
|
||||||
|
// test chunks
|
||||||
|
x.Stream(10).chunk((c)=>print(c));
|
||||||
|
x.Level += 900;
|
||||||
|
|
||||||
|
print("Done");
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user