mirror of
https://github.com/inthehand/32feet.git
synced 2026-10-20 07:38:22 +08:00
146 lines
4.1 KiB
C#
146 lines
4.1 KiB
C#
// 32feet.NET - Personal Area Networking for .NET
|
|
//
|
|
// InTheHand.Net.Sockets.iOS.ExternalAccessoryNetworkStream (iOS)
|
|
//
|
|
// Copyright (c) 2018-2022 In The Hand Ltd, All rights reserved.
|
|
// This source code is licensed under the MIT License
|
|
|
|
using ExternalAccessory;
|
|
using Foundation;
|
|
using System;
|
|
using System.IO;
|
|
using System.Net.Sockets;
|
|
|
|
namespace InTheHand.Net.Sockets.iOS
|
|
{
|
|
internal class ExternalAccessoryNetworkStream : NonSocketNetworkStream
|
|
{
|
|
private NSInputStream _inputStream;
|
|
private NSOutputStream _outputStream;
|
|
private MemoryStream _outputBuffer = new MemoryStream();
|
|
private EAStreamDelegate _delegate;
|
|
private bool _streamReady = false;
|
|
|
|
internal ExternalAccessoryNetworkStream(EASession session)
|
|
{
|
|
_delegate = new EAStreamDelegate(this);
|
|
_inputStream = session.InputStream;
|
|
_outputStream = session.OutputStream;
|
|
|
|
_inputStream.Open();
|
|
_outputStream.Delegate = _delegate;
|
|
_outputStream.Schedule(NSRunLoop.Current,
|
|
#if NET6_0_OR_GREATER
|
|
NSRunLoopMode.Default
|
|
#else
|
|
NSRunLoop.NSDefaultRunLoopMode
|
|
#endif
|
|
);
|
|
_outputStream.Open();
|
|
}
|
|
|
|
internal class EAStreamDelegate : NSStreamDelegate
|
|
{
|
|
private ExternalAccessoryNetworkStream _stream;
|
|
|
|
internal EAStreamDelegate(ExternalAccessoryNetworkStream stream)
|
|
{
|
|
_stream = stream;
|
|
}
|
|
|
|
public override void HandleEvent(NSStream theStream, NSStreamEvent streamEvent)
|
|
{
|
|
if (theStream == _stream._outputStream && streamEvent == NSStreamEvent.HasSpaceAvailable)
|
|
{
|
|
_stream._streamReady = true;
|
|
_stream.Flush();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if(_inputStream is object)
|
|
{
|
|
_inputStream.Close();
|
|
_inputStream.Dispose();
|
|
_inputStream = null;
|
|
}
|
|
|
|
if(_outputStream is object)
|
|
{
|
|
_outputStream.Close();
|
|
_outputStream.Unschedule(NSRunLoop.Current,
|
|
#if NET6_0_OR_GREATER
|
|
NSRunLoopMode.Default
|
|
#else
|
|
NSRunLoop.NSDefaultRunLoopMode
|
|
#endif
|
|
);
|
|
_outputStream.Dispose();
|
|
_outputStream = null;
|
|
}
|
|
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
public override bool CanRead => true;
|
|
|
|
public override bool CanSeek => false;
|
|
|
|
public override bool CanWrite => true;
|
|
|
|
public override long Length => 0;
|
|
|
|
public override long Position { get => 0; set => throw new NotSupportedException(); }
|
|
|
|
public override void Flush()
|
|
{
|
|
if (_outputBuffer is object && _outputBuffer.Length > 0)
|
|
{
|
|
byte[] buffer = new byte[_outputBuffer.Length];
|
|
_outputBuffer.Read(buffer, 0, buffer.Length);
|
|
_outputBuffer.Dispose();
|
|
_outputBuffer = null;
|
|
_outputStream.Write(buffer);
|
|
}
|
|
}
|
|
|
|
public override int Read(byte[] buffer, int offset, int count)
|
|
{
|
|
return (int)_inputStream.Read(buffer, offset, (nuint)count);
|
|
}
|
|
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public override void SetLength(long value)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
{
|
|
if (_streamReady)
|
|
{
|
|
_outputStream.Write(buffer, offset, (nuint)count);
|
|
}
|
|
else
|
|
{
|
|
_outputBuffer.Write(buffer, offset, count);
|
|
}
|
|
}
|
|
|
|
public override bool DataAvailable
|
|
{
|
|
get
|
|
{
|
|
return _inputStream.HasBytesAvailable();
|
|
}
|
|
}
|
|
}
|
|
}
|