mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-05-06 04: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