mirror of
				https://github.com/esiur/esiur-dart.git
				synced 2025-10-31 07:41:34 +00:00 
			
		
		
		
	null-safety
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,18 +1,11 @@ | ||||
| import 'DistributedConnection.dart'; | ||||
| class DistributedPropertyContext | ||||
| { | ||||
|     dynamic value; | ||||
|     DistributedConnection connection; | ||||
|     dynamic Function(DistributedConnection) method; | ||||
|  | ||||
| class DistributedPropertyContext { | ||||
|   dynamic value; | ||||
|   DistributedConnection? connection; | ||||
|   dynamic Function(DistributedConnection)? method; | ||||
|  | ||||
|     DistributedPropertyContext(this.method) | ||||
|     { | ||||
|   DistributedPropertyContext(this.method) {} | ||||
|  | ||||
|     } | ||||
|  | ||||
|     DistributedPropertyContext.setter(this.value, this.connection) | ||||
|     { | ||||
|  | ||||
|     } | ||||
|   DistributedPropertyContext.setter(this.value, this.connection) {} | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,9 @@ SOFTWARE. | ||||
|  | ||||
| */ | ||||
|  | ||||
|  | ||||
| import '../../Resource/Instance.dart'; | ||||
|  | ||||
| import '../../Core/AsyncException.dart'; | ||||
| import '../../Core/ErrorType.dart'; | ||||
| import '../../Core/ExceptionCode.dart'; | ||||
| @@ -40,18 +43,17 @@ import '../Packets/IIPPacketAction.dart'; | ||||
|  | ||||
| import '../../Resource/Template/EventTemplate.dart'; | ||||
|  | ||||
|  | ||||
| class DistributedResource extends IResource { | ||||
|   int _instanceId; | ||||
|   DistributedConnection _connection; | ||||
|   int? _instanceId; | ||||
|   DistributedConnection? _connection; | ||||
|  | ||||
|   bool _attached = false; | ||||
|   //bool _isReady = false; | ||||
|  | ||||
|   String _link; | ||||
|   int _age; | ||||
|   String? _link; | ||||
|   int? _age; | ||||
|  | ||||
|   List _properties; | ||||
|   List _properties = []; | ||||
|   bool _destroyed = false; | ||||
|  | ||||
|   List<KeyValuePair<int, dynamic>> _queued_updates = []; | ||||
| @@ -59,17 +61,17 @@ class DistributedResource extends IResource { | ||||
|   /// <summary> | ||||
|   /// Connection responsible for the distributed resource. | ||||
|   /// </summary> | ||||
|   DistributedConnection get connection => _connection; | ||||
|   DistributedConnection? get connection => _connection; | ||||
|  | ||||
|   /// <summary> | ||||
|   /// Resource link | ||||
|   /// </summary> | ||||
|   String get link => _link; | ||||
|   String? get link => _link; | ||||
|  | ||||
|   /// <summary> | ||||
|   /// Instance Id given by the other end. | ||||
|   /// </summary> | ||||
|   int get id => _instanceId; | ||||
|   int? get id => _instanceId; | ||||
|  | ||||
|   //bool get destroyed => _destroyed; | ||||
|  | ||||
| @@ -84,7 +86,7 @@ class DistributedResource extends IResource { | ||||
|   void destroy() { | ||||
|     _destroyed = true; | ||||
|     _attached = false; | ||||
|     _connection.sendDetachRequest(_instanceId); | ||||
|     _connection?.sendDetachRequest(_instanceId as int); | ||||
|     emitArgs("destroy", [this]); | ||||
|   } | ||||
|  | ||||
| @@ -137,13 +139,19 @@ class DistributedResource extends IResource { | ||||
|   /// </summary> | ||||
|   /// <returns></returns> | ||||
|   List<PropertyValue> internal_serialize() { | ||||
|     var props = new List<PropertyValue>(_properties.length); | ||||
|     // var props = _properties as List; | ||||
|     // var rt = List<PropertyValue>(_properties.length); | ||||
|  | ||||
|     for (var i = 0; i < _properties.length; i++) | ||||
|       props[i] = new PropertyValue( | ||||
|           _properties[i], instance.getAge(i), instance.getModificationDate(i)); | ||||
|     // for (var i = 0; i < _properties.length; i++) | ||||
|     //   rt[i] = new PropertyValue(_properties[i], instance?.getAge(i) as int, | ||||
|     //       instance?.getModificationDate(i) as DateTime); | ||||
|  | ||||
|     return props; | ||||
|     return List<PropertyValue>.generate( | ||||
|         _properties.length, | ||||
|         (i) => PropertyValue(_properties[i], instance?.getAge(i) as int, | ||||
|             instance?.getModificationDate(i) as DateTime)); | ||||
|  | ||||
|     //return rt; | ||||
|   } | ||||
|  | ||||
|   bool internal_attach(List<PropertyValue> properties) { | ||||
| @@ -152,14 +160,16 @@ class DistributedResource extends IResource { | ||||
|     else { | ||||
|       _suspended = false; | ||||
|  | ||||
|       _properties = new List(properties.length); // object[properties.Length]; | ||||
|       //_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; | ||||
|         instance?.setAge(i, properties[i].age); | ||||
|         instance?.setModificationDate(i, properties[i].date); | ||||
|  | ||||
|         _properties.add(properties[i].value); | ||||
|         //_properties[i] = properties[i].value; | ||||
|       } | ||||
|  | ||||
|       // trigger holded events/property updates. | ||||
| @@ -180,9 +190,12 @@ class DistributedResource extends IResource { | ||||
|   } | ||||
|  | ||||
|   AsyncReply<dynamic> listen(event) { | ||||
|     EventTemplate et = event is EventTemplate | ||||
|     if (_destroyed) throw new Exception("Trying to access destroyed object"); | ||||
|     if (_suspended) throw new Exception("Trying to access suspended object"); | ||||
|  | ||||
|     EventTemplate? et = event is EventTemplate | ||||
|         ? event | ||||
|         : instance.template.getEventTemplateByName(event); | ||||
|         : instance?.template.getEventTemplateByName(event); | ||||
|  | ||||
|     if (et == null) | ||||
|       return AsyncReply<dynamic>().triggerError(new AsyncException( | ||||
| @@ -192,13 +205,17 @@ class DistributedResource extends IResource { | ||||
|       return AsyncReply().triggerError(new AsyncException( | ||||
|           ErrorType.Management, ExceptionCode.NotListenable.index, "")); | ||||
|  | ||||
|     return _connection.sendListenRequest(_instanceId, et.index); | ||||
|     return _connection?.sendListenRequest(_instanceId as int, et.index) | ||||
|         as AsyncReply; | ||||
|   } | ||||
|  | ||||
|   AsyncReply<dynamic> unlisten(event) { | ||||
|     EventTemplate et = event is EventTemplate | ||||
|     if (_destroyed) throw new Exception("Trying to access destroyed object"); | ||||
|     if (_suspended) throw new Exception("Trying to access suspended object"); | ||||
|  | ||||
|     EventTemplate? et = event is EventTemplate | ||||
|         ? event | ||||
|         : instance.template.getEventTemplateByName(event); | ||||
|         : instance?.template.getEventTemplateByName(event); | ||||
|  | ||||
|     if (et == null) | ||||
|       return AsyncReply().triggerError(new AsyncException( | ||||
| @@ -208,48 +225,60 @@ class DistributedResource extends IResource { | ||||
|       return AsyncReply().triggerError(new AsyncException( | ||||
|           ErrorType.Management, ExceptionCode.NotListenable.index, "")); | ||||
|  | ||||
|     return connection.sendUnlistenRequest(_instanceId, et.index); | ||||
|     return connection?.sendUnlistenRequest(_instanceId as int, et.index) | ||||
|         as AsyncReply; | ||||
|   } | ||||
|  | ||||
|   void internal_emitEventByIndex(int index, dynamic args) { | ||||
|     // neglect events when the object is not yet attached | ||||
|     if (!_attached) return; | ||||
|  | ||||
|     var et = instance.template.getEventTemplateByIndex(index); | ||||
|     emitArgs(et.name, [args]); | ||||
|     //emitArgs(event, arguments) | ||||
|     instance.emitResourceEvent(null, null, et.name, args); | ||||
|     var et = instance?.template.getEventTemplateByIndex(index); | ||||
|     if (et != null) { | ||||
|       emitArgs(et.name, [args]); | ||||
|       instance?.emitResourceEvent(null, null, et.name, args); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   AsyncReply<dynamic> internal_invokeByNamedArguments(int index, Structure namedArgs) { | ||||
|   AsyncReply<dynamic> internal_invokeByNamedArguments( | ||||
|       int index, Structure namedArgs) { | ||||
|     if (_destroyed) throw new Exception("Trying to access destroyed object"); | ||||
|     if (_suspended) throw new Exception("Trying to access suspended object"); | ||||
|  | ||||
|     if (instance == null) throw Exception("Object not initialized."); | ||||
|  | ||||
|     var ins = instance as Instance; | ||||
|  | ||||
|     if (index >= ins.template.functions.length) | ||||
|       throw new Exception("Function index is incorrect"); | ||||
|  | ||||
|     return connection?.sendInvokeByNamedArguments( | ||||
|         _instanceId as int, index, namedArgs) as AsyncReply<dynamic>; | ||||
|   } | ||||
|  | ||||
|   AsyncReply<dynamic> internal_invokeByArrayArguments( | ||||
|       int index, List<dynamic> args) { | ||||
|     if (_destroyed) throw new Exception("Trying to access destroyed object"); | ||||
|  | ||||
|     if (_suspended) throw new Exception("Trying to access suspended object"); | ||||
|     if (instance == null) throw Exception("Object not initialized."); | ||||
|  | ||||
|     if (index >= instance.template.functions.length) | ||||
|     var ins = instance as Instance; | ||||
|  | ||||
|     if (index >= ins.template.functions.length) | ||||
|       throw new Exception("Function index is incorrect"); | ||||
|  | ||||
|     return connection.sendInvokeByNamedArguments(_instanceId, index, namedArgs); | ||||
|   } | ||||
|  | ||||
|   AsyncReply<dynamic> internal_invokeByArrayArguments(int index, List<dynamic> args) { | ||||
|     if (_destroyed) throw new Exception("Trying to access destroyed object"); | ||||
|  | ||||
|     if (_suspended) throw new Exception("Trying to access suspended object"); | ||||
|  | ||||
|     if (index >= instance.template.functions.length) | ||||
|       throw new Exception("Function index is incorrect"); | ||||
|  | ||||
|     return connection.sendInvokeByArrayArguments(_instanceId, index, args); | ||||
|     return _connection?.sendInvokeByArrayArguments( | ||||
|         _instanceId as int, index, args) as AsyncReply; | ||||
|   } | ||||
|  | ||||
|   operator [](String index) { | ||||
|     var pt = instance.template.getPropertyTemplateByName(index); | ||||
|     var pt = instance?.template.getPropertyTemplateByName(index); | ||||
|     if (pt != null) return get(pt.index); | ||||
|   } | ||||
|  | ||||
|   operator []=(String index, value) { | ||||
|     var pt = instance.template.getPropertyTemplateByName(index); | ||||
|     var pt = instance?.template.getPropertyTemplateByName(index); | ||||
|     if (pt != null) set(pt.index, value); | ||||
|   } | ||||
|  | ||||
| @@ -266,7 +295,7 @@ class DistributedResource extends IResource { | ||||
|     var memberName = _getMemberName(invocation.memberName); | ||||
|  | ||||
|     if (invocation.isMethod) { | ||||
|       var ft = instance.template.getFunctionTemplateByName(memberName); | ||||
|       var ft = instance?.template.getFunctionTemplateByName(memberName); | ||||
|  | ||||
|       if (_attached && ft != null) { | ||||
|         if (invocation.namedArguments.length > 0) { | ||||
| @@ -281,14 +310,14 @@ class DistributedResource extends IResource { | ||||
|         } | ||||
|       } | ||||
|     } else if (invocation.isSetter) { | ||||
|       var pt = instance.template.getPropertyTemplateByName(memberName); | ||||
|       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); | ||||
|       var pt = instance?.template.getPropertyTemplateByName(memberName); | ||||
|  | ||||
|       if (pt != null) { | ||||
|         return get(pt.index); | ||||
| @@ -304,7 +333,9 @@ class DistributedResource extends IResource { | ||||
|   /// <param name="index">Zero-based property index.</param> | ||||
|   /// <returns>Value</returns> | ||||
|   get(int index) { | ||||
|     if (index >= _properties.length) return null; | ||||
|     //if (_properties == null) return null; | ||||
|     //var props = _properties as List; | ||||
|     //if (index >= props.length) return null; | ||||
|     return _properties[index]; | ||||
|   } | ||||
|  | ||||
| @@ -312,9 +343,12 @@ class DistributedResource extends IResource { | ||||
|     if (!_attached) { | ||||
|       _queued_updates.add(KeyValuePair(index, value)); | ||||
|     } else { | ||||
|       var pt = instance.template.getPropertyTemplateByIndex(index); | ||||
|       _properties[index] = value; | ||||
|       instance.emitModification(pt, value); | ||||
|       var pt = instance?.template.getPropertyTemplateByIndex(index); | ||||
|  | ||||
|       if (pt != null) { | ||||
|         _properties[index] = value; | ||||
|         instance?.emitModification(pt, value); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -325,23 +359,24 @@ class DistributedResource extends IResource { | ||||
|   /// <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; | ||||
|     if (index >= _properties.length) | ||||
|       throw Exception("Property with index `${index}` not found."); | ||||
|  | ||||
|     var reply = new AsyncReply<dynamic>(); | ||||
|     var con = _connection as DistributedConnection; | ||||
|  | ||||
|     var parameters = Codec.compose(value, connection); | ||||
|     connection | ||||
|         .sendRequest(IIPPacketAction.SetProperty) | ||||
|         .addUint32(_instanceId) | ||||
|         .addUint8(index) | ||||
|         .addDC(parameters) | ||||
|     var parameters = Codec.compose(value, con); | ||||
|     (con.sendRequest(IIPPacketAction.SetProperty) | ||||
|           ..addUint32(_instanceId as int) | ||||
|           ..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); | ||||
|     }); | ||||
|           ..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; | ||||
|   } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ class DistributedServer extends IResource { | ||||
|     return AsyncReply.ready(true); | ||||
|   } | ||||
|  | ||||
|   EntryPoint entryPoint; | ||||
|   EntryPoint? entryPoint; | ||||
|  | ||||
|   @override | ||||
|   getProperty(String name) => null; | ||||
|   | ||||
| @@ -25,110 +25,82 @@ SOFTWARE. | ||||
| import '../Data/DC.dart'; | ||||
| import 'dart:core'; | ||||
|  | ||||
| class NetworkBuffer | ||||
| { | ||||
|     DC _data; | ||||
| class NetworkBuffer { | ||||
|   DC _data = new DC(0); | ||||
|  | ||||
|     int _neededDataLength = 0; | ||||
|      | ||||
|     NetworkBuffer() | ||||
|     { | ||||
|   int _neededDataLength = 0; | ||||
|  | ||||
|   NetworkBuffer() {} | ||||
|  | ||||
|   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); | ||||
|     } | ||||
|  | ||||
|     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; | ||||
|             } | ||||
|         } | ||||
|         //} | ||||
|  | ||||
|         _neededDataLength = 0; | ||||
|         return rt; | ||||
|       } else { | ||||
|         return null; | ||||
|       } | ||||
| } | ||||
|     } | ||||
|     //} | ||||
|  | ||||
|     return rt; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -32,9 +32,9 @@ import '../Data/DC.dart'; | ||||
| import 'Sockets/IPEndPoint.dart'; | ||||
|  | ||||
| class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|   ISocket _sock; | ||||
|   ISocket? _sock; | ||||
|  | ||||
|   DateTime _lastAction; | ||||
|   DateTime _lastAction = DateTime.now(); | ||||
|  | ||||
|   //public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data); | ||||
|   //public delegate void ConnectionClosedEvent(NetworkConnection sender); | ||||
| @@ -48,7 +48,6 @@ class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|  | ||||
|   bool _processing = false; | ||||
|  | ||||
|  | ||||
|   void destroy() { | ||||
|     // if (connected) | ||||
|     close(); | ||||
| @@ -58,7 +57,7 @@ class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|  | ||||
|   NetworkConnection() {} | ||||
|  | ||||
|   ISocket get socket => _sock; | ||||
|   ISocket? get socket => _sock; | ||||
|  | ||||
|   void assign(ISocket socket) { | ||||
|     _lastAction = DateTime.now(); | ||||
| @@ -71,14 +70,14 @@ class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|     //socket.on("connect", socket_OnConnect); | ||||
|   } | ||||
|  | ||||
|   ISocket unassign() { | ||||
|   ISocket? unassign() { | ||||
|     if (_sock != null) { | ||||
|       // connected = false; | ||||
|       // _sock.off("close", socket_OnClose); | ||||
|       // _sock.off("connect", socket_OnConnect); | ||||
|       // _sock.off("receive", socket_OnReceive); | ||||
|  | ||||
|       _sock.receiver = null; | ||||
|       _sock?.receiver = null; | ||||
|       var rt = _sock; | ||||
|       _sock = null; | ||||
|  | ||||
| @@ -92,17 +91,13 @@ class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|     emitArgs("dataReceived", [data]); | ||||
|   } | ||||
|  | ||||
|   void connected(){ | ||||
|   void connected() {} | ||||
|  | ||||
|   } | ||||
|  | ||||
|   void disconnected(){ | ||||
|  | ||||
|   } | ||||
|   void disconnected() {} | ||||
|  | ||||
|   void close() { | ||||
|     try { | ||||
|       if (_sock != null) _sock.close(); | ||||
|       if (_sock != null) _sock?.close(); | ||||
|     } catch (ex) { | ||||
|       //Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString()); | ||||
|  | ||||
| @@ -111,17 +106,17 @@ class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|  | ||||
|   DateTime get lastAction => _lastAction; | ||||
|  | ||||
|   IPEndPoint get remoteEndPoint => _sock?.remoteEndPoint; | ||||
|   IPEndPoint? get remoteEndPoint => _sock?.remoteEndPoint; | ||||
|  | ||||
|   IPEndPoint get localEndPoint => _sock?.localEndPoint; | ||||
|   IPEndPoint? get localEndPoint => _sock?.localEndPoint; | ||||
|  | ||||
|   bool get isConnected => _sock.state == SocketState.Established; | ||||
|   bool get isConnected => _sock?.state == SocketState.Established; | ||||
|  | ||||
|   void send(DC msg) { | ||||
|     try { | ||||
|       if (_sock != null) { | ||||
|         _lastAction = DateTime.now(); | ||||
|         _sock.send(msg); | ||||
|         _sock?.send(msg); | ||||
|       } | ||||
|     } catch (ex) { | ||||
|       //Console.WriteLine(ex.ToString()); | ||||
| @@ -151,8 +146,8 @@ class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> { | ||||
|       if (_sock == null) return; | ||||
|  | ||||
|       // Closed ? | ||||
|       if (_sock.state == SocketState.Closed || | ||||
|           _sock.state == SocketState.Terminated) // || !connected) | ||||
|       if (_sock?.state == SocketState.Closed || | ||||
|           _sock?.state == SocketState.Terminated) // || !connected) | ||||
|         return; | ||||
|  | ||||
|       _lastAction = DateTime.now(); | ||||
|   | ||||
| @@ -26,276 +26,215 @@ import 'IIPAuthPacketAction.dart'; | ||||
| import 'IIPAuthPacketCommand.dart'; | ||||
| import '../../Security/Authority/AuthenticationMethod.dart'; | ||||
|  | ||||
| class IIPAuthPacket | ||||
| { | ||||
| class IIPAuthPacket { | ||||
|   int command = 0; | ||||
|   int action = 0; | ||||
|  | ||||
|     int command; | ||||
|     int action; | ||||
|   int errorCode = 0; | ||||
|   String errorMessage = ""; | ||||
|  | ||||
|     int errorCode; | ||||
|     String errorMessage; | ||||
|   AuthenticationMethod localMethod = AuthenticationMethod.None; | ||||
|  | ||||
|     AuthenticationMethod localMethod; | ||||
|   DC? sourceInfo; | ||||
|  | ||||
|     DC sourceInfo; | ||||
|   DC? hash; | ||||
|  | ||||
|     DC hash; | ||||
|   DC? sessionId; | ||||
|  | ||||
|     DC sessionId; | ||||
|   AuthenticationMethod remoteMethod = AuthenticationMethod.None; | ||||
|  | ||||
|     AuthenticationMethod remoteMethod; | ||||
|   String? domain; | ||||
|  | ||||
|     String domain; | ||||
|   int certificateId = 0; | ||||
|  | ||||
|     int certificateId; | ||||
|   String? localUsername; | ||||
|  | ||||
|     String localUsername; | ||||
|   String? remoteUsername; | ||||
|  | ||||
|     String remoteUsername; | ||||
|   DC? localPassword; | ||||
|  | ||||
|     DC localPassword; | ||||
|   DC? remotePassword; | ||||
|  | ||||
|     DC remotePassword; | ||||
|   DC? localToken; | ||||
|  | ||||
|     DC localToken; | ||||
|   DC? remoteToken; | ||||
|  | ||||
|     DC remoteToken; | ||||
|   DC? asymetricEncryptionKey; | ||||
|  | ||||
|     DC asymetricEncryptionKey; | ||||
|   DC? localNonce; | ||||
|  | ||||
|     DC localNonce; | ||||
|   DC? remoteNonce; | ||||
|  | ||||
|     DC remoteNonce; | ||||
|   int remoteTokenIndex = 0; | ||||
|  | ||||
|     int remoteTokenIndex; | ||||
|   int _dataLengthNeeded = 0; | ||||
|  | ||||
|     int _dataLengthNeeded; | ||||
|   bool _notEnough(int offset, int ends, int needed) { | ||||
|     if (offset + needed > ends) { | ||||
|       _dataLengthNeeded = needed - (ends - offset); | ||||
|       return true; | ||||
|     } else | ||||
|       return false; | ||||
|   } | ||||
|  | ||||
|     bool _notEnough(int offset, int ends, int needed) | ||||
|     { | ||||
|         if (offset + needed > ends) | ||||
|         { | ||||
|             _dataLengthNeeded = needed - (ends - offset); | ||||
|             return true; | ||||
|   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 = AuthenticationMethod.values[((data[offset] >> 4) & 0x3)]; | ||||
|       localMethod = AuthenticationMethod.values[((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 == AuthenticationMethod.Credentials) { | ||||
|         if (localMethod == AuthenticationMethod.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; | ||||
|         } | ||||
|         else | ||||
|             return false; | ||||
|       } else if (remoteMethod == AuthenticationMethod.Token) { | ||||
|         if (localMethod == AuthenticationMethod.None) { | ||||
|           if (_notEnough(offset, ends, 40)) return -_dataLengthNeeded; | ||||
|  | ||||
|           remoteNonce = data.clip(offset, 32); | ||||
|  | ||||
|           offset += 32; | ||||
|  | ||||
|           remoteTokenIndex = data.getUint64(offset); | ||||
|           offset += 8; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       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 = AuthenticationMethod.values[((data[offset] >> 4) & 0x3)]; | ||||
|       localMethod = AuthenticationMethod.values[((data[offset] >> 2) & 0x3)]; | ||||
|       var encrypt = ((data[offset++] & 0x2) == 0x2); | ||||
|  | ||||
|       if (remoteMethod == AuthenticationMethod.None) { | ||||
|         if (localMethod == AuthenticationMethod.None) { | ||||
|           // do nothing | ||||
|         } | ||||
|       } else if (remoteMethod == AuthenticationMethod.Credentials || | ||||
|           remoteMethod == AuthenticationMethod.Token) { | ||||
|         if (localMethod == AuthenticationMethod.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; | ||||
|     } | ||||
|  | ||||
|     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 = AuthenticationMethod.values[((data[offset] >> 4) & 0x3)]; | ||||
|             localMethod = AuthenticationMethod.values[((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 == AuthenticationMethod.Credentials) | ||||
|             { | ||||
|                 if (localMethod == AuthenticationMethod.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; | ||||
|                 } | ||||
|             } | ||||
|             else if (remoteMethod == AuthenticationMethod.Token) | ||||
|             { | ||||
|                 if (localMethod == AuthenticationMethod.None) | ||||
|                 { | ||||
|                     if (_notEnough(offset, ends, 40)) | ||||
|                             return -_dataLengthNeeded; | ||||
|                      | ||||
|                     remoteNonce = data.clip(offset, 32); | ||||
|  | ||||
|                     offset += 32; | ||||
|  | ||||
|                     remoteTokenIndex = data.getUint64(offset); | ||||
|                     offset += 8; | ||||
|                  } | ||||
|             } | ||||
|  | ||||
|  | ||||
|          | ||||
|             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  = AuthenticationMethod.values[ ((data[offset] >> 4) & 0x3)]; | ||||
|             localMethod = AuthenticationMethod.values[ ((data[offset] >> 2) & 0x3)]; | ||||
|             var encrypt = ((data[offset++] & 0x2) == 0x2); | ||||
|  | ||||
|             if (remoteMethod == AuthenticationMethod.None) | ||||
|             { | ||||
|                 if (localMethod == AuthenticationMethod.None) | ||||
|                 { | ||||
|                     // do nothing | ||||
|                 } | ||||
|             } | ||||
|             else if (remoteMethod == AuthenticationMethod.Credentials | ||||
|               || remoteMethod == AuthenticationMethod.Token) | ||||
|             { | ||||
|                 if (localMethod == AuthenticationMethod.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; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|     return offset - oOffset; | ||||
|   } | ||||
| } | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -2,21 +2,16 @@ import '../Data/BinaryList.dart'; | ||||
| import '../Core/AsyncReply.dart'; | ||||
| import 'NetworkConnection.dart'; | ||||
|  | ||||
| class SendList extends BinaryList | ||||
| { | ||||
|     NetworkConnection connection; | ||||
|     AsyncReply<List<dynamic>> reply; | ||||
| class SendList extends BinaryList { | ||||
|   NetworkConnection connection; | ||||
|   AsyncReply<List<dynamic>>? reply; | ||||
|  | ||||
|     SendList(NetworkConnection connection, AsyncReply<List<dynamic>> reply) | ||||
|     { | ||||
|         this.reply = reply; | ||||
|         this.connection = connection; | ||||
|     } | ||||
|   SendList(this.connection, this.reply) {} | ||||
|  | ||||
|     @override  | ||||
|     AsyncReply<List<dynamic>> done() | ||||
|     { | ||||
|         connection.send(super.toDC()); | ||||
|         return reply; | ||||
|     } | ||||
|   @override | ||||
|   AsyncReply<List<dynamic>> done() { | ||||
|     connection.send(super.toDC()); | ||||
|  | ||||
|     return reply ?? AsyncReply.ready([]); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -37,7 +37,7 @@ abstract class ISocket extends IDestructible { | ||||
|  | ||||
|   //void send(DC message); | ||||
|  | ||||
|   INetworkReceiver<ISocket> receiver; | ||||
|   INetworkReceiver<ISocket>? receiver; | ||||
|  | ||||
|   void send(DC message, [int offset, int size]); | ||||
|   void close(); | ||||
| @@ -45,6 +45,6 @@ abstract class ISocket extends IDestructible { | ||||
|   bool begin(); | ||||
|  | ||||
|   AsyncReply<ISocket> accept(); | ||||
|   IPEndPoint remoteEndPoint; | ||||
|   IPEndPoint localEndPoint; | ||||
|   IPEndPoint? remoteEndPoint; | ||||
|   IPEndPoint? localEndPoint; | ||||
| } | ||||
|   | ||||
| @@ -37,7 +37,7 @@ import 'IPEndPoint.dart'; | ||||
| import '../../Core/AsyncReply.dart'; | ||||
|  | ||||
| class TCPSocket extends ISocket { | ||||
|   Socket sock; | ||||
|   Socket? sock; | ||||
|   NetworkBuffer receiveNetworkBuffer = new NetworkBuffer(); | ||||
|  | ||||
|   //bool asyncSending; | ||||
| @@ -61,15 +61,18 @@ class TCPSocket extends ISocket { | ||||
|     } | ||||
|     */ | ||||
|  | ||||
|   IPEndPoint _localEP, _remoteEP; | ||||
|   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); | ||||
|     if (sock != null) { | ||||
|       var s = sock as Socket; | ||||
|       _localEP = IPEndPoint(s.address.rawAddress, s.port); | ||||
|       _remoteEP = IPEndPoint(s.remoteAddress.rawAddress, s.remotePort); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
| @@ -82,7 +85,7 @@ class TCPSocket extends ISocket { | ||||
|  | ||||
|       var dc = new DC.fromList(data); | ||||
|       receiveNetworkBuffer.write(dc, 0, dc.length); | ||||
|       receiver.networkReceive(this, receiveNetworkBuffer); | ||||
|       receiver?.networkReceive(this, receiveNetworkBuffer); | ||||
|  | ||||
|       //emitArgs("receive", [receiveNetworkBuffer]); | ||||
|  | ||||
| @@ -101,7 +104,7 @@ class TCPSocket extends ISocket { | ||||
|  | ||||
|   void doneHandler() { | ||||
|     close(); | ||||
|     sock.destroy(); | ||||
|     sock?.destroy(); | ||||
|   } | ||||
|  | ||||
|   AsyncReply<bool> connect(String hostname, int port) { | ||||
| @@ -134,13 +137,13 @@ class TCPSocket extends ISocket { | ||||
|     return rt; | ||||
|   } | ||||
|  | ||||
|   IPEndPoint get localEndPoint => _localEP; | ||||
|   IPEndPoint get remoteEndPoint => _remoteEP; | ||||
|   IPEndPoint? get localEndPoint => _localEP; | ||||
|   IPEndPoint? get remoteEndPoint => _remoteEP; | ||||
|  | ||||
|   SocketState get state => _state; | ||||
|  | ||||
|   TCPSocket.fromSocket(Socket socket) { | ||||
|     sock = socket; | ||||
|   TCPSocket.fromSocket(this.sock) { | ||||
|     //sock = socket; | ||||
|     //if (socket.) | ||||
|     //  _state = SocketState.Established; | ||||
|   } | ||||
| @@ -160,8 +163,16 @@ class TCPSocket extends ISocket { | ||||
|     //emitArgs("close", []); | ||||
|   } | ||||
|  | ||||
|   void send(DC message, [int offset, int size]) { | ||||
|     if (state == SocketState.Established) sock.add(message.toList()); | ||||
|   void send(DC message, [int? offset, int? size]) { | ||||
|     if (state == SocketState.Established) { | ||||
|       if (offset != null && size == null) { | ||||
|         sock?.add(message.clip(offset, message.length - offset).toList()); | ||||
|       } else if (offset != null && size != null) { | ||||
|         sock?.add(message.clip(offset, size).toList()); | ||||
|       } else { | ||||
|         sock?.add(message.toList()); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void destroy() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user